Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into smc09
Browse files Browse the repository at this point in the history
  • Loading branch information
CBonnell committed Nov 25, 2024
2 parents 65fef9d + d699b23 commit cede6a4
Show file tree
Hide file tree
Showing 51 changed files with 1,279 additions and 223 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project from version 0.9.3 onwards are documented in this file.

## 0.12.4 - 2024-11-XX

### New features/enhancements

- Add support for TLS BR ballot SC-79 (#XXX)

## 0.12.3 - 2024-10-23

### New features/enhancements
Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.12.3
0.12.4
6 changes: 3 additions & 3 deletions pkilint/bin/lint_pkix_signer_signee_cert_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pyasn1_alt_modules import rfc5280

from pkilint import loader, document, cli_util, validation, pkix, report
from pkilint.pkix import certificate, name, extension, algorithm
from pkilint.pkix import certificate, name, extension, algorithm, key
from pkilint.pkix.certificate import certificate_extension, certificate_key


Expand All @@ -19,8 +19,8 @@ def create_decoder_validation_container():
path="certificate.tbsCertificate.signature",
),
certificate.create_spki_decoder(
certificate_key.SUBJECT_PUBLIC_KEY_ALGORITHM_IDENTIFIER_MAPPINGS,
certificate_key.SUBJECT_KEY_PARAMETER_ALGORITHM_IDENTIFIER_MAPPINGS,
key.SUBJECT_PUBLIC_KEY_ALGORITHM_IDENTIFIER_MAPPINGS,
key.SUBJECT_KEY_PARAMETER_ALGORITHM_IDENTIFIER_MAPPINGS,
),
]

Expand Down
4 changes: 2 additions & 2 deletions pkilint/cabf/cabf_key.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pyasn1_alt_modules import rfc3279, rfc5480, rfc5280

from pkilint.pkix import key
from pkilint import validation
from pkilint.pkix.certificate import certificate_key


class RsaKeyValidator(validation.Validator):
Expand Down Expand Up @@ -238,7 +238,7 @@ def __init__(self):

def validate(self, node):
try:
key_obj = certificate_key.convert_spki_to_object(node)
key_obj = key.convert_spki_to_object(node)

if key_obj is None:
raise validation.ValidationFindingEncountered(
Expand Down
5 changes: 5 additions & 0 deletions pkilint/cabf/serverauth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
serverauth_finding_filter,
)
from pkilint.common import alternative_name
from pkilint.msft import msft_extension
from pkilint.pkix import name, certificate
from pkilint.pkix.certificate import certificate_validity

Expand Down Expand Up @@ -358,6 +359,10 @@ def create_subscriber_extension_validator_container(
serverauth_subscriber.SubscriberKeyUsageValidator(),
serverauth_subscriber.SubscriberBasicConstraintsValidator(),
serverauth_subscriber.SubscriberPoliciesValidator(certificate_type),
serverauth_subscriber.SubscriberRevocationInformationPresenceValidator(
validity_period_start_retriever
),
msft_extension.EndEntityRevocationInformationPresenceValidator(),
]
)

