Skip to content

Commit

Permalink
Gracefully handle SAN decoding errors when subject emailAddress attrb…
Browse files Browse the repository at this point in the history
…ute is present (#143)

* Gracefully handle SAN decoding errors when subject emailAddress attribute is present

* Properly report invalid string encoding errors
  • Loading branch information
CBonnell authored Jan 9, 2025
1 parent cd91521 commit 529c066
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 14 deletions.
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.12.5
0.12.6
9 changes: 8 additions & 1 deletion pkilint/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 18 additions & 1 deletion pkilint/pkix/certificate/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 11 additions & 11 deletions pkilint/pkix/certificate/certificate_name.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pyasn1_alt_modules import rfc5280

from pkilint import validation
from pkilint.pkix import general_name


class SubjectEmailAddressInSanValidator(validation.Validator):
Expand Down Expand Up @@ -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',
)
39 changes: 39 additions & 0 deletions tests/integration_certificate/pkix/bad_san_encoding.crttest
Original file line number Diff line number Diff line change
@@ -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 ""[email protected]"" not found in SAN"
certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified,

0 comments on commit 529c066

Please sign in to comment.