Fix FFDH CryptographyDeprecationWarning raised when importing spiffe - #446
Conversation
`certificate_utils.PRIVATE_KEY_TYPES` was a hand-rolled `Union` that duplicated cryptography's `PrivateKeyTypes`. It was added as `_PRIVATE_KEY_TYPES` in 77537c6, and `dh.DHPrivateKey` was added to it later in 95b2e32. That copy had two problems: - It referenced `dh.DHPrivateKey`. cryptography 50.0.0 deprecated Diffie-Hellman over finite fields (FFDH) (https://cryptography.io/en/latest/changelog/#v50-0-0), so touching that attribute now emits a `CryptographyDeprecationWarning` at module import time. Because that warning subclasses `UserWarning` (not `DeprecationWarning`), a strict `filterwarnings = error` policy turns importing `spiffe` into an ImportError before any code runs. This became reachable once the cryptography upper bound was removed in 429c165, relaxing the `>=46,<48` pin from 8deed17 to `>=46` and letting cryptography 50 resolve. - The copy had drifted from cryptography and no longer matched what the loaders return (e.g. it predated the ML-DSA/ML-KEM key types). Alias `cryptography.hazmat.primitives.asymmetric.types.PrivateKeyTypes` directly. That is exactly what `load_der_private_key`/`load_pem_private_key` are declared to return: both are annotated `-> PrivateKeyTypes` in cryptography's type stub `hazmat/bindings/_rust/openssl/keys.pyi` (https://github.com/pyca/cryptography/blob/50.0.0/src/cryptography/hazmat/bindings/_rust/openssl/keys.pyi#L13-L26). The `parse_*_private_key` wrappers just return those calls, so they now annotate precisely what they produce. The alias also avoids the deprecated attribute reference and stays in sync with cryptography. `PRIVATE_KEY_TYPES` is only used as a type annotation, so there is no runtime behaviour change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Carlo Teubner <cteubner1@bloomberg.net>
8873d12 to
40e5ed7
Compare
|
Hi @c4rlo, thanks for this. Is it ready for review? |
|
Hi, yes it's ready for review, thanks! I've still got it in draft because I still need to get internal signoff to contribute code to this project, which I hope won't take long to arrive. So please don't merge it just yet, if that's okay. |
Sounds good, thanks! I'll review it and hold off on merging. |
maxlambrecht
left a comment
There was a problem hiding this comment.
LGTM, thanks @c4rlo!
|
Thank you, good to merge from my end! I'd much appreciate it if this could make its way into a new release soon. |
|
Released in v0.3.1. Thanks again @c4rlo! |
Summary
certificate_utils.PRIVATE_KEY_TYPESis a hand-rolledUnionthat duplicatescryptography'sPrivateKeyTypes. It was added as_PRIVATE_KEY_TYPESin 77537c6 (#41), anddh.DHPrivateKeywas added to it later in 95b2e32 (#107).cryptography50.0.0 deprecated Diffie-Hellman over finite fields (FFDH), so merely touchingdh.DHPrivateKeynow emits aCryptographyDeprecationWarningat module import time:Because
CryptographyDeprecationWarningsubclassesUserWarning(notDeprecationWarning), any downstream project that runs under a strictfilterwarnings = errorpolicy fails to importspiffeat all — the warning is raised as an error during import, before any code runs.This became reachable once the
cryptographyupper bound was removed in 429c165 (>=46,<48→>=46, relaxing the pin from 8deed17), allowingcryptography50 to resolve.The copied union had also drifted from
cryptography: it no longer matches what the key loaders can return (e.g. it predates the ML-DSA / ML-KEM key types).Change
Alias
cryptography's canonical type instead of hand-maintaining a copy:This is exactly what
load_der_private_key/load_pem_private_keyare declared to return — both are annotated-> PrivateKeyTypesincryptography's type stubhazmat/bindings/_rust/openssl/keys.pyi— andparse_*_private_keysimply returns those calls, so the annotations now match precisely what is produced. It also removes the deprecated attribute reference and stays in sync withcryptographygoing forward.PRIVATE_KEY_TYPESis only ever used as a type annotation (no runtimeisinstance), so there is no runtime behaviour change. Lint (ruff/mypy/pyright, 100% type completeness) and the full unit suite (376 passed) are green.🤖 Generated with Claude Code