SecurityEngineering/mozpkix-testing

From MozillaWiki
Jump to: navigation, search

mozilla::pkix

Network Security Services (NSS) is a set of libraries designed to support cross-platform development of security-enabled client and server applications. Applications built with NSS can support SSL v2 and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3 certificates, OCSP, PKIX, and other security standards.

NSS currently has two code paths for doing certificate verification. "Classic" verification has been used for verification of non-EV certificates, and libPKIX has been used for verification of EV certificates.

As many of you are aware, the NSS team has wanted to replace the "classic" verification with libPKIX for a long time. However, the current libPKIX code was auto-translated from Java to C, and has proven to be very difficult to maintain and use. Therefore, Mozilla has created a new certificate verification library called mozilla::pkix.

Request for Testing

Replacing the certificate verification library can only be done after gaining sufficient confidence in the new code by having as many people and organizations test it as possible. So we ask that all of you help us test this new library as follows.

  1. Download Firefox 31 or later
    • Browse to ftp://ftp.mozilla.org/pub/firefox/tinderbox-builds/
    • Scroll down to mozilla-central-<platform> and select the folder that matches the platform you are working on.
    • Select the most recent build in the list.
    • Download by selecting the .tar.bz2 (Linux), .dmg (Mac), or .exe (Windows) file.
    • After downloading, extract and run this nightly browser, which will be called FirefoxNightly.
  2. In Firefox 33 and later, mozilla::pkix is enabled by default, and there is no longer an about:config option to disable it.
  3. In Firefox 31 and Firefox 32 mozilla::pkix is enabled by default, and there is an about:config option that can be used to disable and enable it. In Firefox 31 and Firefox 32 you can ensure that mozilla::pkix is enabled by doing the following:
    • Open about:config in Firefox
    • Locate the preference "security.use_mozillapkix_verification"
    • If it is true, nothing more needs to be done
    • If it is false, set it to true
    • If it is not present, update to a more recent FirefoxNightly build
    • Clear your browser cache if you are going to browse to a site you visited with mozilla::pkix off
  4. Browse to various websites with known valid and expired/revoked/etc SSL certificates.
    • Note to CAs: Be sure to check EV status, and check chains through all currently-used intermediate certs.
  5. If you don't get the expected result, then in Firefox 31 and Firefox 32 you can try again without using mozilla::pkix to see if the unexpected result is actually due to mozilla::pkix.
    • In about:config toggle "security.use_mozillapkix_verification" to false
      • Or switch to a previously released version of Firefox
    • Clear your browser cache if you are going to browse to a site you visited with mozilla::pkix on
  6. If you find an issue, please file a Bugzilla bug.

Request for Code Review

We will greatly appreciate your help in reviewing the new code, which may be found here:

