diff --git a/CHANGELOG.md b/CHANGELOG.md index 63d7fe6..9599891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ All notable changes to this project from version 0.9.3 onwards are documented in this file. -## 0.11.4 - 2024-08-28 +## 0.11.4 - 2024-08-29 ### New features/enhancements - Use pyasn1-fasder for ASN.1 DER decoding by default (#98) +- Add support for S/MIME working group ballot SMC-08 (#101) ## 0.11.3 - 2024-07-17 diff --git a/README.md b/README.md index 36e34be..db73676 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,13 @@ For example, the following mapping file is used to map policy OID `1.2.3.4.5.6` The `-o`/`--output` option is used to specify that the validation level and generation used by the linter is written to standard error. This is useful when using the `--guess` option to see which validation level and generation was determined by the heuristics logic. +The `--validity-period-start` option is used to override how the issuance date/time of a certificate is determined. Many requirements are applicable based on the date/time of issuance of certificates, so this option is useful +to evaluate whether a certificate complies with an upcoming requirement. There are three possible types of values for this option: + +1. `DOCUMENT`: Use the value of the `notBefore` field to determine the issuance date/time. This is the default value. +2. `NOW`: Use the current date/time to override the issuance date/time. +3. An ISO 8601 timestamp: Use the specified timestamp to override the issuance date/time. + #### Example command execution ```shell diff --git a/pkilint/bin/lint_cabf_smime_cert.py b/pkilint/bin/lint_cabf_smime_cert.py index 37721ef..930d8c0 100644 --- a/pkilint/bin/lint_cabf_smime_cert.py +++ b/pkilint/bin/lint_cabf_smime_cert.py @@ -93,6 +93,8 @@ def main(cli_args=None) -> int: help='Output the type of S/MIME certificate to standard error. This option may be ' 'useful when using the --detect, --guess, or --mapping options.') + util.add_certificate_validity_period_start_arg(lint_parser) + util.add_standard_args(lint_parser) lint_parser.add_argument('file', @@ -142,7 +144,7 @@ def main(cli_args=None) -> int: doc_validator = certificate.create_pkix_certificate_validator_container( smime.create_decoding_validators(), smime.create_subscriber_validators( - validation_level, generation + validation_level, generation, args.validity_period_start ) ) diff --git a/pkilint/cabf/serverauth/finding_metadata.csv b/pkilint/cabf/serverauth/finding_metadata.csv index 6d559bf..e5c2475 100644 --- a/pkilint/cabf/serverauth/finding_metadata.csv +++ b/pkilint/cabf/serverauth/finding_metadata.csv @@ -231,6 +231,7 @@ ERROR,pkix.rfc6818_certificate_policies_invalid_explicit_text_encoding,"RFC 6818 ERROR,pkix.san_extension_not_critical_empty_subject,"RFC 5280 4.2.1.6: ""If the subject field contains an empty sequence, then the issuing CA MUST include a subjectAltName extension that is marked as critical""" ERROR,pkix.sct_list_empty,"RFC 6962 3.3: ""At least one SCT MUST be included""" ERROR,pkix.smime_capabilities_extension_critical,"RFC 4262 2: ""This extension MUST NOT be marked critical.""" +ERROR,pkix.smtp_utf8_mailbox_domain_part_invalid_syntax,"RFC 9598, section 3: "". In SmtpUTF8Mailbox, labels that include non-ASCII characters MUST be stored in A-label (rather than U-label) form [RFC5890].""" ERROR,pkix.smtp_utf8_mailbox_has_bom,"RFC 8398 3: ""The UTF8String encoding MUST NOT contain a Byte-Order-Mark (BOM) [RFC3629] to aid consistency across implementations, particularly for comparison.""" ERROR,pkix.smtp_utf8_mailbox_has_uppercase,"RFC 8398 3: ""In SmtpUTF8Mailbox, domain labels that solely use ASCII characters (meaning neither A- nor U-labels) SHALL use NR-LDH restrictions as specified by Section 2.3.1 of [RFC5890] and SHALL be restricted to lowercase letters.""" ERROR,pkix.smtp_utf8_mailbox_invalid_syntax,"RFC 8398 3: Value does not contain ""@""" diff --git a/pkilint/cabf/smime/__init__.py b/pkilint/cabf/smime/__init__.py index 5c0a4fd..a16f530 100644 --- a/pkilint/cabf/smime/__init__.py +++ b/pkilint/cabf/smime/__init__.py @@ -1,5 +1,5 @@ import operator -from typing import Mapping, Tuple +from typing import Mapping, Tuple, Optional from dateutil.relativedelta import relativedelta from pyasn1.type import univ @@ -15,7 +15,7 @@ from pkilint.adobe import adobe_validator from pkilint.cabf import cabf_extension, cabf_key, cabf_name from pkilint.cabf.smime import ( - smime_constants, smime_name, smime_key, smime_extension + smime_constants, smime_name, smime_key, smime_extension, smime_validity ) from pkilint.cabf.smime.smime_constants import Generation from pkilint.common import alternative_name @@ -23,6 +23,7 @@ from pkilint.msft import asn1 as microsoft_asn1 from pkilint.msft import msft_name from pkilint.pkix import certificate, time +from pkilint.pkix.certificate import certificate_validity from pkilint.pkix.general_name import OTHER_NAME_MAPPINGS as PKIX_OTHERNAME_MAPPINGS OTHER_NAME_MAPPINGS = { @@ -192,7 +193,7 @@ def create_extensions_validator_container(validation_level, generation): ) -def create_validity_validators(generation): +def create_validity_validators(generation, validity_period_start_retriever: document.ValidityPeriodStartRetriever): days = 1185 if generation == Generation.LEGACY else 825 threshold_error = ( @@ -212,7 +213,8 @@ def create_validity_validators(generation): 'cabf.smime.certificate_validity_period_at_maximum' ) ) - return [ + + validators = [ time.ValidityPeriodThresholdsValidator( path='certificate.tbsCertificate.validity.notBefore', end_validity_node_retriever=lambda n: n.navigate('^.notAfter'), @@ -221,8 +223,20 @@ def create_validity_validators(generation): ) ] + if generation == smime_constants.Generation.LEGACY: + validators.append(smime_validity.LegacyGenerationSunsetValidator(validity_period_start_retriever)) + + return validators + + +def create_subscriber_validators( + validation_level, + generation, + validity_period_start_retriever: Optional[document.ValidityPeriodStartRetriever] = None +): + if validity_period_start_retriever is None: + validity_period_start_retriever = certificate_validity.CertificateValidityPeriodStartRetriever() -def create_subscriber_validators(validation_level, generation): return [ smime_name.create_subscriber_certificate_subject_validator_container(validation_level, generation), create_spki_validation_container(), @@ -230,7 +244,7 @@ def create_subscriber_validators(validation_level, generation): [] ), certificate.create_validity_validator_container( - create_validity_validators(generation) + create_validity_validators(generation, validity_period_start_retriever) ), create_extensions_validator_container(validation_level, generation), smime_key.SmimeAllowedSignatureAlgorithmEncodingValidator( diff --git a/pkilint/cabf/smime/finding_metadata.csv b/pkilint/cabf/smime/finding_metadata.csv index 58144fe..990367f 100644 --- a/pkilint/cabf/smime/finding_metadata.csv +++ b/pkilint/cabf/smime/finding_metadata.csv @@ -37,6 +37,7 @@ ERROR,cabf.smime.extended_key_usage_extension_missing,SMBR 7.1.2.3 (f),"""SHALL ERROR,cabf.smime.invalid_lei_scheme_format,SMBR 7.1.4.2.2 (d) and SMBR 7.1.2.3 (l),LEI value does not conform to standard LEI format (20 alphanumeric characters) ERROR,cabf.smime.is_ca_certificate,SMBR 7.1.2.3 (d),"""The cA field SHALL NOT be true""" ERROR,cabf.smime.key_usage_extension_missing,SMBR 7.1.2.3 (e),"""SHALL be present""" +ERROR,cabf.smime.legacy_generation_certificate_issued_after_prohibition,SMBR 7.1.6.1,"Effective July 15, 2025 S/MIME Subscriber Certificates SHALL NOT be issued using the Legacy Generation profiles 2.23.140.1.5.1.1, 2.23.140.1.5.2.1, 2.23.140.1.5.3.1, or 2.23.140.1.5.4.1." ERROR,cabf.smime.lei_extension_critical,SMBR 7.1.2.3 (l),""" SHALL NOT be marked critical""" ERROR,cabf.smime.lei_extension_prohibited,SMBR 7.1.2.3 (l),Mailbox- and individual-validated: Prohibited ERROR,cabf.smime.lei_role_extension_critical,SMBR 7.1.2.3 (l),"""SHALL NOT be marked critical""" @@ -108,6 +109,7 @@ ERROR,pkix.rfc6818_certificate_policies_invalid_explicit_text_encoding,RFC 6818 ERROR,pkix.san_extension_not_critical,RFC 5280 4.2.1.6,"""If the subject field contains an empty sequence, then the issuing CA MUST include a subjectAltName extension that is marked as critical""" ERROR,pkix.sct_list_empty,"RFC 6962 3.3: ""At least one SCT MUST be included""", ERROR,pkix.smime_capabilities_extension_critical,RFC 4262 2,"""This extension MUST NOT be marked critical.""" +ERROR,pkix.smtp_utf8_mailbox_domain_part_invalid_syntax,"RFC 9598, section 3: "". In SmtpUTF8Mailbox, labels that include non-ASCII characters MUST be stored in A-label (rather than U-label) form [RFC5890].""" ERROR,pkix.smtp_utf8_mailbox_has_bom,RFC 8398 3,"""The UTF8String encoding MUST NOT contain a Byte-Order-Mark (BOM) [RFC3629] to aid consistency across implementations, particularly for comparison.""" ERROR,pkix.smtp_utf8_mailbox_has_uppercase,RFC 8398 3,"""In SmtpUTF8Mailbox, domain labels that solely use ASCII characters (meaning neither A- nor U-labels) SHALL use NR-LDH restrictions as specified by Section 2.3.1 of [RFC5890] and SHALL be restricted to lowercase letters.""" ERROR,pkix.smtp_utf8_mailbox_invalid_syntax,RFC 8398 3,"Value does not contain ""@""" diff --git a/pkilint/cabf/smime/smime_constants.py b/pkilint/cabf/smime/smime_constants.py index fd9b906..730cf78 100644 --- a/pkilint/cabf/smime/smime_constants.py +++ b/pkilint/cabf/smime/smime_constants.py @@ -5,7 +5,7 @@ from pyasn1.type.univ import ObjectIdentifier -BR_VERSION = '1.0.4' +BR_VERSION = '1.0.6' CABF_SMIME_OID_ARC = ObjectIdentifier('2.23.140.1.5') diff --git a/pkilint/cabf/smime/smime_validity.py b/pkilint/cabf/smime/smime_validity.py new file mode 100644 index 0000000..d128236 --- /dev/null +++ b/pkilint/cabf/smime/smime_validity.py @@ -0,0 +1,33 @@ +import datetime + +from pyasn1_alt_modules import rfc5280 + +from pkilint import validation, document + + +class LegacyGenerationSunsetValidator(validation.Validator): + """ + SMBR, section 7.1.6.1: + Effective July 15, 2025 S/MIME Subscriber Certificates SHALL NOT be issued using the Legacy Generation profiles + 2.23.140.1.5.1.1, 2.23.140.1.5.2.1, 2.23.140.1.5.3.1, or 2.23.140.1.5.4.1. + """ + VALIDATION_LEGACY_GENERATION_CERTIFICATE_ISSUED_AFTER_PROHIBITION = validation.ValidationFinding( + validation.ValidationFindingSeverity.ERROR, + 'cabf.smime.legacy_generation_certificate_issued_after_prohibition' + ) + + _LEGACY_GENERATION_SUNSET_DATE = datetime.datetime(2025, 7, 15, 0, 0, 0, tzinfo=datetime.timezone.utc) + + def __init__(self, validity_period_start_retriever: document.ValidityPeriodStartRetriever): + super().__init__( + validations=[self.VALIDATION_LEGACY_GENERATION_CERTIFICATE_ISSUED_AFTER_PROHIBITION], + pdu_class=rfc5280.Validity + ) + + self._validity_period_start_retriever = validity_period_start_retriever + + def validate(self, node): + if self._validity_period_start_retriever(node.document) >= self._LEGACY_GENERATION_SUNSET_DATE: + raise validation.ValidationFindingEncountered( + self.VALIDATION_LEGACY_GENERATION_CERTIFICATE_ISSUED_AFTER_PROHIBITION + ) diff --git a/pkilint/pkix/general_name.py b/pkilint/pkix/general_name.py index 0bc1f36..2aceb1b 100644 --- a/pkilint/pkix/general_name.py +++ b/pkilint/pkix/general_name.py @@ -307,6 +307,16 @@ class SmtpUTF8MailboxValidator(validation.Validator): 'pkix.smtp_utf8_mailbox_has_uppercase' ) + """ + RFC 9598, section 3: + In SmtpUTF8Mailbox, labels that include non-ASCII characters MUST be stored in A-label (rather than U-label) + form [RFC5890]. + """ + VALIDATION_DOMAIN_PART_INVALID_DOMAIN_SYNTAX = validation.ValidationFinding( + validation.ValidationFindingSeverity.ERROR, + 'pkix.smtp_utf8_mailbox_domain_part_invalid_syntax' + ) + def __init__(self): super().__init__( validations=[ @@ -314,6 +324,7 @@ def __init__(self): self.VALIDATION_ASCII_ONLY, self.VALIDATION_HAS_BOM, self.VALIDATION_DOMAIN_PART_NOT_LOWERCASE, + self.VALIDATION_DOMAIN_PART_INVALID_DOMAIN_SYNTAX, ], pdu_class=rfc8398.SmtpUTF8Mailbox ) @@ -336,6 +347,9 @@ def validate(self, node): if domain_part != domain_part.lower(): raise validation.ValidationFindingEncountered(self.VALIDATION_DOMAIN_PART_NOT_LOWERCASE) + if not domain_part.isascii() or not validators_predicate(validators.domain, domain_part): + raise validation.ValidationFindingEncountered(self.VALIDATION_DOMAIN_PART_INVALID_DOMAIN_SYNTAX) + class DomainNameLengthValidator(validation.Validator): # https://devblogs.microsoft.com/oldnewthing/20120412-00/?p=7873 diff --git a/tests/integration_certificate/pkix/smtputf8mailbox_ulabel_domain_part.crttest b/tests/integration_certificate/pkix/smtputf8mailbox_ulabel_domain_part.crttest new file mode 100644 index 0000000..49694fa --- /dev/null +++ b/tests/integration_certificate/pkix/smtputf8mailbox_ulabel_domain_part.crttest @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIGJjCCBA6gAwIBAgIUVVqfvGiErUkRzwZ09xzjZpwLC0QwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0 +ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0yMzA0MTkwMDAwMDBaFw0y +MzA3MTgyMzU5NTlaMG8xIzAhBgNVBGETGkxFSVhHLUFFWUUwMEVLWEVTVlpVVUVC +UDY3MR4wHAYDVQQKExVBY21lIEluZHVzdHJpZXMsIEx0ZC4xKDAmBgkqhkiG9w0B +CQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI+1GS +qyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0fqXmG +8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0yg+8 +01SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIeNWMF +32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1JNPc +/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMBAAGjggHfMIIB2zAMBgNV +HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSMEGDAWgBTWRAAyfKgN/6xP +a2buta6bLMU4VDAdBgNVHQ4EFgQUiRlZXg7xafXLvUfhNPzimMxpMJEwFAYDVR0g +BA0wCzAJBgdngQwBBQIDMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwuY2Eu +ZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsGCCsGAQUFBwEBBD8wPTA7 +BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2EuZXhhbXBsZS5jb20vaXNz +dWluZ19jYS5kZXIwEwYDVR0lBAwwCgYIKwYBBQUHAwQwgZ4GA1UdEQSBljCBk4EZ +aGFuYWtvLnlhbWFkYUBleGFtcGxlLmNvbaAnBggrBgEFBQcICaAbDBnljLvnlJ9A +5aSn5a2mLmV4YW1wbGUuY29tpE0wSzEjMCEGA1UEYRMaTEVJWEctQUVZRTAwRUtY +RVNWWlVVRUJQNjcxJDAiBgNVBAoMG+OCouOCr+ODn+W3pealreagquW8j+S8muek +vjAjBgkrBgEEAYOYKgEEFhMUQUVZRTAwRUtYRVNWWlVVRUJQNjcwDQYJKoZIhvcN +AQELBQADggIBAFVF5H7vBBmRJlAIdSDcAghTDfPfMg0f5D+cFs4SQUJxcS+YePJa ++xd39vpSQktHrRsUjqU0jr54iFU/AmMM2d+QFUv+1dL5bCTZP2obq2A95LtCBKPZ +lNGf+wb/DzKJSrNazTW2dL1Fx6GZX5ixfduyI6KAhBwGMEZnlrXJlsZah4Bl1RR8 +K4gabGQhaZBsnw+Lr6blp/6gTr+2+c3SVO/7j/Sh64QCwy5qT6FLnYBiiErY/JJV +J39EYYlY60LDQx25UVsGeXw6Y96VJSz4gbQqSnM4NbF+02+K4XT2l2q9tx9Y+lm2 +U2qeW2UgLoTqnDTzeYwO79AvnHEG2qDrvhcB59myJbXsAUblyTCVgaygJ5VS2q63 +PpBO3YXllBYjwMWyD5R9Tmmq9IvDWNQQBo19wEIKInsml/K5TKpn0EsldsMzy9wd +ubLnaIkqPm47+ZOCGlpadFtnPzXOYnn2YS4UbpcJlWhVc5Wq2S+ok4ayqfjy3gcD +3lXYsGXWzJNDeg5be49w1kqC6vWl1Wj4amgBq0VHA97B55W22xcwDqZ3FWRqi609 +efbypy8HVZqDX7zCRDrPAcv6qni4jMZX25k462Kl+SxNn1c1jcoq1Pz8QHs1078Y +mdERsaRMUlq2ikE7tOQLL7AJ0GMWGpQnd797sMdNrGJ24SXXJIUxCXRB +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified, +certificate.tbsCertificate.extensions.8.extnValue.subjectAltName.1.otherName.value.smtpUTF8Mailbox,SmtpUTF8MailboxValidator,ERROR,pkix.smtp_utf8_mailbox_domain_part_invalid_syntax, diff --git a/tests/integration_certificate/smime_br/individual/legacy/issued_after_legacy_sunset.crttest b/tests/integration_certificate/smime_br/individual/legacy/issued_after_legacy_sunset.crttest new file mode 100644 index 0000000..24ebf0e --- /dev/null +++ b/tests/integration_certificate/smime_br/individual/legacy/issued_after_legacy_sunset.crttest @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIF1DCCA7ygAwIBAgIUL745jJJYnvMFGPE42o7ukLDYP/IwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCVVMxHzAdBgNVBAoMFkZvbyBJbmR1c3RyaWVzIExpbWl0 +ZWQxGDAWBgNVBAMMD0ludGVybWVkaWF0ZSBDQTAeFw0yNjA0MjgwMDAwMDBaFw0y +NzA3MjcyMzU5NTlaMEIxFjAUBgNVBAMMDVlBTUFEQSBIYW5ha28xKDAmBgkqhkiG +9w0BCQEWGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI ++1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0f +qXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0 +yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIe +NWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1 +JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMBAAGjggG6MIIBtjAM +BgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDAfBgNVHSMEGDAWgBTWRAAyfKgN +/6xPa2buta6bLMU4VDAdBgNVHQ4EFgQUiRlZXg7xafXLvUfhNPzimMxpMJEwFAYD +VR0gBA0wCzAJBgdngQwBBQQBMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwu +Y2EuZXhhbXBsZS5jb20vaXNzdWluZ19jYV9jcmwuY3JsMEsGCCsGAQUFBwEBBD8w +PTA7BggrBgEFBQcwAoYvaHR0cDovL3JlcG9zaXRvcnkuY2EuZXhhbXBsZS5jb20v +aXNzdWluZ19jYS5kZXIwHQYDVR0lBBYwFAYIKwYBBQUHAwQGCCsGAQUFBwMCMIGU +BgNVHREEgYwwgYmBGWhhbmFrby55YW1hZGFAZXhhbXBsZS5jb22gKQYKKwYBBAGC +NxQCA6AbDBloYW5ha28ueWFtYWRhQGV4YW1wbGUuY29toCYGCCsGAQUFBwgJoBoM +GOWxseeUsOiKseWtkEBleGFtcGxlLmNvbaQZMBcxFTATBgNVBAMMDOWxseeUsOiK +seWtkDANBgkqhkiG9w0BAQsFAAOCAgEAjEOEra5mkkzlUePGTbMa8KoXh7eo/xfx +8SzPuE6HF4O6kCmh6AD1bq0T2ahLYwniSOtE3iBg9KhauALzjqYL+ko0JkvmIRLN +BHGS3UNDMz5FW8+7+coU4MwlVuQUOyt9t01ZkbOBx5FkLupcONYcbAuY4gGPUEcu +kjyCQnIA6LjlqCtD9DhIjFr7f7DFsMXP2iNXBQs/TgZwxX+OIb9JIhkDhEPy0kou +5p7hzbJwnveA7cKxLUx9LuYBln65VB4iBdLjHRwbnc7LVOx9oZk/V9yNg/h3UjfB +L6MH6Kgac7o2dkdnH9yGTrhCkt9K09tzmi3ODv1bxjUbojzGDJbVC2YQ6HMntn88 +9S98J461+qYfZuxIoFp1HCXtJs1iZ2HPuz7sma+vUtd9s4S9OWGruyDkxZlClcZ+ +IgH7MZYnvByo3XZd+c3jk6692bqEYBgvu5tWrId4h9hVh7TY4pbKwwZnFojPLkHH +2OMkjJqK54R/PS3Ea0V8vInxwr8ESmLo/DZUuUNaX82UOkOXd2wwhHexlVtZM5Hs +IVDZxDulQS1lll+M6vAzHq9buxAdkRAiyC5X+dSqkP5itNCQBkJrnfi8tVfHg69X +APeclV11R1Ksnjn6OjwAKBmWnU99HzScksMx0SOI5G99+6mzz3zZLVQdPlnSj5V+ +tgkVdJ0YdSw= +-----END CERTIFICATE----- + +node_path,validator,severity,code,message +certificate.tbsCertificate.validity,LegacyGenerationSunsetValidator,ERROR,cabf.smime.legacy_generation_certificate_issued_after_prohibition, +certificate.tbsCertificate.extensions.3.extnValue.subjectKeyIdentifier,SubjectKeyIdentifierValidator,INFO,pkix.subject_key_identifier_method_1_identified,