aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/_cffi_src/openssl/asn1.py1
-rw-r--r--src/_cffi_src/openssl/x509v3.py3
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py58
3 files changed, 58 insertions, 4 deletions
diff --git a/src/_cffi_src/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py
index 01d6f4c2..5f8ca697 100644
--- a/src/_cffi_src/openssl/asn1.py
+++ b/src/_cffi_src/openssl/asn1.py
@@ -157,6 +157,7 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *);
int ASN1_STRING_set_default_mask_asc(char *);
int i2d_ASN1_TYPE(ASN1_TYPE *, unsigned char **);
+ASN1_TYPE *d2i_ASN1_TYPE(ASN1_TYPE **, const unsigned char **, long);
"""
CUSTOMIZATIONS = """
diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
index 0f5306d0..8e42b65d 100644
--- a/src/_cffi_src/openssl/x509v3.py
+++ b/src/_cffi_src/openssl/x509v3.py
@@ -193,6 +193,9 @@ void AUTHORITY_KEYID_free(AUTHORITY_KEYID *);
NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void);
void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *);
+OTHERNAME *OTHERNAME_new(void);
+void OTHERNAME_free(OTHERNAME *);
+
void *X509V3_set_ctx_nodb(X509V3_CTX *);
int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index d6493778..637b28cc 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -83,14 +83,22 @@ def _encode_asn1_str(backend, data, length):
Create an ASN1_OCTET_STRING from a Python byte string.
"""
s = backend._lib.ASN1_OCTET_STRING_new()
+ res = backend._lib.ASN1_OCTET_STRING_set(s, data, length)
+ assert res == 1
+ return s
+
+
+def _encode_asn1_str_gc(backend, data, length):
+ s = _encode_asn1_str(backend, data, length)
s = backend._ffi.gc(s, backend._lib.ASN1_OCTET_STRING_free)
- backend._lib.ASN1_OCTET_STRING_set(s, data, length)
return s
def _encode_name(backend, attributes):
+ """
+ The X509_NAME created will not be gc'd. Use _encode_name_gc if needed.
+ """
subject = backend._lib.X509_NAME_new()
- subject = backend._ffi.gc(subject, backend._lib.X509_NAME_free)
for attribute in attributes:
value = attribute.value.encode('utf8')
obj = _txt2obj(backend, attribute.oid.dotted_string)
@@ -105,6 +113,12 @@ def _encode_name(backend, attributes):
return subject
+def _encode_name_gc(backend, attributes):
+ subject = _encode_name(backend, attributes)
+ subject = backend._ffi.gc(subject, backend._lib.X509_NAME_free)
+ return subject
+
+
def _txt2obj(backend, name):
"""
Converts a Python string with an ASN.1 object ID in dotted form to a
@@ -171,6 +185,42 @@ def _encode_subject_alt_name(backend, san):
)
assert obj != backend._ffi.NULL
gn.d.registeredID = obj
+ elif isinstance(alt_name, x509.DirectoryName):
+ gn = backend._lib.GENERAL_NAME_new()
+ assert gn != backend._ffi.NULL
+ name = _encode_name(backend, alt_name.value)
+ gn.type = backend._lib.GEN_DIRNAME
+ gn.d.directoryName = name
+ elif isinstance(alt_name, x509.IPAddress):
+ gn = backend._lib.GENERAL_NAME_new()
+ assert gn != backend._ffi.NULL
+ ipaddr = _encode_asn1_str(
+ backend, alt_name.value.packed, len(alt_name.value.packed)
+ )
+ gn.type = backend._lib.GEN_IPADD
+ gn.d.iPAddress = ipaddr
+ elif isinstance(alt_name, x509.OtherName):
+ gn = backend._lib.GENERAL_NAME_new()
+ assert gn != backend._ffi.NULL
+ other_name = backend._lib.OTHERNAME_new()
+ assert other_name != backend._ffi.NULL
+
+ type_id = backend._lib.OBJ_txt2obj(
+ alt_name.type_id.dotted_string.encode('ascii'), 1
+ )
+ assert type_id != backend._ffi.NULL
+ data = backend._ffi.new("unsigned char[]", alt_name.value)
+ data_ptr_ptr = backend._ffi.new("unsigned char **")
+ data_ptr_ptr[0] = data
+ value = backend._lib.d2i_ASN1_TYPE(
+ backend._ffi.NULL, data_ptr_ptr, len(alt_name.value)
+ )
+ if value == backend._ffi.NULL:
+ raise ValueError("Invalid ASN.1 data")
+ other_name.type_id = type_id
+ other_name.value = value
+ gn.type = backend._lib.GEN_OTHERNAME
+ gn.d.otherName = other_name
else:
raise NotImplementedError(
"Only DNSName and RegisteredID supported right now"
@@ -874,7 +924,7 @@ class Backend(object):
# Set subject name.
res = self._lib.X509_REQ_set_subject_name(
- x509_req, _encode_name(self, builder._subject_name)
+ x509_req, _encode_name_gc(self, builder._subject_name)
)
assert res == 1
@@ -905,7 +955,7 @@ class Backend(object):
self._ffi.NULL,
obj,
1 if extension.critical else 0,
- _encode_asn1_str(self, pp[0], r),
+ _encode_asn1_str_gc(self, pp[0], r),
)
assert extension != self._ffi.NULL
res = self._lib.sk_X509_EXTENSION_push(extensions, extension)