Repository: pyca/cryptography (Python)

Issue:
AuthorityKeyIdentifier.from_issuer_subject_key_identifier takes the wrong object
Found by randomly browsing:
https://github.com/Netflix/lemur/blob/73ac1591e015fb576c2a53954f64f422472a15dd/lemur/plugins/lemur_cryptography/plugin.py#L87-L91

The bug here is that the function (and our test) assume that you're passing an `Extension` object that has a `SubjectKeyIdentifier` in it. This is not what we documented and not what we want. Instead it should take an SKI! However, for compatibility we're going to need to do some sort of try:except and raise a deprecation warning on the wrong type.


Hints:

Patch:
diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py
--- a/src/cryptography/utils.py
+++ b/src/cryptography/utils.py
@@ -23,6 +23,7 @@ class CryptographyDeprecationWarning(UserWarning):
 PersistentlyDeprecated2017 = CryptographyDeprecationWarning
 PersistentlyDeprecated2018 = CryptographyDeprecationWarning
 DeprecatedIn25 = CryptographyDeprecationWarning
+DeprecatedIn27 = CryptographyDeprecationWarning
 
 
 def _check_bytes(name, value):
diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -8,6 +8,7 @@
 import datetime
 import hashlib
 import ipaddress
+import warnings
 from enum import Enum
 
 from asn1crypto.keys import PublicKeyInfo
@@ -188,8 +189,21 @@ def from_issuer_public_key(cls, public_key):
 
     @classmethod
     def from_issuer_subject_key_identifier(cls, ski):
+        if isinstance(ski, SubjectKeyIdentifier):
+            digest = ski.digest
+        else:
+            digest = ski.value.digest
+            warnings.warn(
+                "Extension objects are deprecated as arguments to "
+                "from_issuer_subject_key_identifier and support will be "
+                "removed soon. Please migrate to passing a "
+                "SubjectKeyIdentifier directly.",
+                utils.DeprecatedIn27,
+                stacklevel=2,
+            )
+
         return cls(
-            key_identifier=ski.value.digest,
+            key_identifier=digest,
             authority_cert_issuer=None,
             authority_cert_serial_number=None
         )


Test patch:
diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py
--- a/tests/x509/test_x509_ext.py
+++ b/tests/x509/test_x509_ext.py
@@ -3196,11 +3196,18 @@ def test_from_issuer_subject_key_identifier(self, backend):
         ext = cert.extensions.get_extension_for_oid(
             ExtensionOID.AUTHORITY_KEY_IDENTIFIER
         )
-        ski = issuer_cert.extensions.get_extension_for_class(
+        ski_ext = issuer_cert.extensions.get_extension_for_class(
             x509.SubjectKeyIdentifier
         )
+        # This was the incorrect arg we want to deprecate and remove
+        with pytest.warns(utils.CryptographyDeprecationWarning):
+            aki = x509.AuthorityKeyIdentifier.\
+                from_issuer_subject_key_identifier(ski_ext)
+            assert ext.value == aki
+
+        # Here's what we actually documented and want to do
         aki = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
-            ski
+            ski_ext.value
         )
         assert ext.value == aki