From e06cab4de07897fecf6da40b29b460f7d4c258d3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 30 Apr 2015 10:23:33 -0500 Subject: add support for rfc822name general names --- src/cryptography/hazmat/backends/openssl/x509.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 5558f140..a3cf4618 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function import datetime import ipaddress +from email.utils import parseaddr import idna @@ -107,6 +108,21 @@ def _build_general_name(backend, gn): return x509.DirectoryName( _build_x509_name(backend, gn.d.directoryName) ) + elif gn.type == backend._lib.GEN_EMAIL: + data = backend._ffi.buffer( + gn.d.rfc822Name.data, gn.d.rfc822Name.length + )[:].decode("ascii") + name, address = parseaddr(data) + parts = address.split("@") + if name or len(parts) > 2: + raise ValueError("Invalid rfc822name value") + else: + if len(parts) == 1: + return x509.RFC822Name(address) + else: + return x509.RFC822Name( + parts[0] + u"@" + idna.decode(parts[1]) + ) else: # otherName, x400Address or ediPartyName raise x509.UnsupportedGeneralNameType( -- cgit v1.2.3 From cf2a5a504e8082477788aa627f2e8f132dbc4461 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 1 May 2015 23:01:40 -0500 Subject: improve if/elif chain, add some comments --- src/cryptography/hazmat/backends/openssl/x509.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index a3cf4618..13684bcc 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -115,14 +115,19 @@ def _build_general_name(backend, gn): name, address = parseaddr(data) parts = address.split("@") if name or len(parts) > 2: + # parseaddr has found a name (e.g. Name ) or the split + # has found more than 2 parts (which means more than one @ sign) raise ValueError("Invalid rfc822name value") + elif len(parts) == 1: + # Single label email name. This is valid for local delivery. No + # IDNA decoding can be done since there is no domain component. + return x509.RFC822Name(address) else: - if len(parts) == 1: - return x509.RFC822Name(address) - else: - return x509.RFC822Name( - parts[0] + u"@" + idna.decode(parts[1]) - ) + # A normal email of the form user@domain.com. Let's attempt to + # decode the domain component and return the entire address. + return x509.RFC822Name( + parts[0] + u"@" + idna.decode(parts[1]) + ) else: # otherName, x400Address or ediPartyName raise x509.UnsupportedGeneralNameType( -- cgit v1.2.3 From 778bc6092139dca93f1a9ac4311eafeaa7ebf107 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 15:16:41 -0500 Subject: u prefixes for everyone --- src/cryptography/hazmat/backends/openssl/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 13684bcc..e311e6ab 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -113,7 +113,7 @@ def _build_general_name(backend, gn): gn.d.rfc822Name.data, gn.d.rfc822Name.length )[:].decode("ascii") name, address = parseaddr(data) - parts = address.split("@") + parts = address.split(u"@") if name or len(parts) > 2: # parseaddr has found a name (e.g. Name ) or the split # has found more than 2 parts (which means more than one @ sign) -- cgit v1.2.3 From e518faefba934a2bbf2589458170d50a69f9bdfc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 18:50:56 -0500 Subject: error if it's all empty --- src/cryptography/hazmat/backends/openssl/x509.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index e311e6ab..25cb5704 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -114,9 +114,10 @@ def _build_general_name(backend, gn): )[:].decode("ascii") name, address = parseaddr(data) parts = address.split(u"@") - if name or len(parts) > 2: + if name or len(parts) > 2 or not address: # parseaddr has found a name (e.g. Name ) or the split # has found more than 2 parts (which means more than one @ sign) + # or the entire value is an empty string. raise ValueError("Invalid rfc822name value") elif len(parts) == 1: # Single label email name. This is valid for local delivery. No -- cgit v1.2.3 From b047617df8aeb51efed4ed761ff84c8b49cfced0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 19:34:51 -0500 Subject: add eq/ne to ExtendedKeyUsage --- src/cryptography/x509.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b22ac8be..6fcbfe6f 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -277,11 +277,10 @@ class Extension(object): class ExtendedKeyUsage(object): def __init__(self, usages): - for oid in usages: - if not isinstance(oid, ObjectIdentifier): - raise TypeError( - "Every item in the usages list must be an ObjectIdentifier" - ) + if not all(isinstance(x, ObjectIdentifier) for x in usages): + raise TypeError( + "Every item in the usages list must be an ObjectIdentifier" + ) self._usages = usages @@ -294,6 +293,17 @@ class ExtendedKeyUsage(object): def __repr__(self): return "".format(self._usages) + def __eq__(self, other): + if not isinstance(other, ExtendedKeyUsage): + return NotImplemented + + return ( + self._usages == other._usages + ) + + def __ne__(self, other): + return not self == other + class BasicConstraints(object): def __init__(self, ca, path_length): -- cgit v1.2.3 From f24bad7ee68fe0a10756f428d3bc742c53e22efa Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 19:36:20 -0500 Subject: let's not wrap this for no reason --- src/cryptography/x509.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 6fcbfe6f..a37e2d08 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -297,9 +297,7 @@ class ExtendedKeyUsage(object): if not isinstance(other, ExtendedKeyUsage): return NotImplemented - return ( - self._usages == other._usages - ) + return self._usages == other._usages def __ne__(self, other): return not self == other -- cgit v1.2.3 From 94c6960ca70b3e5b2fcf8bed8aaf2fd983f8c1c5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 19:29:40 -0500 Subject: Extended key usage support for the openssl backend --- src/cryptography/hazmat/backends/openssl/x509.py | 20 ++++++++++++++++++++ src/cryptography/hazmat/bindings/openssl/x509.py | 6 ++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 4ba66bb7..dd2aba65 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -267,6 +267,8 @@ class _Certificate(object): value = self._build_key_usage(ext) elif oid == x509.OID_SUBJECT_ALTERNATIVE_NAME: value = self._build_subject_alt_name(ext) + elif oid == x509.OID_EXTENDED_KEY_USAGE: + value = self._build_extended_key_usage(ext) elif critical: raise x509.UnsupportedExtension( "{0} is not currently supported".format(oid), oid @@ -366,6 +368,24 @@ class _Certificate(object): return x509.SubjectAlternativeName(general_names) + def _build_extended_key_usage(self, ext): + sk = self._backend._ffi.cast( + "Cryptography_STACK_OF_ASN1_OBJECT *", + self._backend._lib.X509V3_EXT_d2i(ext) + ) + assert sk != self._backend._ffi.NULL + sk = self._backend._ffi.gc(sk, self._backend._lib.sk_ASN1_OBJECT_free) + num = self._backend._lib.sk_ASN1_OBJECT_num(sk) + ekus = [] + + for i in range(num): + obj = self._backend._lib.sk_ASN1_OBJECT_value(sk, i) + assert obj != self._backend._ffi.NULL + oid = x509.ObjectIdentifier(_obj2txt(self._backend, obj)) + ekus.append(oid) + + return x509.ExtendedKeyUsage(ekus) + @utils.register_interface(x509.CertificateSigningRequest) class _CertificateSigningRequest(object): diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py index a1fb7ffb..0c6c325d 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509.py +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -17,6 +17,7 @@ INCLUDES = """ typedef STACK_OF(X509) Cryptography_STACK_OF_X509; typedef STACK_OF(X509_CRL) Cryptography_STACK_OF_X509_CRL; typedef STACK_OF(X509_REVOKED) Cryptography_STACK_OF_X509_REVOKED; +typedef STACK_OF(ASN1_OBJECT) Cryptography_STACK_OF_ASN1_OBJECT; """ TYPES = """ @@ -303,6 +304,11 @@ EC_KEY *d2i_EC_PUBKEY_bio(BIO *, EC_KEY **); int i2d_EC_PUBKEY_bio(BIO *, EC_KEY *); EC_KEY *d2i_ECPrivateKey_bio(BIO *, EC_KEY **); int i2d_ECPrivateKey_bio(BIO *, EC_KEY *); + +// declared in safestack +int sk_ASN1_OBJECT_num(Cryptography_STACK_OF_ASN1_OBJECT *); +ASN1_OBJECT *sk_ASN1_OBJECT_value(Cryptography_STACK_OF_ASN1_OBJECT *, int); +void sk_ASN1_OBJECT_free(Cryptography_STACK_OF_ASN1_OBJECT *); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From e94f0fdf6ec8f9860d2e8d04aa31a4e0d879d2cc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 21:16:36 -0500 Subject: oops this was already defined --- src/cryptography/hazmat/bindings/openssl/x509.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py index 0c6c325d..fa6a16b3 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509.py +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -17,7 +17,6 @@ INCLUDES = """ typedef STACK_OF(X509) Cryptography_STACK_OF_X509; typedef STACK_OF(X509_CRL) Cryptography_STACK_OF_X509_CRL; typedef STACK_OF(X509_REVOKED) Cryptography_STACK_OF_X509_REVOKED; -typedef STACK_OF(ASN1_OBJECT) Cryptography_STACK_OF_ASN1_OBJECT; """ TYPES = """ -- cgit v1.2.3 From 3e6d558d1b845cf2df31efec08235b15998174d4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 21:57:56 -0500 Subject: add authority information access classes --- src/cryptography/x509.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index a37e2d08..2bbd14d7 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -67,6 +67,8 @@ _OID_NAMES = { "1.3.6.1.5.5.7.1.1": "authorityInfoAccess", "1.3.6.1.5.5.7.1.11": "subjectInfoAccess", "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck", + "1.3.6.1.5.5.7.48.2": "caIssuers", + "1.3.6.1.5.5.7.48.1": "OCSP", } @@ -394,6 +396,68 @@ class KeyUsage(object): self, encipher_only, decipher_only) +class AuthorityInformationAccess(object): + def __init__(self, descriptions): + if not all(isinstance(x, AccessDescription) for x in descriptions): + raise TypeError( + "Every item in the descriptions list must be an " + "AccessDescription" + ) + + self._descriptions = descriptions + + def __iter__(self): + return iter(self._descriptions) + + def __len__(self): + return len(self._descriptions) + + def __repr__(self): + return "".format(self._descriptions) + + def __eq__(self, other): + if not isinstance(other, AuthorityInformationAccess): + return NotImplemented + + return self._descriptions == other._descriptions + + def __ne__(self, other): + return not self == other + + +class AccessDescription(object): + def __init__(self, access_method, access_location): + if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS): + raise TypeError("access_method must be OID_OCSP or OID_CA_ISSUERS") + + if not isinstance(access_location, GeneralName): + raise TypeError("access_location must be a GeneralName") + + self._access_method = access_method + self._access_location = access_location + + def __repr__(self): + return ( + "".format(self) + ) + + def __eq__(self, other): + if not isinstance(other, AccessDescription): + return NotImplemented + + return ( + self.access_method == other.access_method and + self.access_location == other.access_location + ) + + def __ne__(self, other): + return not self == other + + access_method = utils.read_only_property("_access_method") + access_location = utils.read_only_property("_access_location") + + class SubjectKeyIdentifier(object): def __init__(self, digest): self._digest = digest @@ -680,6 +744,9 @@ OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4") OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8") OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9") +OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2") +OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1") + @six.add_metaclass(abc.ABCMeta) class Certificate(object): -- cgit v1.2.3 From f506bca3d2bb449c3889cbbaba11749304e81563 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 2 May 2015 22:31:47 -0500 Subject: updates based on review feedback --- src/cryptography/x509.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 2bbd14d7..27337092 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -67,8 +67,8 @@ _OID_NAMES = { "1.3.6.1.5.5.7.1.1": "authorityInfoAccess", "1.3.6.1.5.5.7.1.11": "subjectInfoAccess", "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck", - "1.3.6.1.5.5.7.48.2": "caIssuers", "1.3.6.1.5.5.7.48.1": "OCSP", + "1.3.6.1.5.5.7.48.2": "caIssuers", } @@ -428,7 +428,9 @@ class AuthorityInformationAccess(object): class AccessDescription(object): def __init__(self, access_method, access_location): if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS): - raise TypeError("access_method must be OID_OCSP or OID_CA_ISSUERS") + raise ValueError( + "access_method must be OID_OCSP or OID_CA_ISSUERS" + ) if not isinstance(access_location, GeneralName): raise TypeError("access_location must be a GeneralName") -- cgit v1.2.3 From c6e0f06135d36533a7543b0a24f144b44019a9dc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 3 May 2015 11:04:34 -0500 Subject: Fix AKI authority_cert_issuer type It was originally defined as an X509 Name, but in reality it is a list of GeneralName objects (albeit typically a list of one DirectoryName). --- src/cryptography/x509.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 27337092..0d87cd51 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -666,8 +666,13 @@ class AuthorityKeyIdentifier(object): "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( -- cgit v1.2.3 From d774de9d49512a16b58e1461dd982c072fd36b8e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 3 May 2015 10:52:25 -0500 Subject: authority key identifier support in the openssl backend --- src/cryptography/hazmat/backends/openssl/x509.py | 41 ++++++++++++++++++++++ src/cryptography/hazmat/bindings/openssl/x509v3.py | 3 ++ 2 files changed, 44 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index dd2aba65..c6b85c9f 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -269,6 +269,8 @@ class _Certificate(object): 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 @@ class _Certificate(object): 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 28dd7f32..311261f0 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -109,6 +109,9 @@ MACROS = """ /* 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 *); -- cgit v1.2.3 From 118d49601551d59572e30e19b3a0ae7a0df6d3e9 Mon Sep 17 00:00:00 2001 From: Eeshan Garg Date: Mon, 4 May 2015 17:41:47 +0530 Subject: Add OpenSSL binding for SSL_get_tlsext_status_ocsp_resp --- src/cryptography/hazmat/bindings/openssl/ssl.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index 4a824ae5..6493e867 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -325,6 +325,7 @@ void SSL_CTX_set_tlsext_servername_callback( is fraught with peril thanks to OS distributions we check some constants to determine if they are supported or not */ long SSL_set_tlsext_status_ocsp_resp(SSL *, unsigned char *, int); +long SSL_get_tlsext_status_ocsp_resp(SSL *, const unsigned char **); long SSL_CTX_set_tlsext_status_cb(SSL_CTX *, int(*)(SSL *, void *)); long SSL_session_reused(SSL *); @@ -434,6 +435,7 @@ static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP = 1; #else static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP = 0; long (*SSL_set_tlsext_status_ocsp_resp)(SSL *, unsigned char *, int) = NULL; +long (*SSL_get_tlsext_status_ocsp_resp)(SSL *, const unsigned char **) = NULL; #endif #ifdef SSL_MODE_RELEASE_BUFFERS @@ -620,6 +622,7 @@ CONDITIONAL_NAMES = { "Cryptography_HAS_STATUS_REQ_OCSP_RESP": [ "SSL_set_tlsext_status_ocsp_resp", + "SSL_get_tlsext_status_ocsp_resp", ], "Cryptography_HAS_RELEASE_BUFFERS": [ -- cgit v1.2.3 From b6bca759310cf9e4917348386139b5ebab15b863 Mon Sep 17 00:00:00 2001 From: Terry Chia Date: Mon, 4 May 2015 22:25:30 +0800 Subject: Rewrite check to read clearer. --- src/cryptography/hazmat/primitives/kdf/hkdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py index 65b7091a..f738bbdc 100644 --- a/src/cryptography/hazmat/primitives/kdf/hkdf.py +++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py @@ -26,7 +26,7 @@ class HKDF(object): self._algorithm = algorithm - if not isinstance(salt, bytes) and salt is not None: + if not (salt is None or isinstance(salt, bytes)): raise TypeError("salt must be bytes.") if salt is None: @@ -77,7 +77,7 @@ class HKDFExpand(object): self._length = length - if not isinstance(info, bytes) and info is not None: + if not (info is None or isinstance(info, bytes)): raise TypeError("info must be bytes.") if info is None: -- cgit v1.2.3 From a147699cabf935b0c770d5c72fb8d2305737d66a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 4 May 2015 17:35:47 -0500 Subject: add support for authority information access in the openssl backend --- src/cryptography/hazmat/backends/openssl/x509.py | 23 ++++++++++++++++++++++ src/cryptography/hazmat/bindings/openssl/x509v3.py | 14 +++++++++++++ 2 files changed, 37 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index c6b85c9f..42ca138d 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -271,6 +271,8 @@ class _Certificate(object): 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 @@ class _Certificate(object): 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 311261f0..c2b6860f 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -19,9 +19,12 @@ typedef LHASH_OF(CONF_VALUE) Cryptography_LHASH_OF_CONF_VALUE; #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 @@ typedef struct { 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_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); +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 *); -- cgit v1.2.3 From 84d61c817d745784e2cfdc29087c169a6e47ab54 Mon Sep 17 00:00:00 2001 From: Eeshan Garg Date: Tue, 5 May 2015 21:53:15 +0530 Subject: Add OpenSSL binding for SSL_set_tlsext_status_type --- src/cryptography/hazmat/bindings/openssl/ssl.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index 6493e867..22ff9bf0 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -22,6 +22,7 @@ static const long Cryptography_HAS_SECURE_RENEGOTIATION; static const long Cryptography_HAS_COMPRESSION; static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB; static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP; +static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE; /* Internally invented symbol to tell us if SNI is supported */ static const long Cryptography_HAS_TLSEXT_HOSTNAME; @@ -326,6 +327,7 @@ void SSL_CTX_set_tlsext_servername_callback( to determine if they are supported or not */ long SSL_set_tlsext_status_ocsp_resp(SSL *, unsigned char *, int); long SSL_get_tlsext_status_ocsp_resp(SSL *, const unsigned char **); +long SSL_set_tlsext_status_type(SSL *, long); long SSL_CTX_set_tlsext_status_cb(SSL_CTX *, int(*)(SSL *, void *)); long SSL_session_reused(SSL *); @@ -438,6 +440,13 @@ long (*SSL_set_tlsext_status_ocsp_resp)(SSL *, unsigned char *, int) = NULL; long (*SSL_get_tlsext_status_ocsp_resp)(SSL *, const unsigned char **) = NULL; #endif +#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE +static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE = 1; +#else +static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE = 0; +long (*SSL_set_tlsext_status_type)(SSL *, long) = NULL; +#endif + #ifdef SSL_MODE_RELEASE_BUFFERS static const long Cryptography_HAS_RELEASE_BUFFERS = 1; #else @@ -625,6 +634,10 @@ CONDITIONAL_NAMES = { "SSL_get_tlsext_status_ocsp_resp", ], + "Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE": [ + "SSL_set_tlsext_status_type", + ], + "Cryptography_HAS_RELEASE_BUFFERS": [ "SSL_MODE_RELEASE_BUFFERS", ], -- cgit v1.2.3 From 5a48552b4b7fc4d108b6d45232769f111fe38896 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 6 May 2015 00:29:12 -0500 Subject: add CRLDistributionPoints and associated classes --- src/cryptography/x509.py | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 0d87cd51..671294e2 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -481,6 +481,150 @@ class SubjectKeyIdentifier(object): return not self == other +class CRLDistributionPoints(object): + def __init__(self, distribution_points): + if not all( + isinstance(x, DistributionPoint) for x in distribution_points + ): + raise TypeError( + "distribution_points must be a list of DistributionPoint " + "objects" + ) + + self._distribution_points = distribution_points + + def __iter__(self): + return iter(self._distribution_points) + + def __len__(self): + return len(self._distribution_points) + + def __repr__(self): + return "".format(self._distribution_points) + + def __eq__(self, other): + if not isinstance(other, CRLDistributionPoints): + return NotImplemented + + return self._distribution_points == other._distribution_points + + def __ne__(self, other): + return not self == other + + +class DistributionPoint(object): + def __init__(self, distribution_point, reasons, crl_issuer): + if distribution_point: + if ( + ( + isinstance(distribution_point, list) and + not all( + isinstance(x, GeneralName) for x in distribution_point + ) + ) or not isinstance(distribution_point, (list, Name)) + ): + raise TypeError( + "distribution_point must be None, a list of general names" + ", or a Name" + ) + + if crl_issuer and not all( + isinstance(x, GeneralName) for x in crl_issuer + ): + raise TypeError( + "crl_issuer must be None or a list of general names" + ) + + if reasons and not isinstance(reasons, ReasonFlags): + raise TypeError("reasons must be None or ReasonFlags") + + if reasons and not crl_issuer and not distribution_point: + raise ValueError( + "You must supply crl_issuer or distribution_point when " + "reasons is not None" + ) + + self._distribution_point = distribution_point + self._reasons = reasons + self._crl_issuer = crl_issuer + + def __repr__(self): + return ( + "".format(self) + ) + + def __eq__(self, other): + if not isinstance(other, DistributionPoint): + return NotImplemented + + return ( + self.distribution_point == other.distribution_point and + self.reasons == other.reasons and + self.crl_issuer == other.crl_issuer + ) + + def __ne__(self, other): + return not self == other + + distribution_point = utils.read_only_property("_distribution_point") + reasons = utils.read_only_property("_reasons") + crl_issuer = utils.read_only_property("_crl_issuer") + + +class ReasonFlags(object): + def __init__(self, key_compromise, ca_compromise, affiliation_changed, + superseded, cessation_of_operation, certificate_hold, + privilege_withdrawn, aa_compromise): + self._key_compromise = key_compromise + self._ca_compromise = ca_compromise + self._affiliation_changed = affiliation_changed + self._superseded = superseded + self._cessation_of_operation = cessation_of_operation + self._certificate_hold = certificate_hold + self._privilege_withdrawn = privilege_withdrawn + self._aa_compromise = aa_compromise + + def __repr__(self): + return ( + "".format(self) + ) + + def __eq__(self, other): + if not isinstance(other, ReasonFlags): + return NotImplemented + + return ( + self.key_compromise == other.key_compromise and + self.ca_compromise == other.ca_compromise and + self.affiliation_changed == other.affiliation_changed and + self.superseded == other.superseded and + self.cessation_of_operation == other.cessation_of_operation and + self.certificate_hold == other.certificate_hold and + self.privilege_withdrawn == other.privilege_withdrawn and + self.aa_compromise == other.aa_compromise + ) + + def __ne__(self, other): + return not self == other + + key_compromise = utils.read_only_property("_key_compromise") + ca_compromise = utils.read_only_property("_ca_compromise") + affiliation_changed = utils.read_only_property("_affiliation_changed") + superseded = utils.read_only_property("_superseded") + cessation_of_operation = utils.read_only_property( + "_cessation_of_operation" + ) + certificate_hold = utils.read_only_property("_certificate_hold") + privilege_withdrawn = utils.read_only_property("_privilege_withdrawn") + aa_compromise = utils.read_only_property("_aa_compromise") + + @six.add_metaclass(abc.ABCMeta) class GeneralName(object): @abc.abstractproperty -- cgit v1.2.3 From c969e89a7936359c582b76a1ffe5968d2c4165fb Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 6 May 2015 22:01:37 +0100 Subject: Expand out definition of X509_STORE_CTX --- src/cryptography/hazmat/bindings/openssl/x509_vfy.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py index 1f75b86f..1334d72d 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py +++ b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py @@ -29,9 +29,22 @@ static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE; typedef ... Cryptography_STACK_OF_ASN1_OBJECT; typedef ... X509_STORE; -typedef ... X509_STORE_CTX; typedef ... X509_VERIFY_PARAM; +typedef struct x509_store_ctx_st { + X509_STORE *ctx; + int current_method; + X509 *cert; + Cryptography_STACK_OF_X509 *untrusted; + Cryptography_STACK_OF_X509_CRL *crls; + X509_VERIFY_PARAM *param; + void *other_ctx; + int (*verify)(struct x509_store_ctx_st *ctx); + int (*verify_cb)(int ok,struct x509_store_ctx_st *ctx); + int (*get_issuer)(X509 **issuer, struct x509_store_ctx_st *ctx, X509 *x); + ...; +} X509_STORE_CTX; + /* While these are defined in the source as ints, they're tagged here as longs, just in case they ever grow to large, such as what we saw with OP_ALL. */ -- cgit v1.2.3 From 4031b63ad9ea30086f28e9ac97812fc93e7df568 Mon Sep 17 00:00:00 2001 From: Eeshan Garg Date: Thu, 7 May 2015 16:56:35 +0530 Subject: Add OpenSSL binding for SSL_set_verify --- src/cryptography/hazmat/bindings/openssl/ssl.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index 6493e867..e1aad307 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -164,6 +164,7 @@ const char *SSL_state_string_long(const SSL *); SSL_SESSION *SSL_get1_session(SSL *); int SSL_set_session(SSL *, SSL_SESSION *); int SSL_get_verify_mode(const SSL *); +void SSL_set_verify(SSL *, int, int (*)(int, X509_STORE_CTX *)); void SSL_set_verify_depth(SSL *, int); int SSL_get_verify_depth(const SSL *); int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *); -- cgit v1.2.3 From 18f913e86f01b1fe5470aa3f3139102d222b0f1e Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Thu, 7 May 2015 19:52:24 +0100 Subject: Cleanup definition --- src/cryptography/hazmat/bindings/openssl/x509_vfy.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py index 1334d72d..02631409 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py +++ b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py @@ -31,7 +31,8 @@ typedef ... Cryptography_STACK_OF_ASN1_OBJECT; typedef ... X509_STORE; typedef ... X509_VERIFY_PARAM; -typedef struct x509_store_ctx_st { +typedef struct x509_store_ctx_st X509_STORE_CTX; +struct x509_store_ctx_st { X509_STORE *ctx; int current_method; X509 *cert; @@ -39,11 +40,11 @@ typedef struct x509_store_ctx_st { Cryptography_STACK_OF_X509_CRL *crls; X509_VERIFY_PARAM *param; void *other_ctx; - int (*verify)(struct x509_store_ctx_st *ctx); - int (*verify_cb)(int ok,struct x509_store_ctx_st *ctx); - int (*get_issuer)(X509 **issuer, struct x509_store_ctx_st *ctx, X509 *x); + int (*verify)(X509_STORE_CTX *); + int (*verify_cb)(int, X509_STORE_CTX *); + int (*get_issuer)(X509 **, X509_STORE_CTX *, X509 *); ...; -} X509_STORE_CTX; +}; /* While these are defined in the source as ints, they're tagged here as longs, just in case they ever grow to large, such as what we saw -- cgit v1.2.3 From ebbeedfd5d0e98e3e47d6d3af90161225a8a3e4a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 8 May 2015 18:13:14 -0500 Subject: add support for secp256k1 --- src/cryptography/hazmat/primitives/asymmetric/ec.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index bf1705db..96809c10 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -201,6 +201,12 @@ class SECP256R1(object): key_size = 256 +@utils.register_interface(EllipticCurve) +class SECP256K1(object): + name = "secp256k1" + key_size = 256 + + @utils.register_interface(EllipticCurve) class SECP224R1(object): name = "secp224r1" @@ -222,6 +228,7 @@ _CURVE_TYPES = { "secp256r1": SECP256R1, "secp384r1": SECP384R1, "secp521r1": SECP521R1, + "secp256k1": SECP256K1, "sect163k1": SECT163K1, "sect233k1": SECT233K1, -- cgit v1.2.3 From 0dd58bce1b7b976dfe00911eabed9f7ff91f7ffb Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2015 08:46:25 -0500 Subject: add bindings for CRLDistributionPoints (courtesy @etrauschke) --- .../hazmat/bindings/openssl/x509name.py | 5 +++++ src/cryptography/hazmat/bindings/openssl/x509v3.py | 24 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509name.py b/src/cryptography/hazmat/bindings/openssl/x509name.py index bda92eb7..a7dde87c 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509name.py +++ b/src/cryptography/hazmat/bindings/openssl/x509name.py @@ -11,12 +11,14 @@ INCLUDES = """ * See the comment above Cryptography_STACK_OF_X509 in x509.py */ typedef STACK_OF(X509_NAME) Cryptography_STACK_OF_X509_NAME; +typedef STACK_OF(X509_NAME_ENTRY) Cryptography_STACK_OF_X509_NAME_ENTRY; """ TYPES = """ typedef ... X509_NAME; typedef ... X509_NAME_ENTRY; typedef ... Cryptography_STACK_OF_X509_NAME; +typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY; """ FUNCTIONS = """ @@ -48,6 +50,9 @@ int sk_X509_NAME_num(Cryptography_STACK_OF_X509_NAME *); int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *); X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int); void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *); +int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *); +X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value( + Cryptography_STACK_OF_X509_NAME_ENTRY *, int); """ CUSTOMIZATIONS = """ diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index c2b6860f..a21a429a 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -20,6 +20,7 @@ typedef LHASH_OF(CONF_VALUE) Cryptography_LHASH_OF_CONF_VALUE; typedef LHASH Cryptography_LHASH_OF_CONF_VALUE; #endif typedef STACK_OF(ACCESS_DESCRIPTION) Cryptography_STACK_OF_ACCESS_DESCRIPTION; +typedef STACK_OF(DIST_POINT) Cryptography_STACK_OF_DIST_POINT; """ TYPES = """ @@ -101,6 +102,26 @@ typedef struct { } ACCESS_DESCRIPTION; typedef ... Cryptography_LHASH_OF_CONF_VALUE; + + +typedef ... Cryptography_STACK_OF_DIST_POINT; + +typedef struct { + int type; + union { + GENERAL_NAMES *fullname; + Cryptography_STACK_OF_X509_NAME_ENTRY *relativename; + } name; + X509_NAME *dpname; +} DIST_POINT_NAME; + +typedef struct { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +} DIST_POINT; + """ @@ -138,6 +159,9 @@ X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *, const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *); const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int); +void sk_DIST_POINT_free(Cryptography_STACK_OF_DIST_POINT *); +int sk_DIST_POINT_num(Cryptography_STACK_OF_DIST_POINT *); +DIST_POINT *sk_DIST_POINT_value(Cryptography_STACK_OF_DIST_POINT *, int); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From a793eac190ac09544852f3b943ddd0239c5169b9 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2015 08:55:42 -0500 Subject: add crl bindings (courtesy @etrauschke) --- src/cryptography/hazmat/bindings/openssl/x509.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py index fa6a16b3..31250165 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509.py +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -64,6 +64,7 @@ typedef struct { typedef struct { X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; ...; } X509_CRL; @@ -183,6 +184,7 @@ int i2d_X509_CRL_bio(BIO *, X509_CRL *); int X509_CRL_print(BIO *, X509_CRL *); int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *); int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *); +int X509_CRL_verify(X509_CRL *, EVP_PKEY *); int X509_CRL_get_ext_count(X509_CRL *); X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int); int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int); @@ -285,6 +287,7 @@ int X509_CRL_get_version(X509_CRL *); ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *); ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *); X509_NAME *X509_CRL_get_issuer(X509_CRL *); +Cryptography_STACK_OF_X509_REVOKED *X509_CRL_get_REVOKED(X509_CRL *); /* These aren't macros these arguments are all const X on openssl > 1.0.x */ int X509_CRL_set_lastUpdate(X509_CRL *, ASN1_TIME *); -- cgit v1.2.3 From b570bf456a4191785542b2b49bdcfff06e96330e Mon Sep 17 00:00:00 2001 From: Zeev Tarantov Date: Sat, 9 May 2015 09:27:06 +0000 Subject: add support for retreiving value of received temporary key in server key exchange message, to implement functionality like openssl's ssl_print_tmp_key --- src/cryptography/hazmat/bindings/openssl/ec.py | 15 +++++++++++++++ src/cryptography/hazmat/bindings/openssl/evp.py | 4 ++++ src/cryptography/hazmat/bindings/openssl/ssl.py | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/ec.py b/src/cryptography/hazmat/bindings/openssl/ec.py index 84a596eb..c5052d36 100644 --- a/src/cryptography/hazmat/bindings/openssl/ec.py +++ b/src/cryptography/hazmat/bindings/openssl/ec.py @@ -17,6 +17,7 @@ static const int Cryptography_HAS_EC; static const int Cryptography_HAS_EC_1_0_1; static const int Cryptography_HAS_EC_NISTP_64_GCC_128; static const int Cryptography_HAS_EC2M; +static const int Cryptography_HAS_EC_1_0_2; static const int OPENSSL_EC_NAMED_CURVE; @@ -188,6 +189,8 @@ const EC_METHOD *EC_GFp_nistp521_method(); const EC_METHOD *EC_GF2m_simple_method(); int EC_METHOD_get_field_type(const EC_METHOD *); + +const char *EC_curve_nid2nist(int); """ CUSTOMIZATIONS = """ @@ -385,6 +388,14 @@ EC_GROUP *(*EC_GROUP_new_curve_GF2m)( #else static const long Cryptography_HAS_EC2M = 1; #endif + +#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000200f || \ + defined(LIBRESSL_VERSION_NUMBER) +static const long Cryptography_HAS_EC_1_0_2 = 0; +const char *(*EC_curve_nid2nist)(int) = NULL; +#else +static const long Cryptography_HAS_EC_1_0_2 = 1; +#endif """ CONDITIONAL_NAMES = { @@ -478,4 +489,8 @@ CONDITIONAL_NAMES = { "EC_GROUP_get_curve_GF2m", "EC_GROUP_new_curve_GF2m", ], + + "Cryptography_HAS_EC_1_0_2": [ + "EC_curve_nid2nist", + ], } diff --git a/src/cryptography/hazmat/bindings/openssl/evp.py b/src/cryptography/hazmat/bindings/openssl/evp.py index 780ce900..93aa83de 100644 --- a/src/cryptography/hazmat/bindings/openssl/evp.py +++ b/src/cryptography/hazmat/bindings/openssl/evp.py @@ -28,6 +28,7 @@ typedef struct evp_pkey_st { typedef ... EVP_PKEY_CTX; static const int EVP_PKEY_RSA; static const int EVP_PKEY_DSA; +static const int EVP_PKEY_DH; static const int EVP_PKEY_EC; static const int EVP_MAX_MD_SIZE; static const int EVP_CTRL_GCM_SET_IVLEN; @@ -154,6 +155,7 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t, const unsigned char *, size_t); int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *); int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *); +int EVP_PKEY_id(const EVP_PKEY *); /* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5 we should move these back to FUNCTIONS. */ @@ -221,6 +223,7 @@ int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t) = NULL; int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, const unsigned char *, size_t) = NULL; +int (*EVP_PKEY_id)(const EVP_PKEY *) = NULL; #endif #ifdef OPENSSL_NO_EC int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; @@ -252,6 +255,7 @@ CONDITIONAL_NAMES = { "Cryptography_EVP_PKEY_decrypt", "EVP_PKEY_decrypt_init", "EVP_PKEY_CTX_set_signature_md", + "EVP_PKEY_id", ], "Cryptography_HAS_EC": [ "EVP_PKEY_assign_EC_KEY", diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index fd719c52..c12624bc 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -23,6 +23,7 @@ static const long Cryptography_HAS_COMPRESSION; static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB; static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP; static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE; +static const long Cryptography_HAS_GET_SERVER_TMP_KEY; /* Internally invented symbol to tell us if SNI is supported */ static const long Cryptography_HAS_TLSEXT_HOSTNAME; @@ -383,6 +384,8 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *, void *), void *); void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *); + +long SSL_get_server_tmp_key(SSL *, EVP_PKEY **); """ CUSTOMIZATIONS = """ @@ -584,6 +587,7 @@ static const long Cryptography_HAS_ALPN = 0; #else static const long Cryptography_HAS_ALPN = 1; #endif + #if defined(OPENSSL_NO_COMP) || defined(LIBRESSL_VERSION_NUMBER) static const long Cryptography_HAS_COMPRESSION = 0; typedef void COMP_METHOD; @@ -591,6 +595,13 @@ typedef void COMP_METHOD; static const long Cryptography_HAS_COMPRESSION = 1; #endif +#if defined(SSL_CTRL_GET_SERVER_TMP_KEY) +static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 1; +#else +static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 0; +long (*SSL_get_server_tmp_key)(SSL *, EVP_PKEY **) = NULL; +#endif + """ CONDITIONAL_NAMES = { @@ -692,5 +703,9 @@ CONDITIONAL_NAMES = { "SSL_get_current_compression", "SSL_get_current_expansion", "SSL_COMP_get_name", - ] + ], + + "Cryptography_HAS_GET_SERVER_TMP_KEY": [ + "SSL_get_server_tmp_key", + ], } -- cgit v1.2.3 From 38b75c1e50e3f90eeb416c8969398bd17d836ae8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2015 09:23:51 -0500 Subject: remove some things not present in 0.9.8 for now --- src/cryptography/hazmat/bindings/openssl/x509v3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index a21a429a..c498f46c 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -112,14 +112,14 @@ typedef struct { GENERAL_NAMES *fullname; Cryptography_STACK_OF_X509_NAME_ENTRY *relativename; } name; - X509_NAME *dpname; + ...; } DIST_POINT_NAME; typedef struct { DIST_POINT_NAME *distpoint; ASN1_BIT_STRING *reasons; GENERAL_NAMES *CRLissuer; - int dp_reasons; + ...; } DIST_POINT; """ -- cgit v1.2.3 From 4e8dacd02ec4c4b8238e5ebdfcd5ab26348ec658 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2015 10:38:23 -0500 Subject: separate full_name/relative_name and change reasons to an enumeration --- src/cryptography/x509.py | 124 +++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 671294e2..cee0cc39 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -513,20 +513,21 @@ class CRLDistributionPoints(object): class DistributionPoint(object): - def __init__(self, distribution_point, reasons, crl_issuer): - if distribution_point: - if ( - ( - isinstance(distribution_point, list) and - not all( - isinstance(x, GeneralName) for x in distribution_point - ) - ) or not isinstance(distribution_point, (list, Name)) - ): - raise TypeError( - "distribution_point must be None, a list of general names" - ", or a Name" - ) + def __init__(self, full_name, relative_name, reasons, crl_issuer): + if full_name and relative_name: + raise ValueError( + "At least one of full_name and relative_name must be None" + ) + + if full_name and not all( + isinstance(x, GeneralName) for x in full_name + ): + raise TypeError( + "full_name must be a list of GeneralName objects" + ) + + if relative_name and not isinstance(relative_name, Name): + raise TypeError("relative_name must be a Name") if crl_issuer and not all( isinstance(x, GeneralName) for x in crl_issuer @@ -535,23 +536,36 @@ class DistributionPoint(object): "crl_issuer must be None or a list of general names" ) - if reasons and not isinstance(reasons, ReasonFlags): - raise TypeError("reasons must be None or ReasonFlags") + if reasons and not all( + isinstance(x, ReasonFlags) for x in reasons + ): + raise TypeError("reasons must be None or list of ReasonFlags") + + if reasons and ( + ReasonFlags.unspecified in reasons or + ReasonFlags.remove_from_crl in reasons + ): + raise ValueError( + "unspecified and remove_from_crl are not valid reasons in a " + "DistributionPoint" + ) - if reasons and not crl_issuer and not distribution_point: + if reasons and not crl_issuer and not (full_name or relative_name): raise ValueError( - "You must supply crl_issuer or distribution_point when " + "You must supply crl_issuer, full_name, or relative_name when " "reasons is not None" ) - self._distribution_point = distribution_point + self._full_name = full_name + self._relative_name = relative_name self._reasons = reasons self._crl_issuer = crl_issuer def __repr__(self): return ( - "".format(self) + "".format(self) ) def __eq__(self, other): @@ -559,7 +573,8 @@ class DistributionPoint(object): return NotImplemented return ( - self.distribution_point == other.distribution_point and + self.full_name == other.full_name and + self.relative_name == other.relative_name and self.reasons == other.reasons and self.crl_issuer == other.crl_issuer ) @@ -567,62 +582,23 @@ class DistributionPoint(object): def __ne__(self, other): return not self == other - distribution_point = utils.read_only_property("_distribution_point") + full_name = utils.read_only_property("_full_name") + relative_name = utils.read_only_property("_relative_name") reasons = utils.read_only_property("_reasons") crl_issuer = utils.read_only_property("_crl_issuer") -class ReasonFlags(object): - def __init__(self, key_compromise, ca_compromise, affiliation_changed, - superseded, cessation_of_operation, certificate_hold, - privilege_withdrawn, aa_compromise): - self._key_compromise = key_compromise - self._ca_compromise = ca_compromise - self._affiliation_changed = affiliation_changed - self._superseded = superseded - self._cessation_of_operation = cessation_of_operation - self._certificate_hold = certificate_hold - self._privilege_withdrawn = privilege_withdrawn - self._aa_compromise = aa_compromise - - def __repr__(self): - return ( - "".format(self) - ) - - def __eq__(self, other): - if not isinstance(other, ReasonFlags): - return NotImplemented - - return ( - self.key_compromise == other.key_compromise and - self.ca_compromise == other.ca_compromise and - self.affiliation_changed == other.affiliation_changed and - self.superseded == other.superseded and - self.cessation_of_operation == other.cessation_of_operation and - self.certificate_hold == other.certificate_hold and - self.privilege_withdrawn == other.privilege_withdrawn and - self.aa_compromise == other.aa_compromise - ) - - def __ne__(self, other): - return not self == other - - key_compromise = utils.read_only_property("_key_compromise") - ca_compromise = utils.read_only_property("_ca_compromise") - affiliation_changed = utils.read_only_property("_affiliation_changed") - superseded = utils.read_only_property("_superseded") - cessation_of_operation = utils.read_only_property( - "_cessation_of_operation" - ) - certificate_hold = utils.read_only_property("_certificate_hold") - privilege_withdrawn = utils.read_only_property("_privilege_withdrawn") - aa_compromise = utils.read_only_property("_aa_compromise") +class ReasonFlags(Enum): + unspecified = "unspecified" + key_compromise = "keyCompromise" + ca_compromise = "cACompromise" + affiliation_changed = "affiliationChanged" + superseded = "superseded" + cessation_of_operation = "cessationOfOperation" + certificate_hold = "certificateHold" + privilege_withdrawn = "privilegeWithdrawn" + aa_compromise = "aACompromise" + remove_from_crl = "removeFromCRL" @six.add_metaclass(abc.ABCMeta) -- cgit v1.2.3 From 3fd0260a3dd110d99c0174c3937aa3d86b0d9ba0 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 9 May 2015 19:46:13 -0500 Subject: switch reasons to frozenset --- src/cryptography/x509.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index cee0cc39..dfc0af8c 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -536,10 +536,10 @@ class DistributionPoint(object): "crl_issuer must be None or a list of general names" ) - if reasons and not all( + if reasons and (not isinstance(reasons, frozenset) or not all( isinstance(x, ReasonFlags) for x in reasons - ): - raise TypeError("reasons must be None or list of ReasonFlags") + )): + raise TypeError("reasons must be None or frozenset of ReasonFlags") if reasons and ( ReasonFlags.unspecified in reasons or -- cgit v1.2.3 From 2b62258a39880518403456bab487360b46ff02f7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 15 Apr 2015 11:04:29 -0400 Subject: certificate policies extension support Adds a bunch of ancillary classes to support this. --- src/cryptography/x509.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index dfc0af8c..3509303f 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -69,6 +69,8 @@ _OID_NAMES = { "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck", "1.3.6.1.5.5.7.48.1": "OCSP", "1.3.6.1.5.5.7.48.2": "caIssuers", + "1.3.6.1.5.5.7.2.1": "id-qt-cps", + "1.3.6.1.5.5.7.2.2": "id-qt-unotice", } @@ -460,6 +462,120 @@ class AccessDescription(object): access_location = utils.read_only_property("_access_location") +class CertificatePolicies(object): + def __init__(self, policies): + if not all(map(lambda x: isinstance(x, PolicyInformation), policies)): + raise TypeError( + "Every item in the policies list must be a " + "PolicyInformation" + ) + + self._policies = policies + + def __iter__(self): + return iter(self._policies) + + def __len__(self): + return len(self._policies) + + def __repr__(self): + return "".format(self._policies) + + +class PolicyInformation(object): + def __init__(self, policy_identifier, policy_qualifiers): + if not isinstance(policy_identifier, ObjectIdentifier): + raise TypeError("policy_identifier must be an ObjectIdentifier") + + self._policy_identifier = policy_identifier + if policy_qualifiers and not all( + map( + lambda x: isinstance(x, PolicyQualifierInfo), policy_qualifiers + ) + ): + raise TypeError( + "policy_qualifiers must be a list of PolicyQualifierInfo " + "objects or None" + ) + + self._policy_qualifiers = policy_qualifiers + + def __repr__(self): + return ( + "".format(self) + ) + + policy_identifier = utils.read_only_property("_policy_identifier") + policy_qualifiers = utils.read_only_property("_policy_qualifiers") + + +class PolicyQualifierInfo(object): + def __init__(self, qualifier): + if not isinstance(qualifier, (six.string_types, UserNotice)): + raise ValueError("qualifier must be string or UserNotice") + + if isinstance(qualifier, six.string_types): + self._policy_qualifier_id = OID_CPS_QUALIFIER + else: + self._policy_qualifier_id = OID_CPS_USER_NOTICE + + self._qualifier = qualifier + + def __repr__(self): + return ( + "".format(self) + ) + + policy_qualifier_id = utils.read_only_property("_policy_qualifier_id") + qualifier = utils.read_only_property("_qualifier") + + +class UserNotice(object): + def __init__(self, notice_reference, explicit_text): + if notice_reference and not isinstance( + notice_reference, NoticeReference + ): + raise TypeError( + "notice_reference must be None or a NoticeReference" + ) + + self._notice_reference = notice_reference + self._explicit_text = explicit_text + + def __repr__(self): + return ( + "".format(self) + ) + + notice_reference = utils.read_only_property("_notice_reference") + explicit_text = utils.read_only_property("_explicit_text") + + +class NoticeReference(object): + def __init__(self, organization, notice_numbers): + self._organization = organization + if notice_numbers and not all( + map(lambda x: isinstance(x, int), notice_numbers) + ): + raise TypeError( + "notice_numbers must be a list of integers or None" + ) + + self._notice_numbers = notice_numbers + + def __repr__(self): + return ( + "".format(self) + ) + + organization = utils.read_only_property("_organization") + notice_numbers = utils.read_only_property("_notice_numbers") + + class SubjectKeyIdentifier(object): def __init__(self, digest): self._digest = digest @@ -874,6 +990,9 @@ OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9") OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2") OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1") +OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1") +OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2") + @six.add_metaclass(abc.ABCMeta) class Certificate(object): -- cgit v1.2.3 From f61ec74821a341e0142297872c95e87b55b7da4d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 18 Apr 2015 20:42:39 -0500 Subject: use list comprehension syntax to make this cleaner --- src/cryptography/x509.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 3509303f..eb7731fc 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -464,7 +464,7 @@ class AccessDescription(object): class CertificatePolicies(object): def __init__(self, policies): - if not all(map(lambda x: isinstance(x, PolicyInformation), policies)): + if not all(isinstance(x, PolicyInformation) for x in policies): raise TypeError( "Every item in the policies list must be a " "PolicyInformation" @@ -489,9 +489,7 @@ class PolicyInformation(object): self._policy_identifier = policy_identifier if policy_qualifiers and not all( - map( - lambda x: isinstance(x, PolicyQualifierInfo), policy_qualifiers - ) + isinstance(x, PolicyQualifierInfo) for x in policy_qualifiers ): raise TypeError( "policy_qualifiers must be a list of PolicyQualifierInfo " @@ -558,7 +556,7 @@ class NoticeReference(object): def __init__(self, organization, notice_numbers): self._organization = organization if notice_numbers and not all( - map(lambda x: isinstance(x, int), notice_numbers) + isinstance(x, int) for x in notice_numbers ): raise TypeError( "notice_numbers must be a list of integers or None" -- cgit v1.2.3 From ba35b3ba85c374dfd0659992cae01255c530679d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 10 May 2015 13:07:59 -0500 Subject: remove policyqualifierinfo object --- src/cryptography/x509.py | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index eb7731fc..b559ae03 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -489,11 +489,13 @@ class PolicyInformation(object): self._policy_identifier = policy_identifier if policy_qualifiers and not all( - isinstance(x, PolicyQualifierInfo) for x in policy_qualifiers + isinstance( + x, (six.text_type, UserNotice) + ) for x in policy_qualifiers ): raise TypeError( - "policy_qualifiers must be a list of PolicyQualifierInfo " - "objects or None" + "policy_qualifiers must be a list of strings and/or UserNotice" + " objects or None" ) self._policy_qualifiers = policy_qualifiers @@ -508,28 +510,6 @@ class PolicyInformation(object): policy_qualifiers = utils.read_only_property("_policy_qualifiers") -class PolicyQualifierInfo(object): - def __init__(self, qualifier): - if not isinstance(qualifier, (six.string_types, UserNotice)): - raise ValueError("qualifier must be string or UserNotice") - - if isinstance(qualifier, six.string_types): - self._policy_qualifier_id = OID_CPS_QUALIFIER - else: - self._policy_qualifier_id = OID_CPS_USER_NOTICE - - self._qualifier = qualifier - - def __repr__(self): - return ( - "".format(self) - ) - - policy_qualifier_id = utils.read_only_property("_policy_qualifier_id") - qualifier = utils.read_only_property("_qualifier") - - class UserNotice(object): def __init__(self, notice_reference, explicit_text): if notice_reference and not isinstance( -- cgit v1.2.3 From d37c5375d5612b170daf8e20c23d0b71bd9af717 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 10 May 2015 16:54:51 -0500 Subject: extract some duplicate logic into a function --- src/cryptography/hazmat/backends/openssl/x509.py | 33 +++++++++++------------- 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 42ca138d..44ad2d6d 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -65,6 +65,17 @@ def _build_x509_name(backend, x509_name): return x509.Name(attributes) +def _build_general_names(backend, gns): + num = backend._lib.sk_GENERAL_NAME_num(gns) + names = [] + for i in range(num): + gn = backend._lib.sk_GENERAL_NAME_value(gns, i) + assert gn != backend._ffi.NULL + names.append(_build_general_name(backend, gn)) + + return names + + def _build_general_name(backend, gn): if gn.type == backend._lib.GEN_DNS: data = backend._ffi.buffer(gn.d.dNSName.data, gn.d.dNSName.length)[:] @@ -342,15 +353,9 @@ class _Certificate(object): )[:] 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) + authority_cert_issuer = _build_general_names( + self._backend, akid.issuer + ) if akid.serial != self._backend._ffi.NULL: bn = self._backend._lib.ASN1_INTEGER_to_BN( @@ -420,15 +425,7 @@ class _Certificate(object): ) assert gns != self._backend._ffi.NULL gns = self._backend._ffi.gc(gns, self._backend._lib.GENERAL_NAMES_free) - num = self._backend._lib.sk_GENERAL_NAME_num(gns) - general_names = [] - - for i in range(num): - gn = self._backend._lib.sk_GENERAL_NAME_value(gns, i) - assert gn != self._backend._ffi.NULL - value = _build_general_name(self._backend, gn) - - general_names.append(value) + general_names = _build_general_names(self._backend, gns) return x509.SubjectAlternativeName(general_names) -- cgit v1.2.3 From 9aaef9e516ae1c54c79f07b0441c21c29f8aeb15 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 11 May 2015 10:49:20 -0500 Subject: use !r for explicit_text in NoticeReference repr --- src/cryptography/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b559ae03..02277658 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -525,7 +525,7 @@ class UserNotice(object): def __repr__(self): return ( "".format(self) + "{0.explicit_text!r})>".format(self) ) notice_reference = utils.read_only_property("_notice_reference") -- cgit v1.2.3 From 73be2ca86049fd15f1ab37d7201a9b32264402ab Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 11 May 2015 21:22:38 -0500 Subject: alter the repr a bit, pass unicode everywhere --- src/cryptography/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 02277658..50fae716 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -546,7 +546,7 @@ class NoticeReference(object): def __repr__(self): return ( - "".format(self) ) -- cgit v1.2.3 From c56ab62c5bce544948825051cdcbf039093d1da4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 3 May 2015 09:56:31 -0500 Subject: add eq/ne methods for all certificate policies classes --- src/cryptography/x509.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 50fae716..cdddfb57 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -481,6 +481,15 @@ class CertificatePolicies(object): def __repr__(self): return "".format(self._policies) + def __eq__(self, other): + if not isinstance(other, CertificatePolicies): + return NotImplemented + + return self._policies == other._policies + + def __ne__(self, other): + return not self == other + class PolicyInformation(object): def __init__(self, policy_identifier, policy_qualifiers): @@ -506,6 +515,18 @@ class PolicyInformation(object): "y_qualifiers={0.policy_qualifiers})>".format(self) ) + def __eq__(self, other): + if not isinstance(other, PolicyInformation): + return NotImplemented + + return ( + self.policy_identifier == other.policy_identifier and + self.policy_qualifiers == other.policy_qualifiers + ) + + def __ne__(self, other): + return not self == other + policy_identifier = utils.read_only_property("_policy_identifier") policy_qualifiers = utils.read_only_property("_policy_qualifiers") @@ -528,6 +549,18 @@ class UserNotice(object): "{0.explicit_text!r})>".format(self) ) + def __eq__(self, other): + if not isinstance(other, UserNotice): + return NotImplemented + + return ( + self.notice_reference == other.notice_reference and + self.explicit_text == other.explicit_text + ) + + def __ne__(self, other): + return not self == other + notice_reference = utils.read_only_property("_notice_reference") explicit_text = utils.read_only_property("_explicit_text") @@ -550,6 +583,18 @@ class NoticeReference(object): "{0.notice_numbers})>".format(self) ) + def __eq__(self, other): + if not isinstance(other, NoticeReference): + return NotImplemented + + return ( + self.organization == other.organization and + self.notice_numbers == other.notice_numbers + ) + + def __ne__(self, other): + return not self == other + organization = utils.read_only_property("_organization") notice_numbers = utils.read_only_property("_notice_numbers") -- cgit v1.2.3 From 2ca2eb3cfd2dff414fdf200bd53f5c82f3b6bc9d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 3 May 2015 10:04:57 -0500 Subject: add eq/ne methods for AuthorityKeyIdentifier --- src/cryptography/x509.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index cdddfb57..173fd084 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -950,6 +950,20 @@ class AuthorityKeyIdentifier(object): ")>".format(self) ) + def __eq__(self, other): + if not isinstance(other, AuthorityKeyIdentifier): + return NotImplemented + + return ( + self.key_identifier == other.key_identifier and + self.authority_cert_issuer == other.authority_cert_issuer and + self.authority_cert_serial_number == + other.authority_cert_serial_number + ) + + def __ne__(self, other): + return not self == other + key_identifier = utils.read_only_property("_key_identifier") authority_cert_issuer = utils.read_only_property("_authority_cert_issuer") authority_cert_serial_number = utils.read_only_property( -- cgit v1.2.3 From 5c45c9ddc12eeb52a08277966ce133525af05af5 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 10:47:05 -0500 Subject: some bindings for certificate policies support in openssl --- src/cryptography/hazmat/bindings/openssl/x509v3.py | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index c498f46c..423eb46e 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -21,10 +21,16 @@ typedef LHASH Cryptography_LHASH_OF_CONF_VALUE; #endif typedef STACK_OF(ACCESS_DESCRIPTION) Cryptography_STACK_OF_ACCESS_DESCRIPTION; typedef STACK_OF(DIST_POINT) Cryptography_STACK_OF_DIST_POINT; +typedef STACK_OF(POLICYQUALINFO) Cryptography_STACK_OF_POLICYQUALINFO; +typedef STACK_OF(POLICYINFO) Cryptography_STACK_OF_POLICYINFO; +typedef STACK_OF(ASN1_INTEGER) Cryptography_STACK_OF_ASN1_INTEGER; """ TYPES = """ typedef ... Cryptography_STACK_OF_ACCESS_DESCRIPTION; +typedef ... Cryptography_STACK_OF_POLICYQUALINFO; +typedef ... Cryptography_STACK_OF_POLICYINFO; +typedef ... Cryptography_STACK_OF_ASN1_INTEGER; typedef struct { X509 *issuer_cert; @@ -122,6 +128,32 @@ typedef struct { ...; } DIST_POINT; +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + Cryptography_STACK_OF_ASN1_INTEGER *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + Cryptography_STACK_OF_POLICYQUALINFO *qualifiers; +} POLICYINFO; + +typedef Cryptography_STACK_OF_POLICYINFO CERTIFICATEPOLICIES; + """ -- cgit v1.2.3 From b372eb89647ef96e808287c7749f2ad5cfe9fd0b Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 11:00:09 -0500 Subject: remove some names we don't need in the struct defs --- src/cryptography/hazmat/bindings/openssl/x509v3.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index 423eb46e..4f9eca89 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -128,17 +128,17 @@ typedef struct { ...; } DIST_POINT; -typedef struct NOTICEREF_st { +typedef struct { ASN1_STRING *organization; Cryptography_STACK_OF_ASN1_INTEGER *noticenos; } NOTICEREF; -typedef struct USERNOTICE_st { +typedef struct { NOTICEREF *noticeref; ASN1_STRING *exptext; } USERNOTICE; -typedef struct POLICYQUALINFO_st { +typedef struct { ASN1_OBJECT *pqualid; union { ASN1_IA5STRING *cpsuri; @@ -147,7 +147,7 @@ typedef struct POLICYQUALINFO_st { } d; } POLICYQUALINFO; -typedef struct POLICYINFO_st { +typedef struct { ASN1_OBJECT *policyid; Cryptography_STACK_OF_POLICYQUALINFO *qualifiers; } POLICYINFO; -- cgit v1.2.3 From 31c453dcd722bd7d04860e3de76854eb70014273 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 14:07:24 -0500 Subject: asn1 integer to python integer helper function --- src/cryptography/hazmat/backends/openssl/x509.py | 28 ++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 44ad2d6d..25b7c8c1 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -38,6 +38,13 @@ def _obj2txt(backend, obj): return backend._ffi.buffer(buf, res)[:].decode() +def _asn1_integer_to_int(backend, asn1_int): + bn = backend._lib.ASN1_INTEGER_to_BN(asn1_int, backend._ffi.NULL) + assert bn != backend._ffi.NULL + bn = backend._ffi.gc(bn, backend._lib.BN_free) + return backend._bn_to_int(bn) + + def _build_x509_name(backend, x509_name): count = backend._lib.X509_NAME_entry_count(x509_name) attributes = [] @@ -193,12 +200,7 @@ class _Certificate(object): def serial(self): asn1_int = self._backend._lib.X509_get_serialNumber(self._x509) assert asn1_int != self._backend._ffi.NULL - bn = self._backend._lib.ASN1_INTEGER_to_BN( - asn1_int, self._backend._ffi.NULL - ) - assert bn != self._backend._ffi.NULL - bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free) - return self._backend._bn_to_int(bn) + return _asn1_integer_to_int(self._backend, asn1_int) def public_key(self): pkey = self._backend._lib.X509_get_pubkey(self._x509) @@ -314,12 +316,9 @@ class _Certificate(object): if basic_constraints.pathlen == self._backend._ffi.NULL: path_length = None else: - bn = self._backend._lib.ASN1_INTEGER_to_BN( - basic_constraints.pathlen, self._backend._ffi.NULL + path_length = _asn1_integer_to_int( + self._backend, basic_constraints.pathlen ) - assert bn != self._backend._ffi.NULL - bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free) - path_length = self._backend._bn_to_int(bn) return x509.BasicConstraints(ca, path_length) @@ -358,12 +357,9 @@ class _Certificate(object): ) if akid.serial != self._backend._ffi.NULL: - bn = self._backend._lib.ASN1_INTEGER_to_BN( - akid.serial, self._backend._ffi.NULL + authority_cert_serial_number = _asn1_integer_to_int( + self._backend, akid.serial ) - 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 -- cgit v1.2.3 From fbc64d3527acd9f70e1d3e7dc404c798f42f3a44 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 15:22:31 -0500 Subject: refactor asn1string->utf8 conversion into a separate function --- src/cryptography/hazmat/backends/openssl/x509.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 25b7c8c1..8b5f3920 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -45,6 +45,17 @@ def _asn1_integer_to_int(backend, asn1_int): return backend._bn_to_int(bn) +def _asn1_string_to_utf8(backend, asn1_string): + buf = backend._ffi.new("unsigned char **") + res = backend._lib.ASN1_STRING_to_UTF8(buf, asn1_string) + assert res >= 0 + assert buf[0] != backend._ffi.NULL + buf = backend._ffi.gc( + buf, lambda buffer: backend._lib.OPENSSL_free(buffer[0]) + ) + return backend._ffi.buffer(buf[0], res)[:].decode('utf8') + + def _build_x509_name(backend, x509_name): count = backend._lib.X509_NAME_entry_count(x509_name) attributes = [] @@ -54,14 +65,7 @@ def _build_x509_name(backend, x509_name): assert obj != backend._ffi.NULL data = backend._lib.X509_NAME_ENTRY_get_data(entry) assert data != backend._ffi.NULL - buf = backend._ffi.new("unsigned char **") - res = backend._lib.ASN1_STRING_to_UTF8(buf, data) - assert res >= 0 - assert buf[0] != backend._ffi.NULL - buf = backend._ffi.gc( - buf, lambda buffer: backend._lib.OPENSSL_free(buffer[0]) - ) - value = backend._ffi.buffer(buf[0], res)[:].decode('utf8') + value = _asn1_string_to_utf8(backend, data) oid = _obj2txt(backend, obj) attributes.append( x509.NameAttribute( -- cgit v1.2.3 From 2b3fc1edf80c0c858fc8c81ecef891e90528feeb Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 11:30:14 -0500 Subject: we also need some stack manipulation macros --- src/cryptography/hazmat/bindings/openssl/x509v3.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index 4f9eca89..9d9bed16 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -151,9 +151,6 @@ typedef struct { ASN1_OBJECT *policyid; Cryptography_STACK_OF_POLICYQUALINFO *qualifiers; } POLICYINFO; - -typedef Cryptography_STACK_OF_POLICYINFO CERTIFICATEPOLICIES; - """ @@ -194,6 +191,19 @@ const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int); void sk_DIST_POINT_free(Cryptography_STACK_OF_DIST_POINT *); int sk_DIST_POINT_num(Cryptography_STACK_OF_DIST_POINT *); DIST_POINT *sk_DIST_POINT_value(Cryptography_STACK_OF_DIST_POINT *, int); + +void sk_POLICYINFO_free(Cryptography_STACK_OF_POLICYINFO *); +int sk_POLICYINFO_num(Cryptography_STACK_OF_POLICYINFO *); +POLICYINFO *sk_POLICYINFO_value(Cryptography_STACK_OF_POLICYINFO *, int); + +void sk_POLICYQUALINFO_free(Cryptography_STACK_OF_POLICYQUALINFO *); +int sk_POLICYQUALINFO_num(Cryptography_STACK_OF_POLICYQUALINFO *); +POLICYQUALINFO *sk_POLICYQUALINFO_value(Cryptography_STACK_OF_POLICYQUALINFO *, + int); + +void sk_ASN1_INTEGER_free(Cryptography_STACK_OF_ASN1_INTEGER *); +int sk_ASN1_INTEGER_num(Cryptography_STACK_OF_ASN1_INTEGER *); +int sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From 6e198b0092a2a320887a234db5227a8c1daa49be Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 15:53:38 -0500 Subject: notice_numbers are not optional in NoticeReference --- src/cryptography/x509.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 173fd084..b0a4a352 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -568,11 +568,11 @@ class UserNotice(object): class NoticeReference(object): def __init__(self, organization, notice_numbers): self._organization = organization - if notice_numbers and not all( + if not isinstance(notice_numbers, list) or not all( isinstance(x, int) for x in notice_numbers ): raise TypeError( - "notice_numbers must be a list of integers or None" + "notice_numbers must be a list of integers" ) self._notice_numbers = notice_numbers -- cgit v1.2.3 From bac98978ceaf681e4702bf9c6c0aec35783e4b32 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 16:16:19 -0500 Subject: having the right return type is helpful --- src/cryptography/hazmat/bindings/openssl/x509v3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index 9d9bed16..23167996 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -203,7 +203,7 @@ POLICYQUALINFO *sk_POLICYQUALINFO_value(Cryptography_STACK_OF_POLICYQUALINFO *, void sk_ASN1_INTEGER_free(Cryptography_STACK_OF_ASN1_INTEGER *); int sk_ASN1_INTEGER_num(Cryptography_STACK_OF_ASN1_INTEGER *); -int sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int); +ASN1_INTEGER *sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int); """ CUSTOMIZATIONS = """ -- cgit v1.2.3 From 11026fec3dc7dd920de512c1c66ff59c656de139 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 11:23:56 -0500 Subject: support certificate policies in the openssl backend --- src/cryptography/hazmat/backends/openssl/x509.py | 71 ++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 8b5f3920..9d70d72f 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -290,6 +290,8 @@ class _Certificate(object): value = self._build_authority_key_identifier(ext) elif oid == x509.OID_AUTHORITY_INFORMATION_ACCESS: value = self._build_authority_information_access(ext) + elif oid == x509.OID_CERTIFICATE_POLICIES: + value = self._build_certificate_policies(ext) elif critical: raise x509.UnsupportedExtension( "{0} is not currently supported".format(oid), oid @@ -304,6 +306,75 @@ class _Certificate(object): return x509.Extensions(extensions) + def _build_certificate_policies(self, ext): + cp = self._backend._ffi.cast( + "Cryptography_STACK_OF_POLICYINFO *", + self._backend._lib.X509V3_EXT_d2i(ext) + ) + assert cp != self._backend._ffi.NULL + cp = self._backend._ffi.gc(cp, self._backend._lib.sk_POLICYINFO_free) + num = self._backend._lib.sk_POLICYINFO_num(cp) + certificate_policies = [] + for i in range(num): + qualifiers = None + pi = self._backend._lib.sk_POLICYINFO_value(cp, i) + oid = x509.ObjectIdentifier(_obj2txt(self._backend, pi.policyid)) + if pi.qualifiers != self._backend._ffi.NULL: + qnum = self._backend._lib.sk_POLICYQUALINFO_num(pi.qualifiers) + qualifiers = [] + for j in range(qnum): + pqi = self._backend._lib.sk_POLICYQUALINFO_value( + pi.qualifiers, j + ) + pqualid = x509.ObjectIdentifier( + _obj2txt(self._backend, pqi.pqualid) + ) + if pqualid == x509.OID_CPS_QUALIFIER: + cpsuri = self._backend._ffi.buffer( + pqi.d.cpsuri.data, pqi.d.cpsuri.length + )[:].decode('ascii') + qualifiers.append(cpsuri) + elif pqualid == x509.OID_CPS_USER_NOTICE: + user_notice = self._build_user_notice(pqi.d.usernotice) + qualifiers.append(user_notice) + + certificate_policies.append( + x509.PolicyInformation(oid, qualifiers) + ) + + return x509.CertificatePolicies(certificate_policies) + + def _build_user_notice(self, un): + explicit_text = None + notice_reference = None + + if un.exptext != self._backend._ffi.NULL: + explicit_text = _asn1_string_to_utf8(self._backend, un.exptext) + + if un.noticeref != self._backend._ffi.NULL: + organization = _asn1_string_to_utf8( + self._backend, un.noticeref.organization + ) + + num = self._backend._lib.sk_ASN1_INTEGER_num( + un.noticeref.noticenos + ) + notice_numbers = [] + for i in range(num): + asn1_int = self._backend._lib.sk_ASN1_INTEGER_value( + un.noticeref.noticenos, i + ) + notice_num = _asn1_integer_to_int( + self._backend, asn1_int + ) + notice_numbers.append(notice_num) + + notice_reference = x509.NoticeReference( + organization, notice_numbers + ) + + return x509.UserNotice(notice_reference, explicit_text) + def _build_basic_constraints(self, ext): bc_st = self._backend._lib.X509V3_EXT_d2i(ext) assert bc_st != self._backend._ffi.NULL -- cgit v1.2.3 From 9a10d59aaaf805a2aecef40df5338d2fc0602be9 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 10 May 2015 14:55:51 -0500 Subject: support CRLDistributionPoints in the OpenSSL backend --- src/cryptography/hazmat/backends/openssl/x509.py | 112 ++++++++++++++++++++--- 1 file changed, 101 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 9d70d72f..7f487d35 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -28,6 +28,18 @@ from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes +_REASONFLAGS_ENUM_MAPPING = { + 1: x509.ReasonFlags.key_compromise, + 2: x509.ReasonFlags.ca_compromise, + 3: x509.ReasonFlags.affiliation_changed, + 4: x509.ReasonFlags.superseded, + 5: x509.ReasonFlags.cessation_of_operation, + 6: x509.ReasonFlags.certificate_hold, + 7: x509.ReasonFlags.privilege_withdrawn, + 8: x509.ReasonFlags.aa_compromise +} + + def _obj2txt(backend, obj): # Set to 80 on the recommendation of # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values @@ -56,22 +68,23 @@ def _asn1_string_to_utf8(backend, asn1_string): return backend._ffi.buffer(buf[0], res)[:].decode('utf8') +def _build_x509_name_entry(backend, x509_name_entry): + obj = backend._lib.X509_NAME_ENTRY_get_object(x509_name_entry) + assert obj != backend._ffi.NULL + data = backend._lib.X509_NAME_ENTRY_get_data(x509_name_entry) + assert data != backend._ffi.NULL + value = _asn1_string_to_utf8(backend, data) + oid = _obj2txt(backend, obj) + + return x509.NameAttribute(x509.ObjectIdentifier(oid), value) + + def _build_x509_name(backend, x509_name): count = backend._lib.X509_NAME_entry_count(x509_name) attributes = [] for x in range(count): entry = backend._lib.X509_NAME_get_entry(x509_name, x) - obj = backend._lib.X509_NAME_ENTRY_get_object(entry) - assert obj != backend._ffi.NULL - data = backend._lib.X509_NAME_ENTRY_get_data(entry) - assert data != backend._ffi.NULL - value = _asn1_string_to_utf8(backend, data) - oid = _obj2txt(backend, obj) - attributes.append( - x509.NameAttribute( - x509.ObjectIdentifier(oid), value - ) - ) + attributes.append(_build_x509_name_entry(backend, entry)) return x509.Name(attributes) @@ -292,6 +305,8 @@ class _Certificate(object): value = self._build_authority_information_access(ext) elif oid == x509.OID_CERTIFICATE_POLICIES: value = self._build_certificate_policies(ext) + elif oid == x509.OID_CRL_DISTRIBUTION_POINTS: + value = self._build_crl_distribution_points(ext) elif critical: raise x509.UnsupportedExtension( "{0} is not currently supported".format(oid), oid @@ -518,6 +533,81 @@ class _Certificate(object): return x509.ExtendedKeyUsage(ekus) + def _build_crl_distribution_points(self, ext): + cdps = self._backend._ffi.cast( + "Cryptography_STACK_OF_DIST_POINT *", + self._backend._lib.X509V3_EXT_d2i(ext) + ) + assert cdps != self._backend._ffi.NULL + cdps = self._backend._ffi.gc( + cdps, self._backend._lib.sk_DIST_POINT_free) + num = self._backend._lib.sk_DIST_POINT_num(cdps) + + dist_points = [] + for i in range(num): + full_name = None + relative_name = None + crl_issuer = None + reasons = None + cdp = self._backend._lib.sk_DIST_POINT_value(cdps, i) + if cdp.reasons != self._backend._ffi.NULL: + reasons = [] + # We will check each bit from RFC 5280 + # ReasonFlags ::= BIT STRING { + # unused (0), + # keyCompromise (1), + # cACompromise (2), + # affiliationChanged (3), + # superseded (4), + # cessationOfOperation (5), + # certificateHold (6), + # privilegeWithdrawn (7), + # aACompromise (8) } + for bit in range(1, 9): + if self._backend._lib.ASN1_BIT_STRING_get_bit( + cdp.reasons, bit + ): + reasons.append(_REASONFLAGS_ENUM_MAPPING[bit]) + + reasons = frozenset(reasons) + + if cdp.CRLissuer != self._backend._ffi.NULL: + crl_issuer = _build_general_names(self._backend, cdp.CRLissuer) + + # Certificates may have a crl_issuer/reasons and no distribution + # point so make sure it's not null. + if cdp.distpoint != self._backend._ffi.NULL: + # Type 0 is fullName, there is no #define for it in the code. + if cdp.distpoint.type == 0: + full_name = _build_general_names( + self._backend, cdp.distpoint.name.fullname + ) + # OpenSSL code doesn't test for a specific type for + # relativename, everything that isn't fullname is considered + # relativename. + else: + rns = cdp.distpoint.name.relativename + rnum = self._backend._lib.sk_X509_NAME_ENTRY_num(rns) + attributes = [] + for i in range(rnum): + rn = self._backend._lib.sk_X509_NAME_ENTRY_value( + rns, i + ) + assert rn != self._backend._ffi.NULL + attributes.append( + _build_x509_name_entry(self._backend, rn) + ) + + relative_name = x509.Name(attributes) + + dist_points.append( + x509.DistributionPoint( + full_name, relative_name, reasons, crl_issuer + ) + ) + + return x509.CRLDistributionPoints(dist_points) + @utils.register_interface(x509.CertificateSigningRequest) class _CertificateSigningRequest(object): -- cgit v1.2.3 From 594a2edf1ead6b7ce3f4e217bada30f2f323dc36 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 12 May 2015 23:27:32 -0500 Subject: change approach for parsing CDP reason flags --- src/cryptography/hazmat/backends/openssl/x509.py | 43 ++++++++++++++---------- 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 7f487d35..07e54baa 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -28,18 +28,6 @@ from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives import hashes -_REASONFLAGS_ENUM_MAPPING = { - 1: x509.ReasonFlags.key_compromise, - 2: x509.ReasonFlags.ca_compromise, - 3: x509.ReasonFlags.affiliation_changed, - 4: x509.ReasonFlags.superseded, - 5: x509.ReasonFlags.cessation_of_operation, - 6: x509.ReasonFlags.certificate_hold, - 7: x509.ReasonFlags.privilege_withdrawn, - 8: x509.ReasonFlags.aa_compromise -} - - def _obj2txt(backend, obj): # Set to 80 on the recommendation of # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values @@ -551,7 +539,6 @@ class _Certificate(object): reasons = None cdp = self._backend._lib.sk_DIST_POINT_value(cdps, i) if cdp.reasons != self._backend._ffi.NULL: - reasons = [] # We will check each bit from RFC 5280 # ReasonFlags ::= BIT STRING { # unused (0), @@ -563,11 +550,31 @@ class _Certificate(object): # certificateHold (6), # privilegeWithdrawn (7), # aACompromise (8) } - for bit in range(1, 9): - if self._backend._lib.ASN1_BIT_STRING_get_bit( - cdp.reasons, bit - ): - reasons.append(_REASONFLAGS_ENUM_MAPPING[bit]) + reasons = [] + get_bit = self._backend._lib.ASN1_BIT_STRING_get_bit + if get_bit(cdp.reasons, 1): + reasons.append(x509.ReasonFlags.key_compromise) + + if get_bit(cdp.reasons, 2): + reasons.append(x509.ReasonFlags.ca_compromise) + + if get_bit(cdp.reasons, 3): + reasons.append(x509.ReasonFlags.affiliation_changed) + + if get_bit(cdp.reasons, 4): + reasons.append(x509.ReasonFlags.superseded) + + if get_bit(cdp.reasons, 5): + reasons.append(x509.ReasonFlags.cessation_of_operation) + + if get_bit(cdp.reasons, 6): + reasons.append(x509.ReasonFlags.certificate_hold) + + if get_bit(cdp.reasons, 7): + reasons.append(x509.ReasonFlags.privilege_withdrawn) + + if get_bit(cdp.reasons, 8): + reasons.append(x509.ReasonFlags.aa_compromise) reasons = frozenset(reasons) -- cgit v1.2.3 From 8565f5ed4e76dbb9ff46cc9c112aa0eb6b259186 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 09:57:09 -0500 Subject: add eq/ne support to KeyUsage --- src/cryptography/x509.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b0a4a352..5eca5d64 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -397,6 +397,25 @@ class KeyUsage(object): "encipher_only={1}, decipher_only={2})>").format( self, encipher_only, decipher_only) + def __eq__(self, other): + if not isinstance(other, KeyUsage): + return NotImplemented + + return ( + self.digital_signature == other.digital_signature and + self.content_commitment == other.content_commitment and + self.key_encipherment == other.key_encipherment and + self.data_encipherment == other.data_encipherment and + self.key_agreement == other.key_agreement and + self.key_cert_sign == other.key_cert_sign and + self.crl_sign == other.crl_sign and + self._encipher_only == other._encipher_only and + self._decipher_only == other._decipher_only + ) + + def __ne__(self, other): + return not self == other + class AuthorityInformationAccess(object): def __init__(self, descriptions): -- cgit v1.2.3 From 58cc3973cf3c3e83d5cb9e1d29e1a4fd9b88eff7 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 10:00:41 -0500 Subject: add eq/ne support to SubjectAlternativeName --- src/cryptography/x509.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b0a4a352..8e9c1aca 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -914,6 +914,15 @@ class SubjectAlternativeName(object): def __repr__(self): return "".format(self._general_names) + def __eq__(self, other): + if not isinstance(other, SubjectAlternativeName): + return NotImplemented + + return self._general_names == other._general_names + + def __ne__(self, other): + return not self == other + class AuthorityKeyIdentifier(object): def __init__(self, key_identifier, authority_cert_issuer, -- cgit v1.2.3 From 3a69b13c38002bc319c5f73df183b8bb558c442a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 10:03:46 -0500 Subject: add eq/ne support to BasicConstraints --- src/cryptography/x509.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index b0a4a352..89b9162b 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -333,6 +333,15 @@ class BasicConstraints(object): return ("").format(self) + def __eq__(self, other): + if not isinstance(other, BasicConstraints): + return NotImplemented + + return self.ca == other.ca and self.path_length == other.path_length + + def __ne__(self, other): + return not self == other + class KeyUsage(object): def __init__(self, digital_signature, content_commitment, key_encipherment, -- cgit v1.2.3 From cec80a15b21e69c6e91fbfcbd2211fe87ceb93a9 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 11:36:28 -0500 Subject: add SSL_set_tlsext_status_arg support --- src/cryptography/hazmat/bindings/openssl/ssl.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index c12624bc..5445f3c9 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -331,6 +331,7 @@ long SSL_set_tlsext_status_ocsp_resp(SSL *, unsigned char *, int); long SSL_get_tlsext_status_ocsp_resp(SSL *, const unsigned char **); long SSL_set_tlsext_status_type(SSL *, long); long SSL_CTX_set_tlsext_status_cb(SSL_CTX *, int(*)(SSL *, void *)); +long SSL_CTX_set_tlsext_status_arg(SSL_CTX *, void *); long SSL_session_reused(SSL *); @@ -434,6 +435,7 @@ static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB = 1; #else static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB = 0; long (*SSL_CTX_set_tlsext_status_cb)(SSL_CTX *, int(*)(SSL *, void *)) = NULL; +long (*SSL_CTX_set_tlsext_status_arg)(SSL_CTX *, void *) = NULL; #endif #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP @@ -639,6 +641,7 @@ CONDITIONAL_NAMES = { "Cryptography_HAS_TLSEXT_STATUS_REQ_CB": [ "SSL_CTX_set_tlsext_status_cb", + "SSL_CTX_set_tlsext_status_arg" ], "Cryptography_HAS_STATUS_REQ_OCSP_RESP": [ -- cgit v1.2.3 From c486ed5275df85df56a9f9161ae2059303571ae4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 17:59:31 -0500 Subject: 0.9 time --- src/cryptography/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index 0f8d4871..f5a48a9e 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -14,7 +14,7 @@ __summary__ = ("cryptography is a package which provides cryptographic recipes" " and primitives to Python developers.") __uri__ = "https://github.com/pyca/cryptography" -__version__ = "0.9.dev1" +__version__ = "0.9" __author__ = "The cryptography developers" __email__ = "cryptography-dev@python.org" -- cgit v1.2.3 From d5257ab7bb2c01d15a05e8c60935cf36e0ddcadf Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 20:48:36 -0500 Subject: open master for tenth release --- src/cryptography/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py index f5a48a9e..359cd819 100644 --- a/src/cryptography/__about__.py +++ b/src/cryptography/__about__.py @@ -14,7 +14,7 @@ __summary__ = ("cryptography is a package which provides cryptographic recipes" " and primitives to Python developers.") __uri__ = "https://github.com/pyca/cryptography" -__version__ = "0.9" +__version__ = "0.10.dev1" __author__ = "The cryptography developers" __email__ = "cryptography-dev@python.org" -- cgit v1.2.3 From 290cd601538c1b5b73ee25b9218abe71b94d2c99 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 13 May 2015 23:38:51 -0500 Subject: deprecation dance. fixes #1950 --- .../hazmat/primitives/asymmetric/dsa.py | 22 -- .../hazmat/primitives/asymmetric/ec.py | 22 -- .../hazmat/primitives/asymmetric/rsa.py | 22 -- .../hazmat/primitives/interfaces/__init__.py | 351 --------------------- src/cryptography/utils.py | 3 +- 5 files changed, 1 insertion(+), 419 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 4d332f2a..733a967c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -71,17 +71,6 @@ class DSAPrivateKeyWithSerialization(DSAPrivateKey): """ -DSAPrivateKeyWithNumbers = utils.deprecated( - DSAPrivateKeyWithSerialization, - __name__, - ( - "The DSAPrivateKeyWithNumbers interface has been renamed to " - "DSAPrivateKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - @six.add_metaclass(abc.ABCMeta) class DSAPublicKey(object): @abc.abstractproperty @@ -118,17 +107,6 @@ class DSAPublicKeyWithSerialization(DSAPublicKey): """ -DSAPublicKeyWithNumbers = utils.deprecated( - DSAPublicKeyWithSerialization, - __name__, - ( - "The DSAPublicKeyWithNumbers interface has been renamed to " - "DSAPublicKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - def generate_parameters(key_size, backend): return backend.generate_dsa_parameters(key_size) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 96809c10..631fcbf7 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -71,17 +71,6 @@ class EllipticCurvePrivateKeyWithSerialization(EllipticCurvePrivateKey): """ -EllipticCurvePrivateKeyWithNumbers = utils.deprecated( - EllipticCurvePrivateKeyWithSerialization, - __name__, - ( - "The EllipticCurvePrivateKeyWithNumbers interface has been renamed to " - "EllipticCurvePrivateKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - @six.add_metaclass(abc.ABCMeta) class EllipticCurvePublicKey(object): @abc.abstractmethod @@ -112,17 +101,6 @@ class EllipticCurvePublicKeyWithSerialization(EllipticCurvePublicKey): """ -EllipticCurvePublicKeyWithNumbers = utils.deprecated( - EllipticCurvePublicKeyWithSerialization, - __name__, - ( - "The EllipticCurvePublicKeyWithNumbers interface has been renamed to " - "EllipticCurvePublicKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - @utils.register_interface(EllipticCurve) class SECT571R1(object): name = "sect571r1" diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index ae00184f..772473fd 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -56,17 +56,6 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey): """ -RSAPrivateKeyWithNumbers = utils.deprecated( - RSAPrivateKeyWithSerialization, - __name__, - ( - "The RSAPrivateKeyWithNumbers interface has been renamed to " - "RSAPrivateKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - @six.add_metaclass(abc.ABCMeta) class RSAPublicKey(object): @abc.abstractmethod @@ -103,17 +92,6 @@ class RSAPublicKeyWithSerialization(RSAPublicKey): """ -RSAPublicKeyWithNumbers = utils.deprecated( - RSAPublicKeyWithSerialization, - __name__, - ( - "The RSAPublicKeyWithNumbers interface has been renamed to " - "RSAPublicKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - - def generate_private_key(public_exponent, key_size, backend): if not isinstance(backend, RSABackend): raise UnsupportedAlgorithm( diff --git a/src/cryptography/hazmat/primitives/interfaces/__init__.py b/src/cryptography/hazmat/primitives/interfaces/__init__.py index c980e5a5..4c95190b 100644 --- a/src/cryptography/hazmat/primitives/interfaces/__init__.py +++ b/src/cryptography/hazmat/primitives/interfaces/__init__.py @@ -8,357 +8,6 @@ import abc import six -from cryptography import utils -from cryptography.hazmat.primitives import ciphers, hashes -from cryptography.hazmat.primitives.asymmetric import ( - AsymmetricSignatureContext, AsymmetricVerificationContext, dsa, ec, - padding, rsa -) -from cryptography.hazmat.primitives.ciphers import modes -from cryptography.hazmat.primitives.kdf import KeyDerivationFunction -from cryptography.hazmat.primitives.padding import PaddingContext - - -BlockCipherAlgorithm = utils.deprecated( - ciphers.BlockCipherAlgorithm, - __name__, - ( - "The BlockCipherAlgorithm interface has moved to the " - "cryptography.hazmat.primitives.ciphers module" - ), - utils.DeprecatedIn08 -) - - -CipherAlgorithm = utils.deprecated( - ciphers.CipherAlgorithm, - __name__, - ( - "The CipherAlgorithm interface has moved to the " - "cryptography.hazmat.primitives.ciphers module" - ), - utils.DeprecatedIn08 -) - - -Mode = utils.deprecated( - modes.Mode, - __name__, - ( - "The Mode interface has moved to the " - "cryptography.hazmat.primitives.ciphers.modes module" - ), - utils.DeprecatedIn08 -) - - -ModeWithAuthenticationTag = utils.deprecated( - modes.ModeWithAuthenticationTag, - __name__, - ( - "The ModeWithAuthenticationTag interface has moved to the " - "cryptography.hazmat.primitives.ciphers.modes module" - ), - utils.DeprecatedIn08 -) - - -ModeWithInitializationVector = utils.deprecated( - modes.ModeWithInitializationVector, - __name__, - ( - "The ModeWithInitializationVector interface has moved to the " - "cryptography.hazmat.primitives.ciphers.modes module" - ), - utils.DeprecatedIn08 -) - - -ModeWithNonce = utils.deprecated( - modes.ModeWithNonce, - __name__, - ( - "The ModeWithNonce interface has moved to the " - "cryptography.hazmat.primitives.ciphers.modes module" - ), - utils.DeprecatedIn08 -) - - -CipherContext = utils.deprecated( - ciphers.CipherContext, - __name__, - ( - "The CipherContext interface has moved to the " - "cryptography.hazmat.primitives.ciphers module" - ), - utils.DeprecatedIn08 -) - - -AEADCipherContext = utils.deprecated( - ciphers.AEADCipherContext, - __name__, - ( - "The AEADCipherContext interface has moved to the " - "cryptography.hazmat.primitives.ciphers module" - ), - utils.DeprecatedIn08 -) - - -AEADEncryptionContext = utils.deprecated( - ciphers.AEADEncryptionContext, - __name__, - ( - "The AEADEncryptionContext interface has moved to the " - "cryptography.hazmat.primitives.ciphers module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurve = utils.deprecated( - ec.EllipticCurve, - __name__, - ( - "The EllipticCurve interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurvePrivateKey = utils.deprecated( - ec.EllipticCurvePrivateKey, - __name__, - ( - "The EllipticCurvePrivateKey interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurvePrivateKeyWithNumbers = utils.deprecated( - ec.EllipticCurvePrivateKeyWithSerialization, - __name__, - ( - "The EllipticCurvePrivateKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurvePublicKey = utils.deprecated( - ec.EllipticCurvePublicKey, - __name__, - ( - "The EllipticCurvePublicKey interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurvePublicKeyWithNumbers = utils.deprecated( - ec.EllipticCurvePublicKeyWithSerialization, - __name__, - ( - "The EllipticCurvePublicKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -EllipticCurveSignatureAlgorithm = utils.deprecated( - ec.EllipticCurveSignatureAlgorithm, - __name__, - ( - "The EllipticCurveSignatureAlgorithm interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.ec module" - ), - utils.DeprecatedIn08 -) - - -DSAParameters = utils.deprecated( - dsa.DSAParameters, - __name__, - ( - "The DSAParameters interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - -DSAParametersWithNumbers = utils.deprecated( - dsa.DSAParametersWithNumbers, - __name__, - ( - "The DSAParametersWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - -DSAPrivateKey = utils.deprecated( - dsa.DSAPrivateKey, - __name__, - ( - "The DSAPrivateKey interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - -DSAPrivateKeyWithNumbers = utils.deprecated( - dsa.DSAPrivateKeyWithSerialization, - __name__, - ( - "The DSAPrivateKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - -DSAPublicKey = utils.deprecated( - dsa.DSAPublicKey, - __name__, - ( - "The DSAPublicKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - -DSAPublicKeyWithNumbers = utils.deprecated( - dsa.DSAPublicKeyWithSerialization, - __name__, - ( - "The DSAPublicKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.dsa.module" - ), - utils.DeprecatedIn08 -) - - -PaddingContext = utils.deprecated( - PaddingContext, - __name__, - ( - "The PaddingContext interface has moved to the " - "cryptography.hazmat.primitives.padding module" - ), - utils.DeprecatedIn08 -) - - -HashContext = utils.deprecated( - hashes.HashContext, - __name__, - ( - "The HashContext interface has moved to the " - "cryptography.hazmat.primitives.hashes module" - ), - utils.DeprecatedIn08 -) - - -HashAlgorithm = utils.deprecated( - hashes.HashAlgorithm, - __name__, - ( - "The HashAlgorithm interface has moved to the " - "cryptography.hazmat.primitives.hashes module" - ), - utils.DeprecatedIn08 -) - - -RSAPrivateKey = utils.deprecated( - rsa.RSAPrivateKey, - __name__, - ( - "The RSAPrivateKey interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.rsa module" - ), - utils.DeprecatedIn08 -) - -RSAPrivateKeyWithNumbers = utils.deprecated( - rsa.RSAPrivateKeyWithSerialization, - __name__, - ( - "The RSAPrivateKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.rsa module and has been " - "renamed RSAPrivateKeyWithSerialization" - ), - utils.DeprecatedIn08 -) - -RSAPublicKey = utils.deprecated( - rsa.RSAPublicKey, - __name__, - ( - "The RSAPublicKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.rsa module" - ), - utils.DeprecatedIn08 -) - -RSAPublicKeyWithNumbers = utils.deprecated( - rsa.RSAPublicKeyWithSerialization, - __name__, - ( - "The RSAPublicKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.rsa module" - ), - utils.DeprecatedIn08 -) - -AsymmetricPadding = utils.deprecated( - padding.AsymmetricPadding, - __name__, - ( - "The AsymmetricPadding interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.padding module" - ), - utils.DeprecatedIn08 -) - -AsymmetricSignatureContext = utils.deprecated( - AsymmetricSignatureContext, - __name__, - ( - "The AsymmetricPadding interface has moved to the " - "cryptography.hazmat.primitives.asymmetric module" - ), - utils.DeprecatedIn08 -) - -AsymmetricVerificationContext = utils.deprecated( - AsymmetricVerificationContext, - __name__, - ( - "The AsymmetricVerificationContext interface has moved to the " - "cryptography.hazmat.primitives.asymmetric module" - ), - utils.DeprecatedIn08 -) - -KeyDerivationFunction = utils.deprecated( - KeyDerivationFunction, - __name__, - ( - "The KeyDerivationFunction interface has moved to the " - "cryptography.hazmat.primitives.kdf module" - ), - utils.DeprecatedIn08 -) - @six.add_metaclass(abc.ABCMeta) class MACContext(object): diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 445554ec..0bf8c0ea 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -10,8 +10,7 @@ import sys import warnings -DeprecatedIn08 = DeprecationWarning -DeprecatedIn09 = PendingDeprecationWarning +DeprecatedIn09 = DeprecationWarning def read_only_property(name): -- cgit v1.2.3 From 393c9162c4239aa7d7ca3853dce77eb1bc49f830 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 14 May 2015 18:54:25 -0400 Subject: Added the bindings needed for implementing a CSR Builder. Refs #1927 --- src/cryptography/hazmat/bindings/openssl/x509.py | 6 ++++++ src/cryptography/hazmat/bindings/openssl/x509v3.py | 2 ++ 2 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py index 31250165..caa33969 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509.py +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -146,9 +146,13 @@ X509_EXTENSION *X509_delete_ext(X509 *, int); X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *); X509_EXTENSION *X509_get_ext(X509 *, int); int X509_get_ext_by_NID(X509 *, int, int); + int X509_EXTENSION_get_critical(X509_EXTENSION *); ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *); void X509_EXTENSION_free(X509_EXTENSION *); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **, + ASN1_OBJECT *, int, + ASN1_OCTET_STRING *); int i2d_X509(X509 *, unsigned char **); @@ -156,11 +160,13 @@ int X509_REQ_set_version(X509_REQ *, long); X509_REQ *X509_REQ_new(void); void X509_REQ_free(X509_REQ *); int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *); +int X509_REQ_set_subject_name(X509_REQ *, X509_NAME *); int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *); int X509_REQ_verify(X509_REQ *, EVP_PKEY *); int X509_REQ_digest(const X509_REQ *, const EVP_MD *, unsigned char *, unsigned int *); EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *); +int X509_REQ_print(BIO *, X509_REQ *); int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long); int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int); diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py index 23167996..054ab624 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -166,6 +166,8 @@ void *X509V3_EXT_d2i(X509_EXTENSION *); MACROS = """ /* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the x509v3.h header. */ +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. */ -- cgit v1.2.3