diff options
author | nelson%bolyard.com <devnull@localhost> | 2008-02-03 06:08:49 +0000 |
---|---|---|
committer | nelson%bolyard.com <devnull@localhost> | 2008-02-03 06:08:49 +0000 |
commit | 1383c0af9e24d12efc4fedd54d64f1aa5e4af2ac (patch) | |
tree | 4b8be185ca1631b86e13ab31f5c1fa4d6a42618f | |
parent | 84330999fc4bacf4855d50fc40b3513d6358fa9d (diff) | |
download | nss-hg-1383c0af9e24d12efc4fedd54d64f1aa5e4af2ac.tar.gz |
Re-commit Bob Relyea's changes for bug 401928. r=nelson.
We'll let these bake for 8-12 hours before taking any more action.
-rw-r--r-- | security/nss/lib/pk11wrap/pk11mech.c | 31 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pbe.c | 9 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/secmodi.h | 5 | ||||
-rw-r--r-- | security/nss/lib/pkcs12/p12.h | 1 | ||||
-rw-r--r-- | security/nss/lib/pkcs12/p12d.c | 11 | ||||
-rw-r--r-- | security/nss/lib/pkcs12/p12e.c | 30 | ||||
-rw-r--r-- | security/nss/lib/pkcs7/p7common.c | 76 | ||||
-rw-r--r-- | security/nss/lib/pkcs7/p7create.c | 36 | ||||
-rw-r--r-- | security/nss/lib/pkcs7/p7local.c | 76 | ||||
-rw-r--r-- | security/nss/lib/smime/cmscipher.c | 84 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsencdata.c | 33 |
11 files changed, 162 insertions, 230 deletions
diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c index 386d855fd..1bc48738c 100644 --- a/security/nss/lib/pk11wrap/pk11mech.c +++ b/security/nss/lib/pk11wrap/pk11mech.c @@ -801,7 +801,7 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type) * like SSL and S-MIME to automatically add them. */ SECItem * -PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) +pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen) { CK_RC2_CBC_PARAMS *rc2_params = NULL; CK_RC2_PARAMS *rc2_ecb_params = NULL; @@ -833,7 +833,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); if (rc2_ecb_params == NULL) break; /* Maybe we should pass the key size in too to get this value? */ - *rc2_ecb_params = 128; + *rc2_ecb_params = keyLen ? keyLen*8 : 128; param->data = (unsigned char *) rc2_ecb_params; param->len = sizeof(CK_RC2_PARAMS); break; @@ -842,7 +842,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); if (rc2_params == NULL) break; /* Maybe we should pass the key size in too to get this value? */ - rc2_params->ulEffectiveBits = 128; + rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128; if (iv && iv->data) PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv)); param->data = (unsigned char *) rc2_params; @@ -939,6 +939,16 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) return param; } +/* These next two utilities are here to help facilitate future + * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions + * like SSL and S-MIME to automatically add them. + */ +SECItem * +PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) +{ + return pk11_ParamFromIVWithLen(type, iv, 0); +} + unsigned char * PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len) { @@ -1343,7 +1353,8 @@ pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) { * key. Use Netscape's S/MIME Rules for the New param block. */ SECItem * -PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { +pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen) +{ CK_RC2_CBC_PARAMS *rc2_params; CK_RC2_PARAMS *rc2_ecb_params; SECItem *mech; @@ -1378,7 +1389,7 @@ PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { } /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ - *rc2_ecb_params = key ? PK11_GetKeyLength(key)*8 : 128; + *rc2_ecb_params = keyLen ? keyLen*8 : 128; mech->data = (unsigned char *) rc2_ecb_params; mech->len = sizeof(CK_RC2_PARAMS); break; @@ -1396,7 +1407,7 @@ PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { } /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ - rc2_params->ulEffectiveBits = key ? PK11_GetKeyLength(key)*8 : 128; + rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128; if (iv.data) PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv)); mech->data = (unsigned char *) rc2_params; @@ -1475,6 +1486,14 @@ PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { } +SECItem * +PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) +{ + int keyLen = key ? PK11_GetKeyLength(key) : 0; + + return pk11_GenerateNewParamWithKeyLen(type, keyLen); +} + #define RC5_V10 0x10 /* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */ diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c index f140ff53f..da416d725 100644 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ b/security/nss/lib/pk11wrap/pk11pbe.c @@ -673,8 +673,8 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, } /* build the PKCS5v2 cipher algorithm id */ - cipherParams = PK11_GenerateNewParam( - PK11_AlgtagToMechanism(cipherAlgorithm), NULL); + cipherParams = pk11_GenerateNewParamWithKeyLen( + PK11_AlgtagToMechanism(cipherAlgorithm), keyLength); if (!cipherParams) { goto loser; } @@ -1407,6 +1407,7 @@ CK_MECHANISM_TYPE pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, SECItem *pbe_pwd, PRBool faulty3DES) { + int keyLen = 0; SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid); CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag); CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM; @@ -1423,7 +1424,9 @@ pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, } } - *param = PK11_ParamFromIV(mech, iv); + keyLen = SEC_PKCS5GetKeyLength(algid); + + *param = pk11_ParamFromIVWithLen(mech, iv, keyLen); if (*param == NULL) { goto loser; } diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h index eca18a982..bf0de3933 100644 --- a/security/nss/lib/pk11wrap/secmodi.h +++ b/security/nss/lib/pk11wrap/secmodi.h @@ -164,6 +164,11 @@ CK_OBJECT_HANDLE pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID); SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType, PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx); + +SECItem *pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen); +SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, + SECItem *iv, int keyLen); + SEC_END_PROTOS #endif diff --git a/security/nss/lib/pkcs12/p12.h b/security/nss/lib/pkcs12/p12.h index 6eb6ecfed..612f4cd3a 100644 --- a/security/nss/lib/pkcs12/p12.h +++ b/security/nss/lib/pkcs12/p12.h @@ -99,6 +99,7 @@ struct SEC_PKCS12DecoderItemStr { SECOidTag type; PRBool hasKey; SECItem *friendlyName; /* UTF-8 string */ + SECAlgorithmID *shroudAlg; }; diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index b18d84774..0be10c701 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -3076,11 +3076,15 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx, if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) { SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE); } + if (p12dcx->decitem.shroudAlg != NULL) { + SECOID_DestroyAlgorithmID(p12dcx->decitem.shroudAlg, PR_TRUE); + } if (p12dcx->decitem.friendlyName != NULL) { SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE); } p12dcx->decitem.type = 0; p12dcx->decitem.der = NULL; + p12dcx->decitem.shroudAlg = NULL; p12dcx->decitem.friendlyName = NULL; p12dcx->decitem.hasKey = PR_FALSE; *ipp = NULL; @@ -3101,8 +3105,13 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx, p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag); p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, bag); break; - case SEC_OID_PKCS12_V1_KEY_BAG_ID: case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID: + p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID); + if (p12dcx->decitem.shroudAlg) { + SECOID_CopyAlgorithmID(NULL, p12dcx->decitem.shroudAlg, + &bag->safeBagContent.pkcs8ShroudedKeyBag->algorithm); + } + case SEC_OID_PKCS12_V1_KEY_BAG_ID: p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag); break; default: diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c index f0fbbcb2e..52f3871c8 100644 --- a/security/nss/lib/pkcs12/p12e.c +++ b/security/nss/lib/pkcs12/p12e.c @@ -1720,8 +1720,8 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp) SECItem *salt = sec_pkcs12_generate_salt(); PK11SymKey *symKey; SECItem *params; - CK_MECHANISM_TYPE integrityMech; - CK_MECHANISM_TYPE hmacMech; + CK_MECHANISM_TYPE integrityMechType; + CK_MECHANISM_TYPE hmacMechType; /* zero out macData and set values */ PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData)); @@ -1742,35 +1742,41 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp) PR_TRUE, PR_TRUE)) { goto loser; } - + /* + * This code only works with PKCS #12 Mac using PKCS #5 v1 + * PBA keygens. PKCS #5 v2 support will require a change to + * the PKCS #12 spec. + */ params = PK11_CreatePBEParams(salt, &pwd, 1); SECITEM_ZfreeItem(salt, PR_TRUE); SECITEM_ZfreeItem(&pwd, PR_FALSE); + /* get the PBA Mechanism to generate the key */ switch (p12exp->integrityInfo.pwdInfo.algorithm) { case SEC_OID_SHA1: - integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break; + integrityMechType = CKM_PBA_SHA1_WITH_SHA1_HMAC; break; case SEC_OID_MD5: - integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break; + integrityMechType = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break; case SEC_OID_MD2: - integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break; + integrityMechType = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break; default: goto loser; } - symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL); + /* generate the key */ + symKey = PK11_KeyGen(NULL, integrityMechType, params, 20, NULL); PK11_DestroyPBEParams(params); if(!symKey) { goto loser; } - /* initialize hmac */ - /* XXX NBB, why is this mech different than the one above? */ - hmacMech = sec_pkcs12_algtag_to_mech( + /* initialize HMAC */ + /* Get the HMAC mechanism from the hash OID */ + hmacMechType= sec_pkcs12_algtag_to_mech( p12exp->integrityInfo.pwdInfo.algorithm); - p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMech, CKA_SIGN, - symKey, &ignore); + p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMechType, + CKA_SIGN, symKey, &ignore); PK11_FreeSymKey(symKey); if(!p12enc->hmacCx) { diff --git a/security/nss/lib/pkcs7/p7common.c b/security/nss/lib/pkcs7/p7common.c index 02f058a25..aef65471b 100644 --- a/security/nss/lib/pkcs7/p7common.c +++ b/security/nss/lib/pkcs7/p7common.c @@ -450,12 +450,10 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, PK11SymKey * eKey = NULL; PK11SlotInfo * slot = NULL; - CK_MECHANISM pbeMech; - CK_MECHANISM cryptoMech; + CK_MECHANISM_TYPE cryptoMechType; int bs; - SECOidTag algtag; SECStatus rv = SECFailure; - SECItem c_param; + SECItem *c_param = NULL; if((cinfo == NULL) || (key == NULL)) return SECFailure; @@ -474,8 +472,6 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, src = &cinfo->content.encryptedData->encContentInfo.plainContent; dest = &cinfo->content.encryptedData->encContentInfo.encContent; - algtag = SECOID_GetAlgorithmTag(algid); - c_param.data = NULL; dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64)); dest->len = (src->len + 64); if(dest->data == NULL) { @@ -488,32 +484,21 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, rv = SECFailure; goto loser; } - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - result = PK11_ParamFromAlgid(algid); - if (result == NULL) { - rv = SECFailure; - goto loser; - } - pbeMech.pParameter = result->data; - pbeMech.ulParameterLen = result->len; - eKey = PK11_RawPBEKeyGen(slot, pbeMech.mechanism, result, key, PR_FALSE, - wincx); + eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); if(eKey == NULL) { rv = SECFailure; goto loser; } - - if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key, - PR_FALSE) != CKR_OK) { + + cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); + if (cryptoMechType == CKM_INVALID_MECHANISM) { rv = SECFailure; goto loser; } - c_param.data = (unsigned char *)cryptoMech.pParameter; - c_param.len = cryptoMech.ulParameterLen; /* block according to PKCS 8 */ - bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param); + bs = PK11_GetBlockSize(cryptoMechType, c_param); rv = SECSuccess; if(bs) { char pad_char; @@ -522,7 +507,8 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, rv = SECSuccess; blocked_data = PK11_BlockData(src, bs); if(blocked_data) { - PORT_Memset((blocked_data->data + blocked_data->len - (int)pad_char), + PORT_Memset((blocked_data->data + blocked_data->len + - (int)pad_char), pad_char, (int)pad_char); } else { rv = SECFailure; @@ -554,8 +540,8 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, } } - cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_ENCRYPT, - eKey, &c_param); + cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, + eKey, c_param); if(cx == NULL) { rv = SECFailure; goto loser; @@ -585,8 +571,8 @@ loser: if(slot != NULL) PK11_FreeSlot(slot); - if(c_param.data != NULL) - SECITEM_ZfreeItem(&c_param, PR_FALSE); + if(c_param != NULL) + SECITEM_ZfreeItem(c_param, PR_TRUE); return rv; } @@ -612,16 +598,15 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, void *wincx) { SECAlgorithmID *algid = NULL; - SECOidTag algtag; SECStatus rv = SECFailure; SECItem *result = NULL, *dest, *src; void *mark; PK11SymKey *eKey = NULL; PK11SlotInfo *slot = NULL; - CK_MECHANISM pbeMech, cryptoMech; + CK_MECHANISM_TYPE cryptoMechType; void *cx; - SECItem c_param; + SECItem *c_param = NULL; int bs; if((cinfo == NULL) || (key == NULL)) @@ -641,8 +626,6 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, src = &cinfo->content.encryptedData->encContentInfo.encContent; dest = &cinfo->content.encryptedData->encContentInfo.plainContent; - algtag = SECOID_GetAlgorithmTag(algid); - c_param.data = NULL; dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64)); dest->len = (src->len + 64); if(dest->data == NULL) { @@ -655,30 +638,21 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, rv = SECFailure; goto loser; } - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - result = PK11_ParamFromAlgid(algid); - if (result == NULL) { - rv = SECFailure; - goto loser; - } - pbeMech.pParameter = result->data; - pbeMech.ulParameterLen = result->len; - eKey = PK11_RawPBEKeyGen(slot,pbeMech.mechanism,result,key,PR_FALSE,wincx); + + eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); if(eKey == NULL) { rv = SECFailure; goto loser; } - - if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key, - PR_FALSE) != CKR_OK) { + + cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); + if (cryptoMechType == CKM_INVALID_MECHANISM) { rv = SECFailure; goto loser; } - c_param.data = (unsigned char *)cryptoMech.pParameter; - c_param.len = cryptoMech.ulParameterLen; - cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_DECRYPT, - eKey, &c_param); + cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, + eKey, c_param); if(cx == NULL) { rv = SECFailure; goto loser; @@ -688,7 +662,7 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, (int)(src->len + 64), src->data, (int)src->len); PK11_DestroyContext((PK11Context *)cx, PR_TRUE); - bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param); + bs = PK11_GetBlockSize(cryptoMechType, c_param); if(bs) { /* check for proper badding in block algorithms. this assumes * RC2 cbc or a DES cbc variant. and the padding is thus defined @@ -718,8 +692,8 @@ loser: if(slot != NULL) PK11_FreeSlot(slot); - if(c_param.data != NULL) - SECITEM_ZfreeItem(&c_param, PR_FALSE); + if(c_param != NULL) + SECITEM_ZfreeItem(c_param, PR_TRUE); return rv; } diff --git a/security/nss/lib/pkcs7/p7create.c b/security/nss/lib/pkcs7/p7create.c index f49871ca3..5c6a4f31a 100644 --- a/security/nss/lib/pkcs7/p7create.c +++ b/security/nss/lib/pkcs7/p7create.c @@ -50,6 +50,7 @@ #include "prtime.h" #include "secerr.h" #include "secder.h" +#include "secpkcs5.h" static SECStatus sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PRArenaPool *poolp, @@ -1281,27 +1282,24 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, enc_data = cinfo->content.encryptedData; algid = &(enc_data->encContentInfo.contentEncAlg); - switch (algorithm) { - case SEC_OID_RC2_CBC: - case SEC_OID_DES_EDE3_CBC: - case SEC_OID_DES_CBC: + if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) { rv = SECOID_SetAlgorithmID (cinfo->poolp, algid, algorithm, NULL); - break; - default: - { - /* - * Assume password-based-encryption. At least, try that. - */ - SECAlgorithmID *pbe_algid; - pbe_algid = PK11_CreatePBEAlgorithmID (algorithm, 1, NULL); - if (pbe_algid == NULL) { - rv = SECFailure; - } else { - rv = SECOID_CopyAlgorithmID (cinfo->poolp, algid, pbe_algid); - SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); - } + } else { + /* Assume password-based-encryption. + * Note: we can't generate pkcs5v2 from this interface. + * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting + * non-PBE oids and assuming that they are pkcs5v2 oids, but + * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular + * CMS encrypted data, so we can't tell SEC_PKCS7CreateEncryptedtedData + * to create pkcs5v2 PBEs */ + SECAlgorithmID *pbe_algid; + pbe_algid = PK11_CreatePBEAlgorithmID (algorithm, 1, NULL); + if (pbe_algid == NULL) { + rv = SECFailure; + } else { + rv = SECOID_CopyAlgorithmID (cinfo->poolp, algid, pbe_algid); + SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); } - break; } if (rv != SECSuccess) { diff --git a/security/nss/lib/pkcs7/p7local.c b/security/nss/lib/pkcs7/p7local.c index 64ec7d950..592ced1d9 100644 --- a/security/nss/lib/pkcs7/p7local.c +++ b/security/nss/lib/pkcs7/p7local.c @@ -103,7 +103,7 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) sec_PKCS7CipherObject *result; SECOidTag algtag; void *ciphercx; - CK_MECHANISM_TYPE mechanism; + CK_MECHANISM_TYPE cryptoMechType; SECItem *param; PK11SlotInfo *slot; @@ -116,8 +116,7 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) algtag = SECOID_GetAlgorithmTag (algid); if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; + SECItem *pwitem; pwitem = (SECItem *)PK11_GetSymKeyUserData(key); if (!pwitem) { @@ -125,33 +124,13 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) return NULL; } - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if (!pbeParams) { + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { PORT_Free(result); return NULL; } - - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - PORT_Free(result); - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - return NULL; - } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - - param = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(!param) { - PORT_Free(result); - return NULL; - } - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; } else { - mechanism = PK11_AlgtagToMechanism(algtag); + cryptoMechType = PK11_AlgtagToMechanism(algtag); param = PK11_ParamFromAlgid(algid); if (param == NULL) { PORT_Free(result); @@ -159,11 +138,12 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) } } - result->pad_size = PK11_GetBlockSize(mechanism,param); + result->pad_size = PK11_GetBlockSize(cryptoMechType, param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, + key, param); SECITEM_FreeItem(param,PR_TRUE); if (ciphercx == NULL) { PORT_Free (result); @@ -200,7 +180,7 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, void *ciphercx; SECItem *param; SECStatus rv; - CK_MECHANISM_TYPE mechanism; + CK_MECHANISM_TYPE cryptoMechType; PRBool needToEncodeAlgid = PR_FALSE; PK11SlotInfo *slot; @@ -211,11 +191,7 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, ciphercx = NULL; if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; - - PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); - PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); + SECItem *pwitem; pwitem = (SECItem *)PK11_GetSymKeyUserData(key); if (!pwitem) { @@ -223,34 +199,14 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, return NULL; } - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if(!pbeParams) { + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { PORT_Free(result); return NULL; } - - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - PORT_Free(result); - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - return NULL; - } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - - param = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(!param) { - PORT_Free(result); - return NULL; - } - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; } else { - mechanism = PK11_AlgtagToMechanism(algtag); - param = PK11_GenerateNewParam(mechanism,key); + cryptoMechType = PK11_AlgtagToMechanism(algtag); + param = PK11_GenerateNewParam(cryptoMechType, key); if (param == NULL) { PORT_Free(result); return NULL; @@ -258,11 +214,11 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, needToEncodeAlgid = PR_TRUE; } - result->pad_size = PK11_GetBlockSize(mechanism,param); + result->pad_size = PK11_GetBlockSize(cryptoMechType,param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT, + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, key, param); if (ciphercx == NULL) { PORT_Free (result); diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c index 071e56538..ca9f31d21 100644 --- a/security/nss/lib/smime/cmscipher.c +++ b/security/nss/lib/smime/cmscipher.c @@ -72,7 +72,8 @@ struct NSSCMSCipherContextStr { /* * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption - * based on the given bulk * encryption key and algorithm identifier (which may include an iv). + * based on the given bulk encryption key and algorithm identifier (which + * may include an iv). * * XXX Once both are working, it might be nice to combine this and the * function below (for starting up encryption) into one routine, and just @@ -83,7 +84,7 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) { NSSCMSCipherContext *cc; void *ciphercx; - CK_MECHANISM_TYPE mechanism; + CK_MECHANISM_TYPE cryptoMechType; SECItem *param; PK11SlotInfo *slot; SECOidTag algtag; @@ -92,41 +93,19 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) /* set param and mechanism */ if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; - - PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); - PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); + SECItem *pwitem; pwitem = PK11_GetSymKeyUserData(key); if (!pwitem) return NULL; - /* find correct PK11 mechanism and parameters to initialize pbeMech */ - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if (!pbeParams) - return NULL; - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - - /* now map pbeMech to cryptoMech */ - if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - SECITEM_ZfreeItem(pbeParams, PR_TRUE); + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { return NULL; } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - /* and use it to initialize param & mechanism */ - if ((param = (SECItem *)PORT_ZAlloc(sizeof(SECItem))) == NULL) - return NULL; - - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; } else { - mechanism = PK11_AlgtagToMechanism(algtag); + cryptoMechType = PK11_AlgtagToMechanism(algtag); if ((param = PK11_ParamFromAlgid(algid)) == NULL) return NULL; } @@ -138,13 +117,14 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) } /* figure out pad and block sizes */ - cc->pad_size = PK11_GetBlockSize(mechanism, param); + cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); slot = PK11_GetSlotFromKey(key); cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; PK11_FreeSlot(slot); /* create PK11 cipher context */ - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, + key, param); SECITEM_FreeItem(param, PR_TRUE); if (ciphercx == NULL) { PORT_Free (cc); @@ -162,8 +142,8 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) /* * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption, - * based on the given bulk encryption key and algorithm tag. Fill in the algorithm - * identifier (which may include an iv) appropriately. + * based on the given bulk encryption key and algorithm tag. Fill in the + * algorithm identifier (which may include an iv) appropriately. * * XXX Once both are working, it might be nice to combine this and the * function above (for starting up decryption) into one routine, and just @@ -176,49 +156,26 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori void *ciphercx; SECItem *param; SECStatus rv; - CK_MECHANISM_TYPE mechanism; + CK_MECHANISM_TYPE cryptoMechType; PK11SlotInfo *slot; PRBool needToEncodeAlgid = PR_FALSE; SECOidTag algtag = SECOID_GetAlgorithmTag(algid); /* set param and mechanism */ if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - CK_MECHANISM pbeMech, cryptoMech; - SECItem *pbeParams, *pwitem; - - PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); - PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); + SECItem *pwitem; pwitem = PK11_GetSymKeyUserData(key); if (!pwitem) return NULL; - /* find correct PK11 mechanism and parameters to initialize pbeMech */ - pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); - pbeParams = PK11_ParamFromAlgid(algid); - if (!pbeParams) - return NULL; - pbeMech.pParameter = pbeParams->data; - pbeMech.ulParameterLen = pbeParams->len; - - /* now map pbeMech to cryptoMech */ - if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem, - PR_FALSE) != CKR_OK) { - SECITEM_ZfreeItem(pbeParams, PR_TRUE); + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { return NULL; } - SECITEM_ZfreeItem(pbeParams, PR_TRUE); - - /* and use it to initialize param & mechanism */ - if ((param = (SECItem *)PORT_ZAlloc(sizeof(SECItem))) == NULL) - return NULL; - - param->data = (unsigned char *)cryptoMech.pParameter; - param->len = cryptoMech.ulParameterLen; - mechanism = cryptoMech.mechanism; } else { - mechanism = PK11_AlgtagToMechanism(algtag); - if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL) + cryptoMechType = PK11_AlgtagToMechanism(algtag); + if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL) return NULL; needToEncodeAlgid = PR_TRUE; } @@ -229,13 +186,14 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori } /* now find pad and block sizes for our mechanism */ - cc->pad_size = PK11_GetBlockSize(mechanism,param); + cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); slot = PK11_GetSlotFromKey(key); cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; PK11_FreeSlot(slot); /* and here we go, creating a PK11 cipher context */ - ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT, key, param); + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, + key, param); if (ciphercx == NULL) { PORT_Free(cc); cc = NULL; diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c index 0bcbb680a..a14a3b7c7 100644 --- a/security/nss/lib/smime/cmsencdata.c +++ b/security/nss/lib/smime/cmsencdata.c @@ -61,7 +61,8 @@ * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ NSSCMSEncryptedData * -NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize) +NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, + int keysize) { void *mark; NSSCMSEncryptedData *encd; @@ -73,7 +74,7 @@ NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysiz mark = PORT_ArenaMark(poolp); - encd = (NSSCMSEncryptedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEncryptedData)); + encd = PORT_ArenaZNew(poolp, NSSCMSEncryptedData); if (encd == NULL) goto loser; @@ -81,23 +82,25 @@ NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysiz /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */ - switch (algorithm) { - /* XXX hmmm... hardcoded algorithms? */ - case SEC_OID_RC2_CBC: - case SEC_OID_DES_EDE3_CBC: - case SEC_OID_DES_CBC: - rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo), algorithm, NULL, keysize); - break; - default: - /* Assume password-based-encryption. At least, try that. */ + if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) { + rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo), + algorithm, NULL, keysize); + } else { + /* Assume password-based-encryption. + * Note: we can't generate pkcs5v2 from this interface. + * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting + * non-PBE oids and assuming that they are pkcs5v2 oids, but + * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular + * CMS encrypted data, so we can't tell NSS_CMS_EncryptedData_Create + * to create pkcs5v2 PBEs */ pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL); if (pbe_algid == NULL) { rv = SECFailure; - break; + } else { + rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, + &(encd->contentInfo), pbe_algid, keysize); + SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); } - rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, &(encd->contentInfo), pbe_algid, keysize); - SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); - break; } if (rv != SECSuccess) goto loser; |