Code Monkey home page Code Monkey logo

certvalidator's Introduction

certvalidator

A Python library for validating X.509 certificates or paths. Supports various options, including: validation at a specific moment in time, whitelisting and revocation checks.

GitHub Actions CI CircleCI PyPI

Features

  • X.509 path building
  • X.509 basic path validation
    • Signatures
      • RSA, DSA and EC algorithms
    • Name chaining
    • Validity dates
    • Basic constraints extension
      • CA flag
      • Path length constraint
    • Key usage extension
    • Extended key usage extension
    • Certificate policies
      • Policy constraints
      • Policy mapping
      • Inhibit anyPolicy
    • Failure on unknown/unsupported critical extensions
  • TLS/SSL server validation
  • Whitelisting certificates
  • Blacklisting hash algorithms
  • Revocation checks
    • CRLs
      • Indirect CRLs
      • Delta CRLs
    • OCSP checks
      • Delegated OCSP responders
    • Disable, require or allow soft failures
    • Caching of CRLs/OCSP responses
  • CRL and OCSP HTTP clients
  • Point-in-time validation

Unsupported features:

  • Name constraints

Related Crypto Libraries

certvalidator is part of the modularcrypto family of Python packages:

Current Release

0.11.1 - changelog

Dependencies

  • asn1crypto
  • oscrypto
  • Python 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9 or pypy

Installation

pip install certvalidator

License

certvalidator is licensed under the terms of the MIT license. See the LICENSE file for the exact license text.

Documentation

certvalidator documentation

Continuous Integration

Various combinations of platforms and versions of Python are tested via:

Testing

Tests are written using unittest and require no third-party packages.

Depending on what type of source is available for the package, the following commands can be used to run the test suite.

Git Repository

When working within a Git working copy, or an archive of the Git repository, the full test suite is run via:

python run.py tests

To run only some tests, pass a regular expression as a parameter to tests.

python run.py tests path

PyPi Source Distribution

When working within an extracted source distribution (aka .tar.gz) from PyPi, the full test suite is run via:

python setup.py test

Test Cases

The test cases for the library are comprised of:

Development

To install the package used for linting, execute:

pip install --user -r requires/lint

The following command will run the linter:

python run.py lint

Support for code coverage can be installed via:

pip install --user -r requires/coverage

Coverage is measured by running:

python run.py coverage

To install the packages requires to generate the API documentation, run:

pip install --user -r requires/api_docs

The documentation can then be generated by running:

python run.py api_docs

The following will run a test that connects to all (non-adult) sites in the Alexa top 1000 that respond on port 443:

python run.py stress_test

Once the script is complete, results that differ between the OS validation and the certvalidator validation will be listed for further debugging.

To change the version number of the package, run:

python run.py version {pep440_version}

To install the necessary packages for releasing a new version on PyPI, run:

pip install --user -r requires/release

Releases are created by:

  • Making a git tag in PEP 440 format

  • Running the command:

    python run.py release

Existing releases can be found at https://pypi.org/project/certvalidator.

CI Tasks

A task named deps exists to ensure a modern version of pip is installed, along with all necessary testing dependencies.

The ci task runs lint (if flake8 is avaiable for the version of Python) and coverage (or tests if coverage is not available for the version of Python). If the current directory is a clean git working copy, the coverage data is submitted to codecov.io.

python run.py deps
python run.py ci

certvalidator's People

Contributors

annakz avatar snijderc avatar viraptor avatar wbond avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

certvalidator's Issues

revocation_response is optional

According to rfc6960 (https://tools.ietf.org/html/rfc6960#section-4.2.1) the revocation reason is optional. Perhaps I have misunderstood some part of the spec, but as far as I can see (and have found in my own tests), the line 1101 in validate.py (

reason = revocation_info['revocation_reason'].human_friendly
) does not first check that the revocation_info['revocation_reason'] is not Void before attempting to use the human_friendly property.

Please become the official supported crypto library

This series of libraries is

  • modular
  • easy to understand
  • save/relied on safe underlying o/s libs
  • easier to package/ship/build
  • self documenting

Can we please all rally together to support this? I like it too much.

Listing of subclassed validation related exceptions is misleading

The API documentation of validate.validate_usage and validate.validate_tls lists the following exceptions:

> > :raises:
> > certvalidator.errors.PathValidationError - when an error occurs validating the path
> > certvalidator.errors.RevokedError - when the certificate or another certificate in its path has been revoked
> > certvalidator.errors.InvalidCertificateError - when the certificate is not valid for the usages specified

When someone tries to catch and distinguish those exceptions, its important to know that both RevokedError and InvalidCertificateError are subclass of PathValidationError. If exceptions are attempted to be caught in the order the API documentation lists them, RevokedError and InvalidCertificateError will never be caught:

try:
    validation_path = validator.validate_usage(key_usage)
except PathValidationError as ex:
    # handle PathValidationError
    # This will catch RevokedError and InvalidCertificateError too!
    pass
except RevokedError as ex:
    # control is never passed here!
    pass
except InvalidCertificateError as ex:
    # control is never passed here!
    pass

On the other hand those exceptions can be properly handled if PathValidationError is the last to be caught:

try:
    validation_path = validator.validate_usage(key_usage)
except RevokedError as ex:
    # handle RevokedError
    pass
except InvalidCertificateError as ex:
    # handle InvalidCertificateError
    pass
except PathValidationError as ex:
    # handle PathValidationError
    pass

I suggest to modify the API documentation to clarify subclassing of those exceptions and list them in a more appropriate order.

Weak version check for Extensions

Allows the presence of (version 3) extensions even if the certificate version is 1 or 2.
Allow the presence of extensions even if the version is greater than 3.
What is version 4? It is not rejected.

Fetching OCSP responses may result in TypeError

First of all, thank you for certvalidator! It makes an important task easy to complete in Python. 👍

While I was experimenting with certificate revocation status checking I ran into some issues. I'll create separate GitHub issues for those.


When certvalidator tries to fetch OCSP responses, but the certificate to be validated does not contain any reference to OCSP responders, TypeError is raised:

TypeError: exceptions must derive from BaseException

The root of that error is that cert.ocsp_urls returns an empty list, so at the end of the following code block None is raised:

last_e = None
for ocsp_url in cert.ocsp_urls:
try:
request = Request(ocsp_url)
request.add_header('Accept', 'application/ocsp-response')
request.add_header('Content-Type', 'application/ocsp-request')
request.add_header('User-Agent', user_agent)
response = urlopen(request, ocsp_request.dump(), timeout)
ocsp_response = ocsp.OCSPResponse.load(response.read())
request_nonce = ocsp_request.nonce_value
response_nonce = ocsp_response.nonce_value
if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
raise errors.OCSPValidationError(
'Unable to verify OCSP response since the request and response nonces do not match'
)
return ocsp_response
except (URLError) as e:
last_e = e
raise last_e

The cert.ocsp_urls == [] case could be handled here (for safety) e.g. by raising an appropriate error, but in that case ocsp_client.fetch probably shouldn't be called at all, since it can not return any meaningful result.

test: test_revocation_mode_soft failing due to expired cert

Similar to the issue fixed in fc82b79, the revocation_mode tests are once again failing:

