diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a98455..bd46d34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project from version 0.9.3 onwards are documented in this file. +## 0.11.2 - 2024-07-16 + +### Fixes + +- Gracefully handle mis-encoded extensions and fields exposed as properties (#88) + ## 0.11.1 - 2024-07-02 ### New features/enhancements diff --git a/LICENSE b/LICENSE index ca5b958..4dd9dd9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2023 DigiCert, Inc. +Copyright (c) 2020-2024 DigiCert, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/VERSION.txt b/VERSION.txt index 027934e..a8839f7 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.11.1 \ No newline at end of file +0.11.2 \ No newline at end of file diff --git a/pkilint/document.py b/pkilint/document.py index 1e72652..9334155 100644 --- a/pkilint/document.py +++ b/pkilint/document.py @@ -1,4 +1,3 @@ -import binascii import datetime import logging import re @@ -12,12 +11,10 @@ Choice, BitString ) - logger = logging.getLogger(__name__) PATH_REGEX = re.compile(r'^((?P[^:]*):)?(?P([^.]+\.)*[^.]+)?$') - try: # noinspection PyUnresolvedReferences from pyasn1_fasder import decode_der @@ -50,7 +47,7 @@ def __str__(self) -> str: ) -class Document(object): +class Document: """Represents an ASN.1-encoded document.""" def __init__( @@ -92,7 +89,7 @@ def __repr__(self): return f'{self.root.name} document "{self.substrate_source}"' -class PDUNode(object): +class PDUNode: """Represents a node of a document.""" def __init__(self, document: Document, name: str, pdu: Asn1Type, @@ -234,7 +231,7 @@ def __repr__(self): return f'{self.pdu.__class__.__name__} @ {path}' -class NodeVisitor(object): +class NodeVisitor: def __init__(self, *, path: str = None, path_re: re.Pattern = None, @@ -263,21 +260,98 @@ def match(self, node: PDUNode) -> bool: return True -class ValueDecodingFailedError(Exception): - def __init__(self, value_node: PDUNode, type_oid: ObjectIdentifier, - pdu_type: Optional[Asn1Type], message: str - ): - self.value_node = value_node - self.type_oid = type_oid - self.pdu_type = pdu_type +def get_node_name_for_pdu(pdu: Asn1Type) -> str: + name = pdu.__class__.__name__ + # convert PDU class name to camelCase + return name[0].lower() + name[1:] + + +class SubstrateDecodingFailedError(ValueError): + def __init__( + self, source_document: Document, pdu_instance: Optional[Asn1Type], parent_node: Optional[PDUNode], + message: Optional[str] + ): + self.source_document = source_document + self.pdu_instance = pdu_instance + self.parent_node = parent_node self.message = message + def __str__(self): + message = f'Error occurred while decoding substrate in document "{self.source_document.name}"' + + if self.parent_node: + message += f' @ {self.parent_node.path}' + + if self.pdu_instance: + message += f' using schema "{self.pdu_instance.__class__.__name__}"' + + if self.message: + message += f': {self.message}' + + return message + + +def decode_substrate(source_document: Document, substrate: bytes, + pdu_instance: Asn1Type, parent_node: Optional[PDUNode] = None) -> PDUNode: + if parent_node is not None and any(parent_node.children): + logger.debug("%s has child node; not creating new PDU node", + parent_node.path + ) + return next(iter(parent_node.children.values())) + + if _USE_PYASN1_FASDER: + try: + decoded, _ = decode_der(substrate, asn1Spec=pdu_instance) + except (ValueError, PyAsn1Error) as e: + raise SubstrateDecodingFailedError(source_document, pdu_instance, parent_node, str(e)) from e + + decoded_pdu_name = get_node_name_for_pdu(decoded) + else: + try: + decoded, rest = decode(substrate, asn1Spec=pdu_instance) + except (ValueError, PyAsn1Error) as e: + raise SubstrateDecodingFailedError(source_document, pdu_instance, parent_node, str(e)) from e + + decoded_pdu_name = get_node_name_for_pdu(decoded) + type_name = decoded.__class__.__name__ + + if len(rest) > 0: + rest_hex = bytes(rest).hex() + + raise SubstrateDecodingFailedError( + source_document, pdu_instance, parent_node, + f'{len(rest)} unexpected octet(s) following "{type_name}" TLV: "{rest_hex}"' + ) + + try: + encoded = encode(decoded) + + substrate_is_der = encoded == substrate + except (ValueError, PyAsn1Error): + substrate_is_der = False + + if not substrate_is_der: + raise SubstrateDecodingFailedError( + source_document, pdu_instance, parent_node, + f'Substrate of type "{type_name}" is not DER-encoded' + ) + + node = PDUNode(source_document, decoded_pdu_name, decoded, parent_node) + + if parent_node is not None: + parent_node.children[decoded_pdu_name] = node + logger.debug("Appended %s node to %s", node.name, + parent_node.path + ) + + return node + class OptionalAsn1TypeWrapper(NamedTuple): asn1_type: Asn1Type -class ValueDecoder(object): +class ValueDecoder: _BITSTRING_SCHEMA_OBJ = BitString() VALUE_NODE_ABSENT = object() @@ -319,16 +393,19 @@ def __call__(self, node): # value node must be absent, but it exists elif pdu_type is self.VALUE_NODE_ABSENT and value_node is not None: - raise ValueDecodingFailedError( - value_node, type_node.pdu, pdu_type, - 'Value node is present, but the ASN.1 schema specifies that it must be absent' + raise SubstrateDecodingFailedError( + node.document, None, value_node, + f'Value node is present, but type OID {type_node.pdu} specifies that it must be absent' ) # value node must be present, but it doesn't exist elif pdu_type is not self.VALUE_NODE_ABSENT and value_node is None: - raise ValueDecodingFailedError( - node, type_node.pdu, pdu_type, - 'Value node is absent, but the ASN.1 schema specifies that it must be present' + schema_name = pdu_type.__class__.__name__ + + raise SubstrateDecodingFailedError( + node.document, pdu_type, value_node, + f'Value node is absent, but type OID {type_node.pdu} specifies that a ' + f'"{schema_name}" value must be present' ) if pdu_type is self.VALUE_NODE_ABSENT or pdu_type is None: @@ -337,19 +414,18 @@ def __call__(self, node): value_octets = self.filter_value(node, type_node, value_node, pdu_type) try: - decode_substrate(value_node.document, value_octets, - pdu_type, value_node - ) - except (PyAsn1Error, ValueError) as e: - raise ValueDecodingFailedError( - value_node, type_node.pdu, pdu_type, str(e) - ) + decode_substrate(value_node.document, value_octets, pdu_type, value_node) + except SubstrateDecodingFailedError as e: + schema_name = pdu_type.__class__.__name__ + message = ( + f'ASN.1 decoding failure occurred at "{value_node.path}" with schema "{schema_name}" corresponding to ' + f'type OID {type_node.pdu}: {e.message}' + ) -def get_node_name_for_pdu(pdu: Asn1Type) -> str: - name = pdu.__class__.__name__ - # convert PDU class name to camelCase - return name[0].lower() + name[1:] + raise SubstrateDecodingFailedError( + e.source_document, e.pdu_instance, e.parent_node, message + ) from e def get_document_by_name(node: PDUNode, document_name: str) -> Document: @@ -357,49 +433,6 @@ def get_document_by_name(node: PDUNode, document_name: str) -> Document: return node.document.parent[document_name] -def decode_substrate(source_document: Document, substrate: bytes, - pdu_instance: Asn1Type, parent_node: Optional[PDUNode] = None) -> PDUNode: - if parent_node is not None and any(parent_node.children): - logger.debug("%s has child node; not creating new PDU node", - parent_node.path - ) - return next(iter(parent_node.children.values())) - - if _USE_PYASN1_FASDER: - decoded, _ = decode_der(substrate, asn1Spec=pdu_instance) - - decoded_pdu_name = get_node_name_for_pdu(decoded) - else: - decoded, rest = decode(substrate, asn1Spec=pdu_instance) - - decoded_pdu_name = get_node_name_for_pdu(decoded) - - if len(rest) > 0: - raise ValueError( - "Unexpected {} octets following {} DER in {}: {}".format( - len(rest), decoded_pdu_name, source_document.substrate_source, - binascii.hexlify(rest).decode('us-ascii') - ) - ) - - encoded = encode(decoded) - if encoded != substrate: - type_name = decoded.__class__.__name__ - raise ValueError( - f'Substrate of type "{type_name}" is not DER-encoded' - ) - - node = PDUNode(source_document, decoded_pdu_name, decoded, parent_node) - - if parent_node is not None: - parent_node.children[decoded_pdu_name] = node - logger.debug("Appended %s node to %s", node.name, - parent_node.path - ) - - return node - - def get_re_for_path_glob(path_glob: str) -> re.Pattern: return re.compile( path_glob.replace('.', r'\.').replace('?', r'\w').replace('*', r'\w*') diff --git a/pkilint/pkix/__init__.py b/pkilint/pkix/__init__.py index 8117bce..c0c4f0c 100644 --- a/pkilint/pkix/__init__.py +++ b/pkilint/pkix/__init__.py @@ -1,3 +1,4 @@ +import datetime import enum from typing import Optional @@ -8,6 +9,8 @@ from pkilint.document import ValueDecoder from pkilint.pkix import extension, algorithm, name +MAXIMUM_TIME_DATETIME = datetime.datetime(9999, 12, 31, 23, 59, 59, tzinfo=datetime.timezone.utc) + def create_attribute_decoder(type_mappings, decode_unknown_as_directorystring=True): default = rfc5280.DirectoryString() if decode_unknown_as_directorystring else None diff --git a/pkilint/pkix/certificate/__init__.py b/pkilint/pkix/certificate/__init__.py index f93754a..2f8578a 100644 --- a/pkilint/pkix/certificate/__init__.py +++ b/pkilint/pkix/certificate/__init__.py @@ -36,15 +36,21 @@ def __init__(self, substrate_source, substrate, @property def not_before(self): - return time.parse_time_node( - self.root.navigate('tbsCertificate.validity.notBefore') - ) + try: + return time.parse_time_node( + self.root.navigate('tbsCertificate.validity.notBefore') + ) + except ValueError: + return pkix.MAXIMUM_TIME_DATETIME @property def not_after(self): - return time.parse_time_node( - self.root.navigate('tbsCertificate.validity.notAfter') - ) + try: + return time.parse_time_node( + self.root.navigate('tbsCertificate.validity.notAfter') + ) + except ValueError: + return pkix.MAXIMUM_TIME_DATETIME def _decode_and_append_extension( self, ext_oid: univ.ObjectIdentifier, ext_asn1_spec: Asn1Type) -> Optional[document.PDUNode]: @@ -56,7 +62,11 @@ def _decode_and_append_extension( ext, _ = ext_and_idx ext_value = ext.children['extnValue'] - return document.decode_substrate(self, ext_value.pdu.asOctets(), ext_asn1_spec, ext_value) + try: + return document.decode_substrate(self, ext_value.pdu.asOctets(), ext_asn1_spec, ext_value) + except ValueError: + # suppress decoding errors, which will be reported by DecodingValidator instances + return None @functools.cached_property def is_ca(self) -> bool: diff --git a/pkilint/pkix/crl/__init__.py b/pkilint/pkix/crl/__init__.py index 720605f..4409808 100644 --- a/pkilint/pkix/crl/__init__.py +++ b/pkilint/pkix/crl/__init__.py @@ -26,18 +26,23 @@ def __init__(self, substrate_source, substrate, @property def this_update(self): - return time.parse_time_node( - self.root.navigate('tbsCertificateList.thisUpdate') - ) + try: + return time.parse_time_node( + self.root.navigate('tbsCertList.thisUpdate') + ) + except ValueError: + return pkix.MAXIMUM_TIME_DATETIME @property def next_update(self): try: return time.parse_time_node( - self.root.navigate('tbsCertificateList.nextUpdate') + self.root.navigate('tbsCertList.nextUpdate') ) except document.PDUNavigationFailedError: return None + except ValueError: + return pkix.MAXIMUM_TIME_DATETIME def get_extension_by_oid(self, oid): tbs_crl = self.root.children['tbsCertList'] diff --git a/pkilint/rest/model.py b/pkilint/rest/model.py index 72984db..317bca6 100644 --- a/pkilint/rest/model.py +++ b/pkilint/rest/model.py @@ -1,8 +1,6 @@ -import base64 from typing import List, Optional from fastapi import HTTPException -from pyasn1.error import PyAsn1Error from pydantic import BaseModel, Field, model_validator from typing_extensions import Annotated @@ -113,12 +111,12 @@ def validate(self) -> 'CertificateModel': if self.pem is not None: try: self._parsed_document = loader.load_pem_certificate(self.pem, 'request', 'request') - except PyAsn1Error as e: + except ValueError as e: raise ValueError('Invalid PEM text specified') from e else: try: self._parsed_document = loader.load_b64_certificate(self.b64, 'request', 'request') - except PyAsn1Error as e: + except ValueError as e: raise ValueError('Invalid Base-64 encoding specified') from e return self @@ -138,12 +136,12 @@ def validate(self) -> 'OcspResponseModel': if self.pem is not None: try: self._parsed_document = loader.load_pem_ocsp_response(self.pem, 'request', 'request') - except PyAsn1Error as e: + except ValueError as e: raise ValueError('Invalid PEM text specified') from e else: try: self._parsed_document = loader.load_b64_ocsp_response(self.b64, 'request', 'request') - except PyAsn1Error as e: + except ValueError as e: raise ValueError('Invalid Base-64 encoding specified') from e return self diff --git a/pkilint/validation.py b/pkilint/validation.py index bccb5ca..5fd7965 100644 --- a/pkilint/validation.py +++ b/pkilint/validation.py @@ -1,16 +1,14 @@ import enum import itertools import logging -from typing import Any, Callable, Mapping, NamedTuple, List, Tuple, Optional +from typing import Callable, NamedTuple, List, Optional from pyasn1.codec.der.encoder import encode from pyasn1.type.constraint import PermittedAlphabetConstraint, ValueRangeConstraint from pyasn1.type.error import ValueConstraintError from pyasn1.type.univ import ObjectIdentifier -from pkilint.document import (PDUNode, NodeVisitor, ValueDecodingFailedError, - PDUNavigationFailedError - ) +from pkilint.document import PDUNode, NodeVisitor, SubstrateDecodingFailedError, PDUNavigationFailedError logger = logging.getLogger(__name__) @@ -250,25 +248,15 @@ class DecodingValidator(Validator): def __init__(self, *, decode_func=Callable[[PDUNode], None], **kwargs): self.decode_func = decode_func - super().__init__(validations=[self.VALIDATION_ASN1_DECODING_FAILURE], - **kwargs - ) + super().__init__(validations=[self.VALIDATION_ASN1_DECODING_FAILURE], **kwargs) def validate(self, node): try: self.decode_func(node) - except ValueDecodingFailedError as e: - schema_name = e.pdu_type.__class__.__name__ - path = e.value_node.path - - description = (f'ASN.1 decoding failure occurred at "{path}"' - f' with schema "{schema_name}", OID {str(e.type_oid)}: ' - f'{e.message}' - ) - + except SubstrateDecodingFailedError as e: raise ValidationFindingEncountered( self.VALIDATION_ASN1_DECODING_FAILURE, - description + e.message ) diff --git a/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/orgname_too_long.crttest b/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/orgname_too_long.crttest index 555c0c6..50ad0bd 100644 --- a/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/orgname_too_long.crttest +++ b/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/orgname_too_long.crttest @@ -34,6 +34,6 @@ znmLPhLy02J9g6T7g24= -----END CERTIFICATE----- node_path,validator,severity,code,message -certificate.tbsCertificate.subject.rdnSequence.3.0,NameDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.subject.rdnSequence.3.0.value"" with schema ""X520OrganizationName"", OID 2.5.4.10: , payload [64]>>> failed at: ValueConstraintError("", payload [64]>> failed at: ValueConstraintError('A loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong company name')"") at UTF8String" +certificate.tbsCertificate.subject.rdnSequence.3.0,NameDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.subject.rdnSequence.3.0.value"" with schema ""X520OrganizationName"" corresponding to type OID 2.5.4.10: , payload [64]>>> failed at: ValueConstraintError("", payload [64]>> failed at: ValueConstraintError('A loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong company name')"") at UTF8String" certificate.tbsCertificate.extensions.4.extnValue.certificatePolicies.0.policyQualifiers.0,CertificatePolicyQualifierValidator,WARNING,cabf.serverauth.certificate_policy_qualifier_present, certificate.tbsCertificate.extensions,SubscriberExtensionAllowanceValidator,WARNING,cabf.serverauth.subscriber.unknown_extension_present,Unknown extension present: 1.3.6.1.5.5.7.1.3 diff --git a/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/qctype_bad_encoding.crttest b/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/qctype_bad_encoding.crttest new file mode 100644 index 0000000..d342f72 --- /dev/null +++ b/tests/integration_certificate/etsi/qevcp_w_eidas_pre_certificate/qctype_bad_encoding.crttest @@ -0,0 +1,53 @@ +-----BEGIN CERTIFICATE----- +MIIHSzCCBjOgAwIBAgIQIiJLgYNs1fzLjp+t/dc2bjANBgkqhkiG9w0BAQsFADCB +8zELMAkGA1UEBhMCREUxJTAjBgNVBAoMHFQtU3lzdGVtcyBJbnRlcm5hdGlvbmFs +IEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxHDAaBgNVBAgM +E05vcmRyaGVpbiBXZXN0ZmFsZW4xDjAMBgNVBBEMBTU3MjUwMRAwDgYDVQQHDAdO +ZXRwaGVuMSAwHgYDVQQJDBdVbnRlcmUgSW5kdXN0cmllc3RyLiAyMDE6MDgGA1UE +AwwxVGVsZVNlYyBTZXJ2ZXJQYXNzIEV4dGVuZGVkIFZhbGlkYXRpb24gQ2xhc3Mg +MyBDQTAeFw0xODEwMTUxMjM1MjhaFw0yMDEwMjAyMzU5NTlaMIIBLjEdMBsGA1UE +DxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgNVBAUTCkhSQSA0MTEyNzIxGTAX +BgsrBgEEAYI3PAIBARMIRnJlaWJ1cmcxIzAhBgsrBgEEAYI3PAIBAgwSQmFkZW4t +V8O8cnR0ZW1iZXJnMRMwEQYLKwYBBAGCNzwCAQMTAkRFMQswCQYDVQQGEwJERTEb +MBkGA1UECBMSQmFkZW4tV3VlcnR0ZW1iZXJnMRYwFAYDVQQHEw1XZWlsIGFtIFJo +ZWluMTUwMwYDVQQKEyxFbmRyZXNzIGFuZCBIYXVzZXIgSW5mb1NlcnZlIEdtYkgg +YW5kIENvLiBLRzEPMA0GA1UECxMGSVMtT0lOMRkwFwYDVQQDExBhcHBzLmVuZHJl +c3MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9GJ+L2dku7VF +AFzCuLqq62t/H3kekVrtxTF9//grBBjGANZmSd58nr8Am/DeUwJKbFnCezsyH2zT +96ea0ad0vU82+5uDxiEnsPJJVudZhlGMNYKJ49YzL7HVXVjb1RWfT5fjqDIxc31b +OA0/g5oC7Qhon06mqXWe50eA3PWEeYBffRY7KhElNzAbCrOemlUGu072YoioT9ic +0aJR084a8NKn3WOxk9+7IFH3RXopPyPu+Or1hVA1cIrrBKID6SOxFNSmTMWRavjU +c4kYFLIcVWAD0WpzO1S1XSnRwSdI4vxYTUVHGziZ/GtWIMl48GWIz+6xazb/kd11 +7QKlRkHtyQIDAQABo4ICmzCCApcwHwYDVR0jBBgwFoAUMCzVT9II0T3jp4KSgjeJ +bWa5D68wHQYDVR0OBBYEFFNshf4Z5A5XN6hndnnzGusT7xHEMA4GA1UdDwEB/wQE +AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwbgYDVR0gBGcwZTBF +BgorBgEEAb1HDRgBMDcwNQYIKwYBBQUHAgEWKWh0dHA6Ly93d3cudGVsZXNlYy5k +ZS9zZXJ2ZXJwYXNzL2Nwcy5odG1sMAcGBWeBDAEBMAgGBgQAj3oBBDAJBgcEAIvs +QAEEME4GA1UdHwRHMEUwQ6BBoD+GPWh0dHA6Ly9jcmwuc2VydmVycGFzcy50ZWxl +c2VjLmRlL3JsL1NlcnZlclBhc3NfRVZfQ2xhc3NfMy5jcmwwga0GCCsGAQUFBwEB +BIGgMIGdMDMGCCsGAQUFBzABhidodHRwOi8vb2NzcC5zZXJ2ZXJwYXNzLnRlbGVz +ZWMuZGUvb2NzcHIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jcmwuc2VydmVycGFzcy50 +ZWxlc2VjLmRlL2NydC9UZWxlU2VjX1NlcnZlclBhc3NfRXh0ZW5kZWRfVmFsaWRh +dGlvbl9DbGFzc18zX0NBLmNlcjAMBgNVHRMBAf8EAjAAMDEGA1UdEQQqMCiCEGFw +cHMuZW5kcmVzcy5jb22CFHd3dy5hcHBzLmVuZHJlc3MuY29tMGAGCCsGAQUFBwED +BFQwUjAIBgYEAI5GAQEwPAYGBACORgEFMDIwMBYqaHR0cHM6Ly93d3cudGVsZXNl +Yy5kZS9zZXJ2ZXJwYXNzL2Nwcy5odG1sEwJFTjAIBgYEAI5GAQYwEwYKKwYBBAHW +eQIEAwEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBAF9z1ECajUOZ0NZ8VkpsAAsD +ZSLZD82arDkOOroEjW6HKhXrrfOcTltMfebN7E6yBCbyjHkgAaIPXEvS/fGEFU72 +cFAkr+6WxJN92fRMd7PmXmQ6VXINBGtfJ7fPWdFGxaa0XyQ3Yezk0bRj4rZdGa8c +OQWg0Cb58WpA5KeKyTFWEDBWIRK1ujgp2lEGflKfkDT7MokdKxw7svbnXDV3IWKK +QooD518a+bGTUgXZYpTTZ3VFNhU+a66iskpQjgZeFig7sEEwM7KW1S/K5Y7K0XPF +VrqKXSf6zxE7vNQTtG4lTID10qjTmj+SD2RvXp8mXklo+kHa1URrKhDOAuX3RWw= +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.extensions.9.extnValue.qCStatements.2,DecodingValidator,FATAL,itu.invalid_asn1_syntax,"Value node is absent, but type OID 0.4.0.1862.1.6 specifies that a ""QcType"" value must be present" +certificate.tbsCertificate.validity.notBefore,SubscriberValidityPeriodValidator,ERROR,cabf.certificate_validity_period_exceeds_398_days,"Validity period of 736 days, 11:24:32 exceeds maximum value of 398 days, 0:00:00" +certificate.tbsCertificate.subject.rdnSequence,EvSubscriberAttributeAllowanceValidator,WARNING,cabf.ev_guidelines.common_name_attribute_present, +certificate.tbsCertificate.subject.rdnSequence,EvSubscriberAttributeAllowanceValidator,ERROR,cabf.ev_guidelines.unknown_attribute_present,Unknown attribute present: 2.5.4.11 +certificate.tbsCertificate.extensions.1.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, +certificate.tbsCertificate.extensions.2.extnValue.keyUsage,SubscriberKeyUsageValidator,WARNING,cabf.serverauth.subscriber_rsa_digitalsignature_and_keyencipherment_present, +certificate.tbsCertificate.extensions.4.extnValue.certificatePolicies,SubscriberPoliciesValidator,WARNING,cabf.serverauth.subscriber_first_policy_oid_not_reserved, +certificate.tbsCertificate.extensions.4.extnValue.certificatePolicies.0.policyQualifiers.0,CertificatePolicyQualifierValidator,WARNING,cabf.serverauth.certificate_policy_qualifier_present, +certificate.tbsCertificate.extensions,SubscriberExtensionAllowanceValidator,WARNING,cabf.serverauth.subscriber.subject_key_identifier_extension_present, +certificate.tbsCertificate.extensions,SubscriberExtensionAllowanceValidator,WARNING,cabf.serverauth.subscriber.unknown_extension_present,Unknown extension present: 1.3.6.1.5.5.7.1.3 diff --git a/tests/integration_certificate/etsi/qncp_w_ov_eidas_pre_certificate/bad_bc_extension_encoding.crttest b/tests/integration_certificate/etsi/qncp_w_ov_eidas_pre_certificate/bad_bc_extension_encoding.crttest new file mode 100644 index 0000000..b105207 --- /dev/null +++ b/tests/integration_certificate/etsi/qncp_w_ov_eidas_pre_certificate/bad_bc_extension_encoding.crttest @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIIIWjCCBkKgAwIBAgIPAYxsZhBmtg+9Y2BGRJmkMA0GCSqGSIb3DQEBDQUAMIG3 +MQswCQYDVQQGEwJGSTEnMCUGA1UECgweRGlnaS0gamEgdmFlc3RvdGlldG92aXJh +c3RvIENBMTgwNgYDVQQLDC9Tb3NpYWFsaS0gamEgdGVydmV5ZGVuaHVvbGxvbiBw +YWx2ZWx1dmFybWVudGVldDFFMEMGA1UEAww8RFZWIFNvY2lhbCBXZWxmYXJlIGFu +ZCBIZWFsdGhjYXJlIFNlcnZpY2UgQ2VydGlmaWNhdGVzIC0gRzNSMB4XDTIzMTIx +NTA3MDM0NloXDTI0MTIxNTIxNTk1OVowgZkxCzAJBgNVBAYTAkZJMRAwDgYDVQQI +DAdGaW5sYW5kMREwDwYDVQQHDAhLYXVuaWFsYTEeMBwGA1UECgwVS2F1bmlhbGFu +IFNhaXJhYWxhIE95MSYwJAYDVQQFEx0xLjIuMjQ2LjEwLjIwNDg4MTU0LjEwLjAu +MTMuMTEdMBsGA1UEAwwUZXJlc2VwdGkua2F1bmlhbGEuZmkwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCePYZ6nuN8AqMiblrfsh6sIu5sx1GyC1DpFNfk +mwonMckM3iDPejE3QBZjSx0n2a1Oo3k98cPn6E1V5RehNsdYrtJOT4qvLNHpA4j+ +SzML/9kWKlFZzFn8wokdnS8hnIp48RY4CVLLrRz9K2XHjMacmjEBjM8BRMSY8u2b +IBSzuGHPN4jU68cNPYaRBntERSzfjjY0U1GupAKOCyP+q2M+lwSU+C42PqRMstRv +85mGE5P6WGg66tqENwTiTVR6MeCgSelLE8PyMPXRgCtEfAqsDwuWNziHOpNMQ6AF +ax54RwVhka0oQ+AgUbQL2wAs5ZKBXFXHuVrfHdL7hwBr3oB0C21qQIHyqXJuBIKN +lrVSHC3sTofv6nwSL8pyINP6xV3CuigZ8F4Ot/rBOndNH2ro5XW9O76sfwiJqB// +PBQLR542i4OcV1kQ6sz0Cank4kVupWotms1rs6kmXxSkxw04vq6Z6Fw0E4aj9SNK +o+xHYy8s1MzW3yqx1ICyl4N+6QcAJMOq2SgSkw0ov7RbVHESEZAsFglhtpoWYYTp +GVjPNhqbseCYZl06+8JiL5Ix5b/N6DIaHew5XYw/v6/ZRZqK2Evkm8TPUHGVrDmh +SUY4dxdD0YQkqqTMRGQgGbzKAKO0i1l9uvxUGfRXMLNnA5yltd4La7As6aH9JjY0 +jQw7+wIDAQABo4ICfTCCAnkwHwYDVR0jBBgwFoAUfqc7m1+FjkbI48WHOM8NLw7y +eQAwHQYDVR0OBBYEFA69jymlkxRHtRUyHD30wlEtipJvMA4GA1UdDwEB/wQEAwIE +sDCB4QYDVR0gBIHZMIHWMAgGBmeBDAECAjAIBgYEAI96AQcwgb8GCiqBdoQFAQqC +NAEwgbAwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZmluZWlkLmZpL2NwczU3LzCB +hAYIKwYBBQUHAgIweBp2VmFybWVubmVwb2xpdGlpa2thIG9uIHNhYXRhdmlsbGEg +LSBDZXJ0aWZpa2F0cG9saWN5IGZpbm5zIC0gQ2VydGlmaWNhdGUgcG9saWN5IGlz +IGF2YWlsYWJsZSBodHRwOi8vd3d3LmZpbmVpZC5maS9jcHM1NzAfBgNVHREEGDAW +ghRlcmVzZXB0aS5rYXVuaWFsYS5maTAPBgNVHRMBAf8EBTADAQEAMDoGA1UdHwQz +MDEwL6AtoCuGKWh0dHA6Ly9wcm94eS5maW5laWQuZmkvY3JsL2R2dnNoc3AzcmMu +Y3JsMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATByBggrBgEFBQcBAQRm +MGQwNAYIKwYBBQUHMAKGKGh0dHA6Ly9wcm94eS5maW5laWQuZmkvY2EvZHZ2c2hz +cDNyYy5jcnQwLAYIKwYBBQUHMAGGIGh0dHA6Ly9vY3NwLmZpbmVpZC5maS9kdnZz +aHNwM3JjMC0GCCsGAQUFBwEDBCEwHzAIBgYEAI5GAQEwEwYGBACORgEGMAkGBwQA +jkYBBgMwEwYKKwYBBAHWeQIEAwEB/wQCBQAwDQYJKoZIhvcNAQENBQADggIBAK60 +WEF0XDxfwq1FjByJkKClWSfQUZ7yo2j2/R0hQ7JdD4D8gzyZsIc5tfrYxTo3gfUT +40amg6pHKRmEhDA4omYY8sVpVnKj6AKZW2DK2uAQ2uW5dq+811uETaQ0NPGztLSf +ZnYf7oMX0n7xXycMSQnCOsP/v7SeIJhHcNss6C9UVqiLr3BVNHCnWOCpH5pQ7p4Q +nxcd3qOBaRXRiI2VRccCUFavOwXVMNmSOznGSuAWCgRwJRZULbHYu3fxWivN11PX +4DUXFyxYjMfziKA3Yxa4wmb9dqTusnkftIh09I3nOiQqwS4/o99FdjWCOuKtG1hu +ug/uhGM43GtJqWJSTY6pnmoJSL8At3UQUjGmzCFPJ/TRxAaU4AtsyoYbVM5DJkdi +1xvg0X14LpwRxryg1FDf5jlFP+rGpLRIhdC+U2GSXU+Br8l/7SiyxixpZjIpojm/ +n+ZBHDkVX5bver6oEZkvwmmvyMA+r+NaxAB0ZDjhzNB2VM+Y1XMCYffoPsRTWmcb +T2ubfO+aPgApMvOWYKptwScqoUvQN3oCXEfQ/iTJEb8z/7+LDNT0cWYmNUa9pF/w +2/3spDQahhpBhEUh/JWHI6RAw+U9hU2kWdyGca/6l22RFzvLRpNWdoWqCYreYgIV +PMeG9uZkYykeSL8vGkuW7QwDUXmnQ5U6hHjM8Wen +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.extensions.5,ExtensionsDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.5.extnValue"" with schema ""BasicConstraints"" corresponding to type OID 2.5.29.19: Substrate of type ""BasicConstraints"" is not DER-encoded" +certificate.tbsCertificate.subject.rdnSequence,OvSubscriberAttributeAllowanceValidator,WARNING,cabf.serverauth.ov.common_name_attribute_present, +certificate.tbsCertificate.subject.rdnSequence,OvSubscriberAttributeAllowanceValidator,WARNING,cabf.serverauth.ov.unknown_attribute_present,Unknown attribute present: 2.5.4.5 +certificate.tbsCertificate.extensions.1.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, +certificate.tbsCertificate.extensions.2.extnValue.keyUsage,SubscriberKeyUsageValidator,WARNING,cabf.serverauth.subscriber_discouraged_ku_present,Discouraged KU present: dataEncipherment +certificate.tbsCertificate.extensions.2.extnValue.keyUsage,SubscriberKeyUsageValidator,WARNING,cabf.serverauth.subscriber_rsa_digitalsignature_and_keyencipherment_present, +certificate.tbsCertificate.extensions.3.extnValue.certificatePolicies,QualifiedCertificatePoliciesValidator,WARNING,etsi.en_319_412_2.qcs-5.2-1.recommended_certificate_type_policy_identifier_missing,"Missing recommended certificate type policy identifier ""0.4.0.194112.1.5""" +certificate.tbsCertificate.extensions.3.extnValue.certificatePolicies.2.policyQualifiers.0,CertificatePolicyQualifierValidator,WARNING,cabf.serverauth.certificate_policy_qualifier_present, +certificate.tbsCertificate.extensions.3.extnValue.certificatePolicies.2.policyQualifiers.1,CertificatePolicyQualifierValidator,WARNING,cabf.serverauth.certificate_policy_qualifier_present, +certificate.tbsCertificate.extensions.3.extnValue.certificatePolicies.2.policyQualifiers.1,CertificatePolicyQualifierValidator,ERROR,cabf.serverauth.prohibited_certificate_policy_qualifier_type,Prohibited qualifier type: 1.3.6.1.5.5.7.2.2 +certificate.tbsCertificate.extensions.3.extnValue.certificatePolicies.2.policyQualifiers.1.qualifier.userNotice,CertificatePoliciesUserNoticeValidator,ERROR,pkix.rfc5280_certificate_policies_invalid_explicit_text_encoding,Invalid encoding: visibleString +certificate.tbsCertificate.extensions,SubscriberExtensionAllowanceValidator,WARNING,cabf.serverauth.subscriber.subject_key_identifier_extension_present, +certificate.tbsCertificate.extensions,SubscriberExtensionAllowanceValidator,WARNING,cabf.serverauth.subscriber.unknown_extension_present,Unknown extension present: 1.3.6.1.5.5.7.1.3 diff --git a/tests/integration_certificate/pkix/ecdsa_with_null_sigalg_param.crttest b/tests/integration_certificate/pkix/ecdsa_with_null_sigalg_param.crttest new file mode 100644 index 0000000..757ce27 --- /dev/null +++ b/tests/integration_certificate/pkix/ecdsa_with_null_sigalg_param.crttest @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIID6zCCA3KgAwIBAgIUEuptorghJNZWoEmXnuVIyVYrqkowDAYIKoZIzj0EAwMF +ADBeMQswCQYDVQQGEwJDTjElMCMGA1UECgwcVHJ1c3RBc2lhIFRlY2hub2xvZ2ll +cywgSW5jLjEoMCYGA1UEAwwfVHJ1c3RBc2lhIERWIFRMUyBFQ0MgVGVzdCBDQSBH +NDAeFw0yNDEwMjIxNjAwMDBaFw0yNDEwMjMxNjAwMDBaMCUxIzAhBgNVBAMMGm9v +bDVldnpzd3AuY3QtdGVzdC5zc2wucHViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAE429f0qXaS9E9goewIIJLabuQZBw18mgbLueve9JmfTq4p2Poo+7dACkXG8AF +v9nxvGKBm61nP8WWMeJQYc6IQqOCAkMwggI/MAwGA1UdEwEB/wQCMAAwHwYDVR0j +BBgwFoAUr4S1dCdw3xSnKsw6Wtz3PAQJU5swgaUGCCsGAQUFBwEBBIGYMIGVMEoG +CCsGAQUFBzAChj5odHRwOi8vaWNhLnd0LXRlc3QudHJ1c3Rhc2lhLmNvbS9UcnVz +dEFzaWFEVlRMU0VDQ1Rlc3RDQUc0LmNydDBHBggrBgEFBQcwAYY7aHR0cDovL29j +c3Aud3QtdGVzdC50cnVzdGFzaWEuY29tL1RydXN0QXNpYURWVExTRUNDVGVzdENB +RzQwJQYDVR0RBB4wHIIab29sNWV2enN3cC5jdC10ZXN0LnNzbC5wdWIwEwYDVR0g +BAwwCjAIBgZngQwBAgEwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBME8G +A1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwud3QtdGVzdC50cnVzdGFzaWEuY29t +L1RydXN0QXNpYURWVExTRUNDVGVzdENBRzQuY3JsMB0GA1UdDgQWBBSANcwZGY1l +mwNdmlipDOiex1EAHDAOBgNVHQ8BAf8EBAMCBaAwgYoGCisGAQQB1nkCBAIEfAR6 +AHgAdgCHT7UNwCnZkx3lc+nyiZ6ORTOzktOLCkYldL8P7rL8HgAAAYQHSgxQAAAE +AwBHMEUCIQD0WQOyiEHIPoanzn+5Y8QfYR1sQIkAb8gHO1/EOTIF+QIgF3zyCELh +/Uzp8MDiQbXeDWXHhFZqXMRxlHwQSqDbr3cwCgYIKoZIzj0EAwMDZwAwZAIwOWCs +D/aGz0c/M4+e/iMor9OSw4K+O2OXKoM/HRrT9bw6/Rtgy+ZdWGRP0XHzCuyWAjAW +N/XpkkZPgkKC941PAOnMsPEdkTVLdx+zn5NZ7qSzCub9BuSLN+GViPErWm7FPdM= +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.signature,AlgorithmIdentifierDecodingValidator,FATAL,itu.invalid_asn1_syntax,"Value node is present, but type OID 1.2.840.10045.4.3.3 specifies that it must be absent" +certificate.tbsCertificate.extensions.7.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, +certificate.signatureAlgorithm,SignatureAlgorithmMatchValidator,ERROR,pkix.certificate_signature_algorithm_mismatch,DER encoding of certificate.signatureAlgorithm and certificate.tbsCertificate.signature are not equal diff --git a/tests/integration_certificate/pkix/trailing_octet_in_ku_value.crttest b/tests/integration_certificate/pkix/trailing_octet_in_ku_value.crttest new file mode 100644 index 0000000..535bf95 --- /dev/null +++ b/tests/integration_certificate/pkix/trailing_octet_in_ku_value.crttest @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +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 +ZF6TmlI5DUrO +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.extensions.0,ExtensionsDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.0.extnValue"" with schema ""KeyUsage"" corresponding to type OID 2.5.29.15: 1 unexpected octet(s) following ""KeyUsage"" TLV: ""41""" +certificate,SubjectKeyIdentifierPresenceValidator,WARNING,pkix.certificate_skid_end_entity_missing, \ No newline at end of file diff --git a/tests/integration_certificate/smime_br/individual/legacy/rsa_key_no_param.crttest b/tests/integration_certificate/smime_br/individual/legacy/rsa_key_no_param.crttest index 63b2669..bf99b55 100644 --- a/tests/integration_certificate/smime_br/individual/legacy/rsa_key_no_param.crttest +++ b/tests/integration_certificate/smime_br/individual/legacy/rsa_key_no_param.crttest @@ -33,7 +33,7 @@ vwa3P9bp46dIC6RB3ZNPCbrR7YMO/GD3Iyu28hE6hrfrkcsQjfe9E1OzSPEadmF8 A9uBf/ih -----END CERTIFICATE----- node_path,validator,severity,code,message -certificate.tbsCertificate.subjectPublicKeyInfo,SubjectPublicKeyParametersDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.subjectPublicKeyInfo"" with schema ""Null"", OID 1.2.840.113549.1.1.1: Value node is absent, but the ASN.1 schema specifies that it must be present" +certificate.tbsCertificate.subjectPublicKeyInfo,SubjectPublicKeyParametersDecodingValidator,FATAL,itu.invalid_asn1_syntax,"Value node is absent, but type OID 1.2.840.113549.1.1.1 specifies that a ""Null"" value must be present" certificate.tbsCertificate.subjectPublicKeyInfo.algorithm,SmimeAllowedPublicKeyAlgorithmEncodingValidator,ERROR,cabf.smime.prohibited_spki_algorithm_encoding,Prohibited encoding: 300b06092a864886f70d010101 certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, diff --git a/tests/integration_certificate/smime_br/organization/multipurpose/bad_qc_statementinfo_encoding.crttest b/tests/integration_certificate/smime_br/organization/multipurpose/bad_qc_statementinfo_encoding.crttest index d79a27a..1667f15 100644 --- a/tests/integration_certificate/smime_br/organization/multipurpose/bad_qc_statementinfo_encoding.crttest +++ b/tests/integration_certificate/smime_br/organization/multipurpose/bad_qc_statementinfo_encoding.crttest @@ -38,6 +38,6 @@ xYO/BhaDlFN5MfHfgc+UK7kAqZClu8CRijbjGscXNiWccyokLuuRCZTf3o32GW7S 4EOQP/DgjMZZ3oxhptjUgDMDGFI7JnQ5xJN+IRW2Xmiz2sTBvUrcvC/IBIA= -----END CERTIFICATE----- node_path,validator,severity,code,message -certificate.tbsCertificate.extensions.10.extnValue.qCStatements.4,DecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.10.extnValue.qCStatements.4.statementInfo"" with schema ""QcEuPDS"", OID 0.4.0.1862.1.5: not in asn1Spec: , subtypeSpec >, encoding us-ascii>" +certificate.tbsCertificate.extensions.10.extnValue.qCStatements.4,DecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.10.extnValue.qCStatements.4.statementInfo"" with schema ""QcEuPDS"" corresponding to type OID 0.4.0.1862.1.5: not in asn1Spec: , subtypeSpec >, encoding us-ascii>" certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, diff --git a/tests/integration_certificate/tls_br/dv_final_certificate/rsa_missing_null_param.crttest b/tests/integration_certificate/tls_br/dv_final_certificate/rsa_missing_null_param.crttest index f92bb50..f581c37 100644 --- a/tests/integration_certificate/tls_br/dv_final_certificate/rsa_missing_null_param.crttest +++ b/tests/integration_certificate/tls_br/dv_final_certificate/rsa_missing_null_param.crttest @@ -32,5 +32,5 @@ QqvHp8PzGVidY5hKeo163oRkEIV75k1Onw== -----END CERTIFICATE----- node_path,validator,severity,code,message -certificate.tbsCertificate.subjectPublicKeyInfo,SubjectPublicKeyParametersDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.subjectPublicKeyInfo"" with schema ""Null"", OID 1.2.840.113549.1.1.1: Value node is absent, but the ASN.1 schema specifies that it must be present" +certificate.tbsCertificate.subjectPublicKeyInfo,SubjectPublicKeyParametersDecodingValidator,FATAL,itu.invalid_asn1_syntax,"Value node is absent, but type OID 1.2.840.113549.1.1.1 specifies that a ""Null"" value must be present" certificate.tbsCertificate.subjectPublicKeyInfo.algorithm,ServerauthAllowedPublicKeyAlgorithmEncodingValidator,ERROR,cabf.serverauth.prohibited_subject_public_key_algorithm_encoding,Prohibited encoding: 300b06092a864886f70d010101 diff --git a/tests/integration_certificate/tls_br/internal_unconstrained_tls_ca/cert_policies_not_der.crttest b/tests/integration_certificate/tls_br/internal_unconstrained_tls_ca/cert_policies_not_der.crttest index 6e00064..38fb046 100644 --- a/tests/integration_certificate/tls_br/internal_unconstrained_tls_ca/cert_policies_not_der.crttest +++ b/tests/integration_certificate/tls_br/internal_unconstrained_tls_ca/cert_policies_not_der.crttest @@ -27,6 +27,6 @@ o3WH27OlZEKVZQw+QOvSOWv0 -----END CERTIFICATE----- node_path,validator,severity,code,message -certificate.tbsCertificate.extensions.7,ExtensionsDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.7.extnValue"" with schema ""CertificatePolicies"", OID 2.5.29.32: Substrate of type ""CertificatePolicies"" is not DER-encoded" +certificate.tbsCertificate.extensions.7,ExtensionsDecodingValidator,FATAL,itu.invalid_asn1_syntax,"ASN.1 decoding failure occurred at ""certificate.tbsCertificate.extensions.7.extnValue"" with schema ""CertificatePolicies"" corresponding to type OID 2.5.29.32: Substrate of type ""CertificatePolicies"" is not DER-encoded" certificate.tbsCertificate.extensions.0.extnValue.keyUsage,CaKeyUsageValidator,NOTICE,cabf.ca_certificate_no_digital_signature_bit, certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, diff --git a/tests/pkix/certificate/test_certificate_properties.py b/tests/pkix/certificate/test_certificate_properties.py new file mode 100644 index 0000000..a8a2f9c --- /dev/null +++ b/tests/pkix/certificate/test_certificate_properties.py @@ -0,0 +1,85 @@ +from pkilint import loader, pkix + +_BAD_VALIDITY_TIMES_CERT_PEM = '''-----BEGIN CERTIFICATE----- +MIIFwjCCA6qgAwIBAgIUH/nOhctN2lspZ2LasyeIMEixJzEwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0 +ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw1BMzA0MTkwMDAwMDBaFw1B +MzA3MTgyMzU5NTlaME4xIjAgBgNVBAMMGWhhbmFrby55YW1hZGFAZXhhbXBsZS5j +b20xKDAmBgkqhkiG9w0BCQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/t +L4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv +8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY +7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjd +i8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSE +onWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMB +AAGjggGcMIIBmDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSME +GDAWgBTWRAAyfKgN/6xPa2buta6bLMU4VDAdBgNVHQ4EFgQUiRlZXg7xafXLvUfh +NPzimMxpMJEwFAYDVR0gBA0wCzAJBgdngQwBBQECMD0GA1UdHwQ2MDQwMqAwoC6G +LGh0dHA6Ly9jcmwuY2EuZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsG +CCsGAQUFBwEBBD8wPTA7BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2Eu +ZXhhbXBsZS5jb20vaXNzdWluZ19jYS5kZXIwHQYDVR0lBBYwFAYIKwYBBQUHAwQG +CCsGAQUFBwMCMHcGA1UdEQRwMG6BGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb22g +KQYKKwYBBAGCNxQCA6AbDBloYW5ha28ueWFtYWRhQGV4YW1wbGUuY29toCYGCCsG +AQUFBwgJoBoMGOWxseeUsOiKseWtkEBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF +AAOCAgEAg4rIcKGMfLh347FX/Y12lx7b9/iVrjsX7lsliirpITuPmfCli76JVrO0 +Fqypfdd2P4ZVvH9WTpQUhRBv06kwHkJRkgpqNPO0WOpNVnsK8vcP1/RylDiJGryz +u6AzOSDqsxomFD6hm71XRYcsgBXXNPUzSGhbqUeuBuZwZe1WmP/yuvNpghMvlWFc +jAHktC9FuNpHhQ/3zZ20GUc6AQwwtn8rviFSwQihVJDJkGiGaJUc7lVVoswx87bS +oGpVluEIY/RK2HsXU0kmek4qq2t9v1OgRL98ZqUgOS26ooOXxqnR3QMx1S5KSLy9 ++hK6y2gPhyiHoaPVTk4s54Es/YDtbCz7piyyyp3DEIzmgrwB/mG2IbOv6dT8Za5B +R7A+ggB7uwo3zYxKd2SFIDmXb+n9ML/s6/3aeyKJms4FmRq+fX8icb+lvVeLMhlC +Re5MFL2tkb72BFku0eeUde4iUnw93fzG6+Wl8VPCzYOwV0j+UTiyygcXaEZW+TpT +EmyY/fQ/7TCbGp+8Ur3rLlY5Okt5T83MmZdMFIHLQxaZUXkT2dBaSnh3VfNKFi0a +re9xdiBQZGkMkvWiKTjrUOwLXSNBnP6TXO9zn51tTK4KPZnQvNvULtn4H7z3FhfW +kie/jPNYkFvMzOaawwPAhG9R6G2ZB7cTOuG0Uu863Hkh5XX2oAo= +-----END CERTIFICATE-----''' + + +_BAD_BC_ENCODING_CERT_PEM = '''-----BEGIN CERTIFICATE----- +MIIGCDCCBPCgAwIBAgIQR97MnKh70qpmTcj8p3ONNzANBgkqhkiG9w0BAQsFADBA +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxHjAcBgNVBAMMFVNIRUNB +IEVWIFNlcnZlciBDQSBHMzAeFw0yNDAzMTgwNTM0MTBaFw0yNTAzMTgxNTU5NTla +MIIBbTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3 +PAIBAxMCQ04xGjAYBgsrBgEEAYI3PAIBAgwJ5LiK5rW35biCMRowGAYLKwYBBAGC +NzwCAQEMCeS4iua1t+W4gjEbMBkGA1UEBRMSOTEzMTAwMDA2MzEyOTEyODlYMQsw +CQYDVQQGEwJDTjESMBAGA1UECAwJ5LiK5rW35biCMRIwEAYDVQQHDAnkuIrmtbfl +uIIxDzANBgNVBBETBjIwMDA4MDFDMEEGA1UECQw65LiK5rW35biC6Jm55Y+j5Yy6 +5Zub5bed5YyX6LevMTcxN+WPtzE4MDjjgIExODA544CBMTgxMOWupDE2MDQGA1UE +Cgwt5LiK5rW35biC5pWw5a2X6K+B5Lmm6K6k6K+B5Lit5b+D5pyJ6ZmQ5YWs5Y+4 +MR8wHQYDVQQDExZyc2FldmczLmdvb2Quc2hlY2EuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAwlNS/toKnTO8fBgSSUTQ9RxiEiFX406s8nPvTziF +SoQ/S/ncHyFe8SeTRUO1tT/tmEzg6YZS5kaxiRFNOCaddZKPBb4nJMH/jliIjFZh +fXq5voZhMafXFJmtjWR3oSGZjienA5Eanra/q9srpACSmhpgL156CPjMqGJfJiOh +Ejxh7fkipX056j6Yrrs0btdrs4ZHcZeqJBz4ioiXNi2f5xqVdJvan53Q9LYp2TBG +v61y6zKj0WXeFh2zJIo32NCosRjAtO32BVJW6eTrmwNR3CmFzT0yILGCpsgIGMEn +hQjfZL/8RyeVYfMYT2mMcLLVlg1BeP30S5Lf1BU3Xg/mEQIDAQABo4IBzTCCAckw +HwYDVR0jBBgwFoAUVOly+3hmn+XL8zuPmEZVU3OcC4QwHQYDVR0OBBYEFFByjRc+ +8e43B7pqhb9senT1Wn4uMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF +BQcDAQYIKwYBBQUHAwIwXwYDVR0gBFgwVjA7BgkqgRyG7zoBAQMwLjAsBggrBgEF +BQcCARYgaHR0cHM6Ly93d3cuc2hlY2EuY29tL3JlcG9zaXRvcnkwFwYFZ4EMAQEw +DjAMBggrBgEFBQcCARYAMCEGA1UdEQQaMBiCFnJzYWV2ZzMuZ29vZC5zaGVjYS5j +b20wDAYDVR0TAQH/BAIwADA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vY3JsLmds +b2JhbC5zaGVjYS5jb20vZXZzY2FnMy5jcmwwdwYIKwYBBQUHAQEEazBpMDAGCCsG +AQUFBzABhiRodHRwOi8vb2NzcC5nbG9iYWwuc2hlY2EuY29tL2V2c2NhZzMwNQYI +KwYBBQUHMAKGKWh0dHA6Ly9jZXJ0cy5nbG9iYWwuc2hlY2EuY29tL2V2c2NhZzMu +Y2VyMBMGCisGAQQB1nkCBAMBAf8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQCk8rXL +a2TIXwOzeGB7oHcq0h67FrGYs58dIxaGYzf/VSOosZ3knCj8iS3gH0knVHg8F+47 +k1kgEWYF70PykQDdDYl0HnI+qapklCgCBC6PbJpU6d9LQ/hSJhfe6arZg5THJCYF +sG/1jEj1SEgJCcUGGX1Rt251m4GnGKxTHKEciGEq0EYKWd8uYkLtktZBpUB1HvJM +AFXfgZmfibVTExqrX+s1TGGUaoz9ktHxoQuc1slclELGmRVv0L4YIrbs3UCCGUSp +PNpRbwFwgDtFcAAI5Oc7q3ruxTrPgJb75uC6LiYNXkHSyB6JIUW8rITPv99tAk3G +1CWF8wYw6JLxGNr7 +-----END CERTIFICATE-----''' + + +def test_bad_time(): + cert = loader.load_pem_certificate(_BAD_VALIDITY_TIMES_CERT_PEM) + + assert cert.not_before == pkix.MAXIMUM_TIME_DATETIME + assert cert.not_after == pkix.MAXIMUM_TIME_DATETIME + + +def test_bad_bc_encoding(): + cert = loader.load_pem_certificate(_BAD_BC_ENCODING_CERT_PEM) + + assert not cert.is_ca diff --git a/tests/pkix/crl/test_crl_properties.py b/tests/pkix/crl/test_crl_properties.py new file mode 100644 index 0000000..0138ebd --- /dev/null +++ b/tests/pkix/crl/test_crl_properties.py @@ -0,0 +1,21 @@ +from pkilint import loader, pkix + +_BAD_VALIDITY_TIMES_CRL_PEM = '''-----BEGIN X509 CRL----- +MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADAiMQswCQYDVQQGEwJYWDETMBEGA1UE +CgwKQ1JMcyAnciBVcxcNWDQwMzI1MTg0NzAwWhcNWDQwNDAxMTg0NzAwWqBgMF4w +CgYDVR0UBAMCAQEwHwYDVR0jBBgwFoAU/NE0t8uklbG2WeoLBWIe6JqPtDowLwYD +VR0cAQH/BCUwI6AeoByGGmh0dHA6Ly9mb28uZXhhbXBsZS9jcmwuZGxshAH/MA0G +CSqGSIb3DQEBCwUAA4IBAQAN8oDSvWsg3JvUJ4MkXvczaFb72VH0J/VL5PV2cBSm +MfaVBKnUsNr1IcxT06KF8gNrDTpKqJ9fetO290swZfcPt9sEVUBVQUpdlQc3tya1 +jYWmFkA3tkpqH5rBCQa3CBm1Cg8cbFBtwWgWr70NsVvfD6etjAEP9Ze+MSXnGV0p +w9EeOV07HnSD/PGQwqCiaSn5DdIDVoH8eFSGmgNLw+b4SwUjmz8PqsZwvHxJvleV +1D8cj7zdR4ywgRMjEfJZ8Bp+Tdu64Gv0doDS0iEJIshLHYkcW1okpq/tPm8kKAbD +reparePNQwhScVcDiSL73eEBIPokgG3QhohiucP5MeF1 +-----END X509 CRL-----''' + + +def test_bad_time(): + crl = loader.load_pem_crl(_BAD_VALIDITY_TIMES_CRL_PEM) + + assert crl.this_update == pkix.MAXIMUM_TIME_DATETIME + assert crl.next_update == pkix.MAXIMUM_TIME_DATETIME diff --git a/tests/test_loader.py b/tests/test_loader.py index f835026..f8af1df 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -1,8 +1,9 @@ +import base64 import tempfile -from pkilint import loader -import base64 +import pytest +from pkilint import loader, document _CERT_B64 = '''MIIGrzCCBJegAwIBAgIUYsQ+Fan+RfQ1ToEaA+PeZh43OTEwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0 @@ -42,6 +43,39 @@ Eqpda1II90v7ae6kNwIPK+140WOhkKilZ526OHvetaZ9XUc=''' +_CERT_WITH_TRAILER_B64 = '''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 +p6o9EaAJgzlOHGRsk5NZTCZkXpOaUjkNSs5B''' + + _OCSP_RESPONSE_B64 = '''MIIDnwoBAKCCA5gwggOUBgkrBgEFBQcwAQEEggOFMIIDgTCBsKIWBBQK46D+ndQl dpi163Lrygznvz318RgPMjAyNDA0MDIxMjM3NDdaMIGEMIGBMFkwDQYJYIZIAWUD BAIBBQAEIDqZRndWgHOnB7/eUBhjReTNYTTbCF66odEEJfA7bwjqBCBHSmyjAfI9 @@ -238,3 +272,8 @@ def test_crl_loader(): def test_ocsp_response_loader(): _test_loader_obj(loader._RFC6960_OCSP_RESPONSE_LOADER, _OCSP_RESPONSE_B64) + + +def test_load_cert_with_trailer(): + with pytest.raises(document.SubstrateDecodingFailedError): + loader.load_der_certificate(base64.b64decode(_CERT_WITH_TRAILER_B64), 'test', 'test') diff --git a/tests/test_server.py b/tests/test_server.py index e138a1f..7dc9697 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -67,6 +67,7 @@ def test_version(client): Eqpda1II90v7ae6kNwIPK+140WOhkKilZ526OHvetaZ9XUc= -----END CERTIFICATE-----''' + _OV_FINAL_CLEAN_PEM = '''-----BEGIN CERTIFICATE----- MIIGxDCCBKygAwIBAgIMS9Kjc1CWWKwCO6fGMA0GCSqGSIb3DQEBCwUAMEUxCzAJ BgNVBAYTAlVTMRMwEQYDVQQKEwpDZXJ0cyBSIFVzMSEwHwYDVQQDExhDZXJ0cyBS @@ -107,6 +108,7 @@ def test_version(client): XpOaUjkNSs4= -----END CERTIFICATE-----''' + _BAD_CERT_POLICIES_DER_PEM = '''-----BEGIN CERTIFICATE----- MIIFxjCCBK6gAwIBAgIQAROrI6zwQH6igXlKWdEvgjANBgkqhkiG9w0BAQsFADBP MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE @@ -139,8 +141,40 @@ def test_version(client): TcujtM2w710EQ+DXIPlXMpMJmtCzzrLzVYdPmIGwiIUoj9BwhgMtBtPInxe7qjm6 B0iBclRQb246wAEPjF/sWAUS+LgmJL2u1CclSWu3h/Ae+yIMKAbdL6Vn5GeLHfCD kJePcGspl/I0jGLIvpG34YRy9mLrgiWskyETVNFDPIzddBDAqWu2JkDK ------END CERTIFICATE----- -''' +-----END CERTIFICATE-----''' + + +_CERT_WITH_TRAILER_B64 = '''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 +p6o9EaAJgzlOHGRsk5NZTCZkXpOaUjkNSs5B''' _OCSP_RESPONSE_B64 = '''MIIDnwoBAKCCA5gwggOUBgkrBgEFBQcwAQEEggOFMIIDgTCBsKIWBBQK46D+ndQl @@ -304,11 +338,16 @@ def test_serverauth_bad_pem(client): assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY -def test_serverauuth_bad_base64(client): +def test_serverauth_bad_base64(client): resp = client.post('/certificate/cabf-serverauth', json={'b64': 'foo'}) assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY +def test_serverauth_with_bad_base64_trailer(client): + resp = client.post('/certificate/cabf-serverauth', json={'b64': _CERT_WITH_TRAILER_B64}) + assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY + + def test_serverauth_detect(client): resp = client.post('/certificate/cabf-serverauth', json={'pem': _OV_FINAL_CLEAN_PEM}) @@ -326,13 +365,6 @@ def test_serverauth_detect_not_serverauth(client): assert j['linter']['name'] == serverauth_constants.CertificateType.DV_FINAL_CERTIFICATE.to_option_str -def test_serverauth_detect_bad_extension_der(client): - resp = client.post('/certificate/cabf-serverauth', json={'pem': _BAD_CERT_POLICIES_DER_PEM}) - assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY - - _assert_validationerror_list_present(resp) - - def test_lint_serverauth_unknown_linter(client): resp = client.post('/certificate/cabf-serverauth/FOOMASTER-BAR', json={'pem': _OV_FINAL_CLEAN_PEM}) assert resp.status_code == HTTPStatus.NOT_FOUND @@ -433,10 +465,3 @@ def test_detect_and_lint_etsi(client): j = resp.json() assert j['linter']['name'] == etsi_constants.CertificateType.OVCP_FINAL_CERTIFICATE.to_option_str - - -def test_etsi_detect_bad_extension_der(client): - resp = client.post('/certificate/etsi', json={'pem': _BAD_CERT_POLICIES_DER_PEM}) - assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY - - _assert_validationerror_list_present(resp)