summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c
index e08b35086..fb3e3edd6 100644
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -749,7 +749,7 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
SECKEYPQGParams *dsaParams;
SECKEYDHParams * dhParams;
CK_MECHANISM mechanism;
- CK_MECHANISM test_mech;
+ CK_MECHANISM test_mech, test_mech2;
CK_SESSION_HANDLE session_handle;
CK_RV crv;
CK_OBJECT_HANDLE privID,pubID;
@@ -824,9 +824,14 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
mechanism.mechanism = type;
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
+
test_mech.pParameter = NULL;
test_mech.ulParameterLen = 0;
+ test_mech2.mechanism = CKM_INVALID_MECHANISM;
+ test_mech2.pParameter = NULL;
+ test_mech2.ulParameterLen = 0;
+
/* set up the private key template */
privattrs = privTemplate;
privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
@@ -894,12 +899,16 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
ecParams->len); attrs++;
pubTemplate = ecPubTemplate;
keyType = ecKey;
- /* XXX An EC key can be used for other mechanisms too such
- * as CKM_ECDSA and CKM_ECDSA_SHA1. How can we reflect
- * that in test_mech.mechanism so the CKA_SIGN, CKA_VERIFY
- * attributes are set correctly?
- */
- test_mech.mechanism = CKM_ECDH1_DERIVE;
+ /*
+ * ECC supports 2 different mechanism types (unlike RSA, which
+ * supports different usages with the same mechanism).
+ * We may need to query both mechanism types and or the results
+ * together -- but we only do that if either the user has
+ * requested both usages, or not specified any usages.
+ */
+ /* neither was specified default to both */
+ test_mech.mechanism = CKM_ECDH1_DERIVE;
+ test_mech2.mechanism = CKM_ECDSA;
break;
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
@@ -910,29 +919,54 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
test_mech.mechanism,&mechanism_info);
+ /*
+ * EC keys are used in multiple different types of mechanism, if we
+ * are using dual use keys, we need to query the the second mechanism
+ * as well.
+ */
+ if (test_mech2.mechanism != CKM_INVALID_MECHANISM) {
+ CK_MECHANISM_INFO mechanism_info2;
+ CK_RV crv2;
+
+ if (crv != CKR_OK) {
+ /* the first failed, make sure there is no trash in the
+ * mechanism flags when we or it below */
+ mechanism_info.flags = 0;
+ }
+ crv2 = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
+ test_mech2.mechanism, &mechanism_info2);
+ if (crv2 == CKR_OK) {
+ crv = CKR_OK; /* succeed if either mechnaism info succeeds */
+ /* combine the 2 sets of mechnanism flags */
+ mechanism_info.flags |= mechanism_info2.flags;
+ }
+ }
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
/* must be old module... guess what it should be... */
switch (test_mech.mechanism) {
- case CKM_RSA_PKCS:
- mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
- CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);;
- break;
- case CKM_DSA:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
- case CKM_DH_PKCS_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- break;
- case CKM_ECDH1_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- break;
- case CKM_ECDSA:
+ case CKM_RSA_PKCS:
+ mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
+ CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);
+ break;
+ case CKM_DSA:
+ mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
+ break;
+ case CKM_DH_PKCS_DERIVE:
+ mechanism_info.flags = CKF_DERIVE;
+ break;
+ case CKM_ECDH1_DERIVE:
+ mechanism_info.flags = CKF_DERIVE;
+ if (test_mech2.mechanism == CKM_ECDSA) {
+ mechanism_info.flags |= CKF_SIGN | CKF_VERIFY;
+ }
+ break;
+ case CKM_ECDSA:
case CKM_ECDSA_SHA1:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
- default:
- break;
+ mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
+ break;
+ default:
+ break;
}
}
/* set the public key attributes */