Bug 1030204 - 1/2 Name constraint ANSSI(DCISS) Root cert in mozilla::pkix. r=keeler
authorCamilo Viecco <cviecco@mozilla.com>
Tue, 08 Jul 2014 16:16:26 -0700
changeset 193024 218997c808a1
parent 193023 5c805d803e11
child 193025 23c24ca46931
push id27103
push usercbook@mozilla.com
push date2014-07-09 13:55 +0000
treeherdermozilla-central@f945d50e50fc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1030204
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1030204 - 1/2 Name constraint ANSSI(DCISS) Root cert in mozilla::pkix. r=keeler
security/pkix/lib/pkixcheck.cpp
--- a/security/pkix/lib/pkixcheck.cpp
+++ b/security/pkix/lib/pkixcheck.cpp
@@ -325,17 +325,17 @@ DecodeBasicConstraints(der::Input& input
 
   return der::Success;
 }
 
 // RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints)
 Result
 CheckBasicConstraints(EndEntityOrCA endEntityOrCA,
                       const SECItem* encodedBasicConstraints,
-                      der::Version version, TrustLevel trustLevel,
+                      const der::Version version, TrustLevel trustLevel,
                       unsigned int subCACount)
 {
   bool isCA = false;
   long pathLenConstraint = UNLIMITED_PATH_LEN;
 
   if (encodedBasicConstraints) {
     der::Input input;
     if (input.Init(encodedBasicConstraints->data,
@@ -408,29 +408,98 @@ PORT_FreeArena_false(PLArenaPool* arena)
   // PL_FreeArenaPool can't be used because it doesn't actually free the
   // memory, which doesn't work well with memory analysis tools
   return PORT_FreeArena(arena, PR_FALSE);
 }
 
 Result
 CheckNameConstraints(const BackCert& cert)
 {
-  if (!cert.GetNameConstraints()) {
-    return Success;
-  }
+  // These hardcoded consts are to handle a post certificate creation
+  // name constraints. In this case for ANSSI.
+  static const char constraintFranceGov[] =
+                                     "\x30\x5D" /* sequence len 93*/
+                                     "\xA0\x5B" /* element len 91 */
+                                     "\x30\x05" /* sequence len 5 */
+                                     "\x82\x03" /* entry len 3 */
+                                     ".fr"
+                                     "\x30\x05\x82\x03" /* sequence len 5, entry len 3 */
+                                     ".gp"
+                                     "\x30\x05\x82\x03"
+                                     ".gf"
+                                     "\x30\x05\x82\x03"
+                                     ".mq"
+                                     "\x30\x05\x82\x03"
+                                     ".re"
+                                     "\x30\x05\x82\x03"
+                                     ".yt"
+                                     "\x30\x05\x82\x03"
+                                     ".pm"
+                                     "\x30\x05\x82\x03"
+                                     ".bl"
+                                     "\x30\x05\x82\x03"
+                                     ".mf"
+                                     "\x30\x05\x82\x03"
+                                     ".wf"
+                                     "\x30\x05\x82\x03"
+                                     ".pf"
+                                     "\x30\x05\x82\x03"
+                                     ".nc"
+                                     "\x30\x05\x82\x03"
+                                     ".tf";
+
+  /* The stringified value for the subject is:
+     E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR
+   */
+  static const char rawANSSISubject[] =
+                                 "\x30\x81\x85\x31\x0B\x30\x09\x06\x03\x55\x04"
+                                 "\x06\x13\x02\x46\x52\x31\x0F\x30\x0D\x06\x03"
+                                 "\x55\x04\x08\x13\x06\x46\x72\x61\x6E\x63\x65"
+                                 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05"
+                                 "\x50\x61\x72\x69\x73\x31\x10\x30\x0E\x06\x03"
+                                 "\x55\x04\x0A\x13\x07\x50\x4D\x2F\x53\x47\x44"
+                                 "\x4E\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13"
+                                 "\x05\x44\x43\x53\x53\x49\x31\x0E\x30\x0C\x06"
+                                 "\x03\x55\x04\x03\x13\x05\x49\x47\x43\x2F\x41"
+                                 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7"
+                                 "\x0D\x01\x09\x01\x16\x14\x69\x67\x63\x61\x40"
+                                 "\x73\x67\x64\x6E\x2E\x70\x6D\x2E\x67\x6F\x75"
+                                 "\x76\x2E\x66\x72";
+
+  const SECItem ANSSI_SUBJECT = {
+    siBuffer,
+    reinterpret_cast<uint8_t *>(const_cast<char *>(rawANSSISubject)),
+    sizeof(rawANSSISubject) - 1
+  };
+
+  const SECItem PERMIT_FRANCE_GOV_NC = {
+    siBuffer,
+    reinterpret_cast<uint8_t *>(const_cast<char *>(constraintFranceGov)),
+    sizeof(constraintFranceGov) - 1
+  };
+
+  const SECItem* nameConstraintsToUse = cert.GetNameConstraints();
+
+  if (!nameConstraintsToUse) {
+    if (SECITEM_ItemsAreEqual(&cert.GetSubject(), &ANSSI_SUBJECT)) {
+      nameConstraintsToUse = &PERMIT_FRANCE_GOV_NC;
+    } else {
+      return Success;
+    }
+   }
 
   ScopedPtr<PLArenaPool, PORT_FreeArena_false>
     arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
   if (!arena) {
     return MapSECStatus(SECFailure);
   }
 
   // Owned by arena
   const CERTNameConstraints* constraints =
-    CERT_DecodeNameConstraintsExtension(arena.get(), cert.GetNameConstraints());
+    CERT_DecodeNameConstraintsExtension(arena.get(), nameConstraintsToUse);
   if (!constraints) {
     return MapSECStatus(SECFailure);
   }
 
   for (const BackCert* child = cert.childCert; child;
        child = child->childCert) {
     ScopedPtr<CERTCertificate, CERT_DestroyCertificate>
       nssCert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),