diff options
author | Richard Barnes <rbarnes@mozilla.com> | 2015-04-11 22:26:44 +0200 |
---|---|---|
committer | Richard Barnes <rbarnes@mozilla.com> | 2015-04-11 22:26:44 +0200 |
commit | 8d4dc5a8d19120e272d6f0a7915785d7532b18f7 (patch) | |
tree | 522be30cab4a9a2296514679b152e6c36b9497c1 | |
parent | 34372b35e32584d40d2be2ad9ca889c481a4c771 (diff) | |
download | nss-hg-8d4dc5a8d19120e272d6f0a7915785d7532b18f7.tar.gz |
Bug 991783 - Add generic mechanism to add name constraints to built-in certificates r=wtc
-rw-r--r-- | lib/certdb/cert.h | 17 | ||||
-rw-r--r-- | lib/certdb/genname.c | 155 | ||||
-rw-r--r-- | lib/nss/nss.def | 6 |
3 files changed, 112 insertions, 66 deletions
diff --git a/lib/certdb/cert.h b/lib/certdb/cert.h index 6e0bdb089..4564dc2dd 100644 --- a/lib/certdb/cert.h +++ b/lib/certdb/cert.h @@ -1172,6 +1172,20 @@ CERT_GetNextGeneralName(CERTGeneralName *current); extern CERTGeneralName * CERT_GetPrevGeneralName(CERTGeneralName *current); +/* + * Look up name constraints for some certs that do not include name constraints + * (Most importantly, root certificates) + * + * If a matching subject is found, |extensions| will be populated with a copy of the + * DER-encoded name constraints extension. The data in |extensions| will point to + * memory that the caller owns. + * + * There is no mechanism to configure imposed name constraints right now. All + * imposed name constraints are built into NSS. + */ +SECStatus +CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions); + CERTNameConstraint * CERT_GetNextNameConstraint(CERTNameConstraint *current); @@ -1543,6 +1557,9 @@ CERT_CheckNameSpace(PLArenaPool *arena, /* * Extract and allocate the name constraints extension from the CA cert. + * If the certificate contains no name constraints extension, but + * CERT_GetImposedNameConstraints returns a name constraints extension + * for the subject of the certificate, then that extension will be returned. */ extern SECStatus CERT_FindNameConstraintsExten(PLArenaPool *arena, diff --git a/lib/certdb/genname.c b/lib/certdb/genname.c index 1b0cc9704..e3bc11d59 100644 --- a/lib/certdb/genname.c +++ b/lib/certdb/genname.c @@ -1556,76 +1556,98 @@ done: return rv; } -/* Add name constraints to certain certs that do not include name constraints - * This is the core of the implementation for bug 952572. +/* + * Here we define a list of name constraints to be imposed on + * certain certificates, most importantly root certificates. + * + * Each entry in the name constraints list is constructed with this + * macro. An entry contains two SECItems, which have names in + * specific forms to make the macro work: + * + * * ${CA}_SUBJECT_DN - The subject DN for which the constraints + * should be applied + * * ${CA}_NAME_CONSTRAINTS - The name constraints extension + * + * Entities subject to name constraints are identified by subject name + * so that we can cover all certificates for that entity, including, e.g., + * cross-certificates. We use subject rather than public key because + * calling methods often have easy access to that field (vs., say, a key ID), + * and in practice, subject names and public keys are usually in one-to-one + * correspondence anyway. + * */ -static SECStatus -getNameExtensionsBuiltIn(CERTCertificate *cert, - SECItem *extensions) +#define STRING_TO_SECITEM(str) \ +{ siBuffer, (unsigned char*) str, sizeof(str) - 1 } + +#define NAME_CONSTRAINTS_ENTRY(CA) \ + { \ + STRING_TO_SECITEM(CA ## _SUBJECT_DN), \ + STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \ + } + +/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ + +#define ANSSI_SUBJECT_DN \ + "\x30\x81\x85" \ + "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ + "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \ + "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \ + "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \ + "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \ + "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \ + +#define ANSSI_NAME_CONSTRAINTS \ + "\x30\x5D\xA0\x5B" \ + "\x30\x05\x82\x03" ".fr" \ + "\x30\x05\x82\x03" ".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" \ + +static const SECItem builtInNameConstraints[][2] = { + NAME_CONSTRAINTS_ENTRY(ANSSI) +}; + +SECStatus +CERT_GetImposedNameConstraints(const SECItem *derSubject, + SECItem *extensions) { - 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 len5, 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 - */ - 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 = {0, (unsigned char *) rawANSSISubject, - sizeof(rawANSSISubject)-1}; - const SECItem permitFranceGovNC = {0, (unsigned char *) constraintFranceGov, - sizeof(constraintFranceGov)-1}; - - if (SECITEM_ItemsAreEqual(&cert->derSubject, &anssi_subject)) { - SECStatus rv; - rv = SECITEM_CopyItem(NULL, extensions, &permitFranceGovNC); - return rv; - } - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); - return SECFailure; + size_t i; + + if (!extensions) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { + if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { + return SECITEM_CopyItem(NULL, + extensions, + &builtInNameConstraints[i][1]); + } + } + + PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + return SECFailure; } -/* Extract the name constraints extension from the CA cert. */ +/* + * Extract the name constraints extension from the CA cert. + * If the certificate contains no name constraints extension, but + * CERT_GetImposedNameConstraints returns a name constraints extension + * for the subject of the certificate, then that extension will be returned. + */ SECStatus CERT_FindNameConstraintsExten(PLArenaPool *arena, CERTCertificate *cert, @@ -1643,7 +1665,8 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena, if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { return rv; } - rv = getNameExtensionsBuiltIn(cert, &constraintsExtension); + rv = CERT_GetImposedNameConstraints(&cert->derSubject, + &constraintsExtension); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { return SECSuccess; diff --git a/lib/nss/nss.def b/lib/nss/nss.def index abe0604f5..fdc8a8a15 100644 --- a/lib/nss/nss.def +++ b/lib/nss/nss.def @@ -1070,3 +1070,9 @@ SEC_GetCrlTimes; ;+ local: ;+ *; ;+}; +;+NSS_3.18.1 { # NSS 3.18.1 release +;+ global: +CERT_GetImposedNameConstraints; +;+ local: +;+ *; +;+}; |