Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(474)

Side by Side Diff: nss/lib/pkcs7/p7decode.c

Issue 13898013: Update NSS to NSS_3_15_BETA2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Update NSS versions and tag in README.chromium Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 /* 5 /*
6 * PKCS7 decoding, verification. 6 * PKCS7 decoding, verification.
7 * 7 *
8 * $Id$ 8 * $Id$
9 */ 9 */
10 10
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 * more complicated before I am finished, so... 1239 * more complicated before I am finished, so...
1240 */ 1240 */
1241 if (signerinfos != NULL && signerinfos[0] != NULL) 1241 if (signerinfos != NULL && signerinfos[0] != NULL)
1242 return PR_TRUE; 1242 return PR_TRUE;
1243 else 1243 else
1244 return PR_FALSE; 1244 return PR_FALSE;
1245 } 1245 }
1246 1246
1247 1247
1248 /* 1248 /*
1249 * SEC_PKCS7ContentVerifySignature 1249 * sec_pkcs7_verify_signature
1250 *
1250 * Look at a PKCS7 contentInfo and check if the signature is good. 1251 * Look at a PKCS7 contentInfo and check if the signature is good.
1251 * The digest was either calculated earlier (and is stored in the 1252 * The digest was either calculated earlier (and is stored in the
1252 * contentInfo itself) or is passed in via "detached_digest". 1253 * contentInfo itself) or is passed in via "detached_digest".
1253 * 1254 *
1254 * The verification checks that the signing cert is valid and trusted 1255 * The verification checks that the signing cert is valid and trusted
1255 *» for the purpose specified by "certusage". 1256 *» for the purpose specified by "certusage" at
1257 * » - "*atTime" if "atTime" is not null, or
1258 * » - the signing time if the signing time is available in "cinfo", or
1259 *» - the current time (as returned by PR_Now).
1256 * 1260 *
1257 * In addition, if "keepcerts" is true, add any new certificates found 1261 * In addition, if "keepcerts" is true, add any new certificates found
1258 * into our local database. 1262 * into our local database.
1259 * 1263 *
1260 * XXX Each place which returns PR_FALSE should be sure to have a good 1264 * XXX Each place which returns PR_FALSE should be sure to have a good
1261 * error set for inspection by the caller. Alternatively, we could create 1265 * error set for inspection by the caller. Alternatively, we could create
1262 * an enumeration of success and each type of failure and return that 1266 * an enumeration of success and each type of failure and return that
1263 * instead of a boolean. For now, the default in a bad situation is to 1267 * instead of a boolean. For now, the default in a bad situation is to
1264 * set the error to SEC_ERROR_PKCS7_BAD_SIGNATURE. But this should be 1268 * set the error to SEC_ERROR_PKCS7_BAD_SIGNATURE. But this should be
1265 * reviewed; better (more specific) errors should be possible (to distinguish 1269 * reviewed; better (more specific) errors should be possible (to distinguish
1266 * a signature failure from a badly-formed pkcs7 signedData, for example). 1270 * a signature failure from a badly-formed pkcs7 signedData, for example).
1267 * Some of the errors should probably just be SEC_ERROR_BAD_SIGNATURE, 1271 * Some of the errors should probably just be SEC_ERROR_BAD_SIGNATURE,
1268 * but that has a less helpful error string associated with it right now; 1272 * but that has a less helpful error string associated with it right now;
1269 * if/when that changes, review and change these as needed. 1273 * if/when that changes, review and change these as needed.
1270 * 1274 *
1271 * XXX This is broken wrt signedAndEnvelopedData. In that case, the 1275 * XXX This is broken wrt signedAndEnvelopedData. In that case, the
1272 * message digest is doubly encrypted -- first encrypted with the signer 1276 * message digest is doubly encrypted -- first encrypted with the signer
1273 * private key but then again encrypted with the bulk encryption key used 1277 * private key but then again encrypted with the bulk encryption key used
1274 * to encrypt the content. So before we can pass the digest to VerifyDigest, 1278 * to encrypt the content. So before we can pass the digest to VerifyDigest,
1275 * we need to decrypt it with the bulk encryption key. Also, in this case, 1279 * we need to decrypt it with the bulk encryption key. Also, in this case,
1276 * there should be NO authenticatedAttributes (signerinfo->authAttr should 1280 * there should be NO authenticatedAttributes (signerinfo->authAttr should
1277 * be NULL). 1281 * be NULL).
1278 */ 1282 */
1279 static PRBool 1283 static PRBool
1280 sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, 1284 sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
1281 SECCertUsage certusage, 1285 SECCertUsage certusage,
1282 const SECItem *detached_digest, 1286 const SECItem *detached_digest,
1283 HASH_HashType digest_type, 1287 HASH_HashType digest_type,
1284 » » » PRBool keepcerts) 1288 » » » PRBool keepcerts,
1289 » » » const PRTime *atTime)
1285 { 1290 {
1286 SECAlgorithmID **digestalgs, *bulkid; 1291 SECAlgorithmID **digestalgs, *bulkid;
1287 const SECItem *digest; 1292 const SECItem *digest;
1288 SECItem **digests; 1293 SECItem **digests;
1289 SECItem **rawcerts; 1294 SECItem **rawcerts;
1290 CERTSignedCrl **crls; 1295 CERTSignedCrl **crls;
1291 SEC_PKCS7SignerInfo **signerinfos, *signerinfo; 1296 SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
1292 CERTCertificate *cert, **certs; 1297 CERTCertificate *cert, **certs;
1293 PRBool goodsig; 1298 PRBool goodsig;
1294 CERTCertDBHandle *certdb, *defaultdb; 1299 CERTCertDBHandle *certdb, *defaultdb;
1295 SECOidTag encTag,digestTag; 1300 SECOidTag encTag,digestTag;
1296 HASH_HashType found_type; 1301 HASH_HashType found_type;
1297 int i, certcount; 1302 int i, certcount;
1298 SECKEYPublicKey *publickey; 1303 SECKEYPublicKey *publickey;
1299 SECItem *content_type; 1304 SECItem *content_type;
1300 PK11SymKey *sigkey; 1305 PK11SymKey *sigkey;
1301 SECItem *encoded_stime; 1306 SECItem *encoded_stime;
1302 int64 stime; 1307 PRTime stime;
1308 PRTime verificationTime;
1303 SECStatus rv; 1309 SECStatus rv;
1304 1310
1305 /* 1311 /*
1306 * Everything needed in order to "goto done" safely. 1312 * Everything needed in order to "goto done" safely.
1307 */ 1313 */
1308 goodsig = PR_FALSE; 1314 goodsig = PR_FALSE;
1309 certcount = 0; 1315 certcount = 0;
1310 cert = NULL; 1316 cert = NULL;
1311 certs = NULL; 1317 certs = NULL;
1312 certdb = NULL; 1318 certdb = NULL;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } 1435 }
1430 1436
1431 /* 1437 /*
1432 * XXX This uses the signing time, if available. Additionally, we 1438 * XXX This uses the signing time, if available. Additionally, we
1433 * might want to, if there is no signing time, get the message time 1439 * might want to, if there is no signing time, get the message time
1434 * from the mail header itself, and use that. That would require 1440 * from the mail header itself, and use that. That would require
1435 * a change to our interface though, and for S/MIME callers to pass 1441 * a change to our interface though, and for S/MIME callers to pass
1436 * in a time (and for non-S/MIME callers to pass in nothing, or 1442 * in a time (and for non-S/MIME callers to pass in nothing, or
1437 * maybe make them pass in the current time, always?). 1443 * maybe make them pass in the current time, always?).
1438 */ 1444 */
1439 if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, 1445 if (atTime) {
1440 » » » encoded_stime != NULL ? stime : PR_Now(), 1446 » verificationTime = *atTime;
1447 } else if (encoded_stime != NULL) {
1448 » verificationTime = stime;
1449 } else {
1450 » verificationTime = PR_Now();
1451 }
1452 if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, verificationTime,
1441 cinfo->pwfn_arg, NULL) != SECSuccess) 1453 cinfo->pwfn_arg, NULL) != SECSuccess)
1442 { 1454 {
1443 /* 1455 /*
1444 * XXX Give the user an option to check the signature anyway? 1456 * XXX Give the user an option to check the signature anyway?
1445 * If we want to do this, need to give a way to leave and display 1457 * If we want to do this, need to give a way to leave and display
1446 * some dialog and get the answer and come back through (or do 1458 * some dialog and get the answer and come back through (or do
1447 * the rest of what we do below elsewhere, maybe by putting it 1459 * the rest of what we do below elsewhere, maybe by putting it
1448 * in a function that we call below and could call from a dialog 1460 * in a function that we call below and could call from a dialog
1449 * finish handler). 1461 * finish handler).
1450 */ 1462 */
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 1523
1512 digest = digests[i]; 1524 digest = digests[i];
1513 } 1525 }
1514 1526
1515 encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm)); 1527 encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm));
1516 if (encTag == SEC_OID_UNKNOWN) { 1528 if (encTag == SEC_OID_UNKNOWN) {
1517 PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); 1529 PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
1518 goto done; 1530 goto done;
1519 } 1531 }
1520 1532
1521 #ifndef NSS_ECC_MORE_THAN_SUITE_B
1522 if (encTag == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
1523 PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
1524 goto done;
1525 }
1526 #endif
1527
1528
1529 if (signerinfo->authAttr != NULL) { 1533 if (signerinfo->authAttr != NULL) {
1530 SEC_PKCS7Attribute *attr; 1534 SEC_PKCS7Attribute *attr;
1531 SECItem *value; 1535 SECItem *value;
1532 SECItem encoded_attrs; 1536 SECItem encoded_attrs;
1533 1537
1534 /* 1538 /*
1535 * We have a sigkey only for signedAndEnvelopedData, which is 1539 * We have a sigkey only for signedAndEnvelopedData, which is
1536 * not supposed to have any authenticated attributes. 1540 * not supposed to have any authenticated attributes.
1537 */ 1541 */
1538 if (sigkey != NULL) { 1542 if (sigkey != NULL) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 encoded_attrs.len = 0; 1587 encoded_attrs.len = 0;
1584 if (sec_PKCS7EncodeAttributes (NULL, &encoded_attrs, 1588 if (sec_PKCS7EncodeAttributes (NULL, &encoded_attrs,
1585 &(signerinfo->authAttr)) == NULL) 1589 &(signerinfo->authAttr)) == NULL)
1586 goto done; 1590 goto done;
1587 1591
1588 if (encoded_attrs.data == NULL || encoded_attrs.len == 0) { 1592 if (encoded_attrs.data == NULL || encoded_attrs.len == 0) {
1589 PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); 1593 PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
1590 goto done; 1594 goto done;
1591 } 1595 }
1592 1596
1593
1594 goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data, 1597 goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data,
1595 encoded_attrs.len, 1598 encoded_attrs.len,
1596 publickey, &(signerinfo->encDigest), 1599 publickey, &(signerinfo->encDigest),
1597 encTag, digestTag, NULL, 1600 encTag, digestTag, NULL,
1598 cinfo->pwfn_arg) == SECSuccess); 1601 cinfo->pwfn_arg) == SECSuccess);
1599 PORT_Free (encoded_attrs.data); 1602 PORT_Free (encoded_attrs.data);
1600 } else { 1603 } else {
1601 SECItem *sig; 1604 SECItem *sig;
1602 SECItem holder; 1605 SECItem holder;
1603 SECStatus rv; 1606 SECStatus rv;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 * 1753 *
1751 * In addition, if "keepcerts" is true, add any new certificates found 1754 * In addition, if "keepcerts" is true, add any new certificates found
1752 * into our local database. 1755 * into our local database.
1753 */ 1756 */
1754 PRBool 1757 PRBool
1755 SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo, 1758 SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
1756 SECCertUsage certusage, 1759 SECCertUsage certusage,
1757 PRBool keepcerts) 1760 PRBool keepcerts)
1758 { 1761 {
1759 return sec_pkcs7_verify_signature (cinfo, certusage, 1762 return sec_pkcs7_verify_signature (cinfo, certusage,
1760 » » » » NULL, HASH_AlgNULL, keepcerts); 1763 » » » » NULL, HASH_AlgNULL, keepcerts, 0);
wtc 2013/04/24 22:49:45 This 0 should be NULL.
1761 } 1764 }
1762 1765
1763 /* 1766 /*
1764 * SEC_PKCS7VerifyDetachedSignature 1767 * SEC_PKCS7VerifyDetachedSignature
1765 * Look at a PKCS7 contentInfo and check if the signature matches 1768 * Look at a PKCS7 contentInfo and check if the signature matches
1766 * a passed-in digest (calculated, supposedly, from detached contents). 1769 * a passed-in digest (calculated, supposedly, from detached contents).
1767 * The verification checks that the signing cert is valid and trusted 1770 * The verification checks that the signing cert is valid and trusted
1768 * for the purpose specified by "certusage". 1771 * for the purpose specified by "certusage".
1769 * 1772 *
1770 * In addition, if "keepcerts" is true, add any new certificates found 1773 * In addition, if "keepcerts" is true, add any new certificates found
1771 * into our local database. 1774 * into our local database.
1772 */ 1775 */
1773 PRBool 1776 PRBool
1774 SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, 1777 SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
1775 SECCertUsage certusage, 1778 SECCertUsage certusage,
1776 const SECItem *detached_digest, 1779 const SECItem *detached_digest,
1777 HASH_HashType digest_type, 1780 HASH_HashType digest_type,
1778 PRBool keepcerts) 1781 PRBool keepcerts)
1779 { 1782 {
1780 return sec_pkcs7_verify_signature (cinfo, certusage, 1783 return sec_pkcs7_verify_signature (cinfo, certusage,
1781 detached_digest, digest_type, 1784 detached_digest, digest_type,
1782 » » » » keepcerts); 1785 » » » » keepcerts, NULL);
1783 } 1786 }
1784 1787
1788 /*
1789 * SEC_PKCS7VerifyDetachedSignatureAtTime
1790 * Look at a PKCS7 contentInfo and check if the signature matches
1791 * a passed-in digest (calculated, supposedly, from detached contents).
1792 * The verification checks that the signing cert is valid and trusted
1793 * for the purpose specified by "certusage" at time "atTime".
1794 *
1795 * In addition, if "keepcerts" is true, add any new certificates found
1796 * into our local database.
1797 */
1798 PRBool
1799 SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
1800 SECCertUsage certusage,
1801 const SECItem *detached_digest,
1802 HASH_HashType digest_type,
1803 PRBool keepcerts,
1804 PRTime atTime)
1805 {
1806 return sec_pkcs7_verify_signature (cinfo, certusage,
1807 detached_digest, digest_type,
1808 keepcerts, &atTime);
1809 }
1785 1810
1786 /* 1811 /*
1787 * Return the asked-for portion of the name of the signer of a PKCS7 1812 * Return the asked-for portion of the name of the signer of a PKCS7
1788 * signed object. 1813 * signed object.
1789 * 1814 *
1790 * Returns a pointer to allocated memory, which must be freed. 1815 * Returns a pointer to allocated memory, which must be freed.
1791 * A NULL return value is an error. 1816 * A NULL return value is an error.
1792 */ 1817 */
1793 1818
1794 #define sec_common_name 1 1819 #define sec_common_name 1
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 /* 1862 /*
1838 * No cert there; see if we can find one by calling verify ourselves. 1863 * No cert there; see if we can find one by calling verify ourselves.
1839 */ 1864 */
1840 if (signercert == NULL) { 1865 if (signercert == NULL) {
1841 /* 1866 /*
1842 * The cert usage does not matter in this case, because we do not 1867 * The cert usage does not matter in this case, because we do not
1843 * actually care about the verification itself, but we have to pick 1868 * actually care about the verification itself, but we have to pick
1844 * some valid usage to pass in. 1869 * some valid usage to pass in.
1845 */ 1870 */
1846 (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner, 1871 (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner,
1847 » » » » » NULL, HASH_AlgNULL, PR_FALSE); 1872 » » » » » NULL, HASH_AlgNULL, PR_FALSE, 0);
wtc 2013/04/24 22:49:45 This 0 should be NULL.
1848 signercert = signerinfos[0]->cert; 1873 signercert = signerinfos[0]->cert;
1849 if (signercert == NULL) 1874 if (signercert == NULL)
1850 return NULL; 1875 return NULL;
1851 } 1876 }
1852 1877
1853 switch (selector) { 1878 switch (selector) {
1854 case sec_common_name: 1879 case sec_common_name:
1855 container = CERT_GetCommonName (&signercert->subject); 1880 container = CERT_GetCommonName (&signercert->subject);
1856 break; 1881 break;
1857 case sec_email_address: 1882 case sec_email_address:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 /* 1925 /*
1901 * No signature, or more than one, means no deal. 1926 * No signature, or more than one, means no deal.
1902 */ 1927 */
1903 if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL) 1928 if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL)
1904 return NULL; 1929 return NULL;
1905 1930
1906 attr = sec_PKCS7FindAttribute (signerinfos[0]->authAttr, 1931 attr = sec_PKCS7FindAttribute (signerinfos[0]->authAttr,
1907 SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE); 1932 SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
1908 return sec_PKCS7AttributeValue (attr); 1933 return sec_PKCS7AttributeValue (attr);
1909 } 1934 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698