======================================================================
ERROR: test_revocation_mode_soft (tests.test_validate.ValidateTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/michael/certvalidator/tests/test_validate.py", line 85, in test_revocation_mode_soft
    validate_path(context, path)
  File "/Users/michael/certvalidator/tests/../certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "/Users/michael/certvalidator/tests/../certvalidator/validate.py", line 358, in _validate_path
    raise PathValidationError(pretty_message(
certvalidator.errors.PathValidationError: The path could not be validated because the end-entity certificate expired 2022-07-27 12:00:00Z

Can not load OCSP response

I got error but it is ok with openssl command.

Traceback (most recent call last):
  File "test_ocsp.py", line 32, in <module>
    valid_path = validator.validate_usage(validator._certificate.key_usage_value.native, set(validator._certificate.extended_key_usage_value.native))
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/validate.py", line 387, in _validate_path
    end_entity_name_override=end_entity_name_override
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/validate.py", line 895, in verify_ocsp_response
    ocsp_responses = validation_context.retrieve_ocsps(cert, issuer)
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/context.py", line 500, in retrieve_ocsps
    **self._ocsp_fetch_params
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/certvalidator/ocsp_client.py", line 112, in fetch
    ocsp_response = ocsp.OCSPResponse.load(response.read())
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/asn1crypto/core.py", line 230, in load
    value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict)
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/asn1crypto/core.py", line 5095, in _parse_build
    info, new_pointer = _parse(encoded_data, encoded_len, pointer)
  File "/Users/huytn/.pyenv/versions/2.7.13/lib/python2.7/site-packages/asn1crypto/parser.py", line 164, in _parse
    raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (2, data_len - pointer))
ValueError: Insufficient data - 2 bytes requested but only 0 available

Validation fails with TypeError

Given an individual PEM-encoded certificate cert, I want to validate it against a certification chain located in ./cc_certs/PT.pem which I open to build a list of intermediate certificates:

def validate(cert):
    intermediates = []
    with open('./cc_certs/PT.pem', 'rb') as f:
        for _, _, der_bytes in pem.unarmor(f.read(), multiple=True):
            intermediates.append(der_bytes)

    validator = CertificateValidator(cert, intermediates)
    validator.validate_usage(set(['digital_signature']))

Simple use-case that's well documented. However when running this it blows up complaining about a TypeError

Traceback (most recent call last):
  File "client.py", line 114, in <module>
    smartcard.validate(cc_cert)
  File "/Users/fabio/Code/security2017-p1g2/src/chat/smartcard.py", line 38, in validate
    validator.validate_usage(set(['digital_signature']))
  File "/usr/local/lib/python3.6/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "/usr/local/lib/python3.6/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 407, in _validate_path
    end_entity_name_override=end_entity_name_override
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 1243, in verify_crl
    if isinstance(distribution_point['crl_issuer'], x509.GeneralNames):
TypeError: string indices must be integers

Sometimes the error also happens to be

Traceback (most recent call last):
  File "client.py", line 114, in <module>
    smartcard.validate(cc_cert)
  File "/Users/fabio/Code/security2017-p1g2/src/chat/smartcard.py", line 39, in validate
    validator.validate_usage(set(['digital_signature']))
  File "/usr/local/lib/python3.6/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "/usr/local/lib/python3.6/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 386, in _validate_path
    end_entity_name_override=end_entity_name_override
  File "/usr/local/lib/python3.6/site-packages/certvalidator/validate.py", line 956, in verify_ocsp_response
    if moment > cert_response['next_update'].native:
TypeError: '>' not supported between instances of 'datetime.datetime' and 'NoneType'

What do these errors mean? Or why does the error appear to be random? I tried to trace the exception in the source code but I don't know why it's being raised.

Certificate validation issue

Hi, I'm using certvalidator 0.11.1 to validate a certificate with a chain.

The validation fails in method verify_crl, with the following traceback:

File "/usr/local/lib/python3.8/site-packages/certvalidator/init.py", line 193, in validate_usage
self._validate_path()
File "/usr/local/lib/python3.8/site-packages/certvalidator/init.py", line 121, in _validate_path
validate_path(self._context, candidate_path)
File "/usr/local/lib/python3.8/site-packages/certvalidator/validate.py", line 50, in validate_path
return _validate_path(validation_context, path)
File "/usr/local/lib/python3.8/site-packages/certvalidator/validate.py", line 402, in _validate_path
verify_crl(
File "/usr/local/lib/python3.8/site-packages/certvalidator/validate.py", line 1243, in verify_crl
if isinstance(distribution_point['crl_issuer'], x509.GeneralNames):
TypeError: string indices must be integers

Apparently one is trying to index a string with a string ...

Attached goes a series of test certificates with a target certificate (sig.der) and its certification chain. I got the error when checking the validity of sig.der.
sig.zip

Confusing behavior when allow_fetching is True

The docstring of context.ValidationContext states that if the value of the allow_fetching parameter is True "and certificates contain the location of a CRL or OCSP responder, an HTTP request will be made to obtain information for revocation checking". The word "allow" seems to indicate that this HTTP request is merely an additional way of obtaining information about revocation status. Moreover, also the following comment (especially the word "also") suggests that CRL or OCSP data requested via HTTP are not the only source of revocation status information if allow_fetching is True:

# By default, any CRLs or OCSP responses that are passed to the constructor
# are chccked. If _allow_fetching is True, any CRLs or OCSP responses that
# can be downloaded will also be checked. The next two attributes change
# that behavior.

The docstring of the crls and ocsps parameters explain that pre-fetched/cached CRL and/or OCSP data can be passed to ValidationContext.

Putting all together, it seems that setting the allow_fetching parameter to True may result in fetching CRL or OCSP data in addition to checking pre-fetched/cached data.

Contrary to this expectation, if ValidationContext._allow_fetching is True, pre-fetched/cached CRL and OCSP data (passed by the crls and ocsps parameters) are completely ignored. (See the crls and ocsps properties and the retrieve_crls and retrieve_ocsps methods of ValidationContext.) If that is the intended behavior, it should be clarified in the documentation. Otherwise - and I would except this more intuitive - the two sources of revocation information should be merged when this is appropriate.

Chain building in certificate validation

Hi,

I'm using certvalidator 0.11.1.

It cannot build a chain with the attached certificates for the one in me.der.
However, it should work, as the chain was extracted from a Windows tools that examines certificate chains.
me.zip

The traceback gives:
File "/usr/local/lib/python3.8/site-packages/certvalidator/init.py", line 193, in validate_usage
self._validate_path()
File "/usr/local/lib/python3.8/site-packages/certvalidator/init.py", line 108, in _validate_path
paths = self._context.certificate_registry.build_paths(self._certificate)
File "/usr/local/lib/python3.8/site-packages/certvalidator/registry.py", line 314, in build_paths
raise PathBuildingError(pretty_message(
certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: ANDRÉ VENTURA DA CRUZ MARNÔTO ZÚQUETE; Serial Number: BI068540477; Given Name: ANDRÉ; Surname: VENTURA DA CRUZ MARNÔTO ZÚQUETE; Organizational Unit: Cidadão Português, Assinatura Qualificada do Cidadão; Organization: Cartão de Cidadão; Country: PT" - no issuer matching "Common Name: ECRaizEstado 002, Organization: Sistema de Certificação Eletrónica do Estado, Country: PT" was found

Update version in https://pypi.org/project/certvalidator/

It's still 0.11.1, which published in 2016.

Collecting certvalidator
  Downloading certvalidator-0.11.1-py2.py3-none-any.whl (31 kB)
Requirement already satisfied: oscrypto>=0.16.1 in d:\programdata\python38\lib\site-packages (from certvalidator) (1.2.1)
Requirement already satisfied: asn1crypto>=0.18.1 in d:\programdata\python38\lib\site-packages (from certvalidator) (1.4.0)
Installing collected packages: certvalidator
Successfully installed certvalidator-0.11.1

Errors in testing

Hey!
I decided to keep your package in the Debian project. It is already under analysis. Soon it will be in the official distribution repositories.
As dependencies undergo constant updates, Debian uses "tests" as a verification tool to find out whether the codes have not been affected by any update.

And cetvalidator is showing errors in tests, both at build time and isolated with "pytest".

Below are the two records for investigation.
CONSTRUCTION TIME:
termediate) ... ok
test_openssl_ocsp_direct_with_intermediate_success (tests.test_validate.ValidateTests.test_openssl_ocsp_direct_with_intermediate_success) ... ok
test_revocation_mode_hard (tests.test_validate.ValidateTests.test_revocation_mode_hard) ... ERROR
test_revocation_mode_soft (tests.test_validate.ValidateTests.test_revocation_mode_soft) ... ERROR

======================================================================
ERROR: test_basic_certificate_validator_tls (tests.test_certificate_validator.CertificateValidatorTests.test_basic_certificate_validator_tls)

Traceback (most recent call last):
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/tests/test_certificate_validator.py", line 44, in test_basic_certificate_validator_tls
path = validator.validate_tls('codexns.io')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/init.py", line 222, in validate_tls
self._validate_path()
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/init.py", line 108, in _validate_path
paths = self.context.certificateregistry.build_paths(self._certificate)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/registry.py", line 314, in build_paths
raise PathBuildingError(pretty_message(
certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Province: Massachusetts, Country: US, Serial Number: 471714639, Business Category: Private Organization, Incorporation State/Province: Massachusetts, Incorporation Country: US" - no issuer matching "Common Name: GeoTrust Primary Certification Authority, Organization: GeoTrust Inc., Country: US" was found

======================================================================
ERROR: test_basic_certificate_validator_tls_expired (tests.test_certificate_validator.CertificateValidatorTests.test_basic_certificate_validator_tls_expired)

Traceback (most recent call last):
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/tests/test_certificate_validator.py", line 54, in test_basic_certificate_validator_tls_expired
validator.validate_tls('codexns.io')
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/init.py", line 222, in validate_tls
self._validate_path()
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/init.py", line 108, in _validate_path
paths = self.context.certificateregistry.build_paths(self._certificate)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/pkgs/trabalhando/PACOTES-PRONTOS/certivalidador/python-certvalidator/certvalidator/registry.py", line 314, in build_paths
raise PathBuildingError(pretty_message(
certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Province: Massachusetts, Country: US, Serial Number: 471714639, Business Category: Private Organization, Incorporation State/Province: Massachusetts, Incorporation Country: US" - no issuer matching "Common Name: GeoTrust Primary Certification Authority, Organization: GeoTrust Inc., Country: US" was found

======================================================================
ERROR: test_basic_certificate_validator_tls_invalid_hostname (tests.test_certificate_validator.CertificateValidatorTests.test_basic_certificate_validator_tls_invalid_hostname)

Traceback (most recent call last):

Inglês

ISOLATED TESTS WITH PYTEST:

FAILED tests/test_certificate_validator.py::CertificateValidatorTests::test_basic_certificate_validator_tls - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_certificate_validator.py::CertificateValidatorTests::test_basic_certificate_validator_tls_expired - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_certificate_validator.py::CertificateValidatorTests::test_basic_certificate_validator_tls_invalid_hostname - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_certificate_validator.py::CertificateValidatorTests::test_basic_certificate_validator_tls_invalid_key_usage - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_certificate_validator.py::CertificateValidatorTests::test_basic_certificate_validator_tls_whitelist - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_crl_client.py::CRLClientTests::test_fetch_crl - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: GeoTrust EV SSL CA - G4, Organization: GeoTrust Inc., Country: US" - no issue...
FAILED tests/test_ocsp_client.py::OCSPClientTests::test_fetch_ocsp - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: GeoTrust EV SSL CA - G4, Organization: GeoTrust Inc., Country: US" - no issue...
FAILED tests/test_registry.py::RegistryTests::test_build_paths - certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: codexns.io, Organization: Codex Non Sufficit LC, Locality: Newbury, State/Pro...
FAILED tests/test_validate.py::ValidateTests::test_revocation_mode_hard - certvalidator.errors.PathValidationError: The path could not be validated because intermediate certificate 1 expired 2022-04-13 10:00:00Z
FAILED tests/test_validate.py::ValidateTests::test_revocation_mode_soft - certvalidator.errors.PathValidationError: The path could not be validated because intermediate certificate 1 expired 2022-04-13 10:00:00Z
======================================================================== 10 failed, 203 passed, 127 warnings in 5.37s ==========

Allows 0 as certificate serial number

You should not allow 0 (zero) as certificate serial number. RFC 5280 says, "The serial number MUST be a positive integer assigned by the CA to each cer- tificate...CAs MUST force the serial Number to be a non-negative integer...Non- conforming CAs may issue certificates with serial numbers that are negative or zero. Certificate users SHOULD be prepared to gracefully handle such certificates."

Potentially anomalous path-building results

Hi there! I'm opening this to help root-cause a handful of anomalous path-building results observed with certvalidator, which we found with x509-limbo.

As a disclaimer: many of these are likely to be non-issues from certvalidator's perspective, so please don't interpret this issue as a demand or expectation for everything on the linked results page to be fixed. X.509 validators have a huge range of behaviors in practice and many of the failures are either due to "pedantic" readings of RFC 5280 or explicitly unsupported features (e.g. Name Constraints, in certvalidator's case).

There are, however, some results for which certvalidator is an outlier or otherwise should probably consider some changes. A non-exhaustive sampling:

  • rfc5280::aki::critical-aki: all other implementations (except Go, which is fixing their behavior) under test reject critical AKIs; certvalidator accepts it;
  • pathological::nc-dos-1 and pathological::nc-dos-3: implementations typically establish a NC comparison budget to prevent quadratic blowup, but certvalidator appears to churn through them instead (taking over 30 seconds on my machine). I haven't fully root-caused this one, but was surprised since certvalidator otherwise appears to reject any critical NC extensions);
  • webpki::san::wildcard-embedded-leftmost-san: implementations should reject SAN patterns with non-leftmost wildcards (e.g. ba*.example.com), per both RFC 6125 and CABF;
  • cve::cve-2024-0567: this is a test for a chain-building failure in an older version of GnuTLS, which certvalidator also fails to construct a chain for here. The error here is pretty strange, since certvalidator appears to handle SANs in other contexts.

There are others as well, but these ones stood out as initial candidates for fixes.

Please let me know if there's any other information I can provide, or if I can help in any way! I'm not super familiar with certvalidator's internals, but I may be able to help resolve some of these with some guidance on the codebase 🙂

A successfully fetched but unusable OCSP response prevents fetching other OCSP responses

ocsp_client.fetch returns the first successfully fetched OCSP response:

for ocsp_url in cert.ocsp_urls:
try:
request = Request(ocsp_url)
request.add_header('Accept', 'application/ocsp-response')
request.add_header('Content-Type', 'application/ocsp-request')
request.add_header('User-Agent', user_agent)
response = urlopen(request, ocsp_request.dump(), timeout)
ocsp_response = ocsp.OCSPResponse.load(response.read())
request_nonce = ocsp_request.nonce_value
response_nonce = ocsp_response.nonce_value
if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
raise errors.OCSPValidationError(
'Unable to verify OCSP response since the request and response nonces do not match'
)
return ocsp_response
except (URLError) as e:
last_e = e

This is the only response which is available for callers: ValidationContext.retrieve_ocsps and in turn validate.verify_ocsp_response. Processing of the response happens in the latter of those. If the revocation status of the certificate can not be determined successfully from that response, at that point there is no way to fetch a new OCSP response, even if that response was not fetched from the last URL from cert.ocsp_urls (i.e. there are more URLs which could be used to fetch OCSP responses from).

To potentially utilize responses from all OCSP responders referenced by the certificate without wastefully fetching responses which later may prove to be unneeded, one could refactor ocsp_client.fetch and ValidationContext.retrieve_ocsps to become generators yielding "a list of" OCSP responses one by one.

URLError and socket.error are expected, but only partially handled

If revocation mode is not "soft-fail", URLError and socket.error are reraised from context.retrieve_crls:

except (URLError, socket.error) as e:
self._fetched_crls[cert.issuer_serial] = []
if self._revocation_mode == "soft-fail":
self._soft_fail_exceptions.append(e)
raise SoftFailError()
else:
raise

and from context.retrieve_ocsps:

except (URLError, socket.error) as e:
self._fetched_ocsps[cert.issuer_serial] = []
if self._revocation_mode == "soft-fail":
self._soft_fail_exceptions.append(e)
raise SoftFailError()
else:
raise

Callers (validate.verify_crl, validate.verify_ocsp_response, and finally validate._validate_path) don't handle these errors, so they may escape from certvalidator, which is probably not intentional and is not documented.

validate_usage: Exception on LDAP CRL URLs

Hi,
I try to validate the chain and usage of a certificate. The CA provides a CRL distribution point using HTTP and another one using LDAP. The later triggers an undocumented exception in certvalidator.validate_usage()

Code

        usage=["digital_signature", "key_encipherment"]
        validation_context = ValidationContext(
            allow_fetching=True, revocation_mode="hard-fail"
        )
        validator = CertificateValidator(
            end_entity_cert, intermediates, validation_context
        )
        validator.validate_usage(set(usage))

Extension

<Extension(oid=<ObjectIdentifier(oid=2.5.29.31, name=cRLDistributionPoints)>, critical=False, value=<CRLDistributionPoints([<DistributionPoint(full_name=[<UniformResourceIdentifier(value='http://crl.swisssign.net/3C9E527903636F4F9C811BD328700C245AEAA587')>], relative_name=None, reasons=None, crl_issuer=None)>, <DistributionPoint(full_name=[<UniformResourceIdentifier(value='ldap://directory.swisssign.net/CN=3C9E527903636F4F9C811BD328700C245AEAA587%2CO=SwissSign%2CC=CH?certificateRevocationList?base?objectClass=cRLDistributionPoint')>], relative_name=None, reasons=None, crl_issuer=None)>])>)>

Traceback

Traceback (most recent call last):
  File "./check_wpa_eapol.py", line 314, in main
    cert_file.file_name, hostname=realm, verbose=args.verbose
  File "./check_wpa_eapol.py", line 152, in validate_certificate_chain
    validator.validate_usage(set(usage))
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/validate.py", line 407, in _validate_path
    end_entity_name_override=end_entity_name_override
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/validate.py", line 1211, in verify_crl
    certificate_lists = validation_context.retrieve_crls(cert)
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/context.py", line 452, in retrieve_crls
    **self._crl_fetch_params
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/crl_client.py", line 59, in fetch
    output.append(_grab_crl(user_agent, url, timeout))
  File "/home/zeuz/git/wpa_eapol_checker/venv/lib64/python3.6/site-packages/certvalidator/crl_client.py", line 86, in _grab_crl
    response = urlopen(request, None, timeout)
  File "/usr/lib64/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib64/python3.6/urllib/request.py", line 526, in open
    response = self._open(req, data)
  File "/usr/lib64/python3.6/urllib/request.py", line 549, in _open
    'unknown_open', req)
  File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/lib64/python3.6/urllib/request.py", line 1419, in unknown_open
    raise URLError('unknown url type: %s' % type)
urllib.error.URLError: <urlopen error unknown url type: ldap>

I'm unsure on how to handle this case. Just ignore the LDAP CRL? Issue a warning?

Workaround

Initialize validator with

        validation_context = ValidationContext(
            allow_fetching=False, revocation_mode="soft-fail"
        )

OCSP validation at moment

First off great set of libraries, they are so much easier to use than pyasn1 and the crypto libs tied directly to OpenSSL.

I understand that according to the documentation the library does not support enabling certificate revocation checks if the moment is set to any value other than now. I feel that at least in the case of OCSP validation this requirement is unnecessary. (based on my possibly incorrect reading of rfc6960 section-3.2)

   5. The time at which the status being indicated is known to be
      correct (thisUpdate) is sufficiently recent;

   6. When available, the time at or before which newer information will
      be available about the status of the certificate (nextUpdate) is
      greater than the current time.

To me those two requirements seem to be related to the time of the OCSP request and not the moment of the certificate validation. As context I'm using your library to validate pkcs#7 SignedData objects that include cross signing timestamp that I am deriving my moment from. I have not looked into the related case of CRL validation.

related code context

ValidationContext allows a moment to be set that is in the past/future, but in doing so the OCSP revocation check is disabled, because the verify_ocsp_response method verifies that moment falls between this_update and next_update

validate_usage() fails when cert doesn't have keyUsage set

If KeyUsage extension is not set, then valid implementations behave as if all the keyUsage bits were set, but validate_usage() fails. I haven't tested, but the same is likely true for the extended_key_usage parameter.

FWIW, there is no equivalent to extended_optional for the keyUsage., which seems valid given the name of the method. That said, for when only wanting to test path validation (not usage), it would be nice if _validate_path() were not a "hidden" (i.e., starting with '_')...

Limited certificate path validation only? are extensions accounted for?

There are many valid/standard extensions that apply to the scope of 'Validate the certificate path'

It appears key usage and basic verification (i.e. OpenSSL only validates hostname, expiry, and root trust) are only considered for Valid certificate path in this library, It does not seem that it is respecting extensions that should also apply.

The simplest example I can think of is the InhibitAnyPolicy because you state it is not done:

# Steps 1 d-f
# We do not use initial-explicit-policy, initial-any-policy-inhibit or
# initial-policy-mapping-inhibit, so they are all set to the path length + 1

But it is just a fairly straight forward counter i.e. https://cryptography.io/en/latest/x509/reference/#cryptography.x509.InhibitAnyPolicy

The inhibit anyPolicy extension indicates that the special OID ANY_POLICY, is not considered an explicit match for other CertificatePolicies except when it appears in an intermediate self-issued CA certificate. The value indicates the number of additional non-self-issued certificates that may appear in the path before ANY_POLICY is no longer permitted. For example, a value of one indicates that ANY_POLICY may be processed in certificates issued by the subject of this certificate, but not in additional certificates in the path.

So there must be some reasoning to just set it to path +1 and not use it? There are a few more comments that have some inherent rationale that is not documented, this one stood out to me but I see others and all really should have the rationale explained in the documentation because the documentation leads us to believe all relevant (i.e. critical extension) checks are performed

The next one that comes to mind that is fairly straight forward to write about is;

subjectKeyIdentifier of the root CA cert should match the authorityKeyIdentifier of the next cert in the chain, and so-on. And I believe this is not taken care of in this library, which is an assumption because I've tried using self-signed.badssl.com which has neither of these and the chain was seemingly able to be validated (not throwing exceptions with missing subjectKeyIdentifier or authorityKeyIdentifier), albeit self-signed so not in any root CA store and ultimately reported invalid.

Does this library aim to properly and completely 'Validate the certificate path'? Or is it only accounting for basic OpenSSL verification + key usages? If it is not aiming or already actually applying complete 'Validate the certificate path' as it claims, you might want to consider updating the docs and main message you're project is stating.

Maybe 'limited certificate path validation, and aim to eventually be a complete certificate path validation solution for python'' would be more accurate?

'Void' object has no attribute 'human_friendly'

When run on revoked.badssl.com

    ctx = ValidationContext(allow_fetching=True, revocation_mode='hard-fail', weak_hash_algos=set(["md2", "md5", "sha1"]))
    validator = CertificateValidator(pem, validation_context=ctx, intermediate_certs=intermediate_certs)
    validator.validate_usage(
        key_usage=set(validator_key_usage),
        extended_key_usage=set(validator_extended_key_usage),
    )

full self-enclosed test:

from socket import socket, AF_INET, SOCK_STREAM
from certvalidator import CertificateValidator, ValidationContext
import idna
from OpenSSL import SSL
from OpenSSL.crypto import dump_certificate, FILETYPE_PEM

host = 'revoked.badssl.com'
ctx = SSL.Context(method=SSL.TLSv1_2_METHOD)
ctx.check_hostname = False
ctx.verify_mode = SSL.VERIFY_NONE
conn = SSL.Connection(ctx, socket(AF_INET, SOCK_STREAM))
conn.connect((host, 443))
conn.settimeout(3)
conn.set_tlsext_host_name(idna.encode(host))
conn.setblocking(1)
conn.do_handshake()
x509 = conn.get_peer_certificate()
intermediate_certs = []
for (_, cert) in enumerate(conn.get_peer_cert_chain()):
    intermediate_certs.append(dump_certificate(FILETYPE_PEM, cert))
conn.close()
pem = dump_certificate(FILETYPE_PEM, x509)
ctx = ValidationContext(allow_fetching=True, revocation_mode='hard-fail', weak_hash_algos=set(["md2", "md5", "sha1"]))
validator = CertificateValidator(pem, validation_context=ctx, intermediate_certs=intermediate_certs)
validator.validate_usage(
    key_usage=set(['digital_signature', 'key_encipherment']),
    extended_key_usage=set(['server_auth']),
)

full trace

Traceback (most recent call last):
  File "<redacted>/src/main.py", line 39, in <module>
    validator.validate_usage(
  File "<redacted>/.venv/lib/python3.9/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "<redacted>/.venv/lib/python3.9/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "<redacted>/.venv/lib/python3.9/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
  File "<redacted>/.venv/lib/python3.9/site-packages/certvalidator/validate.py", line 376, in _validate_path
    verify_ocsp_response(
  File "<redacted>/.venv/lib/python3.9/site-packages/certvalidator/validate.py", line 1101, in verify_ocsp_response
    reason = revocation_info['revocation_reason'].human_friendly
AttributeError: 'Void' object has no attribute 'human_friendly'

Via pip certvalidator==0.11.1

** Expected

Your docs explain I should see RevokedError not AttributeError which seems more about a source code bug within CertificateValidator then an actual error realted to OCSP revocation.

You may want to do some testing against badssl.com if you don't have something better

Certificate chain verification

I am trying to setup certificate verification and I am seeing strange behaviour here. Please loot at the following scenarios:

CertificateValidator(end_entity_cert).validate_usage(set([])) # Fails as no issuer is found
CertificateValidator(end_entity_cert, [intemediate_cerficate]).validate_usage(set([])) # Fails again as no issuer is found
CertificateValidator(end_entity_cert, [root_cerficate]).validate_usage(set([])) # Succeeds even though the intermediate is not provided, openssl fails this
CertificateValidator(end_entity_cert, [root_cerficate, intemediate_cerficate]).validate_usage(set([])) # Succeeds and is correct

Also there is another strange behaviour that I have noted, suppose in this same scenario I use a ValidationContext and just add the end_entity_cert to trusted_roots (no root and intermediate certs added) it seems to pass the validation. I am not sure if this is intended.

OCSP timestamp validation fails due to different date precisions

On my system, checking moment against cert_response['this_update'].native when treating an OCSP response fails here. The reason for this is that moment is a datetime object with nanoseconds (on my Linux system), and cert_response['this_update'].native is a datetime object with seconds precision.
I've fixed this for myself by subtracting a timedelta(seconds = 1) from moment in the comparison (and adding one second to moment in the next comparison here), which is fine for my purposes, but might not be a good solution in general.

updated 'assertRaisesRegexp ' obsolete

Hey!
I am the maintainer of your project on Debian.
We recently migrated to python 3.12.
And some tests failed. I had to make a patch to run some tests:

  • unittest.TestCase.assertRaisesRegexp = _assert_raises_regexp
  • unittest.TestCase.assertRaisesRegex = _assert_raises_regex

following patch:
Index: python-certvalidator/tests/_unittest_compat.py

--- python-certvalidator.orig/tests/_unittest_compat.py
+++ python-certvalidator/tests/_unittest_compat.py
@@ -4,7 +4,7 @@ from future import unicode_literals,
import sys
import unittest
import re

+import pytest

_non_local = {'patched': False}

@@ -18,7 +18,7 @@ def patch():

 unittest.TestCase.assertIsInstance = _assert_is_instance
 unittest.TestCase.assertRaises = _assert_raises
  • unittest.TestCase.assertRaisesRegexp = _assert_raises_regexp
  • unittest.TestCase.assertRaisesRegex = _assert_raises_regex
    unittest.TestCase.assertLess = _assert_less
    unittest.TestCase.assertIn = _assert_in
    _non_local['patched'] = True
    @@ -51,7 +51,7 @@ def _assert_raises(self, excClass, calla
    callableObj(*args, **kwargs)

-def _assert_raises_regexp(self, expected_exception, expected_regexp, callable_obj=None, *args>
+def _assert_raises_regex(self, expected_exception, expected_regexp, callable_obj=None, *args,>
if expected_regexp is not None:
expected_regexp = re.compile(expected_regexp)
context = _AssertRaisesContext(expected_exception, self, expected_regexp)
Index: python-certvalidator/tests/test_certificate_validator.py

--- python-certvalidator.orig/tests/test_certificate_validator.py
+++ python-certvalidator/tests/test_certificate_validator.py
@@ -1,9 +1,11 @@
+#!/usr/bin/env python3

coding: utf-8

from future import unicode_literals, division, absolute_import, print_function

from datetime import datetime
import unittest
import os
+import pytest

from asn1crypto import pem, x509
from asn1crypto.util import timezone
@@ -52,7 +54,7 @@ class CertificateValidatorTests(unittest

     validator = CertificateValidator(cert, other_certs)
  •    with self.assertRaisesRegexp(PathValidationError, 'expired'):
    
  •    with self.assertRaisesRegex(PathValidationError, 'expired'):
           validator.validate_tls('codexns.io')
    

    @unittest.skip("Not running tests")
    @@ -65,7 +67,7 @@ class CertificateValidatorTests(unittest
    context = ValidationContext(moment=moment)
    validator = CertificateValidator(cert, other_certs, context)

  •    with self.assertRaisesRegexp(PathValidationError, 'not valid'):
    
  •    with self.assertRaisesRegex(PathValidationError, 'not valid'):
           validator.validate_tls('google.com')
    

    @unittest.skip("Not running tests")
    @@ -78,7 +80,7 @@ class CertificateValidatorTests(unittest
    context = ValidationContext(moment=moment)
    validator = CertificateValidator(cert, other_certs, context)

  •    with self.assertRaisesRegexp(PathValidationError, 'for the purpose'):
    
  •    with self.assertRaisesRegex(PathValidationError, 'for the purpose'):
           validator.validate_usage(set(['crl_sign']))
    

    @unittest.skip("Not running tests")
    Index: python-certvalidator/tests/test_validate.py
    ===================================================================
    --- python-certvalidator.orig/tests/test_validate.py
    +++ python-certvalidator/tests/test_validate.py
    @@ -1,3 +1,4 @@
    +#!/usr/bin/env python3

coding: utf-8

from future import unicode_literals, division, absolute_import, print_function

@@ -6,6 +7,7 @@ import base64
import unittest
import os
import sys
+import pytest

from asn1crypto import crl, ocsp, pem, x509
from asn1crypto.util import timezone
@@ -113,7 +115,7 @@ class ValidateTests(unittest.TestCase):
'(CRL|OCSP response) indicates the end-entity certificate was '
'revoked at 15:44:10 on 2014-04-23, due to an unspecified reason'
)

  •    with self.assertRaisesRegexp(RevokedError, expected):
    
  •    with self.assertRaisesRegex(RevokedError, expected):
           validate_path(context, path)
    

    @DaTa('ocsp_info', True)
    @@ -135,7 +137,7 @@ class ValidateTests(unittest.TestCase):
    self.assertEqual(path_len, len(path))

       if excp_class:
    
  •        with self.assertRaisesRegexp(excp_class, excp_msg):
    
  •        with self.assertRaisesRegex(excp_class, excp_msg):
               validate_path(context, path)
       else:
           validate_path(context, path)
    

@@ -684,7 +686,7 @@ class ValidateTests(unittest.TestCase):
'The path could not be validated because the end-entity certificate '
'issuer name could not be matched'
)

  •    with self.assertRaisesRegexp(PathValidationError, expected):
    
  •    with self.assertRaisesRegex(PathValidationError, expected):
           validate_path(context, path)
    

    def test_nist_40302_invalid_name_chaining_order_test2(self):
    @@ -716,7 +718,7 @@ class ValidateTests(unittest.TestCase):
    'The path could not be validated because the end-entity certificate '
    'issuer name could not be matched'
    )

  •    with self.assertRaisesRegexp(PathValidationError, expected):
    
  •    with self.assertRaisesRegex(PathValidationError, expected):
           validate_path(context, path)
    

    @DaTa('nist_info', True)
    @@ -742,7 +744,7 @@ class ValidateTests(unittest.TestCase):
    self.assertEqual(path_len, len(path))

       if excp_class:
    
  •        with self.assertRaisesRegexp(excp_class, excp_msg):
    
  •        with self.assertRaisesRegex(excp_class, excp_msg):
               validate_path(context, path)
       else:
           validate_path(context, path)
    

Supporting SubjectAltName critical extension

I ran into the following error:
The path could not be validated because the end-entity certificate contains the following unsupported critical extension: subject_alt_name
SubjectAltName extension must critical if the Subject field is empty (rfc). It is often critical for non-TLS certificate, for example TPM Endorsement Key certificates.

tmp_crl_issuer not checked if it is None

The result from certificate_registry.retrieve_by_key_identifier(certificate_list.authority_key_identifier) (lines 1304 to 1306) is not validated before the subject property is called:

crl_issuer_name = tmp_crl_issuer.subject

I am calling verify_crl directly on some very broken SSL/TLS cert chains, so I can understand that I am using verify_crl out of the expected context, which is probably why I am encountering this problem. On the other hand, I think it would be fairly trivial to check that tmp_crl_issuer is not None before retrieving the subject property (or just continuing the loop if tmp_crl_issuer is None).

Trust store

Hi:

Thank you so much for the great lib.

However, which root store am I validate against if I simply call the validator.validate_usage(set(['digital_signature']))?

Appreciate your help.

Crash on macOS when using python from Homebrew

When using the python distribution from Homebrew on macOS 10.15.1 as soon as I try to import certvalidator the python interpreter crashes.
This doesn't happen if I use the python version provided by macOS.

Step to reproduce if you have homebrew installed:

  1. Install python: brew install python
  2. Check that you are using brew python with which python
  3. Install certvalidator pip3 install certvalidator
  4. Try to load certvalidator python3 -m certvalidator and observer crash

Here's the crash that I get:

Process:               Python [63383]
Path:                  /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python
Identifier:            Python
Version:               3.7.5 (3.7.5)
Code Type:             X86-64 (Native)
Parent Process:        zsh [62259]
Responsible:           iTerm2 [1676]
User ID:               501

Date/Time:             2019-11-28 15:55:02.192 +0100
OS Version:            Mac OS X 10.15.1 (19B88)
Report Version:        12
Anonymous UUID:        11D77264-CC6D-9D02-08E7-6D9EE9F0D0C7

Sleep/Wake UUID:       87443D72-F48A-4FAA-A509-B2922D598D14

Time Awake Since Boot: 57000 seconds
Time Since Wake:       8500 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
/usr/lib/libcrypto.dylib
abort() called
Invalid dylib load. Clients should not load the unversioned libcrypto dylib as it does not have a stable ABI.

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	0x00007fff6576649a __pthread_kill + 10
1   libsystem_pthread.dylib       	0x00007fff658236cb pthread_kill + 384
2   libsystem_c.dylib             	0x00007fff656eea1c abort + 120
3   libcrypto.dylib               	0x00007fff63062804 __report_load + 352
4   dyld                          	0x000000010a8300bd ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 539
5   dyld                          	0x000000010a8304e2 ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
6   dyld                          	0x000000010a82af67 ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 493
7   dyld                          	0x000000010a828ff8 ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 188
8   dyld                          	0x000000010a829098 ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 82
9   dyld                          	0x000000010a81af87 dyld::runInitializers(ImageLoader*) + 82
10  dyld                          	0x000000010a824c6f dlopen_internal + 609
11  libdyld.dylib                 	0x00007fff65607e7f dlopen + 171
12  _ctypes.cpython-37m-darwin.so 	0x000000010acc8a5a py_dl_open + 147
13  org.python.python             	0x0000000109be038f _PyMethodDef_RawFastCallKeywords + 235
14  org.python.python             	0x0000000109bdfa18 _PyCFunction_FastCallKeywords + 41
15  org.python.python             	0x0000000109c74350 call_function + 628
16  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
17  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
18  org.python.python             	0x0000000109bdf658 _PyFunction_FastCallDict + 444
19  org.python.python             	0x0000000109be075f _PyObject_Call_Prepend + 131
20  org.python.python             	0x0000000109c1daaa slot_tp_init + 80
21  org.python.python             	0x0000000109c1a7d6 type_call + 172
22  org.python.python             	0x0000000109bdf88e _PyObject_FastCallKeywords + 358
23  org.python.python             	0x0000000109c743b6 call_function + 730
24  org.python.python             	0x0000000109c6d46e _PyEval_EvalFrameDefault + 7090
25  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
26  org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
27  org.python.python             	0x0000000109c692a3 builtin_exec + 563
28  org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
29  org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
30  org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
31  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
32  org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
33  org.python.python             	0x0000000109c743bd call_function + 737
34  org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
35  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
36  org.python.python             	0x0000000109c743bd call_function + 737
37  org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
38  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
39  org.python.python             	0x0000000109c743bd call_function + 737
40  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
41  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
42  org.python.python             	0x0000000109c743bd call_function + 737
43  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
44  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
45  org.python.python             	0x0000000109be119a object_vacall + 267
46  org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
47  org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
48  org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
49  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
50  org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
51  org.python.python             	0x0000000109c692a3 builtin_exec + 563
52  org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
53  org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
54  org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
55  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
56  org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
57  org.python.python             	0x0000000109c743bd call_function + 737
58  org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
59  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
60  org.python.python             	0x0000000109c743bd call_function + 737
61  org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
62  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
63  org.python.python             	0x0000000109c743bd call_function + 737
64  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
65  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
66  org.python.python             	0x0000000109c743bd call_function + 737
67  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
68  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
69  org.python.python             	0x0000000109be119a object_vacall + 267
70  org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
71  org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
72  org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
73  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
74  org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
75  org.python.python             	0x0000000109c692a3 builtin_exec + 563
76  org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
77  org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
78  org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
79  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
80  org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
81  org.python.python             	0x0000000109c743bd call_function + 737
82  org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
83  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
84  org.python.python             	0x0000000109c743bd call_function + 737
85  org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
86  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
87  org.python.python             	0x0000000109c743bd call_function + 737
88  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
89  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
90  org.python.python             	0x0000000109c743bd call_function + 737
91  org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
92  org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
93  org.python.python             	0x0000000109be119a object_vacall + 267
94  org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
95  org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
96  org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
97  org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
98  org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
99  org.python.python             	0x0000000109c692a3 builtin_exec + 563
100 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
101 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
102 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
103 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
104 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
105 org.python.python             	0x0000000109c743bd call_function + 737
106 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
107 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
108 org.python.python             	0x0000000109c743bd call_function + 737
109 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
110 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
111 org.python.python             	0x0000000109c743bd call_function + 737
112 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
113 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
114 org.python.python             	0x0000000109c743bd call_function + 737
115 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
116 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
117 org.python.python             	0x0000000109be119a object_vacall + 267
118 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
119 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
120 org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
121 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
122 org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
123 org.python.python             	0x0000000109c692a3 builtin_exec + 563
124 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
125 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
126 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
127 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
128 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
129 org.python.python             	0x0000000109c743bd call_function + 737
130 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
131 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
132 org.python.python             	0x0000000109c743bd call_function + 737
133 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
134 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
135 org.python.python             	0x0000000109c743bd call_function + 737
136 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
137 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
138 org.python.python             	0x0000000109c743bd call_function + 737
139 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
140 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
141 org.python.python             	0x0000000109be119a object_vacall + 267
142 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
143 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
144 org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
145 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
146 org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
147 org.python.python             	0x0000000109c692a3 builtin_exec + 563
148 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
149 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
150 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
151 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
152 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
153 org.python.python             	0x0000000109c743bd call_function + 737
154 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
155 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
156 org.python.python             	0x0000000109c743bd call_function + 737
157 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
158 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
159 org.python.python             	0x0000000109c743bd call_function + 737
160 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
161 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
162 org.python.python             	0x0000000109c743bd call_function + 737
163 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
164 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
165 org.python.python             	0x0000000109be119a object_vacall + 267
166 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
167 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
168 org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
169 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
170 org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
171 org.python.python             	0x0000000109c692a3 builtin_exec + 563
172 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
173 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
174 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
175 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
176 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
177 org.python.python             	0x0000000109c743bd call_function + 737
178 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
179 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
180 org.python.python             	0x0000000109c743bd call_function + 737
181 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
182 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
183 org.python.python             	0x0000000109c743bd call_function + 737
184 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
185 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
186 org.python.python             	0x0000000109c743bd call_function + 737
187 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
188 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
189 org.python.python             	0x0000000109be119a object_vacall + 267
190 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
191 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
192 org.python.python             	0x0000000109c6885e builtin___import__ + 122
193 org.python.python             	0x0000000109bdfcba PyCFunction_Call + 208
194 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
195 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
196 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
197 org.python.python             	0x0000000109c743bd call_function + 737
198 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
199 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
200 org.python.python             	0x0000000109bdf658 _PyFunction_FastCallDict + 444
201 org.python.python             	0x0000000109be119a object_vacall + 267
202 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
203 org.python.python             	0x0000000109c89507 PyImport_ImportModuleLevelObject + 1774
204 org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
205 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
206 org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
207 org.python.python             	0x0000000109c692a3 builtin_exec + 563
208 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
209 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
210 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
211 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
212 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
213 org.python.python             	0x0000000109c743bd call_function + 737
214 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
215 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
216 org.python.python             	0x0000000109c743bd call_function + 737
217 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
218 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
219 org.python.python             	0x0000000109c743bd call_function + 737
220 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
221 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
222 org.python.python             	0x0000000109c743bd call_function + 737
223 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
224 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
225 org.python.python             	0x0000000109be119a object_vacall + 267
226 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
227 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
228 org.python.python             	0x0000000109c71f3d _PyEval_EvalFrameDefault + 26241
229 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
230 org.python.python             	0x0000000109c6b819 PyEval_EvalCode + 51
231 org.python.python             	0x0000000109c692a3 builtin_exec + 563
232 org.python.python             	0x0000000109be00ca _PyMethodDef_RawFastCallDict + 549
233 org.python.python             	0x0000000109bdf6db _PyCFunction_FastCallDict + 41
234 org.python.python             	0x0000000109c6d6f6 _PyEval_EvalFrameDefault + 7738
235 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
236 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
237 org.python.python             	0x0000000109c743bd call_function + 737
238 org.python.python             	0x0000000109c6d32b _PyEval_EvalFrameDefault + 6767
239 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
240 org.python.python             	0x0000000109c743bd call_function + 737
241 org.python.python             	0x0000000109c6d312 _PyEval_EvalFrameDefault + 6742
242 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
243 org.python.python             	0x0000000109c743bd call_function + 737
244 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
245 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
246 org.python.python             	0x0000000109c743bd call_function + 737
247 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
248 org.python.python             	0x0000000109bdfdec function_code_fastcall + 106
249 org.python.python             	0x0000000109be119a object_vacall + 267
250 org.python.python             	0x0000000109be1299 _PyObject_CallMethodIdObjArgs + 168
251 org.python.python             	0x0000000109c893eb PyImport_ImportModuleLevelObject + 1490
252 org.python.python             	0x0000000109c6885e builtin___import__ + 122
253 org.python.python             	0x0000000109be04bd _PyMethodDef_RawFastCallKeywords + 537
254 org.python.python             	0x0000000109bdfa18 _PyCFunction_FastCallKeywords + 41
255 org.python.python             	0x0000000109c74350 call_function + 628
256 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
257 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
258 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
259 org.python.python             	0x0000000109c743bd call_function + 737
260 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
261 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
262 org.python.python             	0x0000000109bdf9e0 _PyFunction_FastCallKeywords + 212
263 org.python.python             	0x0000000109c743bd call_function + 737
264 org.python.python             	0x0000000109c6d3c6 _PyEval_EvalFrameDefault + 6922
265 org.python.python             	0x0000000109c74bb1 _PyEval_EvalCodeWithName + 1698
266 org.python.python             	0x0000000109bdf658 _PyFunction_FastCallDict + 444
267 org.python.python             	0x0000000109cb1570 pymain_run_module + 147
268 org.python.python             	0x0000000109cb05dc pymain_main + 4091
269 org.python.python             	0x0000000109cb1194 _Py_UnixMain + 56
270 libdyld.dylib                 	0x00007fff656172e5 start + 1

Thread 1:: Dispatch queue: com.apple.CoreAnalytics::Client
0   libsystem_kernel.dylib        	0x00007fff65760166 mach_msg_trap + 10
1   libsystem_kernel.dylib        	0x00007fff657606cc mach_msg + 60
2   libxpc.dylib                  	0x00007fff6587763a _xpc_pipe_routine + 356
3   libxpc.dylib                  	0x00007fff65877810 xpc_pipe_routine_with_flags + 56
4   libxpc.dylib                  	0x00007fff6585c1fc _xpc_interface_routine + 175
5   libxpc.dylib                  	0x00007fff6586b8a4 _xpc_look_up_endpoint + 191
6   libxpc.dylib                  	0x00007fff6585f4d2 _xpc_connection_bootstrap_look_up_slow + 368
7   libxpc.dylib                  	0x00007fff6585f02d _xpc_connection_init + 371
8   libxpc.dylib                  	0x00007fff6585ee8f _xpc_connection_activate_if_needed + 73
9   libxpc.dylib                  	0x00007fff6585ee1a xpc_connection_resume + 64
10  com.apple.analyticsd          	0x00007fff453a78ca void applesauce::dispatch::v1::async<void applesauce::dispatch::ManagedObject<CoreAnalytics::Client>::execute_wrapped<CoreAnalytics::Client::init()::$_1>(CoreAnalytics::Client::init()::$_1&&) const::'lambda'()>(dispatch_queue_s*, CoreAnalytics::Client::init()::$_1&&)::'lambda'(void*)::__invoke(void*) + 204
11  libdispatch.dylib             	0x00007fff655c750e _dispatch_client_callout + 8
12  libdispatch.dylib             	0x00007fff655ccace _dispatch_lane_serial_drain + 597
13  libdispatch.dylib             	0x00007fff655cd452 _dispatch_lane_invoke + 363
14  libdispatch.dylib             	0x00007fff655d6a9e _dispatch_workloop_worker_thread + 598
15  libsystem_pthread.dylib       	0x00007fff6582071b _pthread_wqthread + 290
16  libsystem_pthread.dylib       	0x00007fff6582057b start_wqthread + 15

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x000000010a8dedc0  rcx: 0x00007ffee6032f48  rdx: 0x0000000000000000
  rdi: 0x0000000000000307  rsi: 0x0000000000000006  rbp: 0x00007ffee6032f70  rsp: 0x00007ffee6032f48
   r8: 0x0000000000000075   r9: 0x000000000000001c  r10: 0x0000000000000000  r11: 0x0000000000000246
  r12: 0x0000000000000307  r13: 0x00007fff8f2d17f0  r14: 0x0000000000000006  r15: 0x0000000000000016
  rip: 0x00007fff6576649a  rfl: 0x0000000000000246  cr2: 0x00007fff8f2d1968
  
Logical CPU:     0
Error Code:      0x02000148
Trap Number:     133


Binary Images:
       0x109bbf000 -        0x109bc0fff +org.python.python (3.7.5 - 3.7.5) <D5086BEF-8279-37AA-A16F-413E42FCDAE0> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python
       0x109bc6000 -        0x109d48ff7 +org.python.python (3.7.5, [c] 2001-2019 Python Software Foundation. - 3.7.5) <3C508706-1C56-32BB-9A6D-59AE3D4043B2> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/Python
       0x10a137000 -        0x10a138fff +_heapq.cpython-37m-darwin.so (0) <BD0337AB-CDAE-349D-AFF6-7ABB71C01BDE> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_heapq.cpython-37m-darwin.so
       0x10a1bd000 -        0x10a1c0fff +_struct.cpython-37m-darwin.so (0) <7498ACF9-AB19-3D21-B79D-59322C5D8B6B> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_struct.cpython-37m-darwin.so
       0x10a1c7000 -        0x10a1caff7 +binascii.cpython-37m-darwin.so (0) <5C9EA6BA-B339-3E61-8134-3DB53774CE36> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/binascii.cpython-37m-darwin.so
       0x10a263000 -        0x10a263fff +_opcode.cpython-37m-darwin.so (0) <EE172C39-4277-362F-819D-202C312FE8C1> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_opcode.cpython-37m-darwin.so
       0x10a2f0000 -        0x10a3eefff +unicodedata.cpython-37m-darwin.so (0) <3BB69E78-716B-31BA-9156-EAACAACF757F> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/unicodedata.cpython-37m-darwin.so
       0x10a3f4000 -        0x10a3f7fff +_hashlib.cpython-37m-darwin.so (0) <067A014F-8DF1-363C-BAEA-5A8AA1056B25> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_hashlib.cpython-37m-darwin.so
       0x10a3fc000 -        0x10a44bfff +libssl.1.1.dylib (0) <8CC754E3-C1EE-37A0-AD64-D89C69816928> /usr/local/opt/[email protected]/lib/libssl.1.1.dylib
       0x10a474000 -        0x10a60d553 +libcrypto.1.1.dylib (0) <0E7D90A2-D870-3A17-B784-81564B61D7B9> /usr/local/opt/[email protected]/lib/libcrypto.1.1.dylib
       0x10a69f000 -        0x10a6a4ffb +_blake2.cpython-37m-darwin.so (0) <A6E3EA40-637F-3F1C-8C3D-956CE33746B7> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_blake2.cpython-37m-darwin.so
       0x10a6a9000 -        0x10a6b9fff +_sha3.cpython-37m-darwin.so (0) <E7674377-E494-3620-9587-0209731896FE> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_sha3.cpython-37m-darwin.so
       0x10a6ff000 -        0x10a707ffb +_socket.cpython-37m-darwin.so (0) <D2975757-0EB6-3603-BD81-4153EC7EB6E3> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_socket.cpython-37m-darwin.so
       0x10a713000 -        0x10a717ff3 +math.cpython-37m-darwin.so (0) <4EFBB237-EFF5-3F46-B38A-AFCF891DD743> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/math.cpython-37m-darwin.so
       0x10a71e000 -        0x10a720fff +select.cpython-37m-darwin.so (0) <5239FFCF-6B3D-33C9-8945-34266BE43AA4> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/select.cpython-37m-darwin.so
       0x10a7a7000 -        0x10a7b2ffb +_datetime.cpython-37m-darwin.so (0) <DFC56622-80F4-3252-B99C-ED783CAA5F85> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_datetime.cpython-37m-darwin.so
       0x10a7bb000 -        0x10a7e8ff3 +_decimal.cpython-37m-darwin.so (0) <1F56B5B3-2E11-35F1-ACB0-DA346D4EEC4C> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_decimal.cpython-37m-darwin.so
       0x10a7fb000 -        0x10a7fbfff +_bisect.cpython-37m-darwin.so (0) <8AFFD4CF-147F-3381-8A1F-AB226B5AC136> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_bisect.cpython-37m-darwin.so
       0x10a7ff000 -        0x10a800ffb +_random.cpython-37m-darwin.so (0) <BD1E4A35-B765-3385-99E1-78CA09EAB61E> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_random.cpython-37m-darwin.so
       0x10a804000 -        0x10a807fff +zlib.cpython-37m-darwin.so (0) <EAC395A0-C0DE-3511-B8CF-A26C04EB1D1B> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/zlib.cpython-37m-darwin.so
       0x10a80d000 -        0x10a80efff +_bz2.cpython-37m-darwin.so (0) <7B1B1DF4-F53F-396F-BAE8-56A63089C376> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_bz2.cpython-37m-darwin.so
       0x10a815000 -        0x10a8a5b5f  dyld (733.6) <DAFEA246-2F9A-3DCB-A37C-4246D4F92770> /usr/lib/dyld
       0x10aad9000 -        0x10aae6fff +_ssl.cpython-37m-darwin.so (0) <B0CB34EA-C7C0-35EE-9C93-398552F63CFF> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_ssl.cpython-37m-darwin.so
       0x10ab75000 -        0x10ab78ff7 +_lzma.cpython-37m-darwin.so (0) <C50B59D2-E54E-3499-B44F-73E77C7CD173> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_lzma.cpython-37m-darwin.so
       0x10ab7e000 -        0x10ab99fff +liblzma.5.dylib (0) <4D3E8014-34F1-34EE-B4EF-FB74B13ED037> /usr/local/opt/xz/lib/liblzma.5.dylib
       0x10aba0000 -        0x10aba1fff +grp.cpython-37m-darwin.so (0) <58AB3958-4FEE-30C1-B7E8-51E21430D11D> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/grp.cpython-37m-darwin.so
       0x10abe5000 -        0x10abe6fff +_scproxy.cpython-37m-darwin.so (0) <3CCCAF50-95C6-3211-9F1E-D81D94BA64FA> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_scproxy.cpython-37m-darwin.so
       0x10acbb000 -        0x10acbcfff +_posixsubprocess.cpython-37m-darwin.so (0) <7DA12ABC-66C9-3166-9EA0-94ADFE10B790> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_posixsubprocess.cpython-37m-darwin.so
       0x10acc0000 -        0x10accffff +_ctypes.cpython-37m-darwin.so (0) <05DB5CB2-C8CB-310D-9F7E-C4773BBF1B35> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/_ctypes.cpython-37m-darwin.so
       0x10ad5b000 -        0x10ad7affb +pyexpat.cpython-37m-darwin.so (0) <EDE6B9DF-1D90-33E6-8E20-8244149F4D74> /usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/pyexpat.cpython-37m-darwin.so
    0x7fff29ed3000 -     0x7fff29ed3fff  com.apple.Accelerate (1.11 - Accelerate 1.11) <956D070C-B522-3A08-891A-CAD6BA4082D1> /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
    0x7fff29eeb000 -     0x7fff2a556fdf  com.apple.vImage (8.1 - 524.2) <DCF3349F-1159-3F46-81E0-C18E041DC940> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage
    0x7fff2a557000 -     0x7fff2a7bffff  libBLAS.dylib (1303) <B950B953-116A-3C78-91A9-F983F61BC795> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
    0x7fff2a7c0000 -     0x7fff2aaafff7  libBNNS.dylib (144.40.3) <BAE2A5E4-14A1-3C54-86DF-888FA26C745E> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBNNS.dylib
    0x7fff2aab1000 -     0x7fff2ae56fff  libLAPACK.dylib (1303) <5C248B39-F233-3074-A3A5-AF8F436FBF87> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
    0x7fff2ae57000 -     0x7fff2ae6cff8  libLinearAlgebra.dylib (1303) <3AEC87AB-568C-3D88-959A-D6D8C2776FEC> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLinearAlgebra.dylib
    0x7fff2ae6d000 -     0x7fff2ae72ff3  libQuadrature.dylib (7) <7EE59014-8FC5-3369-868B-8A87E590BF78> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libQuadrature.dylib
    0x7fff2ae73000 -     0x7fff2aee3fff  libSparse.dylib (103) <093F97A4-47DE-38DF-BB7A-FF5A3FB0BB3B> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparse.dylib
    0x7fff2aee4000 -     0x7fff2aef6fef  libSparseBLAS.dylib (1303) <4536B3F7-7017-36F5-B500-1A63F691CE03> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libSparseBLAS.dylib
    0x7fff2aef7000 -     0x7fff2b0d0ffb  libvDSP.dylib (735) <E849AEB0-2995-38A4-B0C3-4ACEAF434D12> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib
    0x7fff2b0d1000 -     0x7fff2b18cfd3  libvMisc.dylib (735) <18B48679-444E-3680-A9B2-006A8D1DE3EB> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib
    0x7fff2b18d000 -     0x7fff2b18dfff  com.apple.Accelerate.vecLib (3.11 - vecLib 3.11) <79C1A1C7-E97A-3B7A-8737-444B402A7AA0> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib
    0x7fff2c8c4000 -     0x7fff2cc3bffb  com.apple.CFNetwork (1120 - 1120) <5EA797F3-2F7A-3E0C-8DBC-DBE145004EC5> /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
    0x7fff2e103000 -     0x7fff2e582fe7  com.apple.CoreFoundation (6.9 - 1673.126) <15D61616-B29B-3BDB-8624-4B84A4956485> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
    0x7fff2f4f0000 -     0x7fff2f4f0fff  com.apple.CoreServices (1069.11 - 1069.11) <C8F86BE7-AAED-30A6-BBC2-550446137E7C> /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
    0x7fff2f4f1000 -     0x7fff2f576ff7  com.apple.AE (838 - 838) <3301AF1B-D178-306A-9641-B57AA03FB1BE> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
    0x7fff2f577000 -     0x7fff2f858fff  com.apple.CoreServices.CarbonCore (1217 - 1217) <FAA1467B-6D39-3EBE-9810-A4DF49478F10> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
    0x7fff2f859000 -     0x7fff2f8a6ffd  com.apple.DictionaryServices (1.2 - 323) <C1798F09-36D3-3C8E-AF72-A3DE63962AF1> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
    0x7fff2f8a7000 -     0x7fff2f8affff  com.apple.CoreServices.FSEvents (1268.40.5 - 1268.40.5) <9BB76885-7CD7-3369-B759-33F7E5DA5392> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/FSEvents.framework/Versions/A/FSEvents
    0x7fff2f8b0000 -     0x7fff2fae9ff0  com.apple.LaunchServices (1069.11 - 1069.11) <88F59BD5-412A-35EE-AD45-E6BF80B24891> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
    0x7fff2faea000 -     0x7fff2fb82ff9  com.apple.Metadata (10.7.0 - 2074.4) <028AC15A-35B7-3E1F-BCDC-470C8EA0CA09> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
    0x7fff2fb83000 -     0x7fff2fbb0ff7  com.apple.CoreServices.OSServices (1069.11 - 1069.11) <A667F007-A599-3869-99F7-1F8460011015> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
    0x7fff2fbb1000 -     0x7fff2fc18fff  com.apple.SearchKit (1.4.1 - 1.4.1) <F0A931E4-0C31-36BA-8DD7-01FDF9813FB7> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
    0x7fff2fc19000 -     0x7fff2fc3dffd  com.apple.coreservices.SharedFileList (131 - 131) <62C3066A-3991-313F-AE2D-75B2B5934D52> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SharedFileList.framework/Versions/A/SharedFileList
    0x7fff3048e000 -     0x7fff30494ff7  com.apple.DiskArbitration (2.7 - 2.7) <A3D2B0A0-3C72-3893-87BF-D45FE398A905> /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
    0x7fff307c6000 -     0x7fff30b8dff4  com.apple.Foundation (6.9 - 1673.126) <470C2315-3047-39BB-BB6B-2C620087091C> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
    0x7fff30f03000 -     0x7fff30fa6ffb  com.apple.framework.IOKit (2.0.2 - 1726.41.1) <FBB4A97B-D7CF-3B8C-932D-672343D63260> /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
    0x7fff3480e000 -     0x7fff3481affe  com.apple.NetFS (6.0 - 4.0) <5C3C3672-2549-316E-9AC6-A1CFDCD16E9C> /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
    0x7fff373e0000 -     0x7fff373fcfff  com.apple.CFOpenDirectory (10.15 - 220.40.1) <AA81FC34-A7F6-3DA2-A275-B34F75099C7B> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory
    0x7fff373fd000 -     0x7fff37408fff  com.apple.OpenDirectory (10.15 - 220.40.1) <ECFA2FFB-D5B6-3916-96F7-9F3A1EB1E534> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory
    0x7fff3a74e000 -     0x7fff3aa94ff6  com.apple.security (7.0 - 59306.41.2) <FB3774D5-C940-35FB-960A-86253A01BDAE> /System/Library/Frameworks/Security.framework/Versions/A/Security
    0x7fff3aa95000 -     0x7fff3ab1dff7  com.apple.securityfoundation (6.0 - 55236) <6482C994-4DB4-320D-8FD4-50C998EA8856> /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation
    0x7fff3ab77000 -     0x7fff3ab7bff8  com.apple.xpc.ServiceManagement (1.0 - 1) <2B80E13A-AFFC-355A-AA82-CCDEF4718E66> /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
    0x7fff3b908000 -     0x7fff3b972ff7  com.apple.SystemConfiguration (1.19 - 1.19) <A52A533D-DA25-3607-A18E-CA7C539E1C52> /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
    0x7fff3f6ce000 -     0x7fff3f792fef  com.apple.APFS (1412.41.1 - 1412.41.1) <0319F563-43AE-3F80-9107-7F0056E726DB> /System/Library/PrivateFrameworks/APFS.framework/Versions/A/APFS
    0x7fff413e0000 -     0x7fff413effdf  com.apple.AppleFSCompression (119 - 1.0) <7EEDBF8A-8812-33D6-A5B0-F7D36825EE73> /System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression
    0x7fff41961000 -     0x7fff41983ffb  com.apple.applesauce (1.0 - 16.22) <EFF69698-9566-3957-B3F5-CEC2B206EE7C> /System/Library/PrivateFrameworks/AppleSauce.framework/Versions/A/AppleSauce
    0x7fff42b92000 -     0x7fff42b9bff3  com.apple.coreservices.BackgroundTaskManagement (1.0 - 104) <5E2B9000-49D6-3BFA-97F1-3B47A8A7418D> /System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/BackgroundTaskManagement
    0x7fff453a6000 -     0x7fff453c5ff4  com.apple.analyticsd (1.0 - 1) <CFAD97DE-F4F0-3A1B-B6FE-855164CC68CC> /System/Library/PrivateFrameworks/CoreAnalytics.framework/Versions/A/CoreAnalytics
    0x7fff45913000 -     0x7fff45923ff3  com.apple.CoreEmoji (1.0 - 107) <8D1CA277-C4F7-3F3B-919E-73B68D39535E> /System/Library/PrivateFrameworks/CoreEmoji.framework/Versions/A/CoreEmoji
    0x7fff45f74000 -     0x7fff45fdeff8  com.apple.CoreNLP (1.0 - 213) <329A9840-CBD8-33A2-A584-2805042284A9> /System/Library/PrivateFrameworks/CoreNLP.framework/Versions/A/CoreNLP
    0x7fff46bf9000 -     0x7fff46c27ff7  com.apple.CSStore (1069.11 - 1069.11) <792520D2-5D81-3867-8DC7-75F8205D5A5B> /System/Library/PrivateFrameworks/CoreServicesStore.framework/Versions/A/CoreServicesStore
    0x7fff52d13000 -     0x7fff52de1ff5  com.apple.LanguageModeling (1.0 - 215) <D3478ED9-A757-355F-A4A0-464E133182D6> /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
    0x7fff52de2000 -     0x7fff52e2aff7  com.apple.Lexicon-framework (1.0 - 72) <94910CCB-C386-3912-84A2-1A730BB6EF62> /System/Library/PrivateFrameworks/Lexicon.framework/Versions/A/Lexicon
    0x7fff52e31000 -     0x7fff52e35ff6  com.apple.LinguisticData (1.0 - 353) <23AF4473-4FDB-39D9-8862-7D23276606A9> /System/Library/PrivateFrameworks/LinguisticData.framework/Versions/A/LinguisticData
    0x7fff54186000 -     0x7fff541d2ff7  com.apple.spotlight.metadata.utilities (1.0 - 2074.4) <8957F147-9371-3728-896E-FC517AC7E86E> /System/Library/PrivateFrameworks/MetadataUtilities.framework/Versions/A/MetadataUtilities
    0x7fff54bf9000 -     0x7fff54c03fff  com.apple.NetAuth (6.2 - 6.2) <BA114B8C-BE33-3DBB-BDC8-25423DBBD3A3> /System/Library/PrivateFrameworks/NetAuth.framework/Versions/A/NetAuth
    0x7fff5d8ed000 -     0x7fff5d8fdff3  com.apple.TCC (1.0 - 1) <87BE8D5C-5D35-3434-8BDF-1615349C7A21> /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
    0x7fff5e033000 -     0x7fff5e034fff  com.apple.TrustEvaluationAgent (2.0 - 33) <4327B52D-2681-3195-B1F8-270D9137F932> /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
    0x7fff61b5a000 -     0x7fff61b5cff3  com.apple.loginsupport (1.0 - 1) <FFE90A0A-BEBC-3032-9368-94C016BE0795> /System/Library/PrivateFrameworks/login.framework/Versions/A/Frameworks/loginsupport.framework/Versions/A/loginsupport
    0x7fff61ecb000 -     0x7fff61f00ff7  libCRFSuite.dylib (48) <CDEA70A4-318B-3990-9AAE-1D7B18132760> /usr/lib/libCRFSuite.dylib
    0x7fff61f03000 -     0x7fff61f0dff3  libChineseTokenizer.dylib (34) <4D68248B-BD40-32E3-ABCA-CE23BCA0A6A4> /usr/lib/libChineseTokenizer.dylib
    0x7fff61f9a000 -     0x7fff61f9cfff  libDiagnosticMessagesClient.dylib (112) <83F42398-DB41-3BB2-B8A1-10D78C4B5778> /usr/lib/libDiagnosticMessagesClient.dylib
    0x7fff62462000 -     0x7fff62463ff3  libSystem.B.dylib (1281) <1DD1BCD2-2C85-3B81-8CAF-224FB042F441> /usr/lib/libSystem.B.dylib
    0x7fff624f3000 -     0x7fff624f4fff  libThaiTokenizer.dylib (3) <22582C9C-3D32-3832-8925-813E4F2BA8DA> /usr/lib/libThaiTokenizer.dylib
    0x7fff6250c000 -     0x7fff62522fff  libapple_nghttp2.dylib (1.39.2) <9B990E6A-D9EB-3F2C-B7CA-085A47D4BC62> /usr/lib/libapple_nghttp2.dylib
    0x7fff62557000 -     0x7fff625c9ff7  libarchive.2.dylib (72.40.2) <25C00824-621A-3FF1-9B6C-52999B6DDF4E> /usr/lib/libarchive.2.dylib
    0x7fff62664000 -     0x7fff62664ff3  libauto.dylib (187) <F4B3519A-A4FC-30E0-805C-70C99BA3FDDA> /usr/lib/libauto.dylib
    0x7fff62722000 -     0x7fff62732fff  libbsm.0.dylib (60) <E57A0CC6-226D-3529-A23A-D5DD6674DB3E> /usr/lib/libbsm.0.dylib
    0x7fff62733000 -     0x7fff6273ffff  libbz2.1.0.dylib (44) <F3D26C17-BC6E-3A83-A3BB-137343C87303> /usr/lib/libbz2.1.0.dylib
    0x7fff62740000 -     0x7fff62793fff  libc++.1.dylib (800.7) <1D42387D-206A-3F06-9B5F-705B83EAC295> /usr/lib/libc++.1.dylib
    0x7fff62794000 -     0x7fff627a8fff  libc++abi.dylib (800.7) <D89ABFBF-3754-35AB-BAEE-FBF14857F79B> /usr/lib/libc++abi.dylib
    0x7fff627a9000 -     0x7fff627a9ffb  libcharset.1.dylib (59) <EC5B95D9-388B-3351-9192-CD6CDB8C3E0F> /usr/lib/libcharset.1.dylib
    0x7fff627aa000 -     0x7fff627bbffb  libcmph.dylib (8) <49C8E101-945E-369B-91D3-2129000DFF35> /usr/lib/libcmph.dylib
    0x7fff627bc000 -     0x7fff627d3fe7  libcompression.dylib (87) <77B35FFD-CE66-3CCA-BEDD-9771D698CEE3> /usr/lib/libcompression.dylib
    0x7fff62aa0000 -     0x7fff62ab6fff  libcoretls.dylib (167) <4F054E37-783A-3FCD-B90B-23A0A83621D9> /usr/lib/libcoretls.dylib
    0x7fff62ab7000 -     0x7fff62ab8ffb  libcoretls_cfhelpers.dylib (167) <62E31BC8-A823-3816-B130-2BB550433203> /usr/lib/libcoretls_cfhelpers.dylib
    0x7fff62c5b000 -     0x7fff62d55fff  libcrypto.35.dylib (47.11.1) <BE850B43-B562-38AD-9A0B-EBDAD26B9875> /usr/lib/libcrypto.35.dylib
    0x7fff63061000 -     0x7fff63062ff7  libcrypto.dylib (47.11.1) <715361EC-D437-3D7F-B6C5-4CB88EFEA47E> /usr/lib/libcrypto.dylib
    0x7fff631e1000 -     0x7fff631e1ff3  libenergytrace.dylib (21) <1CE2BD78-F68E-36A3-BCE9-E9EAB78D9FF3> /usr/lib/libenergytrace.dylib
    0x7fff63209000 -     0x7fff6320bff7  libfakelink.dylib (149) <528A0ABE-B583-3DA1-8E5B-9CA7E89303DE> /usr/lib/libfakelink.dylib
    0x7fff6321a000 -     0x7fff6321ffff  libgermantok.dylib (24) <5E297121-22A7-3A2F-92B9-DD3E5C829CC7> /usr/lib/libgermantok.dylib
    0x7fff6322a000 -     0x7fff6331aff7  libiconv.2.dylib (59) <EB71AC8F-EA44-3BEE-A210-2D92251CA51D> /usr/lib/libiconv.2.dylib
    0x7fff6331b000 -     0x7fff63573ff7  libicucore.A.dylib (64243.0.1) <4CBF52D7-7235-34C8-9FF1-8657076B604F> /usr/lib/libicucore.A.dylib
    0x7fff6358d000 -     0x7fff6358efff  liblangid.dylib (133) <DCC4FA36-0563-3BD2-AE35-9BAF52F5BD98> /usr/lib/liblangid.dylib
    0x7fff6358f000 -     0x7fff635a7ffb  liblzma.5.dylib (16) <7D2522C8-8CBE-32C9-8743-A8F598602F4C> /usr/lib/liblzma.5.dylib
    0x7fff635bf000 -     0x7fff63666fff  libmecab.dylib (883) <FDA0E623-F6F2-3402-B72C-0C60A32C2CC1> /usr/lib/libmecab.dylib
    0x7fff63667000 -     0x7fff638c7ff9  libmecabra.dylib (883) <2E84458F-5748-3A9B-94F3-CAF3C79E6383> /usr/lib/libmecabra.dylib
    0x7fff63d91000 -     0x7fff64203ff4  libnetwork.dylib (1880.40.26) <D8C5B7F0-04D5-3470-A9C4-EF8B2FF96986> /usr/lib/libnetwork.dylib
    0x7fff642a2000 -     0x7fff642d3ff6  libobjc.A.dylib (781) <D866A31E-5CB1-3327-8D22-C4F83C9225D0> /usr/lib/libobjc.A.dylib
    0x7fff642e6000 -     0x7fff642eafff  libpam.2.dylib (25) <02ABA04D-5843-3850-82A3-EBECA6FC2CDF> /usr/lib/libpam.2.dylib
    0x7fff642ed000 -     0x7fff64320ff7  libpcap.A.dylib (89.40.2) <C4F9F5BD-BA21-3038-9665-4D298FB7511C> /usr/lib/libpcap.A.dylib
    0x7fff64416000 -     0x7fff64603ff7  libsqlite3.dylib (308.4) <2D0B1BE5-9B8A-394F-82F7-F612B1A6C73F> /usr/lib/libsqlite3.dylib
    0x7fff64854000 -     0x7fff64857ffb  libutil.dylib (57) <B88D4C21-DAEF-3566-8EAE-5973C51A16FD> /usr/lib/libutil.dylib
    0x7fff64858000 -     0x7fff64865fff  libxar.1.dylib (420) <46AAA43E-6FC6-38A8-B696-62143706D33B> /usr/lib/libxar.1.dylib
    0x7fff6486b000 -     0x7fff6494dff7  libxml2.2.dylib (32.12) <0DB777D9-F9A1-3921-BFCE-05A000293915> /usr/lib/libxml2.2.dylib
    0x7fff64951000 -     0x7fff64979fff  libxslt.1.dylib (16.7) <C30A840F-E7E7-39D5-A633-9C256650B552> /usr/lib/libxslt.1.dylib
    0x7fff6497a000 -     0x7fff6498cfff  libz.1.dylib (76) <3EC7A143-AF2D-35EE-9C08-542B2907E3D2> /usr/lib/libz.1.dylib
    0x7fff653f2000 -     0x7fff653f7ff7  libcache.dylib (83) <74F6459D-3606-3ADB-9808-F6B0FE70062D> /usr/lib/system/libcache.dylib
    0x7fff653f8000 -     0x7fff65403ff7  libcommonCrypto.dylib (60165) <1333752F-5117-3E86-803A-06E166D80C8C> /usr/lib/system/libcommonCrypto.dylib
    0x7fff65404000 -     0x7fff6540bfff  libcompiler_rt.dylib (101.2) <0437EBEF-8191-3912-A365-D6BB75C7A810> /usr/lib/system/libcompiler_rt.dylib
    0x7fff6540c000 -     0x7fff65415fff  libcopyfile.dylib (166.40.1) <7FAF372E-BAD5-30E6-A8F2-A3D06B91DC80> /usr/lib/system/libcopyfile.dylib
    0x7fff65416000 -     0x7fff654adfef  libcorecrypto.dylib (866.40.8) <AE25C9EE-5D63-3E49-B3AA-D482D35C085A> /usr/lib/system/libcorecrypto.dylib
    0x7fff655c4000 -     0x7fff65605ff0  libdispatch.dylib (1173.40.5) <1FF421B6-4BF0-3B5F-8F56-5ED3B3EFE06F> /usr/lib/system/libdispatch.dylib
    0x7fff65606000 -     0x7fff6563bfff  libdyld.dylib (733.6) <2FA4B359-624B-337C-9207-CDCF841C2E52> /usr/lib/system/libdyld.dylib
    0x7fff6563c000 -     0x7fff6563cffb  libkeymgr.dylib (30) <7EEF9246-30B4-34DD-8AD6-79679D1A7784> /usr/lib/system/libkeymgr.dylib
    0x7fff6563d000 -     0x7fff65649ff7  libkxld.dylib (6153.41.3) <F9FF90CE-DCB0-3918-882F-6E475A6E244A> /usr/lib/system/libkxld.dylib
    0x7fff6564a000 -     0x7fff6564aff7  liblaunch.dylib (1738.40.10) <CC02D5B3-A95D-3B16-8EE5-D62521CFE899> /usr/lib/system/liblaunch.dylib
    0x7fff6564b000 -     0x7fff65650ff7  libmacho.dylib (949.0.1) <6C3E49B2-594D-3B9D-82DB-C4ABEB9788AB> /usr/lib/system/libmacho.dylib
    0x7fff65651000 -     0x7fff65653ff3  libquarantine.dylib (110.40.3) <A1BCAA32-A194-3DBE-9930-8F49A4AEF284> /usr/lib/system/libquarantine.dylib
    0x7fff65654000 -     0x7fff65655ff7  libremovefile.dylib (48) <DD7AE862-F179-3C07-A4FC-5775DDD4D3E6> /usr/lib/system/libremovefile.dylib
    0x7fff65656000 -     0x7fff6566dfff  libsystem_asl.dylib (377.40.1) <ECE44856-D279-3B5D-A0AA-8BE421D200C4> /usr/lib/system/libsystem_asl.dylib
    0x7fff6566e000 -     0x7fff6566efff  libsystem_blocks.dylib (74) <DC521115-905A-3A0D-9337-C55FACCEA85F> /usr/lib/system/libsystem_blocks.dylib
    0x7fff6566f000 -     0x7fff656f6ff7  libsystem_c.dylib (1353.41.1) <5AD50779-955E-3F56-BCB9-1E14833B3455> /usr/lib/system/libsystem_c.dylib
    0x7fff656f7000 -     0x7fff656fafff  libsystem_configuration.dylib (1061.40.2) <7A2329E0-3C84-3DB7-BC32-E7796C50D621> /usr/lib/system/libsystem_configuration.dylib
    0x7fff656fb000 -     0x7fff656feff7  libsystem_coreservices.dylib (114) <DF341577-A307-3722-BB24-D4AACEAB19B3> /usr/lib/system/libsystem_coreservices.dylib
    0x7fff656ff000 -     0x7fff65706fff  libsystem_darwin.dylib (1353.41.1) <E862B5B1-A367-39CA-8319-B2F9DFADF606> /usr/lib/system/libsystem_darwin.dylib
    0x7fff65707000 -     0x7fff6570effb  libsystem_dnssd.dylib (1096.40.7) <2A9C6F3E-427B-332E-BDD3-D4651306F3DE> /usr/lib/system/libsystem_dnssd.dylib
    0x7fff6570f000 -     0x7fff65710ffb  libsystem_featureflags.dylib (17) <B94C0052-B75A-3169-80AA-5F480588AF6E> /usr/lib/system/libsystem_featureflags.dylib
    0x7fff65711000 -     0x7fff6575eff7  libsystem_info.dylib (538) <18CC56C5-5325-3375-BF99-FAE7F4F19DDD> /usr/lib/system/libsystem_info.dylib
    0x7fff6575f000 -     0x7fff6578bff7  libsystem_kernel.dylib (6153.41.3) <18918E9C-45BC-3D5A-A6B6-3DBC60EEE2E1> /usr/lib/system/libsystem_kernel.dylib
    0x7fff6578c000 -     0x7fff657d3ff7  libsystem_m.dylib (3178) <636A1A1C-7AFC-3E82-B86B-0173912A3437> /usr/lib/system/libsystem_m.dylib
    0x7fff657d4000 -     0x7fff657fbff7  libsystem_malloc.dylib (283.40.1) <F82A587B-44A2-3699-A218-9D3ECEE23D5A> /usr/lib/system/libsystem_malloc.dylib
    0x7fff657fc000 -     0x7fff65809ff3  libsystem_networkextension.dylib (1095.40.22) <7F206A43-A941-3BAB-AE3A-16169F2FE6AB> /usr/lib/system/libsystem_networkextension.dylib
    0x7fff6580a000 -     0x7fff65813fff  libsystem_notify.dylib (241) <C95CC58E-35E7-3828-AA2A-6EED73C12DE5> /usr/lib/system/libsystem_notify.dylib
    0x7fff65814000 -     0x7fff6581dfe7  libsystem_platform.dylib (220) <0CCDD81F-0891-3400-8A97-6CAC3BBBE2F9> /usr/lib/system/libsystem_platform.dylib
    0x7fff6581e000 -     0x7fff65828ff7  libsystem_pthread.dylib (416.40.3) <53C65598-9E9E-36FF-BDC2-74F228E58C5C> /usr/lib/system/libsystem_pthread.dylib
    0x7fff65829000 -     0x7fff6582dffb  libsystem_sandbox.dylib (1217.41.1) <2183D15E-2CFD-3160-80CE-A948F0529005> /usr/lib/system/libsystem_sandbox.dylib
    0x7fff6582e000 -     0x7fff65830fff  libsystem_secinit.dylib (62.40.2) <D2782294-ACDC-30FF-A794-B4C1B324526B> /usr/lib/system/libsystem_secinit.dylib
    0x7fff65831000 -     0x7fff65838ffb  libsystem_symptoms.dylib (1238.40.4) <A44E4405-E22E-32E9-83DE-8C7A82401DA0> /usr/lib/system/libsystem_symptoms.dylib
    0x7fff65839000 -     0x7fff6584fff2  libsystem_trace.dylib (1147.40.13) <376CC435-E656-37D9-A5FF-C49B6E4525E2> /usr/lib/system/libsystem_trace.dylib
    0x7fff65851000 -     0x7fff65856ffb  libunwind.dylib (35.4) <44448F1F-08E5-3425-ADBA-C38A9E8F90C7> /usr/lib/system/libunwind.dylib
    0x7fff65857000 -     0x7fff6588bff6  libxpc.dylib (1738.40.10) <99CC9436-D653-3762-ADBB-9054EBD1BA2B> /usr/lib/system/libxpc.dylib

Thank in advance for any help you can provide.

Examples of TLS/SSL server validation

This is the provided example for TLS/SSL server validation in documentation:

from oscrypto import tls
from certvalidator import CertificateValidator, errors

session = tls.TLSSession(manual_validation=True)
connection = tls.TLSSocket('www.google.com', 443, session=session)

try:
validator = CertificateValidator(connection.certificate, connection.intermediates)
validator.validate_tls(connection.hostname)
except (errors.PathValidationError):
# The certificate did not match the hostname, or could not be otherwise validated

However, validator.validate_tls() returns a certvalidator.path.ValidationPath instance and none of its attributes tells whether the tls/ssl to hostname is valid or not. Am I missing something here? How are others consuming this method?

`allow_fetching=True` together with `moment`

I was wondering, in the comment you write:

If certificate validation should be performed based on a date and time other than right now. A datetime.datetime object with a tzinfo value. If this parameter is specified, then the only way to check OCSP and CRL responses is to pass them via the crls and ocsps parameters. Can not be combined with allow_fetching=True.

Why is this? What is wrong with fetching CRLs etc. with some defined moment? This restriction doesn't allow the CRL verification of any digital signature that has a timestamp certificate in it, since when there's a timestamp certificate, the moment is defined by that certificate, and not by current time.

CRLValidationError raised from validate.verify_crl is not handled

When the certificate path of a CRL issuer could not be validated, validate.verify_crl raises a CRLValidationError:

raise CRLValidationError('CRL issuer certificate path could not be validated')

On the other hand, code calling verify_crl handles only derived errors (CRLValidationIndeterminateError and CRLNoMatchesError), not CRLValidationError itself:

try:
cert_description = _cert_type(index, last_index, end_entity_name_override, definite=True)
verify_crl(
cert,
path,
validation_context,
cert_description=cert_description,
end_entity_name_override=end_entity_name_override
)
revocation_check_failed = False
status_good = True
matched = True
except (CRLValidationIndeterminateError) as e:
failures.extend([failure[0] for failure in e.failures])
revocation_check_failed = True
matched = True
except (SoftFailError):
soft_fail = True
except (CRLNoMatchesError):
pass

This way CRLValidationError may escape from certvalidator, which is probably not intentional and is not documented.

verify_ocsp_response() assumes OCSP response has reason

When performing OCSP revocation checks against https://revoked.badssl.com/ using the function certvalidator.validate.verify_ocsp_response() I get the following:

Traceback (most recent call last):
...
  File "/.../venv/lib/python3.6/site-packages/certvalidator/validate.py", line 1101, in verify_ocsp_response
    reason = revocation_info['revocation_reason'].human_friendly
AttributeError: 'Void' object has no attribute 'human_friendly'

It seems that the function assumes that a revocation reason is given, whereas the RFC states (end of https://tools.ietf.org/html/rfc6960#section-4.2.1) that revocation reason is optional (revocationReason [0] EXPLICIT CRLReason OPTIONAL), and hence revocation_info['revocation_reason'] can be an instance of Void. I would therefore suggest that verify_ocsp_response() should check whether revocation_info['revocation_reason'] is Void first before trying get the human_friendly property, or that Void should have a human_friendly property.

OCSPValidationError is not handled

When certvalidator fetches an OCSP response, but request and response nonces do not match OCSPValidationError is raised:

raise errors.OCSPValidationError(
'Unable to verify OCSP response since the request and response nonces do not match'
)

However, this error is neither caught (and handled), nor documented.

Note: Other OCSP related errors are converted into derived exceptions (OCSPValidationIndeterminateError and OCSPNoMatchesError) which are handled in validate._validate_path:

try:
verify_ocsp_response(
cert,
path,
validation_context,
cert_description=_cert_type(
index,
last_index,
end_entity_name_override,
definite=True
),
end_entity_name_override=end_entity_name_override
)
status_good = True
matched = True
except (OCSPValidationIndeterminateError) as e:
failures.extend([failure[0] for failure in e.failures])
revocation_check_failed = True
matched = True
except (SoftFailError):
soft_fail = True
except (OCSPNoMatchesError):
pass

However, its not clear for me how not matching nonces should be handled at the end.

CRL fetch SSL check fail

When the CRL fetch is performed I’m receiving an HTTPS SSL handshake failure error.

I think this is because the fetch is done by the urllib module and this doesn’t have the certificates (that I’ve registered with the validator. via the intermediates arg) they are required for the CA which is over HTTPS signed using the same certificate chain.

What’s the correct approach to this situation?

Validation fails if subject_alt_name extension is critical

Validation of no-subject.badssl.com certificate chain causes the following Python traceback.

Traceback (most recent call last):
  File "//no-subject.py", line 151, in <module>
    cert_validator.validate_usage(set())
  File "/usr/local/lib/python3.11/site-packages/certvalidator/__init__.py", line 193, in validate_usage
    self._validate_path()
  File "/usr/local/lib/python3.11/site-packages/certvalidator/__init__.py", line 128, in _validate_path
    raise exceptions[0]
  File "/usr/local/lib/python3.11/site-packages/certvalidator/__init__.py", line 121, in _validate_path
    validate_path(self._context, candidate_path)
  File "/usr/local/lib/python3.11/site-packages/certvalidator/validate.py", line 50, in validate_path
    return _validate_path(validation_context, path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/certvalidator/validate.py", line 684, in _validate_path
    raise PathValidationError(pretty_message(
certvalidator.errors.PathValidationError: The path could not be validated because the end-entity certificate contains the following unsupported critical extension: subject_alt_name

I used the following versions:

  • python: 3.11.3
  • certvalidator: 0.11.1
  • asn1crypto: 1.5.1
  • oscrypto: 1.3.0

You can use the following code to reproduce the issue:

import asn1crypto.pem
import asn1crypto.x509
import certvalidator


NO_SUBJECT_BADSSL_COM_LEAF_CERTIFICATE = asn1crypto.x509.Certificate.load(asn1crypto.pem.unarmor(b"""
 0 s:
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = UbiquiTLS\\E2\\84\\A2 DV RSA Server CA
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Mar 17 00:00:00 2017 GMT; NotAfter: Jun 16 23:59:59 2020 GMT
-----BEGIN CERTIFICATE-----
MIIGdTCCBV2gAwIBAgIQI+ZPIMN8DYcQH3GS78XTcjANBgkqhkiG9w0BAQsFADCB
gDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJjAkBgNV
BAMMHVViaXF1aVRMU+KEoiBEViBSU0EgU2VydmVyIENBMB4XDTE3MDMxNzAwMDAw
MFoXDTIwMDYxNjIzNTk1OVowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2PmzAS2BMTOqytMAP
gLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMWhyefdOsKnRFSJiFz
bIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3AxPxTuW1CrbV8/q71
FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqveww9HdFxBIuGa+RuT
5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SYQCeFxxC7c3DvaRhB
B0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaOCA2gwggNkMB8GA1UdIwQYMBaAFDgS
xnkCZjgC4zck5YsP/0WVaeYxMB0GA1UdDgQWBBSd7sF7gQs6R2lxGH0RN5O8pRs/
+zAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwUAYDVR0gBEkwRzA7BgwrBgEEAbIxAQIBAwQwKzApBggr
BgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLm5ldC9DUFMwCAYGZ4EMAQIB
MHQGCCsGAQUFBwEBBGgwZjA+BggrBgEFBQcwAoYyaHR0cDovL2NydC5jb21vZG9j
YS5jb20vVWJpcXVpVExTRFZSU0FTZXJ2ZXJDQS5jcnQwJAYIKwYBBQUHMAGGGGh0
dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTAjBgNVHREBAf8EGTAXghVuby1zdWJqZWN0
LmJhZHNzbC5jb20wggH2BgorBgEEAdZ5AgQCBIIB5gSCAeIB4AB2AKS5CZC0GFgU
h7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABWt5t4gUAAAQDAEcwRQIhAIQE7oHj
PQvtURUCoh6+dM8GdC6OEfAANupRYHYMo6a8AiBgL5fwtsOp+XR8vQ8XkMKMXYRs
0awe+B3ZNuIaXGmEWQB3AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+UmFXWidDd
AAABWt5t4CwAAAQDAEgwRgIhAIlY3Jz655VWCZm6WMoEcU2nExX1pyK8SL7oj+fp
3HmPAiEAmHu87c0EInS/wDJrnbiSWzyc47UM2xr3kYhY/lP8OVwAdQDuS723dc5g
uuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAVrebeHfAAAEAwBGMEQCIFMOvF7H
hM3jdnhdM2BwMohT35uuzrGL3DNJhmKtqTg8AiBL8Mjn00eDbR4a1HKipKgmvt87
MfXLexBSoRb/lgXT5QB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGF
AAABWt56EsgAAAQDAEcwRQIhAN7MnjhZoLr3ci0nNfSZ9Ftu/+FT+N3gIfC75fyw
XQR+AiAiExEXXf+G09W8F93gJDPZwC7bM2VoWb1bZlkVcvtRdTANBgkqhkiG9w0B
AQsFAAOCAQEAHv5koaT/MZ+zhKQs+6fHJDgTQ2+66u8k6PKQLV3OcfFusJBt/TrD
P/nNgidru2vObn5NUu2MydVrCfoKwK8hf+7j+fjyLSKZYOvrqhRnN0svqlrX4wWC
01rrEttc5H8UNf/oaylbOG4vePw8bF5n2aiU4vmGkuTPIkvqxtZ6IJjxqSQqaRhA
ZRc7d/YAS+MyFF5JXAo9aSyi+AIvhFeTFi+0nmzPwp6wpxz97ylm6DymFMY3IqmP
RYq4/yqbWE2yz4tRfnedeWBzGSAO4kWDQIN6NDjYwVjGsTk9rSpq/sEtPhUrXWB0
yd8BGrY2DQplAarq7e1IBIK+tBSRIYF3Ag==
-----END CERTIFICATE-----
""")[2])


NO_SUBJECT_BADSSL_COM_INTERMEDIATE_CA = asn1crypto.x509.Certificate.load(asn1crypto.pem.unarmor(b"""
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = UbiquiTLS\\E2\\84\\A2 DV RSA Server CA
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384
   v:NotBefore: Mar 29 00:00:00 2016 GMT; NotAfter: Mar 29 23:59:59 2031 GMT
-----BEGIN CERTIFICATE-----
MIIF+TCCA+GgAwIBAgIRALEh69i9ODvCDLdUvBhDX/swDQYJKoZIhvcNAQEMBQAw
gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD
VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE2MDMy
OTAwMDAwMFoXDTMxMDMyOTIzNTk1OVowgYAxCzAJBgNVBAYTAkdCMRswGQYDVQQI
ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoT
EUNPTU9ETyBDQSBMaW1pdGVkMSYwJAYDVQQDDB1VYmlxdWlUTFPihKIgRFYgUlNB
IFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL23CxiN
bAfZclMlGi9tHpl6dCSxT4yRM79i/h3u/HbErdS+3jiq9oPZfCqgbJ0PVIOBelGb
EhvBBbkW/wPlDq3vEEt9nP/P3cRVGu+i0X/puXA51E5TgrEn5/jdorBANmhItrG4
uZietPJmFx6awA3ANC2MVnvmT1s5qS0cnrdFh2rLRwfANm4S0UbJNpHSItFinh0J
XtQFyc/QE+fGAH1sC8aW34Rt+qQ1+msY7hvNpXKZLR8Fy5AVi089iv5cK8bqzVaQ
F8kJTiukJ9vQ/e9CC7x9/TxX/oYn5bIejxsaoGPi1BgeRkS7J42MeNpYmh7kUFN6
ZZm5Yh8OB571L30CAwEAAaOCAWUwggFhMB8GA1UdIwQYMBaAFLuvfgI9+qbxPISO
re44mOzZMjLUMB0GA1UdDgQWBBQ4EsZ5AmY4AuM3JOWLD/9FlWnmMTAOBgNVHQ8B
Af8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgGBmeBDAECATBMBgNVHR8E
RTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDZXJ0
aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcBAQRlMGMwOwYIKwYBBQUH
MAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUFkZFRydXN0Q0Eu
Y3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
hvcNAQEMBQADggIBAC3C7NUxneoMxtAT5QcdKTxVO2TmjbQtmYaZ6b06ySZC+RZm
GrktbzTwGh0jb33K/Wx9X1GXhsZIACgZM9bbeopskqlg/x5UDtHzaDWs+XtWMhET
aRtQRyRJ6bxTU64DSjnHbgLedToXmA2H8BF+DrRwEGG0twg9EjhIOJbvJ8Jcsdzh
b2hE4w48VwpQzH+Sg78TnGr6MimbnkFpuE+DO5q/x2AmeuOdmcl/3ufs3EjKeJTr
ybyjutGfI+LM3UTw1FhVzeMUPJBrebiy8tTP2/Rn8sJRdK3J+lmfY+sgfkcpXjMO
PA8esFM43Wawn2fLaQALi0Vpm36oc9ECIqjAunxQ/OmLl2uSvERNln/hmSlKvPEY
vA7lUXzRAxbpR0K7n+GBOMvkT9n1JGscHR9Oy3QGVksCT5bVvuGhH9m6BM3lnskp
3eyOXy0PpT9eJVflrpA8HVcJXGNCFDBT3iWUtHXXfopJvBe6RcEyu7aLWPNJ0/wM
n+EdLjUShlFqczNfw15eAdnTHkPCFW588pj7Hz0MaTeIqOBZWTHvc/BADJbRZuh7
jVXvr24Pv15WVEt/GKqm+VkvusRTVMVQm9fDH8rBIxBmpzt0uBTcg8IWY8HtGfEt
5R+qkfsm6EWtj4APtivR5qC2mzEDxbZSlduxifzG194rAGGbcn2KeOA0QwNE
-----END CERTIFICATE-----
""")[2])


NO_SUBJECT_BADSSL_COM_ROOT_CA = asn1crypto.x509.Certificate.load(asn1crypto.pem.unarmor(b"""
 2 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
   i:C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384
   v:NotBefore: May 30 10:48:38 2000 GMT; NotAfter: May 30 10:48:38 2020 GMT
-----BEGIN CERTIFICATE-----
MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow
gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD
VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq
hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw
AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6
2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr
ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt
4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq
m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/
vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT
8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE
IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO
KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO
GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/
s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g
JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD
AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9
MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy
bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6
Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ
zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj
Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY
Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5
B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx
PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR
pu/xO28QOG8=
-----END CERTIFICATE-----
""")[2])


no_common_name_badssl_com_certificate_chain = (
    NO_SUBJECT_BADSSL_COM_ROOT_CA,
    NO_SUBJECT_BADSSL_COM_INTERMEDIATE_CA,
    NO_SUBJECT_BADSSL_COM_LEAF_CERTIFICATE,
)

context = certvalidator.context.ValidationContext(
    whitelisted_certs=list(map(
        lambda certificate: certificate.sha1_fingerprint, no_common_name_badssl_com_certificate_chain
    )),
    trust_roots=[NO_SUBJECT_BADSSL_COM_ROOT_CA],
)
cert_validator = certvalidator.CertificateValidator(
    end_entity_cert=NO_SUBJECT_BADSSL_COM_LEAF_CERTIFICATE,
    intermediate_certs=[NO_SUBJECT_BADSSL_COM_INTERMEDIATE_CA],
    validation_context=context,
)
cert_validator.validate_usage(set())

Please use the following patch just as a hint:

diff --git a/certvalidator/validate.py b/certvalidator/validate.py
index b0cfb05..61693ef 100644
--- a/certvalidator/validate.py
+++ b/certvalidator/validate.py
@@ -677,6 +677,7 @@ def _validate_path(validation_context, path, end_entity_name_override=None):
             'certificate_policies',
             'policy_mappings',
             'policy_constraints',
+            'subject_alt_name',
             'inhibit_any_policy',
         ])
         unsupported_critical_extensions = cert.critical_extensions - supported_extensions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.