Merge pull request #1901 from eeshangarg/openssl-binding-SSL-get-tlsext-status-ocsp-resp

Add OpenSSL binding for SSL_get_tlsext_status_ocsp_resp
diff --git a/docs/development/custom-vectors/secp256k1.rst b/docs/development/custom-vectors/secp256k1.rst
new file mode 100644
index 0000000..b19bf4e
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1.rst
@@ -0,0 +1,32 @@
+SECP256K1 vector creation
+=========================
+
+This page documents the code that was used to generate the SECP256K1 elliptic
+curve test vectors as well as code used to verify them against another
+implementation.
+
+
+Creation
+--------
+
+The vectors are generated using a `pure Python ecdsa`_ implementation. The test
+messages and combinations of algorithms are derived from the NIST vector data.
+
+.. literalinclude:: /development/custom-vectors/secp256k1/generate_secp256k1.py
+
+Download link: :download:`generate_secp256k1.py
+</development/custom-vectors/secp256k1/generate_secp256k1.py>`
+
+
+Verification
+------------
+
+``cryptography`` was modified to support the SECP256K1 curve. Then
+the following python script was run to generate the vector files.
+
+.. literalinclude:: /development/custom-vectors/secp256k1/verify_secp256k1.py
+
+Download link: :download:`verify_secp256k1.py
+</development/custom-vectors/secp256k1/verify_secp256k1.py>`
+
+.. _`pure Python ecdsa`: https://pypi.python.org/pypi/ecdsa
diff --git a/docs/development/custom-vectors/secp256k1/generate_secp256k1.py b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py
new file mode 100644
index 0000000..502a3ff
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1/generate_secp256k1.py
@@ -0,0 +1,89 @@
+from __future__ import absolute_import, print_function
+
+import hashlib
+import os
+from binascii import hexlify
+from collections import defaultdict
+
+from ecdsa import SECP256k1, SigningKey
+from ecdsa.util import sigdecode_der, sigencode_der
+
+from cryptography_vectors import open_vector_file
+
+from tests.utils import (
+    load_fips_ecdsa_signing_vectors, load_vectors_from_file
+)
+
+HASHLIB_HASH_TYPES = {
+    "SHA-1": hashlib.sha1,
+    "SHA-224": hashlib.sha224,
+    "SHA-256": hashlib.sha256,
+    "SHA-384": hashlib.sha384,
+    "SHA-512": hashlib.sha512,
+}
+
+
+class TruncatedHash(object):
+    def __init__(self, hasher):
+        self.hasher = hasher
+
+    def __call__(self, data):
+        self.hasher.update(data)
+        return self
+
+    def digest(self):
+        return self.hasher.digest()[:256 // 8]
+
+
+def build_vectors(fips_vectors):
+    vectors = defaultdict(list)
+    for vector in fips_vectors:
+        vectors[vector['digest_algorithm']].append(vector['message'])
+
+    for digest_algorithm, messages in vectors.items():
+        if digest_algorithm not in HASHLIB_HASH_TYPES:
+            continue
+
+        yield ""
+        yield "[K-256,{0}]".format(digest_algorithm)
+        yield ""
+
+        for message in messages:
+            # Make a hash context
+            hash_func = TruncatedHash(HASHLIB_HASH_TYPES[digest_algorithm]())
+
+            # Sign the message using warner/ecdsa
+            secret_key = SigningKey.generate(curve=SECP256k1)
+            public_key = secret_key.get_verifying_key()
+            signature = secret_key.sign(message, hashfunc=hash_func,
+                                        sigencode=sigencode_der)
+
+            r, s = sigdecode_der(signature, None)
+
+            yield "Msg = {0}".format(hexlify(message))
+            yield "d = {0:x}".format(secret_key.privkey.secret_multiplier)
+            yield "Qx = {0:x}".format(public_key.pubkey.point.x())
+            yield "Qy = {0:x}".format(public_key.pubkey.point.y())
+            yield "R = {0:x}".format(r)
+            yield "S = {0:x}".format(s)
+            yield ""
+
+
+def write_file(lines, dest):
+    for line in lines:
+        print(line)
+        print(line, file=dest)
+
+source_path = os.path.join("asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt")
+dest_path = os.path.join("asymmetric", "ECDSA", "SECP256K1", "SigGen.txt")
+
+fips_vectors = load_vectors_from_file(
+    source_path,
+    load_fips_ecdsa_signing_vectors
+)
+
+with open_vector_file(dest_path, "w") as dest_file:
+    write_file(
+        build_vectors(fips_vectors),
+        dest_file
+    )
diff --git a/docs/development/custom-vectors/secp256k1/verify_secp256k1.py b/docs/development/custom-vectors/secp256k1/verify_secp256k1.py
new file mode 100644
index 0000000..3d2c25b
--- /dev/null
+++ b/docs/development/custom-vectors/secp256k1/verify_secp256k1.py
@@ -0,0 +1,59 @@
+from __future__ import absolute_import, print_function
+
+import os
+
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives.asymmetric.utils import (
+    encode_rfc6979_signature
+)
+
+from tests.utils import (
+    load_fips_ecdsa_signing_vectors, load_vectors_from_file
+)
+
+CRYPTOGRAPHY_HASH_TYPES = {
+    "SHA-1": hashes.SHA1,
+    "SHA-224": hashes.SHA224,
+    "SHA-256": hashes.SHA256,
+    "SHA-384": hashes.SHA384,
+    "SHA-512": hashes.SHA512,
+}
+
+
+def verify_one_vector(vector):
+    digest_algorithm = vector['digest_algorithm']
+    message = vector['message']
+    x = vector['x']
+    y = vector['y']
+    signature = encode_rfc6979_signature(vector['r'], vector['s'])
+
+    numbers = ec.EllipticCurvePublicNumbers(
+        x, y,
+        ec.SECP256K1()
+    )
+
+    key = numbers.public_key(default_backend())
+
+    verifier = key.verifier(
+        signature,
+        ec.ECDSA(CRYPTOGRAPHY_HASH_TYPES[digest_algorithm]())
+    )
+    verifier.update(message)
+    return verifier.verify()
+
+
+def verify_vectors(vectors):
+    for vector in vectors:
+        assert verify_one_vector(vector)
+
+
+vector_path = os.path.join("asymmetric", "ECDSA", "SECP256K1", "SigGen.txt")
+
+secp256k1_vectors = load_vectors_from_file(
+    vector_path,
+    load_fips_ecdsa_signing_vectors
+)
+
+verify_vectors(secp256k1_vectors)
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index f6eecfe..77ec625 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -37,9 +37,14 @@
   Ruby test suite.
 
 
-Custom Asymmetric Vectors
+Custom asymmetric vectors
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
+.. toctree::
+    :maxdepth: 1
+
+    custom-vectors/secp256k1
+
 * ``asymmetric/PEM_Serialization/ec_private_key.pem`` and
   ``asymmetric/DER_Serialization/ec_private_key.der`` - Contains an Elliptic
   Curve key generated by OpenSSL from the curve ``secp256r1``.
@@ -78,6 +83,7 @@
   ``asymmetric/public/PKCS1/rsa.pub.der`` are PKCS1 conversions of the public
   key from ``asymmetric/PKCS8/unenc-rsa-pkcs8.pem`` using PEM and DER encoding.
 
+
 Key exchange
 ~~~~~~~~~~~~
 
@@ -160,6 +166,12 @@
   containing an inhibit any policy extension with the value 5.
 * ``inhibit_any_policy_negative.pem`` - An RSA 2048 bit self-signed certificate
   containing an inhibit any policy extension with the value -1.
+* ``authority_key_identifier.pem`` - An RSA 2048 bit self-signed certificate
+  containing an authority key identifier extension with key identifier,
+  authority certificate issuer, and authority certificate serial number fields.
+* ``authority_key_identifier_no_keyid.pem`` - An RSA 2048 bit self-signed
+  certificate containing an authority key identifier extension with authority
+  certificate issuer and authority certificate serial number fields.
 
 Custom X.509 Request Vectors
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/x509.rst b/docs/x509.rst
index 7cfc74e..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)>)>
@@ -682,10 +683,10 @@
         certificate. This attribute only has meaning if ``ca`` is true.
         If ``ca`` is true then a path length of None means there's no
         restriction on the number of subordinate CAs in the certificate chain.
