MatthiasValvekens / pyHanko

pyHanko: sign and stamp PDF files
MIT License
460 stars 68 forks source link

Certvalidator report crl as good with one trust root, but invalid with two roots #417

Open peteris-zealid opened 3 months ago

peteris-zealid commented 3 months ago

It is possible to make crl validation fail by adding an extra trust root to validation context. The particular roots are taken from ICAO masterlist. A minimal example for reproducing the problem is attached. It depends on cryptography < 42.x.x

crl_validation_problem.py.txt

I would expect that extra trust roots in validation context cannot make validation fail.

MatthiasValvekens commented 3 months ago

Hi @peteris-zealid,

I'm having some issues reproducing this against cryptography 41.0.7. Can you post a stack trace and a pip freeze of the environment where you encounter this issue?

peteris-zealid commented 3 months ago

Pip freeze:

asn1crypto==1.5.1
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cryptography==41.0.7
idna==3.6
oscrypto==1.3.0
pycparser==2.22
pyHanko==0.21.0
pyhanko-certvalidator==0.26.3
pypng==0.20220715.0
PyYAML==6.0.1
qrcode==7.4.2
requests==2.31.0
typing_extensions==4.11.0
tzlocal==5.2
uritools==4.0.2
urllib3==2.2.1

Random environment info

zsh 76504 % python --version
Python 3.11.6

zsh 76508 % ll venv/bin/python3.11 
lrwxr-xr-x  1 peterisratnieks  staff  44 Apr 10 10:57 venv/bin/python3.11@ -> /opt/homebrew/opt/python@3.11/bin/python3.11

zsh 76506 % echo $OSTYPE 
darwin23.0

zsh 76509 % openssl --version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

Took the liberty to add some print statements before the failing assert

        print("==========")
        print(type(pub_key))
        print(issubclass(type(pub_key), ec.EllipticCurvePublicKey))
        print("==========")
        assert isinstance(pub_key, ec.EllipticCurvePublicKey)

Stack trace

zsh 76511 % python crl_validation_problem.py two_roots
==========
<class 'cryptography.hazmat.backends.openssl.ec._EllipticCurvePublicKey'>
True
==========
==========
<class 'cryptography.hazmat.backends.openssl.rsa._RSAPublicKey'>
False
==========
Traceback (most recent call last):
  File "/Users/peterisratnieks/reproduce_pyhanko/crl_validation_problem.py", line 68, in check_revocation
    asyncio.run(_check_revocation(cert, validation_context, path, proc_state))
  File "/opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/validate.py", line 1362, in _check_revocation
    await verify_crl(
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/revinfo/validate_crl.py", line 1072, in verify_crl
    interim_reasons = await _handle_single_crl(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/revinfo/validate_crl.py", line 581, in _handle_single_crl
    crl_issuer_path = await _find_crl_issuer(
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/revinfo/validate_crl.py", line 263, in _find_crl_issuer
    candidate_paths, errs = await _find_candidate_crl_paths(
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/revinfo/validate_crl.py", line 232, in _find_candidate_crl_paths
    _verify_crl_signature(
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/revinfo/validate_crl.py", line 1336, in _verify_crl_signature
    validate_sig(
  File "/Users/peterisratnieks/reproduce_pyhanko/venv/lib/python3.11/site-packages/pyhanko_certvalidator/util.py", line 259, in validate_sig
    assert isinstance(pub_key, ec.EllipticCurvePublicKey)
AssertionError

AssertionError()