Open Bug 835105 Opened 11 years ago Updated 6 months ago

SEC_PKCS7VerifyDetachedSignature and SEC_PKCS7VerifySignature use the untrustworthy signing time as the time at which to verify the certificate chain

Categories

(NSS :: Libraries, defect, P5)

Tracking

(Not tracked)

People

(Reporter: briansmith, Unassigned)

Details

(Keywords: compat)

In these functions, the time passed to CERT_VerifyNow() is the signing time that the signer claimed to have have signed the message, or the current time as returned from PR_Now() if the signing time is not in the message.

This is done so these functions can attempt to answer the question: "Even if the certificate has expired now, was it valid at the time the message was signed?" However, the signing time is under the control of the signer, and since we don't know whether we can trust the signer (because we haven't verified his certificate), we shouldn't trust his input.

Antonio recommended in bug 834091 that we change these functions to always pass PR_Now() to CERT_VerifyCert. I think that is a good idea. However, it may break applications. For example, if you open an old signed message in Thunderbird, where the signer's certificate has now expired, the email would show up as having an invalid signature. Technically, that is true. However, I think Thunderbird users would rather know whether it was valid at the time it was signed and/or at the time they first received/read it. In order to get those semantics, programs like Thunderbird would have to be modified to store the certificate validation status for future use.
Note: The caller may have obtained the signing time through a trusted timestamp service (which is sort of the point of timestamping code signatures), so it's not inherent that the caller-supplied time will be untrustworthy.

As explained in RFC 2985, the presumption is that if the detached signature (of which there may be multiple) is from a trusted timestamp service, it may be used. This is similar to how other codesigning (Blackberry, Apple, Microsoft) systems work.

That said, NSS is doing nothing of that sort (yet), and it's handling of signing time seems to prefer 'attacker' supplied data.

Even in the Thunderbird case, there's the added complexity of revocation checking. Revocation checking may be backdated (eg: the key was lost at time X), and so the signature is not trustworthy, even if it seemed trustworthy at the time. This is where the complexity of OCSP/CRL archiving, since you want the last possible time while the certificate is still non-expired in order to validate that it was not revoked prior to its expiration.

I'm mentioning all of this just to document the context of how it was 'supposed' to work. On the practical concerns, I agree with Brian's assessment, although I think if you guys aren't looking at having timestamped signatures (either by a trusted third party timestamping service or through Mozilla's system itself), then you run the risk of being unable to install 'old' code at some arbitrary point the future. Most code signing certs are limited for 1-3 years, so that seems a rather short period...
(In reply to Brian Smith (:bsmith) from comment #0)
> Antonio recommended in bug 834091 that we change these functions to always
> pass PR_Now() to CERT_VerifyCert. I think that is a good idea. However, it
> may break applications. For example, if you open an old signed message in
> Thunderbird, where the signer's certificate has now expired, the email would
> show up as having an invalid signature.

For the record - that's what happening with Thunderbird since version 1.5.0.8:

http://bonsai.mozilla.org/cvsview2.cgi?file=nsCMS.cpp&subdir=mozilla/security/manager/ssl/src&command=DIFF_FRAMESET&rev1=1.20&rev2=1.20.12.1

Note that Thunderbird does not use any of the SEC_PKCS7* functions, it relies on libsmime exclusively (NSS_CMS* functions, i.e. NSS_CMSSignedData_VerifySignerInfo for verification, specifically).

> programs like Thunderbird would have to be modified to
> store the certificate validation status for future use.

For one proposed solution, see CAdES-X Long (RFC 5126 / ETSI TS 101 733).

(In reply to Ryan Sleevi from comment #1)
> As explained in RFC 2985, the presumption is that if the detached signature
> (of which there may be multiple) is from a trusted timestamp service, it may
> be used. This is similar to how other codesigning (Blackberry, Apple,
> Microsoft) systems work.

For JARs, Java 5 has introduced RFC 3161 timestamp token support, so that would be the natural choice for enhancing JAR support in NSS. In a "timestamped JAR", the token is included in the CMS SignerInfo structure as an unsigned attribute of type id-aa-signatureTimeStampToken (see also RFC 5126, sections 6.1.1 and 7.4).
Severity: normal → S3
Severity: S3 → S4
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.