Expand Down
11 changes: 10 additions & 1 deletion pkilint/cabf/serverauth/finding_metadata.csv
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ ERROR,cabf.serverauth.prohibited_duplicate_attribute_type,Validates that only sp
ERROR,cabf.serverauth.prohibited_san_type,Validates that the types of GeneralNames included in the SAN extension conform to BR 7.1.2.7.12.
ERROR,cabf.serverauth.prohibited_signature_algorithm_encoding,Validates that the signature algorithm conforms with BR 7.1.3.2.
ERROR,cabf.serverauth.prohibited_subject_public_key_algorithm_encoding,Validates that subject public key algorithm conforms with BR 7.1.3.1.
ERROR,cabf.serverauth.subscriber.revocation_information_absent,"Validates that long-lived Subscriber Certificates contains either an OCSP pointer or CRLDP extension per BR 7.1.2.11.2."
ERROR,cabf.serverauth.rdn_contains_multiple_atvs,"Validates that each RelativeDistguishedName contains exactly one AttributeTypeAndValue, as per BR 7.1.4.2."
ERROR,cabf.serverauth.root.basic_constraints_extension_absent,Validates that the included extensions conform to BR 7.1.2.1.2.: A required element is absent
ERROR,cabf.serverauth.root.extended_key_usage_extension_present,Validates that the included extensions conform to BR 7.1.2.1.2.: A prohibited element is present
Expand Down Expand Up @@ -185,6 +186,7 @@ ERROR,cabf.serverauth.subscriber_multiple_reserved_policy_oids,Validates that th
ERROR,cabf.serverauth.subscriber_prohibited_ku_present,Validates that the content of the key usage extension conforms with BR 7.1.2.7.11.
ERROR,cabf.serverauth.subscriber_required_ku_missing,Validates that the content of the key usage extension conforms with BR 7.1.2.7.11.
ERROR,cabf.serverauth.subscriber_stateprovince_and_locality_missing,"Validates that the stateOrProvinceName and/or localityName subject attributes are present, as per EVG 9.2.6, BR 7.1.2.7.3, and BR 7.1.2.7.4."
ERROR,msft.end_entity.revocation_information_absent,"Validates that the end-entity certificate contains either an OCSP or CRL HTTP URI per section 3.A.5 of Microsoft Root Program Requirements."
ERROR,pkix.aki_with_cert_issuer_but_serial_number_absent,"RFC 5280 4.2.1.1: ""The identification MAY be based on either the key identifier (the subject key identifier in the issuer's certificate) or the issuer name and serial number"""
ERROR,pkix.aki_with_serial_number_but_cert_issuer_absent,"RFC 5280 4.2.1.1: ""The identification MAY be based on either the key identifier (the subject key identifier in the issuer's certificate) or the issuer name and serial number"""
ERROR,pkix.authority_information_access_extension_critical,"RFC 5280 4.2.2.1: ""Conforming CAs MUST mark this extension as non-critical."""
Expand Down Expand Up @@ -219,7 +221,12 @@ ERROR,pkix.ip_address_name_constraint_invalid_cidr,"RFC 5280 4.1.2.10: ""For IPv
ERROR,pkix.ip_address_name_constraint_wrong_length,"RFC 5280 4.1.2.10: ""For IPv4 addresses, the iPAddress field of GeneralName MUST contain eight (8) octets, encoded in the style of RFC 4632 (CIDR) to represent an address range [RFC4632]. For IPv6 addresses, the iPAddress field MUST contain 32 octets similarly encoded."""
ERROR,pkix.ip_address_wrong_length,"RFC 5280 4.1.2.6: ""For IP version 4, as specified in [RFC791], the octet string MUST contain exactly four octets. For IP version 6, as specified in [RFC2460], the octet string MUST contain exactly sixteen octets."""
ERROR,pkix.issuer_unique_id_present,"RFC 5280 4.1.2.8: ""CAs conforming to this profile MUST NOT generate certificates with unique identifiers"""
ERROR,pkix.name_constraints_in_ee_certificate,"RFC 5280 4.2.1.10: ""The name constraints extension, which MUST be used only in a CA certificate�"""
ERROR,pkix.key_usage_value_prohibited_for_ec,"RFC 8813 3: If the keyUsage extension is present in a certificate that indicates id-ecPublicKey in SubjectPublicKeyInfo, then the following values MUST NOT be present..."
ERROR,pkix.key_usage_value_prohibited_for_edwards_curve,"RFC 9295 3: and any of the following MUST NOT be present..."
ERROR,pkix.key_usage_value_required_but_missing_for_edwards_curve,"RFC 9295 3: If the keyUsage extension is present in a certificate that indicates id-X25519 or id-X448 in SubjectPublicKeyInfo, then the following MUST be present..."
ERROR,pkix.key_usage_value_prohibited_for_rsa,"RFC 3279 2.3.1: If the keyUsage extension is present in an end entity/CRL issuer/CA certificate which conveys an RSA public key, any combination of the following values MAY be present..."
ERROR,pkix.key_usage_value_prohibited_for_signature_algorithm,"Various RFCs specify the allowed keyUsage values for signature algorithms"
ERROR,pkix.name_constraints_in_ee_certificate,"RFC 5280 4.2.1.10: ""The name constraints extension, which MUST be used only in a CA certificate"""
ERROR,pkix.name_constraints_maximum_specified,"RFC 5280 4.2.1.10: ""Within this profile, the minimum and maximum fields are not used with any name forms, thus, the minimum MUST be zero, and maximum MUST be absent"""
ERROR,pkix.name_constraints_no_subtrees,"RFC 5280 4.2.1.10: ""Conforming CAs MUST NOT issue certificates where name constraints is an empty sequence."""
ERROR,pkix.name_constraints_non_default_minimum,"RFC 5280 4.2.1.10: ""Within this profile, the minimum and maximum fields are not used with any name forms, thus, the minimum MUST be zero, and maximum MUST be absent"""
Expand Down Expand Up @@ -301,7 +308,9 @@ WARNING,pkix.san_extension_is_critical_non_empty_subject,"RFC 5280 4.2.1.6: "" W
NOTICE,cabf.ca_certificate_no_digital_signature_bit,CA certificates with no digitalSignature bit asserted imply that the CA Private Key cannot sign OCSP responses
NOTICE,cabf.serverauth.unparsed_common_name_encountered,Validates that the content of the commonName attribute conforms to BR 7.1.4.3.
NOTICE,cabf.serverauth.unparsed_san_extension_encountered,Validates that the content of the commonName attribute conforms to BR 7.1.4.3.
NOTICE,pkix.aki_absent_self_issued_and_unsupported_public_key_algorithm,Authority Key Identifier extension is absent is a self-issued certificate and the certificate certifies a public key of an unsupported algorithm.
NOTICE,pkix.certificate_policies_policy_has_qualifier,"RFC 5280 4.2.1.4: ""To promote interoperability, this profile RECOMMENDS that policy information terms consist of only an OID. Where an OID alone is insufficient, this profile strongly recommends that the use of qualifiers be limited to those identified in this section"""
NOTICE,pkix.public_key_algorithm_unsupported,"The algorithm of the certified public key is not supported"
NOTICE,pkix.ldap_uri_not_validated,": Notice that the linter encountered a LDAP URI but did not validate the correctness of the URI, as support for LDAP validation has not (yet) been implemented. This NOTICE should probably be of a lower severity or supressed entirely."
NOTICE,pkix.unknown_subject_key_identifier_calculation_method,RFC 5280 4.2.1.2: The Subject key identifier was not calculated using one of the algorithms defined in RFC 5280
INFO,pkix.subject_key_identifier_method_1_identified,RFC 5280 4.2.1.2: The Subject key identifier was calculated using the first algorithm defined in RFC 5280
Expand Down
10 changes: 7 additions & 3 deletions pkilint/cabf/serverauth/serverauth_ca.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,19 @@ def validate(self, node):

