authority key identifier support in the openssl backend
diff --git a/docs/x509.rst b/docs/x509.rst
index f9c9af2..f4ea2a5 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -317,6 +317,7 @@
 
             >>> for ext in cert.extensions:
             ...     print(ext)
+            <Extension(oid=<ObjectIdentifier(oid=2.5.29.35, name=authorityKeyIdentifier)>, critical=False, value=<AuthorityKeyIdentifier(key_identifier='\xe4}_\xd1\\\x95\x86\x08,\x05\xae\xbeu\xb6e\xa7\xd9]\xa8f', authority_cert_issuer=None, authority_cert_serial_number=None)>)>
             <Extension(oid=<ObjectIdentifier(oid=2.5.29.14, name=subjectKeyIdentifier)>, critical=False, value=<SubjectKeyIdentifier(digest='X\x01\x84$\x1b\xbc+R\x94J=\xa5\x10r\x14Q\xf5\xaf:\xc9')>)>
             <Extension(oid=<ObjectIdentifier(oid=2.5.29.15, name=keyUsage)>, critical=True, value=<KeyUsage(digital_signature=False, content_commitment=False, key_encipherment=False, data_encipherment=False, key_agreement=False, key_cert_sign=True, crl_sign=True, encipher_only=None, decipher_only=None)>)>
             <Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConstraints)>, critical=True, value=<BasicConstraints(ca=True, path_length=None)>)>
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index dd2aba6..c6b85c9 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -269,6 +269,8 @@
                 value = self._build_subject_alt_name(ext)
             elif oid == x509.OID_EXTENDED_KEY_USAGE:
                 value = self._build_extended_key_usage(ext)
+            elif oid == x509.OID_AUTHORITY_KEY_IDENTIFIER:
+                value = self._build_authority_key_identifier(ext)
             elif critical:
                 raise x509.UnsupportedExtension(
                     "{0} is not currently supported".format(oid), oid
@@ -321,6 +323,45 @@
             self._backend._ffi.buffer(asn1_string.data, asn1_string.length)[:]
         )
 
+    def _build_authority_key_identifier(self, ext):
+        akid = self._backend._lib.X509V3_EXT_d2i(ext)
+        assert akid != self._backend._ffi.NULL
+        akid = self._backend._ffi.cast("AUTHORITY_KEYID *", akid)
+        akid = self._backend._ffi.gc(
+            akid, self._backend._lib.AUTHORITY_KEYID_free
+        )
+        key_identifier = None
+        authority_cert_issuer = None
+        authority_cert_serial_number = None
+
+        if akid.keyid != self._backend._ffi.NULL:
+            key_identifier = self._backend._ffi.buffer(
+                akid.keyid.data, akid.keyid.length
+            )[:]
+
+        if akid.issuer != self._backend._ffi.NULL:
+            authority_cert_issuer = []
+
+            num = self._backend._lib.sk_GENERAL_NAME_num(akid.issuer)
+            for i in range(num):
+                gn = self._backend._lib.sk_GENERAL_NAME_value(akid.issuer, i)
+                assert gn != self._backend._ffi.NULL
+                value = _build_general_name(self._backend, gn)
+
+                authority_cert_issuer.append(value)
+
+        if akid.serial != self._backend._ffi.NULL:
+            bn = self._backend._lib.ASN1_INTEGER_to_BN(
+                akid.serial, self._backend._ffi.NULL
+            )
+            assert bn != self._backend._ffi.NULL
+            bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free)
+            authority_cert_serial_number = self._backend._bn_to_int(bn)
+
+        return x509.AuthorityKeyIdentifier(
+            key_identifier, authority_cert_issuer, authority_cert_serial_number
+        )
+
     def _build_key_usage(self, ext):
         bit_string = self._backend._lib.X509V3_EXT_d2i(ext)
         assert bit_string != self._backend._ffi.NULL
diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py
index 28dd7f3..311261f 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509v3.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py
@@ -109,6 +109,9 @@
 /* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the
    x509v3.h header. */
 void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *);
+/* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the
+   x509v3.h header. */
+void AUTHORITY_KEYID_free(AUTHORITY_KEYID *);
 void *X509V3_set_ctx_nodb(X509V3_CTX *);
 int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
 int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index ab6d6ff..ad36b5c 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -1136,3 +1136,87 @@
 
         assert aia != aia2
         assert aia != object()
+
+
+@pytest.mark.requires_backend_interface(interface=RSABackend)
+@pytest.mark.requires_backend_interface(interface=X509Backend)
+class TestAuthorityKeyIdentifierExtension(object):
+    def test_aki_keyid(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "cryptography.io.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_KEY_IDENTIFIER
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value.key_identifier == (
+            b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08\xcbY"
+        )
+        assert ext.value.authority_cert_issuer is None
+        assert ext.value.authority_cert_serial_number is None
+
+    def test_aki_all_fields(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "authority_key_identifier.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_KEY_IDENTIFIER
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value.key_identifier == (
+            b"9E>\xca=b\x1d\xea\x86I\xf6Z\xab@\xb7\xa4p\x98\xf1\xec"
+        )
+        assert ext.value.authority_cert_issuer == [
+            x509.DirectoryName(
+                x509.Name([
+                    x509.NameAttribute(
+                        x509.OID_ORGANIZATION_NAME, u"PyCA"
+                    ),
+                    x509.NameAttribute(
+                        x509.OID_COMMON_NAME, u"cryptography.io"
+                    )
+                ])
+            )
+        ]
+        assert ext.value.authority_cert_serial_number == 3
+
+    def test_aki_no_keyid(self, backend):
+        cert = _load_cert(
+            os.path.join(
+                "x509", "custom", "authority_key_identifier_no_keyid.pem"
+            ),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_KEY_IDENTIFIER
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value.key_identifier is None
+        assert ext.value.authority_cert_issuer == [
+            x509.DirectoryName(
+                x509.Name([
+                    x509.NameAttribute(
+                        x509.OID_ORGANIZATION_NAME, u"PyCA"
+                    ),
+                    x509.NameAttribute(
+                        x509.OID_COMMON_NAME, u"cryptography.io"
+                    )
+                ])
+            )
+        ]
+        assert ext.value.authority_cert_serial_number == 3