If you find an issue, please file a Bugzilla bug (https://bugzilla.mozilla.org/enter_bug.cgi) with Product=Core, Component=Security:PSM, and put "(mozilla::pkix)" at the beginning of the Summary.

High level description of folders/files/classes

The main entry-point for verification is mozilla::pkix::BuildCertChain in security/pkix/include/pkix/pkix.h. This function takes a number of required arguments, including an implementation of a mozilla::pkix::TrustDomain, the certificate to verify, the time at which to verify, and whether this is an end-entity certificate or a CA certificate. Additionally, the caller may specify some required properties of some extensions if present. A known-in-advance OCSP response may be included as well. The function returns SECSuccess upon successful verification and SECFailure upon failure (in which case it sets an error code that can be obtained by calling PR_GetError()). The function will optionally return the trusted certificate chain found.

mozilla::pkix::TrustDomain is declared in security/pkix/include/pkix/pkixtypes.h. An implementation of a TrustDomain is responsible for deciding the trust level of a given certificate, finding potential issuers of a given certificate, verifying the signature of a certificate, and determining the revocation status of a certificate. In most cases, a TrustDomain implementation will be able to call mozilla::pkix::VerifySignedData for signature verification. The TrustDomain implementation used by PSM is mozilla::psm::NSSCertDBTrustDomain. See security/certverifier/NSSCertDBTrustDomain.h and NSSCertDBTrustDomain.cpp. NSSCertDBTrustDomain uses mozilla::psm::OCSPCache as an in-memory revocation cache. See security/certverifier/OCSPCache.h and OCSPCache.cpp.

The core of BuildCertChain consists of the path-building logic in security/pkix/lib/pkixbuild.cpp. That code makes a number of checks as implemented in security/pkix/lib/pkixcheck.cpp. This is where, for instance, key usages are examined and enforced.

To verify OCSP responses, the library provides mozilla::pkix::VerifyEncodedOCSPResponse (declared in security/pkix/include/pkix/pkix.h). The implementation is in security/pkix/lib/pkixocsp.cpp.

To decode OCSP responses and other DER-encoded data, there is a minimal DER decoding implementation in security/pkix/lib/pkixder.h and pkixder.cpp

For reference, the NSS certificate verification code is here:

What To Report

We are especially interested in finding errors that cause the following to happen:

  1. SSL connections succeed when they should fail, and they did fail in previous releases.
  2. EV treatment is given when it should not be given, and was not being given in previous releases.
  3. An SSL connection fails when it should have succeeded.
  4. EV treatment is not given when it should be.
  5. An SSL connection gives a different error than expected.
  6. SSL connections succeed when they should fail, and they did not fail in previous releases. For example, see the Things for CAs to Fix section below.
  7. EV treatment is given when it should not be given and was being given in previous releases. For example, see the Future Considerations section below.
  8. Code Signing certificates do not work as expected.

Mozilla::pkix Bug list

Behavior Changes

Mozilla::pkix includes some changes in support of current best practices and policies, as listed below. If you notice an issue due to any of these changes, please feel free to let us know. However, we believe that in most cases, the simplest resolution will be to update the SSL certificate in your webserver.

  1. End-entity certificates used in SSL/TLS servers:
    • Are not allowed to have basic constraints asserting isCA=TRUE.
    • When the EKU extension is specified, must assert the serverAuth bit.
    • Are no longer allowed to include the OCSPSigning EKU.
    • Cannot have the Netscape Cert Type extension marked as critical.
  2. Mozilla::pkix does not allow x509 version 2 certificates in any position (root, intermediate or end-entity), and version 1 certificates are only allowed as trust anchors. bug 969188
  3. Version 3 root and intermediate certificates are now required to have the basic constraints extension and assert the isCA bit.
  4. Mozilla::pkix performs chaining based on issuer name alone, and does not require that issuer's subject key match the authority key info (AKI) extension in the certificate.
  5. If a root or intermediate certificate contains the EKU extension, and that intermediate certificate will be used to issue SSL/TLS certificates, then the EKU must include the id-kp-serverAuth (1.3.6.1.5.5.7.3.1) bit or the Netscape Server Gated Crypto bit (support for NSGC is provided temporarily for backward compatibility). bug 982292

Things for CAs to Fix

Workarounds were implemented to allow mozilla::pkix to handle some of the following situations. We will be asking CAs to immediately stop issuing new certificates with these issues, and we will identify dates for removing these workarounds.

  1. All new intermediate certificates that include the EKU extension and will be used for SSL certificate issuance, must include the id-kp-serverAuth (1.3.6.1.5.5.7.3.1) EKU. Mozilla will stop recognizing the "Netscape Server Gated Crypto (2.16.840.1.113730.4.1)" EKU.
  2. Default values in a SEQUENCE must not be explicitly encoded.
    • ITU-T X.690 section 11.5: "The encoding of a set value or sequence value shall not include an encoding for any component value which is equal to its default value."
    • Note: We encountered certificates with a basicConstraints extension that explicitly encoded the default value cA:false. The solution that we recommend is to not include the basicConstraints extension in end-entity certificates.
    • Related Bugs: bug 988633, bug 989516, bug 989518
  3. Basic constraints: pathLenConstraint must not be included if cA is false
    • RFC 5280 section 4.2.1.9: "CAs MUST NOT include the pathLenConstraint field unless the cA boolean is asserted and the key usage extension asserts the keyCertSign bit."
    • Related Bugs: bug 982878, bug 985021, bug 985025
  4. OCSP responders should not include a responseExtensions consisting of an empty SEQUENCE (e.g. A2 02 30 00 - see http://tools.ietf.org/html/rfc6960#section-4.2.1 under ResponseData for reference). RFC 3280 defines Extensions as SEQUENCE SIZE (1..MAX) OF Extension, so the empty SEQUENCE is not a valid encoding. Instead of using an empty SEQUENCE, the OCSP responder should just omit the responseExtensions in the ResponseData.
  5. OCSP responses for subscriber certificates must have a maximum expiration time of ten days. BR #13.2.2: "For the status of Subscriber Certificates: ... The CA SHALL update information provided via an Online Certificate Status Protocol at least every four days. OCSP responses from this service MUST have a maximum expiration time of ten days."
  6. All times in all certificates must be encoded in a way that conforms to the stricter requirements in RFC 5280. In particular, the timezone must always be specified as "Z" (Zulu/GMT).
  7. When signing OCSP responses with a delegated OCSP response signing certificate, ensure that the delegated OCSP response signing certificate will not expire before the OCSP response expires. Otherwise, when doing OCSP stapling, some servers will cache the OCSP response past the point where the delegated response signing certificate expires, and then Firefox will reject the connection.
  8. RSA end-entity certificates that have a KeyUsage extension should include keyEncipherment in the KeyUsage extension if the subscriber intends for the certificate to be used for RSA key exchange in TLS. In other words, include keyEncipherment in RSA certificates--but not ECDSA certificates--unless the subscriber asks for it not to be included. This way, Firefox can start enforcing the correct KeyUsage.
  9. Include the subjectAltName extension with appropriate dNSName/iPAddress entries in all certificates. Hopefully soon Firefox will be able to stop falling back on the subject CN when there are no dNSName/iPAddress SAN entries.
  10. Do not use any string types other than PrintableString and UTF8String in DirectoryString components of names. In particular, RFC 5280 says "TeletexString, BMPString, and UniversalString are included for backward compatibility, and SHOULD NOT be used for certificates for new subjects." Hopefully we will stop accepting certificates that use those obsolete encodings soon.
  11. Use the same encoding for name constraints as subject alternative names.

Future Considerations

While testing mozilla::pkix, we noticed the following things that we would like to consider.

  1. In the BRs, the statement: "OCSP responses from this service MUST have a maximum expiration time of ten days." needs to be added to the Subordinate CA Certificates section of BR #13.2.2. If a CA with an intermediate OCSP nextUpdate six months in the future actually revokes that intermediate today because an attacker got its private key, then an attacker could still MitM users for 6 months from today. We need to require intermediate OCSP nextUpdate values to be 10 days from thisUpdate or less.
    • Related Bugs: bug 991815, bug 1009110
    • OneCRL will reduce our dependence on intermediate cert OCSP responses, so this is probably not worth pushing.
  2. EV treatment should not be given when the end-entity cert is signed directly by the root cert. The EV Guidelines say: "Root CA Private Keys MUST NOT be used to sign EV Certificates." We should programmatically enforce this.
  3. Consider only giving EV treatment when the intermediate and end-entity certs in the chain have the specific EV policy OID that we are expecting; in other words, don’t give EV treatment when the intermediate certificate has the anyPolicy OID. To make this change, would need to change the CAB Forum’s EV Guidelines to also require the EV policy OID in intermediate certs (section 9.3.4 says the subordinate CA certificate may contain anyPolicy OID 2.5.29.32.0).
    • Related Bugs: bug 986156
    • On consideration, this would be a big change, affecting almost all intermediates which issue EV certs. So it's probably not worth it.