diff options
Diffstat (limited to 'security/nss/lib/smime')
-rw-r--r-- | security/nss/lib/smime/cmscinfo.c | 92 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsdigdata.c | 4 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsencdata.c | 4 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsenvdata.c | 5 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsmessage.c | 72 | ||||
-rw-r--r-- | security/nss/lib/smime/cmssiginfo.c | 107 | ||||
-rw-r--r-- | security/nss/lib/smime/cmsudf.c | 2 | ||||
-rw-r--r-- | security/nss/lib/smime/smimeutil.c | 19 |
8 files changed, 255 insertions, 50 deletions
diff --git a/security/nss/lib/smime/cmscinfo.c b/security/nss/lib/smime/cmscinfo.c index 08db662f8..453ccaada 100644 --- a/security/nss/lib/smime/cmscinfo.c +++ b/security/nss/lib/smime/cmscinfo.c @@ -51,6 +51,10 @@ NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo) { SECOidTag kind; + if (cinfo == NULL) { + return; + } + kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo); switch (kind) { case SEC_OID_PKCS7_ENVELOPED_DATA: @@ -86,6 +90,11 @@ NSSCMSContentInfo * NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo) { NSSCMSContentInfo *ccinfo = NULL; + + if (cinfo == NULL) { + return NULL; + } + SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); switch (tag) { case SEC_OID_PKCS7_SIGNED_DATA: @@ -127,6 +136,9 @@ SECStatus NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream) { SECStatus rv; + if (cinfo == NULL) { + return SECFailure; + } rv = NSS_CMSContentInfo_Private_Init(cinfo); if (rv != SECSuccess) { @@ -145,15 +157,20 @@ NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr) { SECStatus rv; + if (cinfo == NULL || cmsg == NULL) { + return SECFailure; + } cinfo->contentTypeTag = SECOID_FindOIDByTag(type); - if (cinfo->contentTypeTag == NULL) + if (cinfo->contentTypeTag == NULL) { return SECFailure; + } /* do not copy the oid, just create a reference */ rv = SECITEM_CopyItem(cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid)); - if (rv != SECSuccess) + if (rv != SECSuccess) { return SECFailure; + } cinfo->content.pointer = ptr; @@ -185,8 +202,9 @@ SECStatus NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached) { - if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) + if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) { return SECFailure; + } if (detached) { cinfo->rawContent = NULL; } @@ -230,6 +248,10 @@ NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentIn void * NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo) { + if (cinfo == NULL) { + return NULL; + } + SECOidTag tag = cinfo->contentTypeTag ? cinfo->contentTypeTag->offset : SEC_OID_UNKNOWN; @@ -260,6 +282,10 @@ NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo) SECOidTag tag; SECItem *pItem = NULL; + if (cinfo == NULL) { + return NULL; + } + tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo); if (NSS_CMSType_IsData(tag)) { pItem = cinfo->content.data; @@ -282,6 +308,10 @@ NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo) SECOidTag NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo) { + if (cinfo == NULL) { + return SEC_OID_UNKNOWN; + } + if (cinfo->contentTypeTag == NULL) cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); @@ -294,11 +324,17 @@ NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo) SECItem * NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo) { - if (cinfo->contentTypeTag == NULL) + if (cinfo == NULL) { + return NULL; + } + + if (cinfo->contentTypeTag == NULL) { cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); + } - if (cinfo->contentTypeTag == NULL) + if (cinfo->contentTypeTag == NULL) { return NULL; + } return &(cinfo->contentTypeTag->oid); } @@ -310,8 +346,13 @@ NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo) SECOidTag NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo) { - if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN) + if (cinfo == NULL) { + return SEC_OID_UNKNOWN; + } + + if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN) { cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg)); + } return cinfo->contentEncAlgTag; } @@ -322,6 +363,10 @@ NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo) SECAlgorithmID * NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo) { + if (cinfo == NULL) { + return NULL; + } + return &(cinfo->contentEncAlg); } @@ -330,10 +375,14 @@ NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo SECOidTag bulkalgtag, SECItem *parameters, int keysize) { SECStatus rv; + if (cinfo == NULL) { + return SECFailure; + } rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters); - if (rv != SECSuccess) + if (rv != SECSuccess) { return SECFailure; + } cinfo->keysize = keysize; return SECSuccess; } @@ -343,27 +392,42 @@ NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cin SECAlgorithmID *algid, int keysize) { SECStatus rv; + if (cinfo == NULL) { + return SECFailure; + } rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid); - if (rv != SECSuccess) + if (rv != SECSuccess) { return SECFailure; - if (keysize >= 0) + } + if (keysize >= 0) { cinfo->keysize = keysize; + } return SECSuccess; } void NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey) { - cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey); - cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg)); + if (cinfo == NULL) { + return; + } + + if (bulkkey == NULL) { + cinfo->bulkkey = NULL; + cinfo->keysize = 0; + } else { + cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey); + cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg)); + } } PK11SymKey * NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo) { - if (cinfo->bulkkey == NULL) + if (cinfo == NULL || cinfo->bulkkey == NULL) { return NULL; + } return PK11_ReferenceSymKey(cinfo->bulkkey); } @@ -371,5 +435,9 @@ NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo) int NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo) { + if (cinfo == NULL) { + return 0; + } + return cinfo->keysize; } diff --git a/security/nss/lib/smime/cmsdigdata.c b/security/nss/lib/smime/cmsdigdata.c index 9ea22702e..a249686bb 100644 --- a/security/nss/lib/smime/cmsdigdata.c +++ b/security/nss/lib/smime/cmsdigdata.c @@ -56,7 +56,9 @@ void NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd) { /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); + if (digd != NULL) { + NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); + } return; } diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c index d2fc3358b..f2a27468e 100644 --- a/security/nss/lib/smime/cmsencdata.c +++ b/security/nss/lib/smime/cmsencdata.c @@ -87,7 +87,9 @@ void NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd) { /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(encd->contentInfo)); + if (encd != NULL) { + NSS_CMSContentInfo_Destroy(&(encd->contentInfo)); + } return; } diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c index d5d5c4123..95b3fb98b 100644 --- a/security/nss/lib/smime/cmsenvdata.c +++ b/security/nss/lib/smime/cmsenvdata.c @@ -144,6 +144,11 @@ NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd) poolp = envd->cmsg->poolp; cinfo = &(envd->contentInfo); + if (cinfo == NULL) { + PORT_SetError(SEC_ERROR_BAD_DATA); + goto loser; + } + recipientinfos = envd->recipientInfos; if (recipientinfos == NULL) { PORT_SetError(SEC_ERROR_BAD_DATA); diff --git a/security/nss/lib/smime/cmsmessage.c b/security/nss/lib/smime/cmsmessage.c index 27d1256ec..366b71aba 100644 --- a/security/nss/lib/smime/cmsmessage.c +++ b/security/nss/lib/smime/cmsmessage.c @@ -29,8 +29,9 @@ NSS_CMSMessage_Create(PLArenaPool *poolp) if (poolp == NULL) { poolp = PORT_NewArena(1024); /* XXX what is right value? */ - if (poolp == NULL) + if (poolp == NULL) { return NULL; + } poolp_is_ours = PR_TRUE; } @@ -44,8 +45,9 @@ NSS_CMSMessage_Create(PLArenaPool *poolp) if (mark) { PORT_ArenaRelease(poolp, mark); } - } else + } else { PORT_FreeArena(poolp, PR_FALSE); + } return NULL; } @@ -53,8 +55,9 @@ NSS_CMSMessage_Create(PLArenaPool *poolp) cmsg->poolp_is_ours = poolp_is_ours; cmsg->refCount = 1; - if (mark) + if (mark) { PORT_ArenaUnmark(poolp, mark); + } return cmsg; } @@ -73,8 +76,13 @@ NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg, NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, SECAlgorithmID **detached_digestalgs, SECItem **detached_digests) { - if (pwfn) + if (cmsg == NULL) { + return; + } + if (pwfn) { PK11_SetPasswordFunc(pwfn); + } + cmsg->pwfn_arg = pwfn_arg; cmsg->decrypt_key_cb = decrypt_key_cb; cmsg->decrypt_key_cb_arg = decrypt_key_cb_arg; @@ -88,19 +96,25 @@ NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg, void NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg) { + if (cmsg == NULL) + return; + PORT_Assert(cmsg->refCount > 0); - if (cmsg->refCount <= 0) /* oops */ + if (cmsg->refCount <= 0) { /* oops */ return; + } cmsg->refCount--; /* thread safety? */ - if (cmsg->refCount > 0) + if (cmsg->refCount > 0) { return; + } NSS_CMSContentInfo_Destroy(&(cmsg->contentInfo)); /* if poolp is not NULL, cmsg is the owner of its arena */ - if (cmsg->poolp_is_ours) + if (cmsg->poolp_is_ours) { PORT_FreeArena(cmsg->poolp, PR_FALSE); /* XXX clear it? */ + } } /* @@ -112,8 +126,9 @@ NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg) NSSCMSMessage * NSS_CMSMessage_Copy(NSSCMSMessage *cmsg) { - if (cmsg == NULL) + if (cmsg == NULL) { return NULL; + } PORT_Assert(cmsg->refCount > 0); @@ -127,6 +142,10 @@ NSS_CMSMessage_Copy(NSSCMSMessage *cmsg) PLArenaPool * NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg) { + if (cmsg == NULL) { + return NULL; + } + return cmsg->poolp; } @@ -136,6 +155,10 @@ NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg) NSSCMSContentInfo * NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg) { + if (cmsg == NULL) { + return NULL; + } + return &(cmsg->contentInfo); } @@ -147,6 +170,10 @@ NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg) SECItem * NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg) { + if (cmsg == NULL) { + return NULL; + } + /* this is a shortcut */ NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(cmsg); SECItem *pItem = NSS_CMSContentInfo_GetInnerContent(cinfo); @@ -164,6 +191,10 @@ NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg) int count = 0; NSSCMSContentInfo *cinfo; + if (cmsg == NULL) { + return 0; + } + /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL;) { count++; @@ -183,6 +214,10 @@ NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n) int count = 0; NSSCMSContentInfo *cinfo; + if (cmsg == NULL) { + return NULL; + } + /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { @@ -200,6 +235,10 @@ NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg) { NSSCMSContentInfo *cinfo; + if (cmsg == NULL) { + return PR_FALSE; + } + /* descend into CMS message */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { @@ -221,6 +260,10 @@ NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg) { NSSCMSContentInfo *cinfo; + if (cmsg == NULL) { + return PR_FALSE; + } + /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { @@ -251,13 +294,21 @@ NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg) { NSSCMSContentInfo *cinfo; + if (cmsg == NULL) { + return PR_FALSE; + } + /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) { switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) { case SEC_OID_PKCS7_SIGNED_DATA: - if (!NSS_CMSArray_IsEmpty((void **)cinfo->content.signedData->signerInfos)) + if (cinfo->content.signedData == NULL) { + return PR_FALSE; + } + if (!NSS_CMSArray_IsEmpty((void **)cinfo->content.signedData->signerInfos)) { return PR_TRUE; + } break; default: /* callback here for generic wrappers? */ @@ -278,8 +329,9 @@ NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen) { SECItem *item = NULL; - if (cmsg == NULL) + if (cmsg == NULL) { return PR_TRUE; + } item = NSS_CMSContentInfo_GetContent(NSS_CMSMessage_GetContentInfo(cmsg)); diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c index 79aaf8f0a..ed966f889 100644 --- a/security/nss/lib/smime/cmssiginfo.c +++ b/security/nss/lib/smime/cmssiginfo.c @@ -131,6 +131,22 @@ NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si) /* XXX storage ??? */ } +static SECOidTag +NSS_CMSSignerInfo_GetSignatureAlgorithmOidTag(KeyType keyType, + SECOidTag pubkAlgTag, + SECOidTag signAlgTag) +{ + switch (keyType) { + case rsaKey: + return pubkAlgTag; + case rsaPssKey: + case dsaKey: + case ecKey: + return signAlgTag; + default: + return SEC_OID_UNKNOWN; + } +} /* * NSS_CMSSignerInfo_Sign - sign something @@ -144,6 +160,8 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECKEYPrivateKey *privkey = NULL; SECOidTag digestalgtag; SECOidTag pubkAlgTag; + SECOidTag signAlgTag; + SECOidTag cmsSignAlgTag; SECItem signature = { 0 }; SECStatus rv; PLArenaPool *poolp, *tmppoolp = NULL; @@ -182,12 +200,29 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, * so that I do not have to know about subjectPublicKeyInfo... */ pubkAlgTag = SECOID_GetAlgorithmTag(algID); - if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) { + if (algID == &freeAlgID) { SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE); } + signAlgTag = SEC_GetSignatureAlgorithmOidTag(SECKEY_GetPrivateKeyType(privkey), + digestalgtag); + if (signAlgTag == SEC_OID_UNKNOWN) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + goto loser; + } + + cmsSignAlgTag = NSS_CMSSignerInfo_GetSignatureAlgorithmOidTag( + SECKEY_GetPrivateKeyType(privkey), pubkAlgTag, signAlgTag); + if (cmsSignAlgTag == SEC_OID_UNKNOWN) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + goto loser; + } + + if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), + cmsSignAlgTag, NULL) != SECSuccess) + goto loser; + if (signerinfo->authAttr != NULL) { - SECOidTag signAlgTag; SECItem encoded_attrs; /* find and fill in the message digest attribute. */ @@ -230,13 +265,6 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, &encoded_attrs) == NULL) goto loser; - signAlgTag = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, - digestalgtag); - if (signAlgTag == SEC_OID_UNKNOWN) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - goto loser; - } - rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len, privkey, signAlgTag); PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */ @@ -255,10 +283,6 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECITEM_FreeItem(&signature, PR_FALSE); - if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag, - NULL) != SECSuccess) - goto loser; - return SECSuccess; loser: @@ -326,6 +350,8 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, PLArenaPool *poolp; SECOidTag digestalgtag; SECOidTag pubkAlgTag; + SECOidTag digestalgtagCmp; + SECOidTag sigAlgTag; if (signerinfo == NULL) return SECFailure; @@ -345,8 +371,10 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, } digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)); - if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN)) { + pubkAlgTag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); + sigAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)); + if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN) || + (sigAlgTag == SEC_OID_UNKNOWN)) { vs = NSSCMSVS_SignatureAlgorithmUnknown; goto loser; } @@ -414,11 +442,28 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, goto loser; } - vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len, - publickey, &(signerinfo->encDigest), pubkAlgTag, - digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess) - ? NSSCMSVS_BadSignature - : NSSCMSVS_GoodSignature; + if (sigAlgTag == pubkAlgTag) { + /* This is to handle cases in which signatureAlgorithm field + * specifies the public key algorithm rather than a signature + * algorithm. */ + vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len, + publickey, &(signerinfo->encDigest), pubkAlgTag, + digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess) + ? NSSCMSVS_BadSignature + : NSSCMSVS_GoodSignature; + } else { + if (VFY_VerifyDataWithAlgorithmID(encoded_attrs.data, + encoded_attrs.len, publickey, &(signerinfo->encDigest), + &(signerinfo->digestEncAlg), &digestalgtagCmp, + signerinfo->cmsg->pwfn_arg) != SECSuccess) { + vs = NSSCMSVS_BadSignature; + } else if (digestalgtagCmp != digestalgtag) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + vs = NSSCMSVS_BadSignature; + } else { + vs = NSSCMSVS_GoodSignature; + } + } PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */ @@ -432,11 +477,23 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, if (sig->len == 0) goto loser; - vs = (!digest || - VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag, - digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess) - ? NSSCMSVS_BadSignature - : NSSCMSVS_GoodSignature; + if (sigAlgTag == pubkAlgTag) { + /* This is to handle cases in which signatureAlgorithm field + * specifies the public key algorithm rather than a signature + * algorithm. */ + vs = (!digest || + VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag, + digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess) + ? NSSCMSVS_BadSignature + : NSSCMSVS_GoodSignature; + } else { + vs = (!digest || + VFY_VerifyDigestWithAlgorithmID(digest, publickey, sig, + &(signerinfo->digestEncAlg), digestalgtag, + signerinfo->cmsg->pwfn_arg) != SECSuccess) + ? NSSCMSVS_BadSignature + : NSSCMSVS_GoodSignature; + } } if (vs == NSSCMSVS_BadSignature) { diff --git a/security/nss/lib/smime/cmsudf.c b/security/nss/lib/smime/cmsudf.c index 3ef4268d4..5c8a81e6d 100644 --- a/security/nss/lib/smime/cmsudf.c +++ b/security/nss/lib/smime/cmsudf.c @@ -239,7 +239,7 @@ NSS_CMSGenericWrapperData_Destroy(SECOidTag type, NSSCMSGenericWrapperData *gd) { const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type); - if (typeInfo && typeInfo->destroy) { + if (typeInfo && (typeInfo->destroy) && (gd != NULL)) { (*typeInfo->destroy)(gd); } } diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c index 0e6bd32fd..a7df96e91 100644 --- a/security/nss/lib/smime/smimeutil.c +++ b/security/nss/lib/smime/smimeutil.c @@ -457,6 +457,25 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts) cipher_votes[strong_mapi] += pref; pref--; } else { + if (pklen_bits > 3072) { + /* While support for AES 256 is a SHOULD+ in RFC 5751 + * rather than a MUST, RSA and DSA keys longer than 3072 + * bits provide more than 128 bits of security strength. + * So, AES 256 should be used to provide comparable + * security. */ + cipher_abilities[aes256_mapi]++; + cipher_votes[aes256_mapi] += pref; + pref--; + } + if (pklen_bits > 1023) { + /* RFC 5751 mandates support for AES 128, but also says + * that RSA and DSA signature keys SHOULD NOT be less than + * 1024 bits. So, cast vote for AES 128 if key length + * is at least 1024 bits. */ + cipher_abilities[aes128_mapi]++; + cipher_votes[aes128_mapi] += pref; + pref--; + } if (pklen_bits > 512) { /* cast votes for the strong algorithm */ cipher_abilities[strong_mapi]++; |