summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcgreer%netscape.com <devnull@localhost>2001-08-03 18:50:54 +0000
committermcgreer%netscape.com <devnull@localhost>2001-08-03 18:50:54 +0000
commit8acf4e6dd8a6a6b259023239b6c7050d7f015ec3 (patch)
tree56f4c859527678855b98a5a6f67b7374ef0cdbad
parent99dc39f9c13f1ce30698af9a31e2596d5eeaa550 (diff)
downloadnss-hg-8acf4e6dd8a6a6b259023239b6c7050d7f015ec3.tar.gz
fix for #92940, PKCS#12 broken in FIPS mode. Force keygen to occur on token, added new PKCS#11 mechanisms to handle PKCS#12 integrity key generation.
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h11
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c47
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c3
-rw-r--r--security/nss/lib/pkcs12/p12d.c50
-rw-r--r--security/nss/lib/pkcs12/p12e.c36
-rw-r--r--security/nss/lib/softoken/pkcs11.c3
-rw-r--r--security/nss/lib/softoken/pkcs11c.c45
-rw-r--r--security/nss/lib/softoken/pkcs11t.h3
8 files changed, 156 insertions, 42 deletions
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index f3411681c..67fb9edc2 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -455,6 +455,17 @@ void PK11_SetFortezzaHack(PK11SymKey *symKey) ;
/**********************************************************************
* PBE functions
**********************************************************************/
+
+/* This function creates PBE parameters from the given inputs. The result
+ * can be used to create a password integrity key for PKCS#12, by sending
+ * the return value to PK11_KeyGen along with the appropriate mechanism.
+ */
+SECItem *
+PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations);
+
+/* free params created above (can be called after keygen is done */
+void PK11_DestroyPBEParams(SECItem *params);
+
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
PK11SymKey *
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index 16417a8d8..607deeba8 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -1207,7 +1207,7 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
int keySize, SECItem *keyid, PRBool isToken, void *wincx)
{
PK11SymKey *symKey;
- CK_ATTRIBUTE genTemplate[4];
+ CK_ATTRIBUTE genTemplate[5];
CK_ATTRIBUTE *attrs = genTemplate;
int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
CK_SESSION_HANDLE session;
@@ -1243,6 +1243,8 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
}
+ PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(cktrue)); attrs++;
+
count = attrs - genTemplate;
PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
@@ -4053,6 +4055,49 @@ PK11_DigestFinal(PK11Context *context,unsigned char *data,
*
****************************************************************************/
+static void
+pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
+{
+ if (pbe_params) {
+ if (pbe_params->pPassword)
+ PORT_ZFree(pbe_params->pPassword, PR_FALSE);
+ if (pbe_params->pSalt)
+ PORT_ZFree(pbe_params->pSalt, PR_FALSE);
+ PORT_ZFree(pbe_params, PR_TRUE);
+ }
+}
+
+SECItem *
+PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
+{
+ CK_PBE_PARAMS *pbe_params = NULL;
+ SECItem *paramRV = NULL;
+ pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS));
+ pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
+ if (pbe_params->pPassword != NULL) {
+ PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
+ pbe_params->ulPasswordLen = pwd->len;
+ } else goto loser;
+ pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
+ if (pbe_params->pSalt != NULL) {
+ PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
+ pbe_params->ulSaltLen = salt->len;
+ } else goto loser;
+ pbe_params->ulIteration = (CK_ULONG)iterations;
+ paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
+ paramRV->data = (unsigned char *)pbe_params;
+ return paramRV;
+loser:
+ pk11_destroy_ck_pbe_params(pbe_params);
+ return NULL;
+}
+
+void
+PK11_DestroyPBEParams(SECItem *params)
+{
+ pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data);
+}
+
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
{
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 64601e46b..595bf4065 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -2829,6 +2829,9 @@ PK11_GetKeyGen(CK_MECHANISM_TYPE type)
return CKM_GENERIC_SECRET_KEY_GEN;
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
+ case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
+ case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
+ case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index 9abae13c8..076e722ec 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1152,14 +1152,16 @@ static SECStatus
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
{
SECStatus rv = SECFailure;
- PBEBitGenContext *pbeCtxt = NULL;
- SECItem *hmacKey = NULL, hmacRes;
+ SECItem hmacRes;
unsigned char buf[IN_BUF_LEN];
unsigned int bufLen;
int iteration;
PK11Context *pk11cx;
- SECOidTag algtag;
SECItem ignore = {0};
+ PK11SymKey *symKey;
+ SECItem *params;
+ SECOidTag algtag;
+ CK_MECHANISM_TYPE integrityMech;
if(!p12dcx || p12dcx->error) {
return SECFailure;
@@ -1171,28 +1173,28 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
} else {
iteration = 1;
}
- pbeCtxt = PBE_CreateContext(SECOID_GetAlgorithmTag(
- &p12dcx->macData.safeMac.digestAlgorithm),
- pbeBitGenIntegrityKey, p12dcx->pwitem,
- &p12dcx->macData.macSalt, 160, iteration);
- if(!pbeCtxt) {
- return SECFailure;
- }
- hmacKey = PBE_GenerateBits(pbeCtxt);
- PBE_DestroyContext(pbeCtxt);
- pbeCtxt = NULL;
- if(!hmacKey) {
- return SECFailure;
+
+ params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,
+ iteration);
+
+ algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
+ switch (algtag) {
+ case SEC_OID_SHA1:
+ integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
+ case SEC_OID_MD5:
+ integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
+ case SEC_OID_MD2:
+ integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
+ default:
+ goto loser;
}
+ symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
+ PK11_DestroyPBEParams(params);
+ if (!symKey) goto loser;
/* init hmac */
- algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
- pk11cx = PK11_CreateContextByRawKey(NULL,
- sec_pkcs12_algtag_to_mech(algtag),
- PK11_OriginDerive, CKA_SIGN,
- hmacKey, &ignore, NULL);
- SECITEM_ZfreeItem(hmacKey, PR_TRUE);
- hmacKey = NULL;
+ pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
+ CKA_SIGN, symKey, &ignore);
if(!pk11cx) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -1247,10 +1249,6 @@ loser:
PK11_DestroyContext(pk11cx, PR_TRUE);
}
- if(hmacKey) {
- SECITEM_ZfreeItem(hmacKey, PR_TRUE);
- }
-
return rv;
}
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
index 4e6d76ebf..22ff31104 100644
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -1660,9 +1660,11 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
/* init password pased integrity mode */
if(p12exp->integrityEnabled) {
- SECItem pwd = {siBuffer,NULL, 0}, *key;
+ SECItem pwd = {siBuffer,NULL, 0};
SECItem *salt = sec_pkcs12_generate_salt();
- PBEBitGenContext *pbeCtxt = NULL;
+ PK11SymKey *symKey;
+ SECItem *params;
+ CK_MECHANISM_TYPE integrityMech;
/* zero out macData and set values */
PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData));
@@ -1676,7 +1678,6 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
}
- SECITEM_ZfreeItem(salt, PR_TRUE);
/* generate HMAC key */
if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
@@ -1684,25 +1685,32 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
PR_TRUE, PR_TRUE)) {
goto loser;
}
- pbeCtxt = PBE_CreateContext(p12exp->integrityInfo.pwdInfo.algorithm,
- pbeBitGenIntegrityKey, &pwd,
- &(p12enc->mac.macSalt), 160, 1);
+
+ params = PK11_CreatePBEParams(salt, &pwd, 1);
+ SECITEM_ZfreeItem(salt, PR_TRUE);
SECITEM_ZfreeItem(&pwd, PR_FALSE);
- if(!pbeCtxt) {
+
+ switch (p12exp->integrityInfo.pwdInfo.algorithm) {
+ case SEC_OID_SHA1:
+ integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
+ case SEC_OID_MD5:
+ integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
+ case SEC_OID_MD2:
+ integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
+ default:
goto loser;
}
- key = PBE_GenerateBits(pbeCtxt);
- PBE_DestroyContext(pbeCtxt);
- if(!key) {
+
+ symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
+ PK11_DestroyPBEParams(params);
+ if(!symKey) {
goto loser;
}
/* initialize hmac */
- p12enc->hmacCx = PK11_CreateContextByRawKey(NULL,
+ p12enc->hmacCx = PK11_CreateContextBySymKey(
sec_pkcs12_algtag_to_mech(p12exp->integrityInfo.pwdInfo.algorithm),
- PK11_OriginDerive, CKA_SIGN,
- key, &ignore, NULL);
- SECITEM_ZfreeItem(key, PR_TRUE);
+ CKA_SIGN, symKey, &ignore);
if(!p12enc->hmacCx) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index e0a73fa2b..4795a5d72 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -406,6 +406,9 @@ static struct mechanismList mechanisms[] = {
{CKM_PBE_SHA1_RC2_128_CBC, {128,128, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC4_40, {40,40, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC4_128, {128,128, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
};
static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
/* load up our token database */
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index c96c8073f..634574a43 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -2832,6 +2832,40 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
**************************** Key Functions: ************************
*/
+CK_RV
+pk11_pbe_hmac_key_gen(CK_MECHANISM_PTR pMechanism, char *buf,
+ unsigned long *len, PRBool faultyPBE3DES)
+{
+ PBEBitGenContext *pbeCx;
+ SECItem pwd, salt, *key;
+ SECOidTag hashAlg;
+ unsigned long keylenbits;
+ CK_PBE_PARAMS *pbe_params = NULL;
+ pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
+ pwd.data = (unsigned char *)pbe_params->pPassword;
+ pwd.len = (unsigned int)pbe_params->ulPasswordLen;
+ salt.data = (unsigned char *)pbe_params->pSalt;
+ salt.len = (unsigned int)pbe_params->ulSaltLen;
+ switch (pMechanism->mechanism) {
+ case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
+ hashAlg = SEC_OID_SHA1; keylenbits = 160; break;
+ case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
+ hashAlg = SEC_OID_MD5; keylenbits = 128; break;
+ case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+ hashAlg = SEC_OID_MD2; keylenbits = 128; break;
+ default:
+ return CKR_MECHANISM_INVALID;
+ }
+ pbeCx = PBE_CreateContext(hashAlg, pbeBitGenIntegrityKey, &pwd,
+ &salt, keylenbits, pbe_params->ulIteration);
+ key = PBE_GenerateBits(pbeCx);
+ PORT_Memcpy(buf, key->data, key->len);
+ *len = key->len;
+ PBE_DestroyContext(pbeCx);
+ SECITEM_ZfreeItem(key, PR_TRUE);
+ return CKR_OK;
+}
+
/*
* generate a password based encryption key. This code uses
* PKCS5 to do the work. Note that it calls PBE_PK11ParamToAlgid, which is
@@ -3041,7 +3075,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
int i;
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
char buf[MAX_KEY_LEN];
- enum {pk11_pbe, pk11_ssl, pk11_bulk} key_gen_type;
+ enum {pk11_pbe, pk11_pbe_hmac, pk11_ssl, pk11_bulk} key_gen_type;
SECOidTag algtag = SEC_OID_UNKNOWN;
SSL3RSAPreMasterSecret *rsa_pms;
CK_VERSION *version;
@@ -3106,6 +3140,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
break;
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
faultyPBE3DES = PR_TRUE;
+ case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
+ case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
+ case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+ key_gen_type = pk11_pbe_hmac;
+ break;
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
@@ -3142,6 +3181,10 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
* now to the actual key gen.
*/
switch (key_gen_type) {
+ case pk11_pbe_hmac:
+ crv = pk11_pbe_hmac_key_gen(pMechanism, buf, &key_length,
+ faultyPBE3DES);
+ break;
case pk11_pbe:
crv = pk11_pbe_key_gen(algtag, pMechanism, buf, &key_length,
faultyPBE3DES);
diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h
index c626036c8..6cb3e74c4 100644
--- a/security/nss/lib/softoken/pkcs11t.h
+++ b/security/nss/lib/softoken/pkcs11t.h
@@ -1112,6 +1112,9 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
+#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L
+#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL
+#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL
#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
#define CKM_TLS_PRF_GENERAL 0x80000373L