Skip to content

_set_signature_type returning "Unsupported signing algorithm info" due to isinstance check #793

Closed

Description

@jvan1997

Security issue notifications

If you discover a potential security issue in the AWS Encryption SDK we ask that you notify AWS Security via our vulnerability reporting page. Please do not create a public GitHub issue.

Problem:

aws-encryption-sdk version 4.x introduced a regression in _set_signature_type() via PR #467 (specific line) that replaced a verify_interface call with a bare isinstance check:

def _set_signature_type(self):
    if not isinstance(self.algorithm.signing_algorithm_info, type(ec.EllipticCurve)):
        raise NotSupportedError("Unsupported signing algorithm info")
    return ec.EllipticCurve

type(ec.EllipticCurve) evaluates to ABCMeta. This worked when cryptography implemented EC curve classes as pure Python ABCs, where isinstance(ec.SECP384R1, ABCMeta) returned True because the class itself is an instance of its metaclass.

However, in newer versions of cryptography, ec.SECP384R1 is backed by Rust internals via rust_openssl, and its metaclass is type, not ABCMeta. This causes both of the following to return False at runtime:

isinstance(ec.SECP384R1, type(ec.EllipticCurve))  # False — metaclass is 'type', not ABCMeta
isinstance(ec.SECP384R1, ec.EllipticCurve)         # False — it's a class, not an instance

This raises NotSupportedError("Unsupported signing algorithm info") when decrypting with AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, which is used by clients such as the Odin encryption client.

ec.SECP384R1 is a valid subclass of ec.EllipticCurve as defined here. The existing issue #625 notes that cryptography>=3.4.6 is required, but the root cause is the metaclass check — not the cryptography version itself.

Solution:

Replace the metaclass-based isinstance check with issubclass, which correctly handles both pure Python ABCs and Rust-backed types:

def _set_signature_type(self):
    try:
        if not issubclass(self.algorithm.signing_algorithm_info, ec.EllipticCurve):
            raise NotSupportedError(
                f"Unsupported signing algorithm info: {self.algorithm.signing_algorithm_info}"
            )
    except TypeError:
        raise NotSupportedError(
            f"Unsupported signing algorithm info: {self.algorithm.signing_algorithm_info}"
        )
    return ec.EllipticCurve

issubclass returns True for any class that is a subclass of ec.EllipticCurve regardless of metaclass, and raises TypeError if the argument is not a class at all, which is caught and re-raised as NotSupportedError.

Additionally, the README/docs should clarify that the cryptography>=3.4.6 minimum exists specifically because of this metaclass behavior change, so consumers understand why the floor exists.

Out of scope:

Does not address any other algorithm suite compatibility issues or cryptography version pinning recommendations beyond _set_signature_type.

Activity

  1. added a commit that references this issue on Apr 29, 2026
    87c17c9
  2. sharmabikram commented on Apr 30, 2026

    @sharmabikram
    Contributor

    Thanks for the detailed report, @jvan1997. This is a valid bug — the isinstance metaclass
    check in generate_ecc_signing_key() in elliptic_curve.py is fragile and breaks when the
    cryptography library's EC curve classes use a different metaclass. This fix is pending release.

  3. added a commit that references this issue on Apr 30, 2026
    b5ce922
  4. added a commit that references this issue on Apr 30, 2026
    6e958bd
  5. josecorella commented on May 7, 2026

    @josecorella
    Contributor

    Hello @jvan1997!

    We have published 4.0.6 of the ESDK for Python with this fix. Let us know if you have any issues.

    Thanks!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions