| Index: nss/lib/certdb/genname.c
|
| diff --git a/nss/lib/certdb/genname.c b/nss/lib/certdb/genname.c
|
| index 1b0cc970489478dc36bd9a4c38d8bca6231eb9b3..e3bc11d59109d83a24daaf82aacd91a4969e49c1 100644
|
| --- a/nss/lib/certdb/genname.c
|
| +++ b/nss/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;
|
|
|