diff --git a/VERSION.txt b/VERSION.txt index 6799343..0ec9201 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.12.5 \ No newline at end of file +0.12.6 \ No newline at end of file diff --git a/pkilint/document.py b/pkilint/document.py index dc2645c..9a28d77 100644 --- a/pkilint/document.py +++ b/pkilint/document.py @@ -13,7 +13,7 @@ NamedTuple, ) -from pyasn1.error import PyAsn1Error +from pyasn1.error import PyAsn1Error, PyAsn1UnicodeDecodeError from pyasn1.type.base import Asn1Type from pyasn1.type.univ import ( ObjectIdentifier, @@ -328,6 +328,13 @@ def decode_substrate( try: decoded, _ = decode_der(substrate, asn1Spec=pdu_instance) + except PyAsn1UnicodeDecodeError as e: + # hack to obtain the error string for string type decoding failures + underlying_error = UnicodeDecodeError(*e.args) + + raise SubstrateDecodingFailedError( + source_document, pdu_instance, parent_node, str(underlying_error) + ) from e except (ValueError, PyAsn1Error) as e: raise SubstrateDecodingFailedError( source_document, pdu_instance, parent_node, str(e) diff --git a/pkilint/pkix/certificate/__init__.py b/pkilint/pkix/certificate/__init__.py index 0cb6427..d654e4c 100644 --- a/pkilint/pkix/certificate/__init__.py +++ b/pkilint/pkix/certificate/__init__.py @@ -1,7 +1,7 @@ import datetime import functools import logging -from typing import Set, Optional +from typing import Set, Optional, List from cryptography import x509, exceptions from pyasn1.codec.der.encoder import encode @@ -195,6 +195,23 @@ def policy_oids(self) -> Set[univ.ObjectIdentifier]: else set() ) + def get_san_general_names_by_type( + self, general_name_type: general_name.GeneralNameTypeName + ) -> List[document.PDUNode]: + decoded = self._decode_and_append_extension( + rfc5280.id_ce_subjectAltName, rfc5280.SubjectAltName() + ) + + return ( + [] + if decoded is None + else [ + gn.children[general_name_type] + for gn in decoded.children.values() + if general_name_type in gn.children + ] + ) + def create_spki_decoder( subject_public_key_type_mappings, subject_public_key_parameters_type_mappings diff --git a/pkilint/pkix/certificate/certificate_name.py b/pkilint/pkix/certificate/certificate_name.py index 504280e..328ae4c 100644 --- a/pkilint/pkix/certificate/certificate_name.py +++ b/pkilint/pkix/certificate/certificate_name.py @@ -1,6 +1,7 @@ from pyasn1_alt_modules import rfc5280 from pkilint import validation +from pkilint.pkix import general_name class SubjectEmailAddressInSanValidator(validation.Validator): @@ -28,14 +29,13 @@ def validate(self, node): email_address = str(node.pdu) - for gn in ext.navigate("extnValue.subjectAltName").children.values(): - value_node = gn.children.get("rfc822Name") - if value_node is None: - continue - if str(value_node.pdu) == email_address: - return - - raise validation.ValidationFindingEncountered( - self.VALIDATION_SUBJECT_EMAIL_NOT_IN_SAN, - f'Subject DN e-mail address "{email_address}" not found in SAN', - ) + if not any( + str(rfc822name_node.pdu) == email_address + for rfc822name_node in node.document.get_san_general_names_by_type( + general_name.GeneralNameTypeName.RFC822_NAME + ) + ): + raise validation.ValidationFindingEncountered( + self.VALIDATION_SUBJECT_EMAIL_NOT_IN_SAN, + f'Subject DN e-mail address "{email_address}" not found in SAN', + ) diff --git a/tests/integration_certificate/pkix/bad_san_encoding.crttest b/tests/integration_certificate/pkix/bad_san_encoding.crttest new file mode 100644 index 0000000..e725804 --- /dev/null +++ b/tests/integration_certificate/pkix/bad_san_encoding.crttest @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +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 +Hvi6SnsfcUgkdTU= +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.extensions.8,ExtensionsDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.8.extnValue"" with schema ""SubjectAltName"" corresponding to type OID 2.5.29.17: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)" +certificate.tbsCertificate.subject.rdnSequence.3.0.value.emailAddress,SubjectEmailAddressInSanValidator,ERROR,pkix.subject_email_address_not_in_san,"Subject DN e-mail address ""foo@example.com"" not found in SAN" +certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified,