summaryrefslogtreecommitdiffstats
path: root/lib/ncrypto_nss.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ncrypto_nss.c')
-rw-r--r--lib/ncrypto_nss.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/ncrypto_nss.c b/lib/ncrypto_nss.c
index dfd342c..818091d 100644
--- a/lib/ncrypto_nss.c
+++ b/lib/ncrypto_nss.c
@@ -33,6 +33,7 @@ Red Hat author: Miloslav Trmač <mitr@redhat.com> */
#include <keyhi.h>
#include <nss.h>
#include <pk11pub.h>
+#include <secmodt.h>
#include <ncrypto/ncrypto.h>
@@ -652,6 +653,52 @@ ncr_private_key_destroy (struct ncr_private_key *key)
return CKR_OK;
}
+static CK_RV
+key_pair_generate (struct ncr_public_key **public_key,
+ struct ncr_private_key **private_key, CK_MECHANISM_TYPE mech,
+ bool sensitive, void *params)
+{
+ struct ncr_public_key *pub;
+ struct ncr_private_key *priv;
+ PK11SlotInfo *slot;
+
+ g_return_val_if_fail (public_key != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (private_key != NULL, CKR_ARGUMENTS_BAD);
+
+ pub = malloc (sizeof (*pub));
+ if (pub == NULL)
+ return CKR_HOST_MEMORY;
+ priv = malloc (sizeof (*priv));
+ if (priv == NULL)
+ {
+ free (pub);
+ return CKR_HOST_MEMORY;
+ }
+
+ slot = PK11_GetBestSlot (mech, NULL);
+ if (slot == NULL)
+ goto err_priv;
+
+ /* FIXME: propagate "sensitive" here? */
+ priv->key = PK11_GenerateKeyPair(slot, mech, params, &pub->key,
+ PR_FALSE /* isPerm */,
+ PR_FALSE /* sensitive */, NULL);
+ PK11_FreeSlot (slot);
+ if (priv->key == NULL)
+ goto err_priv;
+
+
+ priv->sensitive = sensitive;
+ *public_key = pub;
+ *private_key = priv;
+ return CKR_OK;
+
+ err_priv:
+ free (priv);
+ free (pub);
+ return CKR_GENERAL_ERROR;
+}
+
/* Multi-precision integers */
/* Validate SRC and use it to set up DEST for ASN.1 encoding */
@@ -925,6 +972,58 @@ ncr_private_key_export_rsa (struct ncr_private_key *key,
return res;
}
+CK_RV
+ncr_key_pair_generate_rsa (struct ncr_public_key **public_key,
+ struct ncr_private_key **private_key,
+ CK_MECHANISM_TYPE mech, _Bool sensitive,
+ CK_ULONG modulus_bits,
+ const struct ncr_mpi *public_exponent)
+{
+ PK11RSAGenParams params;
+ CK_RV res;
+
+ res = ensure_ncr_is_open ();
+ if (res != CKR_OK)
+ return res;
+
+ switch (mech)
+ {
+ case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
+ break;
+
+ default:
+ g_return_val_if_reached (CKR_MECHANISM_INVALID);
+ }
+
+ g_return_val_if_fail (modulus_bits <= INT_MAX, CKR_ARGUMENTS_BAD);
+
+ params.keySizeInBits = modulus_bits;
+ if (public_exponent == NULL)
+ params.pe = 65537;
+ else
+ {
+ unsigned long val;
+ const uint8_t *p, *end;
+
+ end = (const uint8_t *)public_exponent->data + public_exponent->size;
+ for (p = public_exponent->data; p < end && *p == 0; p++)
+ ;
+ g_return_val_if_fail ((size_t)(end - p) <= sizeof (val),
+ CKR_ARGUMENTS_BAD);
+
+ val = 0;
+ while (p < end)
+ {
+ val = (val << 8) | *p;
+ p++;
+ }
+ params.pe = val;
+ }
+
+ return key_pair_generate (public_key, private_key, mech, sensitive, &params);
+}
+
/* Asymmetric operations */
CK_RV