aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-08-03 21:32:45 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-08-03 21:32:45 -0400
commit2d135b759139ef470b753a4c92ec0aa93f6cdff4 (patch)
tree9979699d3d0bc949036d9ae6b9233913a85ed091
parente886575a26fdc686d8f47ae3f6e29d9b68de92fa (diff)
parent3b54ce272df125430907f27c61c86d27531b7f33 (diff)
downloadcryptography-2d135b759139ef470b753a4c92ec0aa93f6cdff4.tar.gz
cryptography-2d135b759139ef470b753a4c92ec0aa93f6cdff4.tar.bz2
cryptography-2d135b759139ef470b753a4c92ec0aa93f6cdff4.zip
Merge pull request #2193 from reaperhulk/encode-aia
Support AuthorityInformationAccess in CertificateBuilder
-rw-r--r--src/_cffi_src/openssl/x509v3.py6
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py30
-rw-r--r--src/cryptography/x509.py4
-rw-r--r--tests/test_x509.py43
4 files changed, 83 insertions, 0 deletions
diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
index a61ad321..fc3c6d46 100644
--- a/src/_cffi_src/openssl/x509v3.py
+++ b/src/_cffi_src/openssl/x509v3.py
@@ -203,6 +203,9 @@ int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **);
int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *, unsigned char **);
+int i2d_AUTHORITY_INFO_ACCESS(Cryptography_STACK_OF_ACCESS_DESCRIPTION *,
+ unsigned char **);
+
int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
@@ -216,6 +219,9 @@ void sk_ACCESS_DESCRIPTION_free(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
int sk_ACCESS_DESCRIPTION_push(Cryptography_STACK_OF_ACCESS_DESCRIPTION *,
ACCESS_DESCRIPTION *);
+ACCESS_DESCRIPTION *ACCESS_DESCRIPTION_new(void);
+void ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *);
+
X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *,
X509V3_CTX *, int, char *);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 5bb91a9b..f9da9ea7 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -202,6 +202,32 @@ def _encode_basic_constraints(backend, basic_constraints):
return pp, r
+def _encode_authority_information_access(backend, authority_info_access):
+ aia = backend._lib.sk_ACCESS_DESCRIPTION_new_null()
+ assert aia != backend._ffi.NULL
+ aia = backend._ffi.gc(
+ aia, backend._lib.sk_ACCESS_DESCRIPTION_free
+ )
+ for access_description in authority_info_access:
+ ad = backend._lib.ACCESS_DESCRIPTION_new()
+ method = _txt2obj(
+ backend, access_description.access_method.dotted_string
+ )
+ gn = _encode_general_name(backend, access_description.access_location)
+ ad.method = method
+ ad.location = gn
+ res = backend._lib.sk_ACCESS_DESCRIPTION_push(aia, ad)
+ assert res >= 1
+
+ pp = backend._ffi.new('unsigned char **')
+ r = backend._lib.i2d_AUTHORITY_INFO_ACCESS(aia, pp)
+ assert r > 0
+ pp = backend._ffi.gc(
+ pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0])
+ )
+ return pp, r
+
+
def _encode_subject_alt_name(backend, san):
general_names = backend._lib.GENERAL_NAMES_new()
assert general_names != backend._ffi.NULL
@@ -1143,6 +1169,10 @@ class Backend(object):
pp, r = _encode_extended_key_usage(self, extension.value)
elif isinstance(extension.value, x509.SubjectAlternativeName):
pp, r = _encode_subject_alt_name(self, extension.value)
+ elif isinstance(extension.value, x509.AuthorityInformationAccess):
+ pp, r = _encode_authority_information_access(
+ self, extension.value
+ )
else:
raise NotImplementedError('Extension not yet supported.')
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index defac248..978eb560 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -1728,6 +1728,10 @@ class CertificateBuilder(object):
extension = Extension(
OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
)
+ elif isinstance(extension, AuthorityInformationAccess):
+ extension = Extension(
+ OID_AUTHORITY_INFORMATION_ACCESS, critical, extension
+ )
elif isinstance(extension, InhibitAnyPolicy):
extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension)
else:
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 668a3bad..e31b57f4 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -1652,6 +1652,49 @@ class TestCertificateSigningRequestBuilder(object):
assert str(exc.value) == "Digest too big for RSA key"
+ @pytest.mark.requires_backend_interface(interface=RSABackend)
+ @pytest.mark.requires_backend_interface(interface=X509Backend)
+ def test_build_cert_with_aia(self, backend):
+ issuer_private_key = RSA_KEY_2048.private_key(backend)
+ subject_private_key = RSA_KEY_2048.private_key(backend)
+
+ not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
+ not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
+
+ aia = x509.AuthorityInformationAccess([
+ x509.AccessDescription(
+ x509.OID_OCSP,
+ x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
+ ),
+ x509.AccessDescription(
+ x509.OID_CA_ISSUERS,
+ x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
+ )
+ ])
+
+ builder = x509.CertificateBuilder().serial_number(
+ 777
+ ).issuer_name(x509.Name([
+ x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
+ ])).subject_name(x509.Name([
+ x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
+ ])).public_key(
+ subject_private_key.public_key()
+ ).add_extension(
+ aia, critical=False
+ ).not_valid_before(
+ not_valid_before
+ ).not_valid_after(
+ not_valid_after
+ )
+
+ cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
+
+ ext = cert.extensions.get_extension_for_oid(
+ x509.OID_AUTHORITY_INFORMATION_ACCESS
+ )
+ assert ext.value == aia
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)