bug 1042889 - use a separate error for untrusted x509v1 certificates used as CAs r=briansmith
authorDavid Keeler <dkeeler@mozilla.com>
Wed, 15 Oct 2014 10:38:51 -0700
changeset 210631 48ab37c7463919f1ca6da76257f6663032dbd6cf
parent 210630 a52b2b37e42a06c973a63b4cf054c3e6a9df6c59
child 210632 3127d128a14d089a73ad641b77ef654688b8442a
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbriansmith
bugs1042889
milestone36.0a1
bug 1042889 - use a separate error for untrusted x509v1 certificates used as CAs r=briansmith
security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
security/pkix/include/pkix/Result.h
security/pkix/include/pkix/pkixnss.h
security/pkix/lib/pkixcheck.cpp
security/pkix/lib/pkixnss.cpp
--- a/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
+++ b/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
@@ -309,8 +309,9 @@ SEC_ERROR_CRL_IMPORT_FAILED=Error attemp
 SEC_ERROR_EXPIRED_PASSWORD=The password expired.
 SEC_ERROR_LOCKED_PASSWORD=The password is locked.
 SEC_ERROR_UNKNOWN_PKCS11_ERROR=Unknown PKCS #11 error.
 SEC_ERROR_BAD_CRL_DP_URL=Invalid or unsupported URL in CRL distribution point name.
 SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED=The certificate was signed using a signature algorithm that is disabled because it is not secure.
 MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE=The server uses key pinning (HPKP) but no trusted certificate chain could be constructed that matches the pinset. Key pinning violations cannot be overridden.
 MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY=The server uses a certificate with a basic constraints extension identifying it as a certificate authority. For a properly-issued certificate, this should not be the case.
 MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE=The server presented a certificate with a key size that is too small to establish a secure connection.
+MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA=An X.509 version 1 certificate that is not a trust anchor was used to issue the server's certificate. X.509 version 1 certificates are deprecated and should not be used to sign other certificates.
--- a/security/pkix/include/pkix/Result.h
+++ b/security/pkix/include/pkix/Result.h
@@ -119,16 +119,18 @@ static const unsigned int FATAL_ERROR_FL
     MOZILLA_PKIX_MAP(ERROR_UNSUPPORTED_KEYALG, 37, \
                      SEC_ERROR_UNSUPPORTED_KEYALG) \
     MOZILLA_PKIX_MAP(ERROR_EXPIRED_ISSUER_CERTIFICATE, 38, \
                      SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE) \
     MOZILLA_PKIX_MAP(ERROR_CA_CERT_USED_AS_END_ENTITY, 39, \
                      MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY) \
     MOZILLA_PKIX_MAP(ERROR_INADEQUATE_KEY_SIZE, 40, \
                      MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE) \
+    MOZILLA_PKIX_MAP(ERROR_V1_CERT_USED_AS_CA, 41, \
+                     MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_ARGS, FATAL_ERROR_FLAG | 1, \
                      SEC_ERROR_INVALID_ARGS) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_STATE, FATAL_ERROR_FLAG | 2, \
                      PR_INVALID_STATE_ERROR) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_LIBRARY_FAILURE, FATAL_ERROR_FLAG | 3, \
                      SEC_ERROR_LIBRARY_FAILURE) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_NO_MEMORY, FATAL_ERROR_FLAG | 4, \
                      SEC_ERROR_NO_MEMORY) \
--- a/security/pkix/include/pkix/pkixnss.h
+++ b/security/pkix/include/pkix/pkixnss.h
@@ -64,17 +64,18 @@ PRErrorCode MapResultToPRErrorCode(Resul
 // a negative value that both doesn't overlap with the current value
 // ranges for NSS errors and that will fit in 16 bits when negated.
 static const PRErrorCode ERROR_BASE = -0x4000;
 static const PRErrorCode ERROR_LIMIT = ERROR_BASE + 1000;
 
 enum ErrorCode {
   MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE = ERROR_BASE + 0,
   MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY = ERROR_BASE + 1,
-  MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE = ERROR_BASE + 2
+  MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE = ERROR_BASE + 2,
+  MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA = ERROR_BASE + 3,
 };
 
 void RegisterErrorTable();
 
 inline SECItem UnsafeMapInputToSECItem(Input input)
 {
   SECItem result = {
     siBuffer,
--- a/security/pkix/lib/pkixcheck.cpp
+++ b/security/pkix/lib/pkixcheck.cpp
@@ -343,20 +343,28 @@ CheckBasicConstraints(EndEntityOrCA endE
     // "If the basic constraints extension is not present in a version 3
     //  certificate, or the extension is present but the cA boolean is not
     //  asserted, then the certified public key MUST NOT be used to verify
     //  certificate signatures."
     //
     // For compatibility, we must accept v1 trust anchors without basic
     // constraints as CAs.
     //
+    // There are devices with v1 certificates that are unlikely to be trust
+    // anchors. In order to allow applications to treat this case differently
+    // from other basic constraints violations (e.g. allowing certificate error
+    // overrides for only this case), we return a different error code.
+    //
     // TODO: add check for self-signedness?
-    if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
-        trustLevel == TrustLevel::TrustAnchor && version == der::Version::v1) {
-      isCA = true;
+    if (endEntityOrCA == EndEntityOrCA::MustBeCA && version == der::Version::v1) {
+      if (trustLevel == TrustLevel::TrustAnchor) {
+        isCA = true;
+      } else {
+        return Result::ERROR_V1_CERT_USED_AS_CA;
+      }
     }
   }
 
   if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
     // CA certificates are not trusted as EE certs.
 
     if (isCA) {
       // Note that this check prevents a delegated OCSP response signing
--- a/security/pkix/lib/pkixnss.cpp
+++ b/security/pkix/lib/pkixnss.cpp
@@ -237,17 +237,21 @@ RegisterErrorTable()
       "could be constructed that matches the pinset. Key pinning violations "
       "cannot be overridden." },
     { "MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY",
       "The server uses a certificate with a basic constraints extension "
       "identifying it as a certificate authority. For a properly-issued "
       "certificate, this should not be the case." },
     { "MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE",
       "The server presented a certificate with a key size that is too small "
-      "to establish a secure connection." }
+      "to establish a secure connection." },
+    { "MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA",
+      "An X.509 version 1 certificate that is not a trust anchor was used to "
+      "issue the server's certificate. X.509 version 1 certificates are "
+      "deprecated and should not be used to sign other certificates." },
   };
   // Note that these error strings are not localizable.
   // When these strings change, update the localization information too.
 
   static const struct PRErrorTable ErrorTable = {
     ErrorTableText,
     "pkixerrors",
     ERROR_BASE,