raise validation.ValidationFindingEncountered(
self.VALIDATION_NON_TLS_CA_HAS_SERVERAUTH_OID,
f"Non-TLS CA has reserved policy OIDs: {oids}",
f"Non-TLS CA has reserved policy OID(s): {oids}",
)
else:
if not any(reserved_oids):
raise validation.ValidationFindingEncountered(
self.VALIDATION_NO_RESERVED_OID
)

if len(reserved_oids) > 1:
if (
len(reserved_oids) > 1
and self._certificate_type
not in serverauth_constants.ROOT_KEY_CROSS_CA_TYPES
):
oids_str = oid.format_oids(reserved_oids)

raise validation.ValidationFindingEncountered(
Expand Down Expand Up @@ -319,7 +323,7 @@ class CaCertificateAuthorityInformationAccessAccessMethodPresenceValidator(
_CODE_CLASSIFIER = "cabf.serverauth.ca"

_ACCESS_METHOD_ALLOWANCES = {
rfc5280.id_ad_ocsp: Rfc2119Word.SHOULD,
rfc5280.id_ad_ocsp: Rfc2119Word.MAY,
rfc5280.id_ad_caIssuers: Rfc2119Word.MAY,
}

Expand Down
49 changes: 33 additions & 16 deletions pkilint/cabf/serverauth/serverauth_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from pyasn1.type.univ import ObjectIdentifier

BR_VERSION = "2.0.3"
BR_VERSION = "2.1.1"


ID_POLICY_EV = ObjectIdentifier("2.23.140.1.1")
Expand All @@ -24,6 +24,8 @@ class CertificateType(enum.IntEnum):
ROOT_CA = auto()
INTERNAL_CROSS_CA = auto()
EXTERNAL_CROSS_CA = auto()
INTERNAL_SUBSCRIBER_ISSUING_CROSS_CA = auto()
EXTERNAL_SUBSCRIBER_ISSUING_CROSS_CA = auto()
NON_TLS_CA = auto()
PRECERT_SIGNING_CA = auto()
INTERNAL_UNCONSTRAINED_TLS_CA = auto()
Expand Down Expand Up @@ -56,23 +58,30 @@ def from_option_str(value):
return CertificateType[value]


INTERMEDIATE_CERTIFICATE_TYPES = {
INTERNAL_CROSS_CA_TYPES = {
CertificateType.INTERNAL_CROSS_CA,
CertificateType.INTERNAL_SUBSCRIBER_ISSUING_CROSS_CA,
}


EXTERNAL_CROSS_CA_TYPES = {
CertificateType.EXTERNAL_CROSS_CA,
CertificateType.EXTERNAL_SUBSCRIBER_ISSUING_CROSS_CA,
}


CROSS_CA_TYPES = INTERNAL_CROSS_CA_TYPES | EXTERNAL_CROSS_CA_TYPES


ROOT_KEY_CROSS_CA_TYPES = {
CertificateType.INTERNAL_CROSS_CA,
CertificateType.EXTERNAL_CROSS_CA,
CertificateType.NON_TLS_CA,
CertificateType.PRECERT_SIGNING_CA,
CertificateType.INTERNAL_UNCONSTRAINED_TLS_CA,
CertificateType.INTERNAL_CONSTRAINED_TLS_CA,
CertificateType.EXTERNAL_UNCONSTRAINED_TLS_CA,
CertificateType.EXTERNAL_UNCONSTRAINED_EV_TLS_CA,
CertificateType.EXTERNAL_CONSTRAINED_TLS_CA,
CertificateType.EXTERNAL_CONSTRAINED_EV_TLS_CA,
}

CROSS_CA_TYPES = {CertificateType.INTERNAL_CROSS_CA, CertificateType.EXTERNAL_CROSS_CA}

INTERNAL_CA_TYPES = {
CertificateType.INTERNAL_CROSS_CA,
CertificateType.INTERNAL_SUBSCRIBER_ISSUING_CROSS_CA,
CertificateType.INTERNAL_UNCONSTRAINED_TLS_CA,
CertificateType.INTERNAL_CONSTRAINED_TLS_CA,
CertificateType.NON_TLS_CA,
Expand All @@ -84,19 +93,27 @@ def from_option_str(value):
CertificateType.EXTERNAL_UNCONSTRAINED_EV_TLS_CA,
CertificateType.EXTERNAL_CONSTRAINED_TLS_CA,
CertificateType.EXTERNAL_CROSS_CA,
CertificateType.EXTERNAL_SUBSCRIBER_ISSUING_CROSS_CA,
}

INTERMEDIATE_CERTIFICATE_TYPES = (
INTERNAL_CA_TYPES | EXTERNAL_CA_TYPES | {CertificateType.PRECERT_SIGNING_CA}
)

CONSTRAINED_TLS_CA_TYPES = {
CertificateType.EXTERNAL_CONSTRAINED_EV_TLS_CA,
CertificateType.EXTERNAL_CONSTRAINED_TLS_CA,
CertificateType.INTERNAL_CONSTRAINED_TLS_CA,
}

TLS_CA_TYPES = {
CertificateType.INTERNAL_CROSS_CA,
CertificateType.INTERNAL_UNCONSTRAINED_TLS_CA,
CertificateType.INTERNAL_CONSTRAINED_TLS_CA,
} | EXTERNAL_CA_TYPES
TLS_CA_TYPES = (
{
CertificateType.INTERNAL_UNCONSTRAINED_TLS_CA,
CertificateType.INTERNAL_CONSTRAINED_TLS_CA,
}
| EXTERNAL_CA_TYPES
| INTERNAL_CROSS_CA_TYPES
)

SUBSCRIBER_FINAL_CERTIFICATE_TYPES = {
CertificateType.DV_FINAL_CERTIFICATE,
Expand Down
14 changes: 4 additions & 10 deletions pkilint/cabf/serverauth/serverauth_cross_ca.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class CrossCertificateExtensionAllowanceValidator(
def __init__(self, certificate_type):
self._extension_allowances = self._EXTENSION_ALLOWANCES.copy()

if certificate_type == serverauth_constants.CertificateType.EXTERNAL_CROSS_CA:
if certificate_type in serverauth_constants.EXTERNAL_CROSS_CA_TYPES:
eku_allowance_word = Rfc2119Word.MUST
elif certificate_type == serverauth_constants.CertificateType.INTERNAL_CROSS_CA:
elif certificate_type in serverauth_constants.INTERNAL_CROSS_CA_TYPES:
eku_allowance_word = Rfc2119Word.SHOULD
else:
raise ValueError(f"Unsupported certificate type: {certificate_type}")
Expand Down Expand Up @@ -81,17 +81,11 @@ def validate(self, node):
ekus = {n.pdu for n in node.children.values()}

if rfc5280.anyExtendedKeyUsage in ekus:
if (
self._certificate_type
== serverauth_constants.CertificateType.EXTERNAL_CROSS_CA
):
if self._certificate_type in serverauth_constants.EXTERNAL_CROSS_CA_TYPES:
raise validation.ValidationFindingEncountered(
self.VALIDATION_EXTERNAL_CROSS_CA_ANYEKU_PRESENT
)
elif (
self._certificate_type
== serverauth_constants.CertificateType.INTERNAL_CROSS_CA
):
elif self._certificate_type in serverauth_constants.INTERNAL_CROSS_CA_TYPES:
if len(node.children) != 1:
raise validation.ValidationFindingEncountered(
self.VALIDATION_INTERNAL_CROSS_CA_ANYEKU_WITH_OTHER_EKU
Expand Down
Loading

0 comments on commit cede6a4

Please sign in to comment.