diff --git a/security/pkix/lib/pkixcheck.cpp b/security/pkix/lib/pkixcheck.cpp index f18a274de23..9b91b96f3a1 100644 --- a/security/pkix/lib/pkixcheck.cpp +++ b/security/pkix/lib/pkixcheck.cpp @@ -330,7 +330,7 @@ DecodeBasicConstraints(der::Input& input, /*out*/ bool& isCA, Result CheckBasicConstraints(EndEntityOrCA endEntityOrCA, const SECItem* encodedBasicConstraints, - der::Version version, TrustLevel trustLevel, + const der::Version version, TrustLevel trustLevel, unsigned int subCACount) { bool isCA = false; @@ -413,9 +413,78 @@ PORT_FreeArena_false(PLArenaPool* arena) { 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(const_cast(rawANSSISubject)), + sizeof(rawANSSISubject) - 1 + }; + + const SECItem PERMIT_FRANCE_GOV_NC = { + siBuffer, + reinterpret_cast(const_cast(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 arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); @@ -425,7 +494,7 @@ CheckNameConstraints(const BackCert& cert) // Owned by arena const CERTNameConstraints* constraints = - CERT_DecodeNameConstraintsExtension(arena.get(), cert.GetNameConstraints()); + CERT_DecodeNameConstraintsExtension(arena.get(), nameConstraintsToUse); if (!constraints) { return MapSECStatus(SECFailure); }