diff options
Diffstat (limited to 'nss/lib/smime/cmssigdata.c')
-rw-r--r-- | nss/lib/smime/cmssigdata.c | 638 |
1 files changed, 319 insertions, 319 deletions
diff --git a/nss/lib/smime/cmssigdata.c b/nss/lib/smime/cmssigdata.c index a4527d9..7dd6ea4 100644 --- a/nss/lib/smime/cmssigdata.c +++ b/nss/lib/smime/cmssigdata.c @@ -32,9 +32,9 @@ NSS_CMSSignedData_Create(NSSCMSMessage *cmsg) mark = PORT_ArenaMark(poolp); - sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSSignedData)); + sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignedData)); if (sigd == NULL) - goto loser; + goto loser; sigd->cmsg = cmsg; @@ -57,7 +57,7 @@ NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd) NSSCMSSignerInfo **signerinfos, *si; if (sigd == NULL) - return; + return; certs = sigd->certs; tempCerts = sigd->tempCerts; @@ -65,28 +65,27 @@ NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd) signerinfos = sigd->signerInfos; if (certs != NULL) { - while ((cert = *certs++) != NULL) - CERT_DestroyCertificate (cert); + while ((cert = *certs++) != NULL) + CERT_DestroyCertificate(cert); } if (tempCerts != NULL) { - while ((cert = *tempCerts++) != NULL) - CERT_DestroyCertificate (cert); + while ((cert = *tempCerts++) != NULL) + CERT_DestroyCertificate(cert); } if (certlists != NULL) { - while ((certlist = *certlists++) != NULL) - CERT_DestroyCertificateList (certlist); + while ((certlist = *certlists++) != NULL) + CERT_DestroyCertificateList(certlist); } if (signerinfos != NULL) { - while ((si = *signerinfos++) != NULL) - NSS_CMSSignerInfo_Destroy(si); + while ((si = *signerinfos++) != NULL) + NSS_CMSSignerInfo_Destroy(si); } /* everything's in a pool, so don't worry about the storage */ - NSS_CMSContentInfo_Destroy(&(sigd->contentInfo)); - + NSS_CMSContentInfo_Destroy(&(sigd->contentInfo)); } /* @@ -122,58 +121,58 @@ NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd) /* we assume that we have precomputed digests if there is a list of algorithms, and */ /* a chunk of data for each of those algorithms */ if (sigd->digestAlgorithms != NULL && sigd->digests != NULL) { - for (i=0; sigd->digestAlgorithms[i] != NULL; i++) { - if (sigd->digests[i] == NULL) - break; - } - if (sigd->digestAlgorithms[i] == NULL) /* reached the end of the array? */ - haveDigests = PR_TRUE; /* yes: we must have all the digests */ - } - + for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) { + if (sigd->digests[i] == NULL) + break; + } + if (sigd->digestAlgorithms[i] == NULL) /* reached the end of the array? */ + haveDigests = PR_TRUE; /* yes: we must have all the digests */ + } + version = NSS_CMS_SIGNED_DATA_VERSION_BASIC; /* RFC2630 5.1 "version is the syntax version number..." */ if (NSS_CMSContentInfo_GetContentTypeTag(&(sigd->contentInfo)) != SEC_OID_PKCS7_DATA) - version = NSS_CMS_SIGNED_DATA_VERSION_EXT; + version = NSS_CMS_SIGNED_DATA_VERSION_EXT; /* prepare all the SignerInfos (there may be none) */ - for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { - signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); - - /* RFC2630 5.1 "version is the syntax version number..." */ - if (NSS_CMSSignerInfo_GetVersion(signerinfo) != NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN) - version = NSS_CMS_SIGNED_DATA_VERSION_EXT; - - /* collect digestAlgorithms from SignerInfos */ - /* (we need to know which algorithms we have when the content comes in) */ - /* do not overwrite any existing digestAlgorithms (and digest) */ - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - if (n < 0 && haveDigests) { - /* oops, there is a digestalg we do not have a digest for */ - /* but we were supposed to have all the digests already... */ - goto loser; - } else if (n < 0) { - /* add the digestAlgorithm & a NULL digest */ - rv = NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, NULL); - if (rv != SECSuccess) - goto loser; - } else { - /* found it, nothing to do */ - } + for (i = 0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { + signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); + + /* RFC2630 5.1 "version is the syntax version number..." */ + if (NSS_CMSSignerInfo_GetVersion(signerinfo) != NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN) + version = NSS_CMS_SIGNED_DATA_VERSION_EXT; + + /* collect digestAlgorithms from SignerInfos */ + /* (we need to know which algorithms we have when the content comes in) */ + /* do not overwrite any existing digestAlgorithms (and digest) */ + digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); + n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); + if (n < 0 && haveDigests) { + /* oops, there is a digestalg we do not have a digest for */ + /* but we were supposed to have all the digests already... */ + goto loser; + } else if (n < 0) { + /* add the digestAlgorithm & a NULL digest */ + rv = NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, NULL); + if (rv != SECSuccess) + goto loser; + } else { + /* found it, nothing to do */ + } } dummy = SEC_ASN1EncodeInteger(poolp, &(sigd->version), (long)version); if (dummy == NULL) - return SECFailure; + return SECFailure; /* this is a SET OF, so we need to sort them guys */ - rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms, + rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), - (void **)sigd->digests); + (void **)sigd->digests); if (rv != SECSuccess) - return SECFailure; - + return SECFailure; + return SECSuccess; loser: @@ -190,16 +189,16 @@ NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd) } rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo); if (rv != SECSuccess) { - return SECFailure; + return SECFailure; } /* set up the digests */ if (sigd->digests && sigd->digests[0]) { - sigd->contentInfo.privateInfo->digcx = NULL; /* don't attempt to make new ones. */ + sigd->contentInfo.privateInfo->digcx = NULL; /* don't attempt to make new ones. */ } else if (sigd->digestAlgorithms != NULL) { - sigd->contentInfo.privateInfo->digcx = - NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); - if (sigd->contentInfo.privateInfo->digcx == NULL) - return SECFailure; + sigd->contentInfo.privateInfo->digcx = + NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); + if (sigd->contentInfo.privateInfo->digcx == NULL) + return SECFailure; } return SECSuccess; } @@ -239,53 +238,53 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd) /* did we have digest calculation going on? */ if (cinfo->privateInfo && cinfo->privateInfo->digcx) { - rv = NSS_CMSDigestContext_FinishMultiple(cinfo->privateInfo->digcx, poolp, - &(sigd->digests)); - /* error has been set by NSS_CMSDigestContext_FinishMultiple */ - cinfo->privateInfo->digcx = NULL; - if (rv != SECSuccess) - goto loser; + rv = NSS_CMSDigestContext_FinishMultiple(cinfo->privateInfo->digcx, poolp, + &(sigd->digests)); + /* error has been set by NSS_CMSDigestContext_FinishMultiple */ + cinfo->privateInfo->digcx = NULL; + if (rv != SECSuccess) + goto loser; } signerinfos = sigd->signerInfos; certcount = 0; /* prepare all the SignerInfos (there may be none) */ - for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { - signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); - - /* find correct digest for this signerinfo */ - digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); - if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) { - /* oops - digest not found */ - PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - goto loser; - } + for (i = 0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) { + signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i); + + /* find correct digest for this signerinfo */ + digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); + n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); + if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) { + /* oops - digest not found */ + PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); + goto loser; + } - /* XXX if our content is anything else but data, we need to force the - * presence of signed attributes (RFC2630 5.3 "signedAttributes is a - * collection...") */ + /* XXX if our content is anything else but data, we need to force the + * presence of signed attributes (RFC2630 5.3 "signedAttributes is a + * collection...") */ - /* pass contentType here as we want a contentType attribute */ - if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL) - goto loser; + /* pass contentType here as we want a contentType attribute */ + if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL) + goto loser; - /* sign the thing */ - rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType); - if (rv != SECSuccess) - goto loser; + /* sign the thing */ + rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType); + if (rv != SECSuccess) + goto loser; - /* while we're at it, count number of certs in certLists */ - certlist = NSS_CMSSignerInfo_GetCertList(signerinfo); - if (certlist) - certcount += certlist->len; + /* while we're at it, count number of certs in certLists */ + certlist = NSS_CMSSignerInfo_GetCertList(signerinfo); + if (certlist) + certcount += certlist->len; } /* this is a SET OF, so we need to sort them guys */ rv = NSS_CMSArray_SortByDER((void **)signerinfos, NSSCMSSignerInfoTemplate, NULL); if (rv != SECSuccess) - goto loser; + goto loser; /* * now prepare certs & crls @@ -293,65 +292,65 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd) /* count the rest of the certs */ if (sigd->certs != NULL) { - for (ci = 0; sigd->certs[ci] != NULL; ci++) - certcount++; + for (ci = 0; sigd->certs[ci] != NULL; ci++) + certcount++; } if (sigd->certLists != NULL) { - for (cli = 0; sigd->certLists[cli] != NULL; cli++) - certcount += sigd->certLists[cli]->len; + for (cli = 0; sigd->certLists[cli] != NULL; cli++) + certcount += sigd->certLists[cli]->len; } if (certcount == 0) { - sigd->rawCerts = NULL; + sigd->rawCerts = NULL; } else { - /* - * Combine all of the certs and cert chains into rawcerts. - * Note: certcount is an upper bound; we may not need that many slots - * but we will allocate anyway to avoid having to do another pass. - * (The temporary space saving is not worth it.) - * - * XXX ARGH - this NEEDS to be fixed. need to come up with a decent - * SetOfDERcertficates implementation - */ - sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *)); - if (sigd->rawCerts == NULL) - return SECFailure; - - /* - * XXX Want to check for duplicates and not add *any* cert that is - * already in the set. This will be more important when we start - * dealing with larger sets of certs, dual-key certs (signing and - * encryption), etc. For the time being we can slide by... - * - * XXX ARGH - this NEEDS to be fixed. need to come up with a decent - * SetOfDERcertficates implementation - */ - rci = 0; - if (signerinfos != NULL) { - for (si = 0; signerinfos[si] != NULL; si++) { - signerinfo = signerinfos[si]; - for (ci = 0; ci < signerinfo->certList->len; ci++) - sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]); - } - } - - if (sigd->certs != NULL) { - for (ci = 0; sigd->certs[ci] != NULL; ci++) - sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert); - } - - if (sigd->certLists != NULL) { - for (cli = 0; sigd->certLists[cli] != NULL; cli++) { - for (ci = 0; ci < sigd->certLists[cli]->len; ci++) - sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]); - } - } - - sigd->rawCerts[rci] = NULL; - - /* this is a SET OF, so we need to sort them guys - we have the DER already, though */ - NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL); + /* + * Combine all of the certs and cert chains into rawcerts. + * Note: certcount is an upper bound; we may not need that many slots + * but we will allocate anyway to avoid having to do another pass. + * (The temporary space saving is not worth it.) + * + * XXX ARGH - this NEEDS to be fixed. need to come up with a decent + * SetOfDERcertficates implementation + */ + sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *)); + if (sigd->rawCerts == NULL) + return SECFailure; + + /* + * XXX Want to check for duplicates and not add *any* cert that is + * already in the set. This will be more important when we start + * dealing with larger sets of certs, dual-key certs (signing and + * encryption), etc. For the time being we can slide by... + * + * XXX ARGH - this NEEDS to be fixed. need to come up with a decent + * SetOfDERcertficates implementation + */ + rci = 0; + if (signerinfos != NULL) { + for (si = 0; signerinfos[si] != NULL; si++) { + signerinfo = signerinfos[si]; + for (ci = 0; ci < signerinfo->certList->len; ci++) + sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]); + } + } + + if (sigd->certs != NULL) { + for (ci = 0; sigd->certs[ci] != NULL; ci++) + sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert); + } + + if (sigd->certLists != NULL) { + for (cli = 0; sigd->certLists[cli] != NULL; cli++) { + for (ci = 0; ci < sigd->certLists[cli]->len; ci++) + sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]); + } + } + + sigd->rawCerts[rci] = NULL; + + /* this is a SET OF, so we need to sort them guys - we have the DER already, though */ + NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL); } ret = SECSuccess; @@ -370,39 +369,38 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd) } rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo); if (rv != SECSuccess) { - return SECFailure; + return SECFailure; } /* handle issue with Windows 2003 servers and kerberos */ if (sigd->digestAlgorithms != NULL) { - int i; - for (i=0; sigd->digestAlgorithms[i] != NULL; i++) { - SECAlgorithmID *algid = sigd->digestAlgorithms[i]; - SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm); - SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag); - - if (maptag != senttag) { - SECOidData *hashoid = SECOID_FindOIDByTag(maptag); - rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm - ,&hashoid->oid); - if (rv != SECSuccess) { - return rv; - } - } - } + int i; + for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) { + SECAlgorithmID *algid = sigd->digestAlgorithms[i]; + SECOidTag senttag = SECOID_FindOIDTag(&algid->algorithm); + SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag); + + if (maptag != senttag) { + SECOidData *hashoid = SECOID_FindOIDByTag(maptag); + rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm, &hashoid->oid); + if (rv != SECSuccess) { + return rv; + } + } + } } /* set up the digests */ if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) { - /* if digests are already there, do nothing */ - sigd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); - if (sigd->contentInfo.privateInfo->digcx == NULL) - return SECFailure; + /* if digests are already there, do nothing */ + sigd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms); + if (sigd->contentInfo.privateInfo->digcx == NULL) + return SECFailure; } return SECSuccess; } /* - * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a + * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a * SignedData after all the encapsulated data was passed through the decoder. */ SECStatus @@ -417,10 +415,10 @@ NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd) /* did we have digest calculation going on? */ if (sigd->contentInfo.privateInfo && sigd->contentInfo.privateInfo->digcx) { - rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.privateInfo->digcx, - sigd->cmsg->poolp, &(sigd->digests)); - /* error set by NSS_CMSDigestContext_FinishMultiple */ - sigd->contentInfo.privateInfo->digcx = NULL; + rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.privateInfo->digcx, + sigd->cmsg->poolp, &(sigd->digests)); + /* error set by NSS_CMSDigestContext_FinishMultiple */ + sigd->contentInfo.privateInfo->digcx = NULL; } return rv; } @@ -445,14 +443,14 @@ NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd) /* set cmsg for all the signerinfos */ if (signerinfos) { - for (i = 0; signerinfos[i] != NULL; i++) - signerinfos[i]->cmsg = sigd->cmsg; + for (i = 0; signerinfos[i] != NULL; i++) + signerinfos[i]->cmsg = sigd->cmsg; } return SECSuccess; } -/* +/* * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list */ NSSCMSSignerInfo ** @@ -485,7 +483,7 @@ NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i) return sigd->signerInfos[i]; } -/* +/* * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list */ SECAlgorithmID ** @@ -511,7 +509,7 @@ NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd) return &(sigd->contentInfo); } -/* +/* * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list */ SECItem ** @@ -526,7 +524,7 @@ NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd) SECStatus NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, - SECCertUsage certusage, PRBool keepcerts) + SECCertUsage certusage, PRBool keepcerts) { int certcount; CERTCertificate **certArray = NULL; @@ -545,99 +543,99 @@ NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, certcount = NSS_CMSArray_Count((void **)sigd->rawCerts); /* get the certs in the temp DB */ - rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, - &certArray, PR_FALSE, PR_FALSE, NULL); + rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, + &certArray, PR_FALSE, PR_FALSE, NULL); if (rv != SECSuccess) { - goto loser; + goto loser; } /* save the certs so they don't get destroyed */ - for (i=0; i < certcount; i++) { - CERTCertificate *cert = certArray[i]; - if (cert) + for (i = 0; i < certcount; i++) { + CERTCertificate *cert = certArray[i]; + if (cert) NSS_CMSSignedData_AddTempCertificate(sigd, cert); } if (!keepcerts) { - goto done; + goto done; } /* build a CertList for filtering */ certList = CERT_NewCertList(); if (certList == NULL) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } - for (i=0; i < certcount; i++) { - CERTCertificate *cert = certArray[i]; - if (cert) - cert = CERT_DupCertificate(cert); - if (cert) - CERT_AddCertToListTail(certList,cert); + for (i = 0; i < certcount; i++) { + CERTCertificate *cert = certArray[i]; + if (cert) + cert = CERT_DupCertificate(cert); + if (cert) + CERT_AddCertToListTail(certList, cert); } /* filter out the certs we don't want */ - rv = CERT_FilterCertListByUsage(certList,certusage, PR_FALSE); + rv = CERT_FilterCertListByUsage(certList, certusage, PR_FALSE); if (rv != SECSuccess) { - goto loser; + goto loser; } /* go down the remaining list of certs and verify that they have * valid chains, then import them. */ now = PR_Now(); - for (node = CERT_LIST_HEAD(certList) ; !CERT_LIST_END(node,certList); - node= CERT_LIST_NEXT(node)) { - CERTCertificateList *certChain; - - if (CERT_VerifyCert(certdb, node->cert, - PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) { - continue; - } - - certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE); - if (!certChain) { - continue; - } - - /* - * CertChain returns an array of SECItems, import expects an array of - * SECItem pointers. Create the SECItem Pointers from the array of - * SECItems. - */ - rawArray = (SECItem **)PORT_Alloc(certChain->len*sizeof (SECItem *)); - if (!rawArray) { - CERT_DestroyCertificateList(certChain); - continue; - } - for (i=0; i < certChain->len; i++) { - rawArray[i] = &certChain->certs[i]; - } - (void )CERT_ImportCerts(certdb, certusage, certChain->len, - rawArray, NULL, keepcerts, PR_FALSE, NULL); - PORT_Free(rawArray); - CERT_DestroyCertificateList(certChain); + for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); + node = CERT_LIST_NEXT(node)) { + CERTCertificateList *certChain; + + if (CERT_VerifyCert(certdb, node->cert, + PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) { + continue; + } + + certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE); + if (!certChain) { + continue; + } + + /* + * CertChain returns an array of SECItems, import expects an array of + * SECItem pointers. Create the SECItem Pointers from the array of + * SECItems. + */ + rawArray = (SECItem **)PORT_Alloc(certChain->len * sizeof(SECItem *)); + if (!rawArray) { + CERT_DestroyCertificateList(certChain); + continue; + } + for (i = 0; i < certChain->len; i++) { + rawArray[i] = &certChain->certs[i]; + } + (void)CERT_ImportCerts(certdb, certusage, certChain->len, + rawArray, NULL, keepcerts, PR_FALSE, NULL); + PORT_Free(rawArray); + CERT_DestroyCertificateList(certChain); } rv = SECSuccess; - /* XXX CRL handling */ +/* XXX CRL handling */ done: if (sigd->signerInfos != NULL) { - /* fill in all signerinfo's certs */ - for (i = 0; sigd->signerInfos[i] != NULL; i++) - (void)NSS_CMSSignerInfo_GetSigningCertificate( - sigd->signerInfos[i], certdb); + /* fill in all signerinfo's certs */ + for (i = 0; sigd->signerInfos[i] != NULL; i++) + (void)NSS_CMSSignerInfo_GetSigningCertificate( + sigd->signerInfos[i], certdb); } loser: /* now free everything */ if (certArray) { - CERT_DestroyCertArray(certArray,certcount); + CERT_DestroyCertArray(certArray, certcount); } if (certList) { - CERT_DestroyCertList(certList); + CERT_DestroyCertList(certList); } return rv; @@ -658,8 +656,8 @@ loser: * for the purpose specified by "certusage". */ SECStatus -NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, - CERTCertDBHandle *certdb, SECCertUsage certusage) +NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, + CERTCertDBHandle *certdb, SECCertUsage certusage) { NSSCMSSignerInfo *signerinfo; NSSCMSContentInfo *cinfo; @@ -680,7 +678,7 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, /* verify certificate */ rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage); if (rv != SECSuccess) - return rv; /* error is set */ + return rv; /* error is set */ /* find digest and contentType for signerinfo */ algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo); @@ -699,8 +697,8 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message */ SECStatus -NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd, - CERTCertDBHandle *certdb, +NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd, + CERTCertDBHandle *certdb, SECCertUsage usage) { CERTCertificate *cert; @@ -708,27 +706,31 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd, int i; int count; PRTime now; + void *pwarg = NULL; if (!sigd || !certdb || !sigd->rawCerts) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } - count = NSS_CMSArray_Count((void**)sigd->rawCerts); + count = NSS_CMSArray_Count((void **)sigd->rawCerts); now = PR_Now(); - for (i=0; i < count; i++) { - if (sigd->certs && sigd->certs[i]) { - cert = CERT_DupCertificate(sigd->certs[i]); - } else { - cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]); - if (!cert) { - rv = SECFailure; - break; - } - } - rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now, - NULL, NULL); - CERT_DestroyCertificate(cert); + for (i = 0; i < count; i++) { + if (sigd->certs && sigd->certs[i]) { + cert = CERT_DupCertificate(sigd->certs[i]); + } else { + cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]); + if (!cert) { + rv = SECFailure; + break; + } + } + if (sigd->cmsg) { + pwarg = sigd->cmsg->pwfn_arg; + } + rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now, + pwarg, NULL); + CERT_DestroyCertificate(cert); } return rv; @@ -764,7 +766,7 @@ NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certl } /* - * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs + * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs */ SECStatus NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert) @@ -783,7 +785,7 @@ NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert) /* do not include root */ certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); if (certlist == NULL) - return SECFailure; + return SECFailure; rv = NSS_CMSSignedData_AddCertList(sigd, certlist); @@ -830,16 +832,16 @@ NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd) return PR_FALSE; } if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL) - return PR_TRUE; + return PR_TRUE; else if (sigd->crls != NULL && sigd->crls[0] != NULL) - return PR_TRUE; + return PR_TRUE; else - return PR_FALSE; + return PR_FALSE; } SECStatus NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, - NSSCMSSignerInfo *signerinfo) + NSSCMSSignerInfo *signerinfo) { void *mark; SECStatus rv; @@ -858,7 +860,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, /* add signerinfo */ rv = NSS_CMSArray_Add(poolp, (void ***)&(sigd->signerInfos), (void *)signerinfo); if (rv != SECSuccess) - goto loser; + goto loser; /* * add empty digest @@ -869,7 +871,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); rv = NSS_CMSSignedData_SetDigestValue(sigd, digestalgtag, NULL); if (rv != SECSuccess) - goto loser; + goto loser; /* * The last thing to get consistency would be adding the digest. @@ -879,7 +881,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd, return SECSuccess; loser: - PORT_ArenaRelease (poolp, mark); + PORT_ArenaRelease(poolp, mark); return SECFailure; } @@ -891,8 +893,8 @@ loser: */ SECStatus NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd, - SECAlgorithmID **digestalgs, - SECItem **digests) + SECAlgorithmID **digestalgs, + SECItem **digests) { int cnt, i, idx; @@ -902,55 +904,54 @@ NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd, } if (sigd->digestAlgorithms == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } /* we assume that the digests array is just not there yet */ PORT_Assert(sigd->digests == NULL); if (sigd->digests != NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } /* now allocate one (same size as digestAlgorithms) */ cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms); sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *)); if (sigd->digests == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; } for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) { - /* try to find the sigd's i'th digest algorithm in the array we passed in */ - idx = NSS_CMSAlgArray_GetIndexByAlgID(digestalgs, sigd->digestAlgorithms[i]); - if (idx < 0) { - PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - return SECFailure; - } - if (!digests[idx]) { - /* We have no digest for this algorithm, probably because it is - ** unrecognized or unsupported. We'll ignore this here. If this - ** digest is needed later, an error will be be generated then. - */ - continue; - } - - /* found it - now set it */ - if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL || - SECITEM_CopyItem(sigd->cmsg->poolp, sigd->digests[i], digests[idx]) != SECSuccess) - { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } + /* try to find the sigd's i'th digest algorithm in the array we passed in */ + idx = NSS_CMSAlgArray_GetIndexByAlgID(digestalgs, sigd->digestAlgorithms[i]); + if (idx < 0) { + PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); + return SECFailure; + } + if (!digests[idx]) { + /* We have no digest for this algorithm, probably because it is + ** unrecognized or unsupported. We'll ignore this here. If this + ** digest is needed later, an error will be be generated then. + */ + continue; + } + + /* found it - now set it */ + if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL || + SECITEM_CopyItem(sigd->cmsg->poolp, sigd->digests[i], digests[idx]) != SECSuccess) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; + } } return SECSuccess; } SECStatus NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digestdata) + SECOidTag digestalgtag, + SECItem *digestdata) { SECItem *digest = NULL; PLArenaPool *poolp; @@ -966,13 +967,12 @@ NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, mark = PORT_ArenaMark(poolp); - if (digestdata) { - digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem)); + digest = (SECItem *)PORT_ArenaZAlloc(poolp, sizeof(SECItem)); - /* copy digestdata item to arena (in case we have it and are not only making room) */ - if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess) - goto loser; + /* copy digestdata item to arena (in case we have it and are not only making room) */ + if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess) + goto loser; } /* now allocate one (same size as digestAlgorithms) */ @@ -980,22 +980,22 @@ NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd, cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms); sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *)); if (sigd->digests == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; } } n = -1; if (sigd->digestAlgorithms != NULL) - n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); + n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); /* if not found, add a digest */ if (n < 0) { - if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess) - goto loser; + if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess) + goto loser; } else { - /* replace NULL pointer with digest item (and leak previous value) */ - sigd->digests[n] = digest; + /* replace NULL pointer with digest item (and leak previous value) */ + sigd->digests[n] = digest; } PORT_ArenaUnmark(poolp, mark); @@ -1008,9 +1008,9 @@ loser: SECStatus NSS_CMSSignedData_AddDigest(PLArenaPool *poolp, - NSSCMSSignedData *sigd, - SECOidTag digestalgtag, - SECItem *digest) + NSSCMSSignedData *sigd, + SECOidTag digestalgtag, + SECItem *digest) { SECAlgorithmID *digestalg; void *mark; @@ -1024,16 +1024,17 @@ NSS_CMSSignedData_AddDigest(PLArenaPool *poolp, digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); if (digestalg == NULL) - goto loser; + goto loser; - if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */ - goto loser; + if (SECOID_SetAlgorithmID(poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */ + goto loser; - if (NSS_CMSArray_Add(poolp, (void ***)&(sigd->digestAlgorithms), (void *)digestalg) != SECSuccess || - /* even if digest is NULL, add dummy to have same-size array */ - NSS_CMSArray_Add(poolp, (void ***)&(sigd->digests), (void *)digest) != SECSuccess) - { - goto loser; + if (NSS_CMSArray_Add(poolp, (void ***)&(sigd->digestAlgorithms), + (void *)digestalg) != SECSuccess || + /* even if digest is NULL, add dummy to have same-size array */ + NSS_CMSArray_Add(poolp, (void ***)&(sigd->digests), + (void *)digest) != SECSuccess) { + goto loser; } PORT_ArenaUnmark(poolp, mark); @@ -1057,7 +1058,7 @@ NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag) if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) { PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND); - return NULL; + return NULL; } n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag); @@ -1099,18 +1100,18 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR sigd = NSS_CMSSignedData_Create(cmsg); if (sigd == NULL) - goto loser; + goto loser; /* no signerinfos, thus no digestAlgorithms */ /* but certs */ if (include_chain) { - rv = NSS_CMSSignedData_AddCertChain(sigd, cert); + rv = NSS_CMSSignedData_AddCertChain(sigd, cert); } else { - rv = NSS_CMSSignedData_AddCertificate(sigd, cert); + rv = NSS_CMSSignedData_AddCertificate(sigd, cert); } if (rv != SECSuccess) - goto loser; + goto loser; /* RFC2630 5.2 sez: * In the degenerate case where there are no signers, the @@ -1121,14 +1122,14 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR */ rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE); if (rv != SECSuccess) - goto loser; + goto loser; PORT_ArenaUnmark(poolp, mark); return sigd; loser: if (sigd) - NSS_CMSSignedData_Destroy(sigd); + NSS_CMSSignedData_Destroy(sigd); PORT_ArenaRelease(poolp, mark); return NULL; } @@ -1138,4 +1139,3 @@ loser: * NSS_CMSSignedData_HasReceiptRequest() * easy way to iterate over signers */ - |