-        If it is zero or greater then that number defines the maximum length.
-        For example, a ``path_length`` of 1 means the certificate can sign a
-        subordinate CA, but the subordinate CA is not allowed to create
-        subordinates with ``ca`` set to true.
+        If it is zero or greater then it defines the maximum length for a
+        subordinate CA's certificate chain. For example, a ``path_length`` of 1
+        means the certificate can sign a subordinate CA, but the subordinate CA
+        is not allowed to create subordinates with ``ca`` set to true.
 
 .. class:: ExtendedKeyUsage
 
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/src/cryptography/x509.py b/src/cryptography/x509.py
index 2733709..0d87cd5 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -666,8 +666,13 @@
                     "must both be present or both None"
                 )
 
-            if not isinstance(authority_cert_issuer, Name):
-                raise TypeError("authority_cert_issuer must be a Name")
+            if not all(
+                isinstance(x, GeneralName) for x in authority_cert_issuer
+            ):
+                raise TypeError(
+                    "authority_cert_issuer must be a list of GeneralName "
+                    "objects"
+                )
 
             if not isinstance(authority_cert_serial_number, six.integer_types):
                 raise TypeError(
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index 0e5cab5..ad36b5c 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -221,29 +221,33 @@
 
 
 class TestAuthorityKeyIdentifier(object):
-    def test_authority_cert_issuer_not_name(self):
+    def test_authority_cert_issuer_not_generalname(self):
         with pytest.raises(TypeError):
-            x509.AuthorityKeyIdentifier(b"identifier", "notname", 3)
+            x509.AuthorityKeyIdentifier(b"identifier", ["notname"], 3)
 
     def test_authority_cert_serial_number_not_integer(self):
-        name = x509.Name([
-            x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
-            x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
-        ])
+        dirname = x509.DirectoryName(
+            x509.Name([
+                x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
+                x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
+            ])
+        )
         with pytest.raises(TypeError):
-            x509.AuthorityKeyIdentifier(b"identifier", name, "notanint")
+            x509.AuthorityKeyIdentifier(b"identifier", [dirname], "notanint")
 
     def test_authority_issuer_none_serial_not_none(self):
         with pytest.raises(ValueError):
             x509.AuthorityKeyIdentifier(b"identifier", None, 3)
 
     def test_authority_issuer_not_none_serial_none(self):
-        name = x509.Name([
-            x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
-            x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
-        ])
+        dirname = x509.DirectoryName(
+            x509.Name([
+                x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
+                x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
+            ])
+        )
         with pytest.raises(ValueError):
-            x509.AuthorityKeyIdentifier(b"identifier", name, None)
+            x509.AuthorityKeyIdentifier(b"identifier", [dirname], None)
 
     def test_authority_cert_serial_and_issuer_none(self):
         aki = x509.AuthorityKeyIdentifier(b"id", None, None)
@@ -252,22 +256,24 @@
         assert aki.authority_cert_serial_number is None
 
     def test_repr(self):
-        name = x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')])
-        aki = x509.AuthorityKeyIdentifier(b"digest", name, 1234)
+        dirname = x509.DirectoryName(
+            x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')])
+        )
+        aki = x509.AuthorityKeyIdentifier(b"digest", [dirname], 1234)
 
         if six.PY3:
             assert repr(aki) == (
                 "<AuthorityKeyIdentifier(key_identifier=b'digest', authority_"
-                "cert_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid="
-                "2.5.4.3, name=commonName)>, value='myCN')>])>, authority_cer"
-                "t_serial_number=1234)>"
+                "cert_issuer=[<DirectoryName(value=<Name([<NameAttribute(oid="
+                "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value='myC"
+                "N')>])>)>], authority_cert_serial_number=1234)>"
             )
         else:
             assert repr(aki) == (
                 "<AuthorityKeyIdentifier(key_identifier='digest', authority_ce"
-                "rt_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5"
-                ".4.3, name=commonName)>, value='myCN')>])>, authority_cert_se"
-                "rial_number=1234)>"
+                "rt_issuer=[<DirectoryName(value=<Name([<NameAttribute(oid=<Ob"
+                "jectIdentifier(oid=2.5.4.3, name=commonName)>, value='myCN')>"
+                "])>)>], authority_cert_serial_number=1234)>"
             )
 
 
@@ -1130,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
diff --git a/tests/utils.py b/tests/utils.py
index 65c99fb..c48a1f9 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -498,6 +498,7 @@
 
     "K-163": "sect163k1",
     "K-233": "sect233k1",
+    "K-256": "secp256k1",
     "K-283": "sect283k1",
     "K-409": "sect409k1",
     "K-571": "sect571k1",
diff --git a/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem b/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem
new file mode 100644
index 0000000..cbe9169
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/authority_key_identifier.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDIjCCAgqgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB
+MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMDk0OTU2WhcNMTYw
+NTAyMDk0OTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw
+aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP
+ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk
+xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK
+vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8
+Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b
+YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8
+Syi39HTpAgMBAAGjVTBTMFEGA1UdIwRKMEiAFDlFPso9Yh3qhkn2WqtAt6RwmPHs
+oS2kKzApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW+C
+AQMwDQYJKoZIhvcNAQEFBQADggEBAFbZYy6aZJUK/f7nJx2Rs/ht6hMbM32/RoXZ
+JGbYapNVqVu/vymcfc/se3FHS5OVmPsnRlo/FIKDn/r5DGl73Sn/FvDJiLJZFucT
+msyYuHZ+ZRYWzWmN2fcB3cfxj0s3qps6f5OoCOqoINOSe4HRGlw4X9keZSD+3xAt
+vHNwQdlPC7zWbPdrzLT+FqR0e/O81vFJJS6drHJWqPcR3NQVtZw+UF7A/HKwbfeL
+Nu2zj6165hzOi9HUxa2/mPr/eLUUV1sTzXp2+TFjt3rVCjW1XnpMLdwNBHzjpyAB
+dTOX3iw0+BPy3s2jtnCW1PLpc74kvSTaBwhg74sq39EXfIKax00=
+-----END CERTIFICATE-----
diff --git a/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem b/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem
new file mode 100644
index 0000000..fffcc65
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/authority_key_identifier_no_keyid.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB
+MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMTAxNTU2WhcNMTYw
+NTAyMTAxNTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw
+aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP
+ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk
+xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK
+vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8
+Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b
+YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8
+Syi39HTpAgMBAAGjPzA9MDsGA1UdIwQ0MDKhLaQrMCkxDTALBgNVBAoMBFB5Q0Ex
+GDAWBgNVBAMMD2NyeXB0b2dyYXBoeS5pb4IBAzANBgkqhkiG9w0BAQUFAAOCAQEA
+AViX0VIVQW2xyf0lfLiuFhrpdgX9i49StZvs+n/qH5yvWxfqRJAyVT1pk2Xs0Goj
+ul7vYMfIGU0nIr8eLMlAH9j6lkllAd/oO1BDONZ1kH6PMdkOdvgz5gmhMQx6MFr6
+zMzzQ+JOAnXKFFUEycOiRJyh3VXiTY1M1IG1kWY+LoqB72S7y9c25yFoHqUNi2Xf
+rbuaR7gNS/4z7XvLJkbNbVS2+y69gQGL+8vk5AG7MiZ1mzUQ44r/zy6HNDBb55kK
+H+YTYavijRApH5hccJBXyoIM0x9ZtKdcrV0h+J2KOFGEyHp3FXViFEB2IZUpJNA/
+aduVbH8gZy5Y+cHzenwzBg==
+-----END CERTIFICATE-----