OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #include "plarena.h" | 5 #include "plarena.h" |
6 #include "seccomon.h" | 6 #include "seccomon.h" |
7 #include "secitem.h" | 7 #include "secitem.h" |
8 #include "secoidt.h" | 8 #include "secoidt.h" |
9 #include "secasn1.h" | 9 #include "secasn1.h" |
10 #include "secder.h" | 10 #include "secder.h" |
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 | 1549 |
1550 done: | 1550 done: |
1551 if (rv == SECFailure) { | 1551 if (rv == SECFailure) { |
1552 PORT_ArenaRelease(arena, mark); | 1552 PORT_ArenaRelease(arena, mark); |
1553 } else { | 1553 } else { |
1554 PORT_ArenaUnmark(arena, mark); | 1554 PORT_ArenaUnmark(arena, mark); |
1555 } | 1555 } |
1556 return rv; | 1556 return rv; |
1557 } | 1557 } |
1558 | 1558 |
1559 /* Add name constraints to certain certs that do not include name constraints | 1559 /* |
1560 * This is the core of the implementation for bug 952572. | 1560 * Here we define a list of name constraints to be imposed on |
| 1561 * certain certificates, most importantly root certificates. |
| 1562 * |
| 1563 * Each entry in the name constraints list is constructed with this |
| 1564 * macro. An entry contains two SECItems, which have names in |
| 1565 * specific forms to make the macro work: |
| 1566 * |
| 1567 * * ${CA}_SUBJECT_DN - The subject DN for which the constraints |
| 1568 * should be applied |
| 1569 * * ${CA}_NAME_CONSTRAINTS - The name constraints extension |
| 1570 * |
| 1571 * Entities subject to name constraints are identified by subject name |
| 1572 * so that we can cover all certificates for that entity, including, e.g., |
| 1573 * cross-certificates. We use subject rather than public key because |
| 1574 * calling methods often have easy access to that field (vs., say, a key ID), |
| 1575 * and in practice, subject names and public keys are usually in one-to-one |
| 1576 * correspondence anyway. |
| 1577 * |
1561 */ | 1578 */ |
1562 | 1579 |
1563 static SECStatus | 1580 #define STRING_TO_SECITEM(str) \ |
1564 getNameExtensionsBuiltIn(CERTCertificate *cert, | 1581 { siBuffer, (unsigned char*) str, sizeof(str) - 1 } |
1565 SECItem *extensions) | 1582 |
| 1583 #define NAME_CONSTRAINTS_ENTRY(CA) \ |
| 1584 { \ |
| 1585 STRING_TO_SECITEM(CA ## _SUBJECT_DN), \ |
| 1586 STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \ |
| 1587 } |
| 1588 |
| 1589 /* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ |
| 1590 |
| 1591 #define ANSSI_SUBJECT_DN \ |
| 1592 "\x30\x81\x85" \ |
| 1593 "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ |
| 1594 "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \ |
| 1595 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \ |
| 1596 "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \ |
| 1597 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \ |
| 1598 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \ |
| 1599 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \ |
| 1600 "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \ |
| 1601 |
| 1602 #define ANSSI_NAME_CONSTRAINTS \ |
| 1603 "\x30\x5D\xA0\x5B" \ |
| 1604 "\x30\x05\x82\x03" ".fr" \ |
| 1605 "\x30\x05\x82\x03" ".gp" \ |
| 1606 "\x30\x05\x82\x03" ".gf" \ |
| 1607 "\x30\x05\x82\x03" ".mq" \ |
| 1608 "\x30\x05\x82\x03" ".re" \ |
| 1609 "\x30\x05\x82\x03" ".yt" \ |
| 1610 "\x30\x05\x82\x03" ".pm" \ |
| 1611 "\x30\x05\x82\x03" ".bl" \ |
| 1612 "\x30\x05\x82\x03" ".mf" \ |
| 1613 "\x30\x05\x82\x03" ".wf" \ |
| 1614 "\x30\x05\x82\x03" ".pf" \ |
| 1615 "\x30\x05\x82\x03" ".nc" \ |
| 1616 "\x30\x05\x82\x03" ".tf" \ |
| 1617 |
| 1618 static const SECItem builtInNameConstraints[][2] = { |
| 1619 NAME_CONSTRAINTS_ENTRY(ANSSI) |
| 1620 }; |
| 1621 |
| 1622 SECStatus |
| 1623 CERT_GetImposedNameConstraints(const SECItem *derSubject, |
| 1624 SECItem *extensions) |
1566 { | 1625 { |
1567 const char constraintFranceGov[] = "\x30\x5D" /* sequence len = 93*/ | 1626 size_t i; |
1568 "\xA0\x5B" /* element len =91 */ | |
1569 "\x30\x05" /* sequence len 5 */ | |
1570 "\x82\x03" /* entry len 3 */ | |
1571 ".fr" | |
1572 "\x30\x05\x82\x03" /* sequence len5, entry
len 3 */ | |
1573 ".gp" | |
1574 "\x30\x05\x82\x03" | |
1575 ".gf" | |
1576 "\x30\x05\x82\x03" | |
1577 ".mq" | |
1578 "\x30\x05\x82\x03" | |
1579 ".re" | |
1580 "\x30\x05\x82\x03" | |
1581 ".yt" | |
1582 "\x30\x05\x82\x03" | |
1583 ".pm" | |
1584 "\x30\x05\x82\x03" | |
1585 ".bl" | |
1586 "\x30\x05\x82\x03" | |
1587 ".mf" | |
1588 "\x30\x05\x82\x03" | |
1589 ".wf" | |
1590 "\x30\x05\x82\x03" | |
1591 ".pf" | |
1592 "\x30\x05\x82\x03" | |
1593 ".nc" | |
1594 "\x30\x05\x82\x03" | |
1595 ".tf"; | |
1596 | 1627 |
1597 /* The stringified value for the subject is: | 1628 if (!extensions) { |
1598 E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR | 1629 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1599 */ | 1630 return SECFailure; |
1600 const char rawANSSISubject[] = "\x30\x81\x85\x31\x0B\x30\x09\x06\x03\x55\x04" | 1631 } |
1601 "\x06\x13\x02\x46\x52\x31\x0F\x30\x0D\x06\x03" | |
1602 "\x55\x04\x08\x13\x06\x46\x72\x61\x6E\x63\x65" | |
1603 "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" | |
1604 "\x50\x61\x72\x69\x73\x31\x10\x30\x0E\x06\x03" | |
1605 "\x55\x04\x0A\x13\x07\x50\x4D\x2F\x53\x47\x44" | |
1606 "\x4E\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13" | |
1607 "\x05\x44\x43\x53\x53\x49\x31\x0E\x30\x0C\x06" | |
1608 "\x03\x55\x04\x03\x13\x05\x49\x47\x43\x2F\x41" | |
1609 "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7" | |
1610 "\x0D\x01\x09\x01\x16\x14\x69\x67\x63\x61\x40" | |
1611 "\x73\x67\x64\x6E\x2E\x70\x6D\x2E\x67\x6F\x75" | |
1612 "\x76\x2E\x66\x72"; | |
1613 | 1632 |
1614 const SECItem anssi_subject = {0, (unsigned char *) rawANSSISubject, | 1633 for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) { |
1615 sizeof(rawANSSISubject)-1}; | 1634 if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) { |
1616 const SECItem permitFranceGovNC = {0, (unsigned char *) constraintFranceGov, | 1635 return SECITEM_CopyItem(NULL, |
1617 sizeof(constraintFranceGov)-1}; | 1636 extensions, |
| 1637 &builtInNameConstraints[i][1]); |
| 1638 } |
| 1639 } |
1618 | 1640 |
1619 if (SECITEM_ItemsAreEqual(&cert->derSubject, &anssi_subject)) { | 1641 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); |
1620 SECStatus rv; | 1642 return SECFailure; |
1621 rv = SECITEM_CopyItem(NULL, extensions, &permitFranceGovNC); | |
1622 return rv; | |
1623 } | |
1624 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); | |
1625 return SECFailure; | |
1626 } | 1643 } |
1627 | 1644 |
1628 /* Extract the name constraints extension from the CA cert. */ | 1645 /* |
| 1646 * Extract the name constraints extension from the CA cert. |
| 1647 * If the certificate contains no name constraints extension, but |
| 1648 * CERT_GetImposedNameConstraints returns a name constraints extension |
| 1649 * for the subject of the certificate, then that extension will be returned. |
| 1650 */ |
1629 SECStatus | 1651 SECStatus |
1630 CERT_FindNameConstraintsExten(PLArenaPool *arena, | 1652 CERT_FindNameConstraintsExten(PLArenaPool *arena, |
1631 CERTCertificate *cert, | 1653 CERTCertificate *cert, |
1632 CERTNameConstraints **constraints) | 1654 CERTNameConstraints **constraints) |
1633 { | 1655 { |
1634 SECStatus rv = SECSuccess; | 1656 SECStatus rv = SECSuccess; |
1635 SECItem constraintsExtension; | 1657 SECItem constraintsExtension; |
1636 void *mark = NULL; | 1658 void *mark = NULL; |
1637 | 1659 |
1638 *constraints = NULL; | 1660 *constraints = NULL; |
1639 | 1661 |
1640 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, | 1662 rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, |
1641 &constraintsExtension); | 1663 &constraintsExtension); |
1642 if (rv != SECSuccess) { | 1664 if (rv != SECSuccess) { |
1643 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { | 1665 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { |
1644 return rv; | 1666 return rv; |
1645 } | 1667 } |
1646 rv = getNameExtensionsBuiltIn(cert, &constraintsExtension); | 1668 rv = CERT_GetImposedNameConstraints(&cert->derSubject, |
| 1669 &constraintsExtension); |
1647 if (rv != SECSuccess) { | 1670 if (rv != SECSuccess) { |
1648 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { | 1671 if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { |
1649 return SECSuccess; | 1672 return SECSuccess; |
1650 } | 1673 } |
1651 return rv; | 1674 return rv; |
1652 } | 1675 } |
1653 } | 1676 } |
1654 | 1677 |
1655 mark = PORT_ArenaMark(arena); | 1678 mark = PORT_ArenaMark(arena); |
1656 | 1679 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 break; | 1984 break; |
1962 } | 1985 } |
1963 list->name = cert_CombineNamesLists(list->name, name); | 1986 list->name = cert_CombineNamesLists(list->name, name); |
1964 list->len++; | 1987 list->len++; |
1965 done: | 1988 done: |
1966 PZ_Unlock(list->lock); | 1989 PZ_Unlock(list->lock); |
1967 } | 1990 } |
1968 return; | 1991 return; |
1969 } | 1992 } |
1970 #endif | 1993 #endif |
OLD | NEW |