OCSP signature verification raises AttributeError on ML-KEM public keys

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Unknown
    • 4.18.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • None
    • Python Drivers
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Detailed steps to reproduce the problem?

      Include full traceback, if possible

      cryptography 50.0.0 added MLKEM768PublicKey and MLKEM1024PublicKey to CertificatePublicKeyTypes, the return type of Certificate.public_key(). pymongo.ocsp_support._verify_signature dispatches on key type and falls through to a generic key.verify(signature, data) branch, but ML-KEM is a key encapsulation mechanism and its public keys have no verify() method.

      >>> from cryptography.hazmat.primitives.asymmetric import mlkem
      >>> from pymongo.ocsp_support import _verify_signature
      >>> key = mlkem.MLKEM768PrivateKey.generate().public_key()
      >>> _verify_signature(key, b"sig", None, b"data")
      AttributeError: 'cryptography.hazmat.bindings._rust.openssl.mlkem.MLKEM768PublicKey' object has no attribute 'verify'
      

      The same drift also breaks type checking. ocsp_support hand-maintains a CertificateIssuerPublicKeyTypes union because cryptography exports no public alias for it, and that union is now narrower than what public_key() returns:

      pymongo/ocsp_support.py:236: error: Argument 1 to "_verify_signature" has incompatible type
        "DSAPublicKey | RSAPublicKey | EllipticCurvePublicKey | Ed25519PublicKey | Ed448PublicKey | <7 more items>";
        expected "DSAPublicKey | ... | MLDSA44PublicKey | MLDSA65PublicKey | MLDSA87PublicKey | X25519PublicKey | X448PublicKey"  [arg-type]
      pymongo/ocsp_support.py:245: error: Argument 1 to "_verify_signature" has incompatible type ... [arg-type]
      

      This currently fails the static and Typing Tests CI jobs on any branch whose typing environment resolves cryptography 50.

      An earlier instance of the same drift was fixed in PYTHON-5915, which added the ML-DSA types when the minimum was raised to cryptography 47.

      Definition of done: what must be done to consider the task complete?

      • _verify_signature handles ML-KEM public keys without raising. It should fail closed and return 0: an ML-KEM key cannot produce a signature, so an OCSP signature can never be verified against one.
      • The CertificateIssuerPublicKeyTypes union matches cryptography's CertificatePublicKeyTypes, so mypy passes on both the minimum supported cryptography (47.0.0) and current (50.0.0).
      • Regression tests covering both ML-KEM key sizes.

      The exact Python version used, with patch level:

      3.14.2 (main, Dec 9 2025, 19:29:30) [Clang 21.1.4]

      The exact version of PyMongo used, with patch level:

      4.18.0.dev0, has_c() is True

      Describe how MongoDB is set up. Local vs Hosted, version, topology, load balanced, etc.

      Not applicable. The defect is in certificate handling and reproduces without a server; it is triggered by the installed cryptography version, not by any deployment.

      The operating system and version (e.g. Windows 7, OSX 10.8, ...)

      macOS 26.6.1. Not platform specific; the CI failures are on Linux.

      Web framework or asynchronous network library used, if any, with version (e.g. Django 1.7, mod_wsgi 4.3.0, gevent 1.0.1, Tornado 4.0.2, ...)

      None.

            Assignee:
            Steve Silvester
            Reporter:
            Steve Silvester
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: