diff options
-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 |
8 files changed, 221 insertions, 126 deletions
diff --git a/security/nss/lib/pkcs12/p12.h b/security/nss/lib/pkcs12/p12.h index 612f4cd3a..6eb6ecfed 100644 --- a/security/nss/lib/pkcs12/p12.h +++ b/security/nss/lib/pkcs12/p12.h @@ -99,7 +99,6 @@ 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 0be10c701..b18d84774 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -3076,15 +3076,11 @@ 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; @@ -3105,13 +3101,8 @@ 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_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: + case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_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 52f3871c8..f0fbbcb2e 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 integrityMechType; - CK_MECHANISM_TYPE hmacMechType; + CK_MECHANISM_TYPE integrityMech; + CK_MECHANISM_TYPE hmacMech; /* zero out macData and set values */ PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData)); @@ -1742,41 +1742,35 @@ 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: - integrityMechType = CKM_PBA_SHA1_WITH_SHA1_HMAC; break; + integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break; case SEC_OID_MD5: - integrityMechType = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break; + integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break; case SEC_OID_MD2: - integrityMechType = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break; + integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break; default: goto loser; } - /* generate the key */ - symKey = PK11_KeyGen(NULL, integrityMechType, params, 20, NULL); + symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL); PK11_DestroyPBEParams(params); if(!symKey) { goto loser; } - /* initialize HMAC */ - /* Get the HMAC mechanism from the hash OID */ - hmacMechType= sec_pkcs12_algtag_to_mech( + /* initialize hmac */ + /* XXX NBB, why is this mech different than the one above? */ + hmacMech = sec_pkcs12_algtag_to_mech( p12exp->integrityInfo.pwdInfo.algorithm); - p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMechType, - CKA_SIGN, symKey, &ignore); + p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMech, 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 aef65471b..02f058a25 100644 --- a/security/nss/lib/pkcs7/p7common.c +++ b/security/nss/lib/pkcs7/p7common.c @@ -450,10 +450,12 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, PK11SymKey * eKey = NULL; PK11SlotInfo * slot = NULL; - CK_MECHANISM_TYPE cryptoMechType; + CK_MECHANISM pbeMech; + CK_MECHANISM cryptoMech; int bs; + SECOidTag algtag; SECStatus rv = SECFailure; - SECItem *c_param = NULL; + SECItem c_param; if((cinfo == NULL) || (key == NULL)) return SECFailure; @@ -472,6 +474,8 @@ 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) { @@ -484,21 +488,32 @@ 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_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); + eKey = PK11_RawPBEKeyGen(slot, pbeMech.mechanism, result, key, PR_FALSE, + wincx); if(eKey == NULL) { rv = SECFailure; goto loser; } - - cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + + if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key, + PR_FALSE) != CKR_OK) { rv = SECFailure; goto loser; } + c_param.data = (unsigned char *)cryptoMech.pParameter; + c_param.len = cryptoMech.ulParameterLen; /* block according to PKCS 8 */ - bs = PK11_GetBlockSize(cryptoMechType, c_param); + bs = PK11_GetBlockSize(cryptoMech.mechanism, &c_param); rv = SECSuccess; if(bs) { char pad_char; @@ -507,8 +522,7 @@ 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; @@ -540,8 +554,8 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp, } } - cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, - eKey, c_param); + cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_ENCRYPT, + eKey, &c_param); if(cx == NULL) { rv = SECFailure; goto loser; @@ -571,8 +585,8 @@ loser: if(slot != NULL) PK11_FreeSlot(slot); - if(c_param != NULL) - SECITEM_ZfreeItem(c_param, PR_TRUE); + if(c_param.data != NULL) + SECITEM_ZfreeItem(&c_param, PR_FALSE); return rv; } @@ -598,15 +612,16 @@ 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_TYPE cryptoMechType; + CK_MECHANISM pbeMech, cryptoMech; void *cx; - SECItem *c_param = NULL; + SECItem c_param; int bs; if((cinfo == NULL) || (key == NULL)) @@ -626,6 +641,8 @@ 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) { @@ -638,21 +655,30 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, rv = SECFailure; goto loser; } - - eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); + 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); if(eKey == NULL) { rv = SECFailure; goto loser; } - - cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + + if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key, + PR_FALSE) != CKR_OK) { rv = SECFailure; goto loser; } + c_param.data = (unsigned char *)cryptoMech.pParameter; + c_param.len = cryptoMech.ulParameterLen; - cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, - eKey, c_param); + cx = PK11_CreateContextBySymKey(cryptoMech.mechanism, CKA_DECRYPT, + eKey, &c_param); if(cx == NULL) { rv = SECFailure; goto loser; @@ -662,7 +688,7 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp, (int)(src->len + 64), src->data, (int)src->len); PK11_DestroyContext((PK11Context *)cx, PR_TRUE); - bs = PK11_GetBlockSize(cryptoMechType, c_param); + bs = PK11_GetBlockSize(cryptoMech.mechanism, &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 @@ -692,8 +718,8 @@ loser: if(slot != NULL) PK11_FreeSlot(slot); - if(c_param != NULL) - SECITEM_ZfreeItem(c_param, PR_TRUE); + if(c_param.data != NULL) + SECITEM_ZfreeItem(&c_param, PR_FALSE); return rv; } diff --git a/security/nss/lib/pkcs7/p7create.c b/security/nss/lib/pkcs7/p7create.c index 5c6a4f31a..f49871ca3 100644 --- a/security/nss/lib/pkcs7/p7create.c +++ b/security/nss/lib/pkcs7/p7create.c @@ -50,7 +50,6 @@ #include "prtime.h" #include "secerr.h" #include "secder.h" -#include "secpkcs5.h" static SECStatus sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PRArenaPool *poolp, @@ -1282,24 +1281,27 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, enc_data = cinfo->content.encryptedData; algid = &(enc_data->encContentInfo.contentEncAlg); - if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) { + switch (algorithm) { + case SEC_OID_RC2_CBC: + case SEC_OID_DES_EDE3_CBC: + case SEC_OID_DES_CBC: rv = SECOID_SetAlgorithmID (cinfo->poolp, algid, algorithm, NULL); - } 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; + 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); + } } + break; } if (rv != SECSuccess) { diff --git a/security/nss/lib/pkcs7/p7local.c b/security/nss/lib/pkcs7/p7local.c index 592ced1d9..64ec7d950 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 cryptoMechType; + CK_MECHANISM_TYPE mechanism; SECItem *param; PK11SlotInfo *slot; @@ -116,7 +116,8 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) algtag = SECOID_GetAlgorithmTag (algid); if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; + CK_MECHANISM pbeMech, cryptoMech; + SECItem *pbeParams, *pwitem; pwitem = (SECItem *)PK11_GetSymKeyUserData(key); if (!pwitem) { @@ -124,13 +125,33 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) return NULL; } - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); + pbeParams = PK11_ParamFromAlgid(algid); + if (!pbeParams) { 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 { - cryptoMechType = PK11_AlgtagToMechanism(algtag); + mechanism = PK11_AlgtagToMechanism(algtag); param = PK11_ParamFromAlgid(algid); if (param == NULL) { PORT_Free(result); @@ -138,12 +159,11 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) } } - result->pad_size = PK11_GetBlockSize(cryptoMechType, param); + result->pad_size = PK11_GetBlockSize(mechanism,param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, - key, param); + ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); SECITEM_FreeItem(param,PR_TRUE); if (ciphercx == NULL) { PORT_Free (result); @@ -180,7 +200,7 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, void *ciphercx; SECItem *param; SECStatus rv; - CK_MECHANISM_TYPE cryptoMechType; + CK_MECHANISM_TYPE mechanism; PRBool needToEncodeAlgid = PR_FALSE; PK11SlotInfo *slot; @@ -191,7 +211,11 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, ciphercx = NULL; if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; + CK_MECHANISM pbeMech, cryptoMech; + SECItem *pbeParams, *pwitem; + + PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); + PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); pwitem = (SECItem *)PK11_GetSymKeyUserData(key); if (!pwitem) { @@ -199,14 +223,34 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, return NULL; } - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); + pbeParams = PK11_ParamFromAlgid(algid); + if(!pbeParams) { 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 { - cryptoMechType = PK11_AlgtagToMechanism(algtag); - param = PK11_GenerateNewParam(cryptoMechType, key); + mechanism = PK11_AlgtagToMechanism(algtag); + param = PK11_GenerateNewParam(mechanism,key); if (param == NULL) { PORT_Free(result); return NULL; @@ -214,11 +258,11 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key, needToEncodeAlgid = PR_TRUE; } - result->pad_size = PK11_GetBlockSize(cryptoMechType,param); + result->pad_size = PK11_GetBlockSize(mechanism,param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, + ciphercx = PK11_CreateContextBySymKey(mechanism, 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 ca9f31d21..071e56538 100644 --- a/security/nss/lib/smime/cmscipher.c +++ b/security/nss/lib/smime/cmscipher.c @@ -72,8 +72,7 @@ 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 @@ -84,7 +83,7 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) { NSSCMSCipherContext *cc; void *ciphercx; - CK_MECHANISM_TYPE cryptoMechType; + CK_MECHANISM_TYPE mechanism; SECItem *param; PK11SlotInfo *slot; SECOidTag algtag; @@ -93,19 +92,41 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) /* set param and mechanism */ if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; + CK_MECHANISM pbeMech, cryptoMech; + SECItem *pbeParams, *pwitem; + + PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); + PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); pwitem = PK11_GetSymKeyUserData(key); if (!pwitem) return NULL; - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + /* 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); 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 { - cryptoMechType = PK11_AlgtagToMechanism(algtag); + mechanism = PK11_AlgtagToMechanism(algtag); if ((param = PK11_ParamFromAlgid(algid)) == NULL) return NULL; } @@ -117,14 +138,13 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid) } /* figure out pad and block sizes */ - cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); + cc->pad_size = PK11_GetBlockSize(mechanism, 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(cryptoMechType, CKA_DECRYPT, - key, param); + ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); SECITEM_FreeItem(param, PR_TRUE); if (ciphercx == NULL) { PORT_Free (cc); @@ -142,8 +162,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 @@ -156,26 +176,49 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori void *ciphercx; SECItem *param; SECStatus rv; - CK_MECHANISM_TYPE cryptoMechType; + CK_MECHANISM_TYPE mechanism; PK11SlotInfo *slot; PRBool needToEncodeAlgid = PR_FALSE; SECOidTag algtag = SECOID_GetAlgorithmTag(algid); /* set param and mechanism */ if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; + CK_MECHANISM pbeMech, cryptoMech; + SECItem *pbeParams, *pwitem; + + PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); + PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); pwitem = PK11_GetSymKeyUserData(key); if (!pwitem) return NULL; - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { + /* 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); 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 { - cryptoMechType = PK11_AlgtagToMechanism(algtag); - if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL) + mechanism = PK11_AlgtagToMechanism(algtag); + if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL) return NULL; needToEncodeAlgid = PR_TRUE; } @@ -186,14 +229,13 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori } /* now find pad and block sizes for our mechanism */ - cc->pad_size = PK11_GetBlockSize(cryptoMechType, param); + cc->pad_size = PK11_GetBlockSize(mechanism,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(cryptoMechType, CKA_ENCRYPT, - key, param); + ciphercx = PK11_CreateContextBySymKey(mechanism, 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 a14a3b7c7..0bcbb680a 100644 --- a/security/nss/lib/smime/cmsencdata.c +++ b/security/nss/lib/smime/cmsencdata.c @@ -61,8 +61,7 @@ * (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; @@ -74,7 +73,7 @@ NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, mark = PORT_ArenaMark(poolp); - encd = PORT_ArenaZNew(poolp, NSSCMSEncryptedData); + encd = (NSSCMSEncryptedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEncryptedData)); if (encd == NULL) goto loser; @@ -82,25 +81,23 @@ NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */ - 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 */ + 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. */ pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL); if (pbe_algid == NULL) { rv = SECFailure; - } else { - rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, - &(encd->contentInfo), pbe_algid, keysize); - SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); + break; } + rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, &(encd->contentInfo), pbe_algid, keysize); + SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); + break; } if (rv != SECSuccess) goto loser; |