Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x509 Verification: base Python support for extension policies #12432

Merged
merged 7 commits into from
Feb 11, 2025

Conversation

deivse
Copy link
Contributor

@deivse deivse commented Feb 11, 2025

No description provided.

Copy link
Member

@alex alex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good, so I'm going to merge as is.

However, I'm not wild about the name rust_policy, since it's all Rust code! What do you think about inner_policy?

@alex alex enabled auto-merge (squash) February 11, 2025 13:51
@alex alex merged commit 5c3219d into pyca:main Feb 11, 2025
64 checks passed
@deivse
Copy link
Contributor Author

deivse commented Feb 11, 2025

Code looks good, so I'm going to merge as is.

However, I'm not wild about the name rust_policy, since it's all Rust code! What do you think about inner_policy?

Yeah that makes sense. I'll rename it in the next PR.

@deivse
Copy link
Contributor Author

deivse commented Feb 11, 2025

Actually I'll make a separate PR. It's a very small change but the other PR is still quite large so I'll try to avoid cluttering it as much as possible.

@@ -201,6 +201,9 @@ class PolicyBuilder:
def time(self, new_time: datetime.datetime) -> PolicyBuilder: ...
def store(self, new_store: Store) -> PolicyBuilder: ...
def max_chain_depth(self, new_max_chain_depth: int) -> PolicyBuilder: ...
def extension_policies(
self, new_ca_policy: ExtensionPolicy, new_ee_policy: ExtensionPolicy
Copy link

@bluetech bluetech Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might I suggest making new_ca_policy and new_ee_policy keyword-only arguments?

  • It will force calling code to be clearer to readers, which I think is good.
  • It will avoid possible confusion between the two parameters, which have the same type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #12476 to address this.

@alex
Copy link
Member

alex commented Feb 15, 2025 via email

@deivse
Copy link
Contributor Author

deivse commented Feb 15, 2025

If not, I can make a PR. Should be quick.

@bluetech
Copy link

@deivse please do, thanks!

BTW, I am testing this and it works well so far!

@bluetech
Copy link

Two more comments from testing:


When I run mypy which has python_version = 3.9 config, it complains:

venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi:229: error: Type parameter lists are only supported in Python 3.12 and greater  [syntax]

that's on this code:

type MaybeExtensionValidatorCallback[T: x509.ExtensionType] = typing.Callable[
[
Policy,
x509.Certificate,
T | None,
],
None,
]
type PresentExtensionValidatorCallback[T: x509.ExtensionType] = (
typing.Callable[
[Policy, x509.Certificate, T],
None,
]
)

with mypy 1.11.2, but I also tried with mypy 1.15.0 and it still complains. So it's probably best to avoid the new Python 3.12 syntax?


The py_webauthn tests use a x509 v1 certificate, which the verification doesn't like even with permit_all extension policy:

E   cryptography.hazmat.bindings._rust.x509.VerificationError: validation failed: certificate must be an X509v3 certificate (encountered processing <Certificate(subject=<Name(C=US,ST=MI,L=AA,O=DuoSecurity,OU=SafetyNetTesting,CN=attest.android.com)>, ...)>)

But, I'm not sure if it's a realistic certificate or just a test thing. I will try to ask the py_webauthn author. Here is the cert for reference

Details

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 10 (0xa)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=MI, L=AA, O=DuoSecurity, OU=SafetyNetTesting, CN=SafetynetTestCA
        Validity
            Not Before: Oct 18 20:26:51 2019 GMT
            Not After : Mar 20 20:26:51 2046 GMT
        Subject: C=US, ST=MI, L=AA, O=DuoSecurity, OU=SafetyNetTesting, CN=attest.android.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:dc:a3:f1:87:97:8d:f9:3b:60:45:78:d5:1a:b7:
                    69:a7:fd:8e:56:17:63:10:01:f6:d0:96:9a:94:56:
                    c9:54:37:d6:0d:ad:15:90:5d:36:17:ef:32:8d:d7:
                    b4:9d:42:b7:99:48:d9:de:de:fb:79:55:c2:7a:7f:
                    a3:3e:67:be:1d:48:fc:e0:f4:f7:bb:c1:15:c4:ab:
                    56:3a:87:70:c0:78:3b:5c:cd:37:c5:ba:03:77:a7:
                    e1:1b:6b:e3:0a:aa:2d:7f:a1:3f:33:b1:2f:b6:fe:
                    db:15:cc:25:36:73:8e:f2:05:3f:8e:55:06:b4:4a:
                    20:65:17:67:b3:d7:00:43:e5:34:08:0f:ec:55:da:
                    9f:5c:7d:89:e5:73:45:c9:8e:08:35:ac:37:a7:18:
                    da:91:a2:cb:43:8f:1d:a3:31:e6:d7:9e:8f:8d:43:
                    77:dc:ee:61:8b:aa:4a:1d:b4:17:c3:99:c1:a9:c6:
                    ad:f0:f6:33:cf:0b:f7:26:e9:28:72:33:78:7d:7a:
                    db:a8:ec:69:55:53:35:e7:f6:de:ef:e7:c1:2f:24:
                    c6:eb:24:6e:b4:cf:e3:85:49:af:48:96:8c:12:b1:
                    7d:3d:3a:8d:1e:87:15:c5:64:a9:c8:5a:ff:b6:d2:
                    45:38:30:7a:95:26:9d:b7:c5:76:c7:21:67:bf:9d:
                    fc:03
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        58:ec:51:10:44:ac:dd:1e:d3:90:58:15:2d:84:13:b6:c5:c9:
        5b:14:d4:73:ce:08:c8:26:4b:b2:b8:ea:63:5d:58:54:2f:30:
        ec:ac:b4:69:11:0f:b2:9f:fa:38:aa:bd:ac:f2:7a:be:46:52:
        76:11:f6:f0:5e:46:45:49:ec:d1:5f:72:1f:f0:34:8f:b4:a6:
        2e:d3:e3:de:99:70:0d:c1:27:38:f1:23:9a:ab:b4:d7:4f:1d:
        c4:25:e8:62:80:f0:67:dd:e6:0d:c4:0a:b4:fa:f2:1e:d9:64:
        28:48:43:21:94:2c:93:16:a5:52:1c:ff:03:8e:42:3e:77:6f:
        11:4f:13:6b:52:11:50:57:88:82:f3:37:1c:7a:2e:77:8b:d6:
        28:19:d0:5b:2e:5a:14:b0:80:43:fe:52:9e:17:3d:7e:ef:3e:
        6b:e1:b3:40:a8:cd:3f:2c:5a:5a:00:f0:1b:25:80:27:62:8b:
        24:7d:7b:c1:40:e3:20:e7:50:cd:50:66:9a:b6:00:c4:4f:2e:
        cb:c8:a7:98:01:c1:66:92:83:3e:35:88:9e:01:36:2f:0c:91:
        90:4e:ac:80:2b:12:d4:b9:a9:cd:47:8d:cc:5f:21:68:83:85:
        1e:32:d7:68:e9:1e:7c:15:e1:ec:d4:b6:c9:93:fa:9b:f5:89:
        40:f4:41:eb
-----BEGIN CERTIFICATE-----
MIIDWzCCAkMCAQowDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxCzAJBgNV
BAgMAk1JMQswCQYDVQQHDAJBQTEUMBIGA1UECgwLRHVvU2VjdXJpdHkxGTAXBgNV
BAsMEFNhZmV0eU5ldFRlc3RpbmcxGDAWBgNVBAMMD1NhZmV0eW5ldFRlc3RDQTAe
Fw0xOTEwMTgyMDI2NTFaFw00NjAzMjAyMDI2NTFaMHUxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJNSTELMAkGA1UEBwwCQUExFDASBgNVBAoMC0R1b1NlY3VyaXR5MRkw
FwYDVQQLDBBTYWZldHlOZXRUZXN0aW5nMRswGQYDVQQDDBJhdHRlc3QuYW5kcm9p
ZC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDco/GHl435O2BF
eNUat2mn/Y5WF2MQAfbQlpqUVslUN9YNrRWQXTYX7zKN17SdQreZSNne3vt5VcJ6
f6M+Z74dSPzg9Pe7wRXEq1Y6h3DAeDtczTfFugN3p+Eba+MKqi1/oT8zsS+2/tsV
zCU2c47yBT+OVQa0SiBlF2ez1wBD5TQID+xV2p9cfYnlc0XJjgg1rDenGNqRostD
jx2jMebXno+NQ3fc7mGLqkodtBfDmcGpxq3w9jPPC/cm6ShyM3h9etuo7GlVUzXn
9t7v58EvJMbrJG60z+OFSa9IlowSsX09Oo0ehxXFZKnIWv+20kU4MHqVJp23xXbH
IWe/nfwDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFjsURBErN0e05BYFS2EE7bF
yVsU1HPOCMgmS7K46mNdWFQvMOystGkRD7Kf+jiqvazyer5GUnYR9vBeRkVJ7NFf
ch/wNI+0pi7T496ZcA3BJzjxI5qrtNdPHcQl6GKA8Gfd5g3ECrT68h7ZZChIQyGU
LJMWpVIc/wOOQj53bxFPE2tSEVBXiILzNxx6LneL1igZ0FsuWhSwgEP+Up4XPX7v
Pmvhs0CozT8sWloA8BslgCdiiyR9e8FA4yDnUM1QZpq2AMRPLsvIp5gBwWaSgz41
iJ4BNi8MkZBOrIArEtS5qc1HjcxfIWiDhR4y12jpHnwV4ezUtsmT+pv1iUD0Qes=
-----END CERTIFICATE-----

@deivse
Copy link
Contributor Author

deivse commented Feb 16, 2025

Hi @bluetech, glad you're finding this useful!

Some observations regarding the first point:

  • Running mypy using python3.9 with python_version = 3.9 set in configresults in a genericerror: invalid syntax [syntax]`
  • Changing python_version = 3.13 in config changes the error message to error: invalid syntax; you likely need to run mypy using Python 3.13 or newer [syntax]
  • Using a newer python (3.13) with python_version = 3.9 set in config results in the original error @bluetech encountered: Type parameter lists are only supported in Python 3.12 and greater [syntax]
  • And using both new python and python_version >= 3.12 of course works.

However, this behaviour only occurs with type parameter lists. The T1 | T2 syntax, which is only supported in python>=3.10 according to mypy docs has been used in x509.pyi for a long time already and doesn't seem to result in any errors, even when running mypy using python3.9 with python_version = 3.9 in config.

I had some doubts about this initially, but me and Alex eventually agreed that this should work since it's only in a .pyi file, and it does seem to work, but only with some syntax?.. 😄 I'm wondering if this behaviour is intended or if we should open an issue with mypy. @alex, any thoughts? I think I should make a PR that fixes this in cryptography either way though.

@deivse
Copy link
Contributor Author

deivse commented Feb 16, 2025

Regarding the x509 v1 certificate, that is intended behaviour. cryptography does still support only x509v3 certs, and a custom ExtensionPolicy can't change that, since it's a core requirement that's not currently user customisable. I'd wager there are no plans to support x509v1 to be honest, but @alex can once again elaborate.

@reaperhulk
Copy link
Member

That’s correct, we don’t support v1 and have no current plans to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants