diff --git a/security/manager/ssl/src/JARSignatureVerification.cpp b/security/manager/ssl/src/JARSignatureVerification.cpp index d0a8b98ff787..8e694d39a713 100644 --- a/security/manager/ssl/src/JARSignatureVerification.cpp +++ b/security/manager/ssl/src/JARSignatureVerification.cpp @@ -586,9 +586,9 @@ OpenSignedJARFile(nsIFile * aJarFile, } // Verify that the signature file is a valid signature of the SF file - if (!SEC_PKCS7VerifyDetachedSignature(p7_info, certUsageObjectSigner, - &sfCalculatedDigest.get(), HASH_AlgSHA1, - false)) { + if (!SEC_PKCS7VerifyDetachedSignatureAtTime(p7_info, certUsageObjectSigner, + &sfCalculatedDigest.get(), + HASH_AlgSHA1, false, PR_Now())) { PRErrorCode error = PR_GetError(); const char * errorName = PR_ErrorToName(error); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Failed to verify detached signature: %s", diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index 51358c393788..326e96ea46c7 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -1282,7 +1282,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, SECCertUsage certusage, const SECItem *detached_digest, HASH_HashType digest_type, - PRBool keepcerts) + PRBool keepcerts, + PRTime atTime) { SECAlgorithmID **digestalgs, *bulkid; const SECItem *digest; @@ -1300,7 +1301,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, SECItem *content_type; PK11SymKey *sigkey; SECItem *encoded_stime; - int64 stime; + PRTime stime; + PRTime verificationTime; SECStatus rv; /* @@ -1437,8 +1439,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * in a time (and for non-S/MIME callers to pass in nothing, or * maybe make them pass in the current time, always?). */ + verificationTime = atTime ? atTime + : (encoded_stime ? stime : PR_Now()); if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, - encoded_stime != NULL ? stime : PR_Now(), + verificationTime, cinfo->pwfn_arg, NULL) != SECSuccess) { /* @@ -1758,7 +1762,7 @@ SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo, PRBool keepcerts) { return sec_pkcs7_verify_signature (cinfo, certusage, - NULL, HASH_AlgNULL, keepcerts); + NULL, HASH_AlgNULL, keepcerts, 0); } /* @@ -1780,9 +1784,34 @@ SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, { return sec_pkcs7_verify_signature (cinfo, certusage, detached_digest, digest_type, - keepcerts); + keepcerts, 0); } +/* + * SEC_PKCS7VerifyDetachedSignatureAtTime + * Look at a PKCS7 contentInfo and check if the signature matches + * a passed-in digest (calculated, supposedly, from detached contents). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage" at time "atTime" + * if "atTime" is non-zero, or at the current time (as returned by + * PR_Now) otherwise. + */ +PRBool +SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts, + PRTime atTime) +{ + if (!atTime) { + atTime = PR_Now(); + } + + return sec_pkcs7_verify_signature (cinfo, certusage, + detached_digest, digest_type, + keepcerts, atTime); +} /* * Return the asked-for portion of the name of the signer of a PKCS7 @@ -1845,7 +1874,7 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector) * some valid usage to pass in. */ (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner, - NULL, HASH_AlgNULL, PR_FALSE); + NULL, HASH_AlgNULL, PR_FALSE, 0); signercert = signerinfos[0]->cert; if (signercert == NULL) return NULL; diff --git a/security/nss/lib/pkcs7/secpkcs7.h b/security/nss/lib/pkcs7/secpkcs7.h index a50f5aedd8bb..d1dd7b935015 100644 --- a/security/nss/lib/pkcs7/secpkcs7.h +++ b/security/nss/lib/pkcs7/secpkcs7.h @@ -133,6 +133,23 @@ extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, HASH_HashType digest_type, PRBool keepcerts); + +/* + * SEC_PKCS7VerifyDetachedSignatureAtTime + * Look at a PKCS7 contentInfo and check if the signature matches + * a passed-in digest (calculated, supposedly, from detached contents). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage" at time "atTime" + * if "atTime" is non-zero, or at the current time (as returned by + * PR_Now) otherwise. + */ +extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts, + PRTime atTime); + /* * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress * The passed-in contentInfo is espected to be Signed, and these diff --git a/security/nss/lib/smime/smime.def b/security/nss/lib/smime/smime.def index 623eaa460878..b205d1c755ce 100644 --- a/security/nss/lib/smime/smime.def +++ b/security/nss/lib/smime/smime.def @@ -267,3 +267,9 @@ NSSSMIME_GetVersion; ;+ local: ;+ *; ;+}; +;+NSS_3.14.2 { # NSS 3.14.2 release +;+ global: +SEC_PKCS7VerifyDetachedSignatureAtTime; +;+ local: +;+ *; +;+}; diff --git a/security/patches/README b/security/patches/README index 4c383551aa34..16493705ab59 100644 --- a/security/patches/README +++ b/security/patches/README @@ -4,3 +4,6 @@ on top of the NSS release. remove-turktrust-bug-827543.patch: Tentatively remove TURKTRUST certificates from B2G 1.0 branch only, pending final decision for all products. +bug-834091.patch: Add SEC_PKCS7VerifyDetachedSignatureAtTime, which is needed + for B2G 1.0. This patch is probably going to be modified + before it can land in upstream NSS. diff --git a/security/patches/bug-834091.patch b/security/patches/bug-834091.patch new file mode 100644 index 000000000000..6295921aeb4f --- /dev/null +++ b/security/patches/bug-834091.patch @@ -0,0 +1,216 @@ +Index: security/nss/lib/pkcs7/p7decode.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/pkcs7/p7decode.c,v +retrieving revision 1.31 +diff -u -8 -p -r1.31 p7decode.c +--- security/nss/lib/pkcs7/p7decode.c 12 Dec 2012 19:25:36 -0000 1.31 ++++ security/nss/lib/pkcs7/p7decode.c 25 Jan 2013 23:22:54 -0000 +@@ -1276,17 +1276,18 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7Conten + * there should be NO authenticatedAttributes (signerinfo->authAttr should + * be NULL). + */ + static PRBool + sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, +- PRBool keepcerts) ++ PRBool keepcerts, ++ PRTime atTime) + { + SECAlgorithmID **digestalgs, *bulkid; + const SECItem *digest; + SECItem **digests; + SECItem **rawcerts; + CERTSignedCrl **crls; + SEC_PKCS7SignerInfo **signerinfos, *signerinfo; + CERTCertificate *cert, **certs; +@@ -1294,17 +1295,18 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont + CERTCertDBHandle *certdb, *defaultdb; + SECOidTag encTag,digestTag; + HASH_HashType found_type; + int i, certcount; + SECKEYPublicKey *publickey; + SECItem *content_type; + PK11SymKey *sigkey; + SECItem *encoded_stime; +- int64 stime; ++ PRTime stime; ++ PRTime verificationTime; + SECStatus rv; + + /* + * Everything needed in order to "goto done" safely. + */ + goodsig = PR_FALSE; + certcount = 0; + cert = NULL; +@@ -1431,18 +1433,20 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont + /* + * XXX This uses the signing time, if available. Additionally, we + * might want to, if there is no signing time, get the message time + * from the mail header itself, and use that. That would require + * a change to our interface though, and for S/MIME callers to pass + * in a time (and for non-S/MIME callers to pass in nothing, or + * maybe make them pass in the current time, always?). + */ ++ verificationTime = atTime ? atTime ++ : (encoded_stime ? stime : PR_Now()); + if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, +- encoded_stime != NULL ? stime : PR_Now(), ++ verificationTime, + cinfo->pwfn_arg, NULL) != SECSuccess) + { + /* + * XXX Give the user an option to check the signature anyway? + * If we want to do this, need to give a way to leave and display + * some dialog and get the answer and come back through (or do + * the rest of what we do below elsewhere, maybe by putting it + * in a function that we call below and could call from a dialog +@@ -1752,17 +1756,17 @@ done: + * into our local database. + */ + PRBool + SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + PRBool keepcerts) + { + return sec_pkcs7_verify_signature (cinfo, certusage, +- NULL, HASH_AlgNULL, keepcerts); ++ NULL, HASH_AlgNULL, keepcerts, 0); + } + + /* + * SEC_PKCS7VerifyDetachedSignature + * Look at a PKCS7 contentInfo and check if the signature matches + * a passed-in digest (calculated, supposedly, from detached contents). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage". +@@ -1774,19 +1778,44 @@ PRBool + SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts) + { + return sec_pkcs7_verify_signature (cinfo, certusage, + detached_digest, digest_type, +- keepcerts); ++ keepcerts, 0); + } + ++/* ++ * SEC_PKCS7VerifyDetachedSignatureAtTime ++ * Look at a PKCS7 contentInfo and check if the signature matches ++ * a passed-in digest (calculated, supposedly, from detached contents). ++ * The verification checks that the signing cert is valid and trusted ++ * for the purpose specified by "certusage" at time "atTime" ++ * if "atTime" is non-zero, or at the current time (as returned by ++ * PR_Now) otherwise. ++ */ ++PRBool ++SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, ++ SECCertUsage certusage, ++ const SECItem *detached_digest, ++ HASH_HashType digest_type, ++ PRBool keepcerts, ++ PRTime atTime) ++{ ++ if (!atTime) { ++ atTime = PR_Now(); ++ } ++ ++ return sec_pkcs7_verify_signature (cinfo, certusage, ++ detached_digest, digest_type, ++ keepcerts, atTime); ++} + + /* + * Return the asked-for portion of the name of the signer of a PKCS7 + * signed object. + * + * Returns a pointer to allocated memory, which must be freed. + * A NULL return value is an error. + */ +@@ -1839,17 +1868,17 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7 + */ + if (signercert == NULL) { + /* + * The cert usage does not matter in this case, because we do not + * actually care about the verification itself, but we have to pick + * some valid usage to pass in. + */ + (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner, +- NULL, HASH_AlgNULL, PR_FALSE); ++ NULL, HASH_AlgNULL, PR_FALSE, 0); + signercert = signerinfos[0]->cert; + if (signercert == NULL) + return NULL; + } + + switch (selector) { + case sec_common_name: + container = CERT_GetCommonName (&signercert->subject); +Index: security/nss/lib/pkcs7/secpkcs7.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/pkcs7/secpkcs7.h,v +retrieving revision 1.10 +diff -u -8 -p -r1.10 secpkcs7.h +--- security/nss/lib/pkcs7/secpkcs7.h 27 Nov 2012 22:48:08 -0000 1.10 ++++ security/nss/lib/pkcs7/secpkcs7.h 25 Jan 2013 23:22:54 -0000 +@@ -128,16 +128,33 @@ extern PRBool SEC_PKCS7VerifySignature(S + * into our local database. + */ + extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts); + ++ ++/* ++ * SEC_PKCS7VerifyDetachedSignatureAtTime ++ * Look at a PKCS7 contentInfo and check if the signature matches ++ * a passed-in digest (calculated, supposedly, from detached contents). ++ * The verification checks that the signing cert is valid and trusted ++ * for the purpose specified by "certusage" at time "atTime" ++ * if "atTime" is non-zero, or at the current time (as returned by ++ * PR_Now) otherwise. ++ */ ++extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, ++ SECCertUsage certusage, ++ const SECItem *detached_digest, ++ HASH_HashType digest_type, ++ PRBool keepcerts, ++ PRTime atTime); ++ + /* + * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress + * The passed-in contentInfo is espected to be Signed, and these + * functions return the specified portion of the full signer name. + * + * Returns a pointer to allocated memory, which must be freed. + * A NULL return value is an error. + */ +Index: security/nss/lib/smime/smime.def +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/smime/smime.def,v +retrieving revision 1.39 +diff -u -8 -p -r1.39 smime.def +--- security/nss/lib/smime/smime.def 25 Apr 2012 14:50:09 -0000 1.39 ++++ security/nss/lib/smime/smime.def 25 Jan 2013 23:22:54 -0000 +@@ -262,8 +262,14 @@ NSS_Get_NSS_PointerToCMSGenericWrapperDa + ;+ *; + ;+}; + ;+NSS_3.13 { # NSS 3.13 release + ;+ global: + NSSSMIME_GetVersion; + ;+ local: + ;+ *; + ;+}; ++;+NSS_3.14.2 { # NSS 3.14.2 release ++;+ global: ++SEC_PKCS7VerifyDetachedSignatureAtTime; ++;+ local: ++;+ *; ++;+};