add support for authority information access in the openssl backend
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index c6b85c9..42ca138 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -271,6 +271,8 @@
                 value = self._build_extended_key_usage(ext)
             elif oid == x509.OID_AUTHORITY_KEY_IDENTIFIER:
                 value = self._build_authority_key_identifier(ext)
+            elif oid == x509.OID_AUTHORITY_INFORMATION_ACCESS:
+                value = self._build_authority_information_access(ext)
             elif critical:
                 raise x509.UnsupportedExtension(
                     "{0} is not currently supported".format(oid), oid
@@ -362,6 +364,27 @@
             key_identifier, authority_cert_issuer, authority_cert_serial_number
         )
 
+    def _build_authority_information_access(self, ext):
+        aia = self._backend._lib.X509V3_EXT_d2i(ext)
+        assert aia != self._backend._ffi.NULL
+        aia = self._backend._ffi.cast(
+            "Cryptography_STACK_OF_ACCESS_DESCRIPTION *", aia
+        )
+        aia = self._backend._ffi.gc(
+            aia, self._backend._lib.sk_ACCESS_DESCRIPTION_free
+        )
+        num = self._backend._lib.sk_ACCESS_DESCRIPTION_num(aia)
+        access_descriptions = []
+        for i in range(num):
+            ad = self._backend._lib.sk_ACCESS_DESCRIPTION_value(aia, i)
+            assert ad.method != self._backend._ffi.NULL
+            oid = x509.ObjectIdentifier(_obj2txt(self._backend, ad.method))
+            assert ad.location != self._backend._ffi.NULL
+            gn = _build_general_name(self._backend, ad.location)
+            access_descriptions.append(x509.AccessDescription(oid, gn))
+
+        return x509.AuthorityInformationAccess(access_descriptions)
+
     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 311261f..c2b6860 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509v3.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py
@@ -19,9 +19,12 @@
 #else
 typedef LHASH Cryptography_LHASH_OF_CONF_VALUE;
 #endif
+typedef STACK_OF(ACCESS_DESCRIPTION) Cryptography_STACK_OF_ACCESS_DESCRIPTION;
 """
 
 TYPES = """
+typedef ... Cryptography_STACK_OF_ACCESS_DESCRIPTION;
+
 typedef struct {
     X509 *issuer_cert;
     X509 *subject_cert;
@@ -92,6 +95,11 @@
     ASN1_INTEGER *serial;
 } AUTHORITY_KEYID;
 
+typedef struct {
+    ASN1_OBJECT *method;
+    GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
 typedef ... Cryptography_LHASH_OF_CONF_VALUE;
 """
 
@@ -117,6 +125,12 @@
 int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
 GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
 
+int sk_ACCESS_DESCRIPTION_num(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
+ACCESS_DESCRIPTION *sk_ACCESS_DESCRIPTION_value(
+    Cryptography_STACK_OF_ACCESS_DESCRIPTION *, int
+);
+void sk_ACCESS_DESCRIPTION_free(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
+
 X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *,
                                     X509V3_CTX *, int, char *);
 
diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py
index ad36b5c..8a22795 100644
--- a/tests/test_x509_ext.py
+++ b/tests/test_x509_ext.py
@@ -1140,6 +1140,104 @@
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)
+class TestAuthorityInformationAccessExtension(object):
+    def test_aia_ocsp_ca_issuers(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_INFORMATION_ACCESS
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value == x509.AuthorityInformationAccess([
+            x509.AccessDescription(
+                x509.OID_OCSP,
+                x509.UniformResourceIdentifier(u"http://gv.symcd.com")
+            ),
+            x509.AccessDescription(
+                x509.OID_CA_ISSUERS,
+                x509.UniformResourceIdentifier(u"http://gv.symcb.com/gv.crt")
+            ),
+        ])
+
+    def test_aia_multiple_ocsp_ca_issuers(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "custom", "aia_ocsp_ca_issuers.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_INFORMATION_ACCESS
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value == x509.AuthorityInformationAccess([
+            x509.AccessDescription(
+                x509.OID_OCSP,
+                x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
+            ),
+            x509.AccessDescription(
+                x509.OID_OCSP,
+                x509.UniformResourceIdentifier(u"http://ocsp2.domain.com")
+            ),
+            x509.AccessDescription(
+                x509.OID_CA_ISSUERS,
+                x509.DirectoryName(x509.Name([
+                    x509.NameAttribute(x509.OID_COMMON_NAME, "myCN"),
+                    x509.NameAttribute(x509.OID_ORGANIZATION_NAME, "some Org"),
+                ]))
+            ),
+        ])
+
+    def test_aia_ocsp_only(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "custom", "aia_ocsp.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_INFORMATION_ACCESS
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value == x509.AuthorityInformationAccess([
+            x509.AccessDescription(
+                x509.OID_OCSP,
+                x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
+            ),
+        ])
+
+    def test_aia_ca_issuers_only(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "custom", "aia_ca_issuers.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        ext = cert.extensions.get_extension_for_oid(
+            x509.OID_AUTHORITY_INFORMATION_ACCESS
+        )
+        assert ext is not None
+        assert ext.critical is False
+
+        assert ext.value == x509.AuthorityInformationAccess([
+            x509.AccessDescription(
+                x509.OID_CA_ISSUERS,
+                x509.DirectoryName(x509.Name([
+                    x509.NameAttribute(x509.OID_COMMON_NAME, "myCN"),
+                    x509.NameAttribute(x509.OID_ORGANIZATION_NAME, "some Org"),
+                ]))
+            ),
+        ])
+
+
+@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(