aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/_cffi_src/openssl/asn1.py5
-rw-r--r--src/_cffi_src/openssl/x509v3.py6
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py63
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py1
-rw-r--r--src/cryptography/x509.py4
5 files changed, 61 insertions, 18 deletions
diff --git a/src/_cffi_src/openssl/asn1.py b/src/_cffi_src/openssl/asn1.py
index c18708c5..5210c7c9 100644
--- a/src/_cffi_src/openssl/asn1.py
+++ b/src/_cffi_src/openssl/asn1.py
@@ -42,7 +42,7 @@ typedef struct asn1_string_st ASN1_OCTET_STRING;
typedef struct asn1_string_st ASN1_IA5STRING;
typedef ... ASN1_BIT_STRING;
typedef ... ASN1_OBJECT;
-typedef ... ASN1_STRING;
+typedef struct asn1_string_st ASN1_STRING;
typedef ... ASN1_TYPE;
typedef ... ASN1_GENERALIZEDTIME;
typedef ... ASN1_ENUMERATED;
@@ -87,6 +87,9 @@ ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void);
void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *);
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int);
+/* ASN1 IA5STRING */
+ASN1_IA5STRING *ASN1_IA5STRING_new(void);
+
/* ASN1 INTEGER */
ASN1_INTEGER *ASN1_INTEGER_new(void);
void ASN1_INTEGER_free(ASN1_INTEGER *);
diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py
index 166fa59d..36d90911 100644
--- a/src/_cffi_src/openssl/x509v3.py
+++ b/src/_cffi_src/openssl/x509v3.py
@@ -172,7 +172,9 @@ FUNCTIONS = """
int X509V3_EXT_add_alias(int, int);
void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int);
X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *);
+GENERAL_NAME *GENERAL_NAME_new(void);
int GENERAL_NAME_print(BIO *, GENERAL_NAME *);
+GENERAL_NAMES *GENERAL_NAMES_new(void);
void GENERAL_NAMES_free(GENERAL_NAMES *);
void *X509V3_EXT_d2i(X509_EXTENSION *);
"""
@@ -183,6 +185,7 @@ MACROS = """
int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **);
BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void);
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 *);
@@ -191,6 +194,9 @@ NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void);
void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *);
void *X509V3_set_ctx_nodb(X509V3_CTX *);
+
+int i2d_GENERAL_NAMES(GENERAL_NAMES *, 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);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 88a17de0..51f68899 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -115,9 +115,7 @@ def _txt2obj(backend, name):
return obj
-def _encode_basic_constraints(backend, basic_constraints, critical):
- obj = _txt2obj(backend, x509.OID_BASIC_CONSTRAINTS.dotted_string)
- assert obj is not None
+def _encode_basic_constraints(backend, basic_constraints):
constraints = backend._lib.BASIC_CONSTRAINTS_new()
constraints = backend._ffi.gc(
constraints, backend._lib.BASIC_CONSTRAINTS_free
@@ -135,18 +133,37 @@ def _encode_basic_constraints(backend, basic_constraints, critical):
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
+ # TODO: GC
+
+ for alt_name in san:
+ assert isinstance(alt_name, x509.DNSName)
+ gn = backend._lib.GENERAL_NAME_new()
+ assert gn != backend._ffi.NULL
+ gn.type = backend._lib.GEN_DNS
+ ia5 = backend._lib.ASN1_IA5STRING_new()
+ assert ia5 != backend._ffi.NULL
+ gn.d.dNSName = ia5
+ # TODO: idna
+ value = alt_name.value.encode("ascii")
+ res = backend._lib.ASN1_STRING_set(gn.d.dNSName, value, len(value))
+ assert res == 1
- # Wrap that in an X509 extension object.
- extension = backend._lib.X509_EXTENSION_create_by_OBJ(
- backend._ffi.NULL,
- obj,
- 1 if critical else 0,
- _encode_asn1_str(backend, pp[0], r),
- )
- assert extension != backend._ffi.NULL
+ res = backend._lib.sk_GENERAL_NAME_push(general_names, gn)
+ assert res == 1
- # Return the wrapped extension.
- return extension
+ pp = backend._ffi.new("unsigned char **")
+ r = backend._lib.i2d_GENERAL_NAMES(general_names, pp)
+ assert r > 0
+ pp = backend._ffi.gc(
+ pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0])
+ )
+ return pp, r
@utils.register_interface(CipherBackend)
@@ -855,13 +872,25 @@ class Backend(object):
)
for extension in builder._extensions:
if isinstance(extension.value, x509.BasicConstraints):
- extension = _encode_basic_constraints(
- self,
- extension.value,
- extension.critical
+ pp, r = _encode_basic_constraints(
+ self, extension.value,
+ )
+ elif isinstance(extension.value, x509.SubjectAlternativeName):
+ pp, r = _encode_subject_alt_name(
+ self, extension.value,
)
else:
raise NotImplementedError('Extension not yet supported.')
+
+ obj = _txt2obj(self, extension.oid.dotted_string)
+ extension = backend._lib.X509_EXTENSION_create_by_OBJ(
+ backend._ffi.NULL,
+ obj,
+ 1 if extension.critical else 0,
+ _encode_asn1_str(backend, pp[0], r)
+ )
+ assert extension != backend._ffi.NULL
+
res = self._lib.sk_X509_EXTENSION_push(extensions, extension)
assert res == 1
res = self._lib.X509_REQ_add_extensions(x509_req, extensions)
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index cc805755..804bce66 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -736,5 +736,6 @@ _CSR_EXTENSION_PARSER = _X509ExtensionParser(
get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i),
handlers={
x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints,
+ x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name,
}
)
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 668bc2ef..a091cd78 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -1472,6 +1472,10 @@ class CertificateSigningRequestBuilder(object):
extension = Extension(
OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
)
+ elif isinstance(extension, KeyUsage):
+ extension = Extension(
+ OID_KEY_USAGE, critical, extension
+ )
else:
raise NotImplementedError('Unsupported X.509 extension.')
# TODO: This is quadratic in the number of extensions