|
|
dbb9a2 |
diff -up ./nss/lib/softoken/lowkey.c.pub-priv-mech ./nss/lib/softoken/lowkey.c
|
|
|
dbb9a2 |
--- ./nss/lib/softoken/lowkey.c.pub-priv-mech 2019-05-10 14:14:18.000000000 -0700
|
|
|
dbb9a2 |
+++ ./nss/lib/softoken/lowkey.c 2019-06-05 10:40:34.302002920 -0700
|
|
|
dbb9a2 |
@@ -261,6 +261,7 @@ NSSLOWKEYPublicKey *
|
|
|
dbb9a2 |
nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
|
|
|
dbb9a2 |
{
|
|
|
dbb9a2 |
NSSLOWKEYPublicKey *pubk;
|
|
|
dbb9a2 |
+ SECItem publicValue;
|
|
|
dbb9a2 |
PLArenaPool *arena;
|
|
|
dbb9a2 |
|
|
|
dbb9a2 |
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
|
|
dbb9a2 |
@@ -301,6 +302,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPr
|
|
|
dbb9a2 |
|
|
|
dbb9a2 |
pubk->arena = arena;
|
|
|
dbb9a2 |
pubk->keyType = privk->keyType;
|
|
|
dbb9a2 |
+ /* if the public key value doesn't exist, calculate it */
|
|
|
dbb9a2 |
+ if (privk->u.dsa.publicValue.len == 0) {
|
|
|
dbb9a2 |
+ rv = DH_Derive(&privk->u.dsa.params.base, &privk->u.dsa.params.prime,
|
|
|
dbb9a2 |
+ &privk->u.dsa.privateValue, &publicValue, 0);
|
|
|
dbb9a2 |
+ if (rv != SECSuccess) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue);
|
|
|
dbb9a2 |
+ SECITEM_FreeItem(&publicValue, PR_FALSE);
|
|
|
dbb9a2 |
+ if (rv != SECSuccess) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
|
|
|
dbb9a2 |
&privk->u.dsa.publicValue);
|
|
|
dbb9a2 |
if (rv != SECSuccess)
|
|
|
dbb9a2 |
@@ -327,6 +341,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPr
|
|
|
dbb9a2 |
|
|
|
dbb9a2 |
pubk->arena = arena;
|
|
|
dbb9a2 |
pubk->keyType = privk->keyType;
|
|
|
dbb9a2 |
+ /* if the public key value doesn't exist, calculate it */
|
|
|
dbb9a2 |
+ if (privk->u.dh.publicValue.len == 0) {
|
|
|
dbb9a2 |
+ rv = DH_Derive(&privk->u.dh.base, &privk->u.dh.prime,
|
|
|
dbb9a2 |
+ &privk->u.dh.privateValue, &publicValue, 0);
|
|
|
dbb9a2 |
+ if (rv != SECSuccess) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue);
|
|
|
dbb9a2 |
+ SECITEM_FreeItem(&publicValue, PR_FALSE);
|
|
|
dbb9a2 |
+ if (rv != SECSuccess) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
|
|
|
dbb9a2 |
&privk->u.dh.publicValue);
|
|
|
dbb9a2 |
if (rv != SECSuccess)
|
|
|
dbb9a2 |
diff -up ./nss/lib/softoken/pkcs11c.c.pub-priv-mech ./nss/lib/softoken/pkcs11c.c
|
|
|
dbb9a2 |
--- ./nss/lib/softoken/pkcs11c.c.pub-priv-mech 2019-06-05 10:40:34.298002922 -0700
|
|
|
dbb9a2 |
+++ ./nss/lib/softoken/pkcs11c.c 2019-06-05 10:43:38.610909153 -0700
|
|
|
dbb9a2 |
@@ -6569,6 +6569,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
|
|
dbb9a2 |
extractValue = PR_FALSE;
|
|
|
dbb9a2 |
classType = CKO_PRIVATE_KEY;
|
|
|
dbb9a2 |
break;
|
|
|
dbb9a2 |
+ case CKM_NSS_PUB_FROM_PRIV:
|
|
|
dbb9a2 |
+ extractValue = PR_FALSE;
|
|
|
dbb9a2 |
+ classType = CKO_PUBLIC_KEY;
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */
|
|
|
dbb9a2 |
case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
|
|
|
dbb9a2 |
case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
|
|
|
dbb9a2 |
@@ -6610,6 +6614,35 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
|
|
dbb9a2 |
}
|
|
|
dbb9a2 |
|
|
|
dbb9a2 |
switch (mechanism) {
|
|
|
dbb9a2 |
+ /* get a public key from a private key. nsslowkey_ConvertToPublickey()
|
|
|
dbb9a2 |
+ * will generate the public portion if it doesn't already exist. */
|
|
|
dbb9a2 |
+ case CKM_NSS_PUB_FROM_PRIV: {
|
|
|
dbb9a2 |
+ NSSLOWKEYPrivateKey *privKey;
|
|
|
dbb9a2 |
+ NSSLOWKEYPublicKey *pubKey;
|
|
|
dbb9a2 |
+ int error;
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE, &keyType);
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ /* privKey is stored in sourceKey and will be destroyed when
|
|
|
dbb9a2 |
+ * the sourceKey is freed. */
|
|
|
dbb9a2 |
+ privKey = sftk_GetPrivKey(sourceKey, keyType, &crv;;
|
|
|
dbb9a2 |
+ if (privKey == NULL) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ pubKey = nsslowkey_ConvertToPublicKey(privKey);
|
|
|
dbb9a2 |
+ if (pubKey == NULL) {
|
|
|
dbb9a2 |
+ error = PORT_GetError();
|
|
|
dbb9a2 |
+ crv = sftk_MapCryptError(error);
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey);
|
|
|
dbb9a2 |
+ nsslowkey_DestroyPublicKey(pubKey);
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
case CKM_NSS_IKE_PRF_DERIVE:
|
|
|
dbb9a2 |
if (pMechanism->ulParameterLen !=
|
|
|
dbb9a2 |
sizeof(CK_NSS_IKE_PRF_DERIVE_PARAMS)) {
|
|
|
dbb9a2 |
diff -up ./nss/lib/softoken/pkcs11.c.pub-priv-mech ./nss/lib/softoken/pkcs11.c
|
|
|
dbb9a2 |
--- ./nss/lib/softoken/pkcs11.c.pub-priv-mech 2019-06-05 10:40:34.284002929 -0700
|
|
|
dbb9a2 |
+++ ./nss/lib/softoken/pkcs11.c 2019-06-05 10:40:34.303002919 -0700
|
|
|
dbb9a2 |
@@ -2208,6 +2208,123 @@ sftk_GetPrivKey(SFTKObject *object, CK_K
|
|
|
dbb9a2 |
return priv;
|
|
|
dbb9a2 |
}
|
|
|
dbb9a2 |
|
|
|
dbb9a2 |
+/* populate a public key object from a lowpublic keys structure */
|
|
|
dbb9a2 |
+CK_RV
|
|
|
dbb9a2 |
+sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey)
|
|
|
dbb9a2 |
+{
|
|
|
dbb9a2 |
+ CK_OBJECT_CLASS classType = CKO_PUBLIC_KEY;
|
|
|
dbb9a2 |
+ CK_BBOOL cktrue = CK_TRUE;
|
|
|
dbb9a2 |
+ CK_RV crv = CKR_OK;
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_CLASS);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_VALUE);
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ switch (keyType) {
|
|
|
dbb9a2 |
+ case CKK_RSA:
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_MODULUS);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_PUBLIC_EXPONENT);
|
|
|
dbb9a2 |
+ /* format the keys */
|
|
|
dbb9a2 |
+ /* fill in the RSA dependent paramenters in the public key */
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_MODULUS,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.rsa.modulus));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK)
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_PUBLIC_EXPONENT,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.rsa.publicExponent));
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ case CKK_DSA:
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_PRIME);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_SUBPRIME);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_BASE);
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dsa.params.prime));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_SUBPRIME,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dsa.params.subPrime));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_BASE,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dsa.params.base));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dsa.publicValue));
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ case CKK_DH:
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_PRIME);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_BASE);
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dh.prime));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_BASE,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dh.base));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.dh.publicValue));
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ case CKK_EC:
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS);
|
|
|
dbb9a2 |
+ sftk_DeleteAttributeType(publicKey, CKA_EC_POINT);
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.ec.ecParams.DEREncoding));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
|
|
|
dbb9a2 |
+ sftk_item_expand(&pubKey->u.ec.publicValue));
|
|
|
dbb9a2 |
+ break;
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
+ default:
|
|
|
dbb9a2 |
+ return CKR_KEY_TYPE_INCONSISTENT;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &classType,
|
|
|
dbb9a2 |
+ sizeof(CK_OBJECT_CLASS));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK)
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &keyType,
|
|
|
dbb9a2 |
+ sizeof(CK_KEY_TYPE));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK)
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ /* now handle the operator attributes */
|
|
|
dbb9a2 |
+ if (sftk_isTrue(privateKey, CKA_DECRYPT)) {
|
|
|
dbb9a2 |
+ crv = sftk_forceAttribute(publicKey, CKA_ENCRYPT, &cktrue, sizeof(CK_BBOOL));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ if (sftk_isTrue(privateKey, CKA_SIGN)) {
|
|
|
dbb9a2 |
+ crv = sftk_forceAttribute(publicKey, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ if (sftk_isTrue(privateKey, CKA_SIGN_RECOVER)) {
|
|
|
dbb9a2 |
+ crv = sftk_forceAttribute(publicKey, CKA_VERIFY_RECOVER, &cktrue, sizeof(CK_BBOOL));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ if (sftk_isTrue(privateKey, CKA_DERIVE)) {
|
|
|
dbb9a2 |
+ crv = sftk_forceAttribute(publicKey, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
|
|
|
dbb9a2 |
+ if (crv != CKR_OK) {
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ }
|
|
|
dbb9a2 |
+ return crv;
|
|
|
dbb9a2 |
+}
|
|
|
dbb9a2 |
+
|
|
|
dbb9a2 |
/*
|
|
|
dbb9a2 |
**************************** Symetric Key utils ************************
|
|
|
dbb9a2 |
*/
|
|
|
dbb9a2 |
diff -up ./nss/lib/softoken/pkcs11i.h.pub-priv-mech ./nss/lib/softoken/pkcs11i.h
|
|
|
dbb9a2 |
--- ./nss/lib/softoken/pkcs11i.h.pub-priv-mech 2019-06-05 10:40:34.306002918 -0700
|
|
|
dbb9a2 |
+++ ./nss/lib/softoken/pkcs11i.h 2019-06-05 10:45:24.205855432 -0700
|
|
|
dbb9a2 |
@@ -695,6 +695,9 @@ extern NSSLOWKEYPublicKey *sftk_GetPubKe
|
|
|
dbb9a2 |
CK_KEY_TYPE key_type, CK_RV *crvp);
|
|
|
dbb9a2 |
extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
|
|
|
dbb9a2 |
CK_KEY_TYPE key_type, CK_RV *crvp);
|
|
|
dbb9a2 |
+extern CK_RV sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privKey,
|
|
|
dbb9a2 |
+ CK_KEY_TYPE keyType,
|
|
|
dbb9a2 |
+ NSSLOWKEYPublicKey *pubKey);
|
|
|
dbb9a2 |
extern void sftk_FormatDESKey(unsigned char *key, int length);
|
|
|
dbb9a2 |
extern PRBool sftk_CheckDESKey(unsigned char *key);
|
|
|
dbb9a2 |
extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type);
|