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.3 { # NSS 3.14.3 release +;+ global: +SEC_PKCS7VerifyDetachedSignatureAtTime; +;+ local: +;+ *; +;+};