diff options
Diffstat (limited to 'lib/ncrypto_nss.c')
-rw-r--r-- | lib/ncrypto_nss.c | 99 |
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, ¶ms); +} + /* Asymmetric operations */ CK_RV |