summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelson%bolyard.com <devnull@localhost>2008-02-03 06:08:49 +0000
committernelson%bolyard.com <devnull@localhost>2008-02-03 06:08:49 +0000
commit1383c0af9e24d12efc4fedd54d64f1aa5e4af2ac (patch)
tree4b8be185ca1631b86e13ab31f5c1fa4d6a42618f
parent84330999fc4bacf4855d50fc40b3513d6358fa9d (diff)
downloadnss-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.c31
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c9
-rw-r--r--security/nss/lib/pk11wrap/secmodi.h5
-rw-r--r--security/nss/lib/pkcs12/p12.h1
-rw-r--r--security/nss/lib/pkcs12/p12d.c11
-rw-r--r--security/nss/lib/pkcs12/p12e.c30
-rw-r--r--security/nss/lib/pkcs7/p7common.c76
-rw-r--r--security/nss/lib/pkcs7/p7create.c36
-rw-r--r--security/nss/lib/pkcs7/p7local.c76
-rw-r--r--security/nss/lib/smime/cmscipher.c84
-rw-r--r--security/nss/lib/smime/cmsencdata.c33
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, &param, 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, &param, 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, &param, 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, &param, 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;