diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 15 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/asn1.py | 4 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/pem.py | 4 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/pkcs7.py | 30 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/ssl.py | 6 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/x509.py | 17 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/asymmetric/dh.py | 89 | ||||
-rw-r--r-- | src/cryptography/x509.py | 61 |
8 files changed, 205 insertions, 21 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 6a7032ba..5d47c5ea 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -170,6 +170,8 @@ class _Certificate(object): ) elif oid == x509.OID_BASIC_CONSTRAINTS: value = self._build_basic_constraints(ext) + elif oid == x509.OID_SUBJECT_KEY_IDENTIFIER: + value = self._build_subject_key_identifier(ext) elif oid == x509.OID_KEY_USAGE and critical: # TODO: remove this obviously. warnings.warn( @@ -217,6 +219,19 @@ class _Certificate(object): return x509.BasicConstraints(ca, path_length) + def _build_subject_key_identifier(self, ext): + asn1_string = self._backend._lib.X509V3_EXT_d2i(ext) + assert asn1_string != self._backend._ffi.NULL + asn1_string = self._backend._ffi.cast( + "ASN1_OCTET_STRING *", asn1_string + ) + asn1_string = self._backend._ffi.gc( + asn1_string, self._backend._lib.ASN1_OCTET_STRING_free + ) + return x509.SubjectKeyIdentifier( + self._backend._ffi.buffer(asn1_string.data, asn1_string.length)[:] + ) + @utils.register_interface(x509.CertificateSigningRequest) class _CertificateSigningRequest(object): diff --git a/src/cryptography/hazmat/bindings/openssl/asn1.py b/src/cryptography/hazmat/bindings/openssl/asn1.py index d8b8331e..45dfe758 100644 --- a/src/cryptography/hazmat/bindings/openssl/asn1.py +++ b/src/cryptography/hazmat/bindings/openssl/asn1.py @@ -40,6 +40,7 @@ struct asn1_string_st { typedef struct asn1_string_st ASN1_OCTET_STRING; typedef struct asn1_string_st ASN1_IA5STRING; +typedef ... ASN1_BIT_STRING; typedef ... ASN1_OBJECT; typedef ... ASN1_STRING; typedef ... ASN1_TYPE; @@ -115,9 +116,12 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long); ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long, const ASN1_ITEM *); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *, int, int); """ MACROS = """ +/* This is not a macro, but is const on some versions of OpenSSL */ +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *, int); ASN1_TIME *M_ASN1_TIME_dup(void *); const ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *); diff --git a/src/cryptography/hazmat/bindings/openssl/pem.py b/src/cryptography/hazmat/bindings/openssl/pem.py index 98c7648f..8ec3fefd 100644 --- a/src/cryptography/hazmat/bindings/openssl/pem.py +++ b/src/cryptography/hazmat/bindings/openssl/pem.py @@ -32,7 +32,9 @@ int i2d_PKCS8PrivateKey_bio(BIO *, EVP_PKEY *, const EVP_CIPHER *, int i2d_PKCS8PrivateKey_nid_bio(BIO *, EVP_PKEY *, int, char *, int, pem_password_cb *, void *); +int i2d_PKCS7_bio(BIO *, PKCS7 *); PKCS7 *d2i_PKCS7_bio(BIO *, PKCS7 **); + EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *, EVP_PKEY **, pem_password_cb *, void *); @@ -45,6 +47,8 @@ X509_CRL *PEM_read_bio_X509_CRL(BIO *, X509_CRL **, pem_password_cb *, void *); int PEM_write_bio_X509_CRL(BIO *, X509_CRL *); PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *); +int PEM_write_bio_PKCS7(BIO *, PKCS7 *); + DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *); DSA *PEM_read_bio_DSAPrivateKey(BIO *, DSA **, pem_password_cb *, void *); diff --git a/src/cryptography/hazmat/bindings/openssl/pkcs7.py b/src/cryptography/hazmat/bindings/openssl/pkcs7.py index 3196fa13..df82afef 100644 --- a/src/cryptography/hazmat/bindings/openssl/pkcs7.py +++ b/src/cryptography/hazmat/bindings/openssl/pkcs7.py @@ -13,10 +13,37 @@ typedef struct { ASN1_OBJECT *type; ...; } PKCS7; + +static const int PKCS7_BINARY; +static const int PKCS7_DETACHED; +static const int PKCS7_NOATTR; +static const int PKCS7_NOCERTS; +static const int PKCS7_NOCHAIN; +static const int PKCS7_NOINTERN; +static const int PKCS7_NOSIGS; +static const int PKCS7_NOSMIMECAP; +static const int PKCS7_NOVERIFY; +static const int PKCS7_STREAM; +static const int PKCS7_TEXT; """ FUNCTIONS = """ +PKCS7 *SMIME_read_PKCS7(BIO *, BIO **); +int SMIME_write_PKCS7(BIO *, PKCS7 *, BIO *, int); + void PKCS7_free(PKCS7 *); + +PKCS7 *PKCS7_sign(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *, + BIO *, int); +int PKCS7_verify(PKCS7 *, Cryptography_STACK_OF_X509 *, X509_STORE *, BIO *, + BIO *, int); +Cryptography_STACK_OF_X509 *PKCS7_get0_signers(PKCS7 *, + Cryptography_STACK_OF_X509 *, + int); + +PKCS7 *PKCS7_encrypt(Cryptography_STACK_OF_X509 *, BIO *, + const EVP_CIPHER *, int); +int PKCS7_decrypt(PKCS7 *, EVP_PKEY *, X509 *, BIO *, int); """ MACROS = """ @@ -26,7 +53,6 @@ int PKCS7_type_is_signedAndEnveloped(PKCS7 *); int PKCS7_type_is_data(PKCS7 *); """ -CUSTOMIZATIONS = """ -""" +CUSTOMIZATIONS = "" CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index bc4b2e79..d680c3a5 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -546,11 +546,7 @@ static const long Cryptography_HAS_ALPN = 0; #else static const long Cryptography_HAS_ALPN = 1; #endif -/* LibreSSL has removed support for compression, and with it the - * COMP_METHOD use in ssl.h. This is a hack to make the function types - * in this code match those in ssl.h. - */ -#ifdef LIBRESSL_VERSION_NUMBER +#if defined(OPENSSL_NO_COMP) || defined(LIBRESSL_VERSION_NUMBER) static const long Cryptography_HAS_COMPRESSION = 0; typedef void COMP_METHOD; #else diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py index e867450b..b5c9ee14 100644 --- a/src/cryptography/hazmat/bindings/openssl/x509.py +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -168,6 +168,9 @@ void X509_REVOKED_free(X509_REVOKED *); int X509_REVOKED_set_serialNumber(X509_REVOKED *, ASN1_INTEGER *); +int X509_REVOKED_get_ext_count(X509_REVOKED *); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *, int); +int X509_REVOKED_add_ext(X509_REVOKED *, X509_EXTENSION*, int); int X509_REVOKED_add1_ext_i2d(X509_REVOKED *, int, void *, int, unsigned long); X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **); @@ -178,6 +181,9 @@ 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_get_ext_count(X509_CRL *); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int); +int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int); int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *); int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *); @@ -262,11 +268,22 @@ void sk_X509_EXTENSION_free(X509_EXTENSIONS *); int sk_X509_REVOKED_num(Cryptography_STACK_OF_X509_REVOKED *); X509_REVOKED *sk_X509_REVOKED_value(Cryptography_STACK_OF_X509_REVOKED *, int); +Cryptography_STACK_OF_X509_CRL *sk_X509_CRL_new_null(void); +void sk_X509_CRL_free(Cryptography_STACK_OF_X509_CRL *); +int sk_X509_CRL_num(Cryptography_STACK_OF_X509_CRL *); +int sk_X509_CRL_push(Cryptography_STACK_OF_X509_CRL *, X509_CRL *); +X509_CRL *sk_X509_CRL_value(Cryptography_STACK_OF_X509_CRL *, int); + int i2d_RSAPublicKey(RSA *, unsigned char **); int i2d_RSAPrivateKey(RSA *, unsigned char **); int i2d_DSAPublicKey(DSA *, unsigned char **); int i2d_DSAPrivateKey(DSA *, unsigned char **); +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 *); + /* These aren't macros these arguments are all const X on openssl > 1.0.x */ int X509_CRL_set_lastUpdate(X509_CRL *, ASN1_TIME *); int X509_CRL_set_nextUpdate(X509_CRL *, ASN1_TIME *); diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py index 61556efb..12d53eed 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dh.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py @@ -1,18 +1,11 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. from __future__ import absolute_import, division, print_function +import abc + import six from cryptography import utils @@ -99,3 +92,75 @@ class DHParameterNumbers(object): p = utils.read_only_property("_p") g = utils.read_only_property("_g") + + +@six.add_metaclass(abc.ABCMeta) +class DHParameters(object): + @abc.abstractmethod + def generate_private_key(self): + """ + Generates and returns a DHPrivateKey. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DHParametersWithSerialization(DHParameters): + @abc.abstractmethod + def parameter_numbers(self): + """ + Returns a DHParameterNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DHPrivateKey(object): + @abc.abstractproperty + def key_size(self): + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def public_key(self): + """ + The DHPublicKey associated with this private key. + """ + + @abc.abstractmethod + def parameters(self): + """ + The DHParameters object associated with this private key. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DHPrivateKeyWithSerialization(DHPrivateKey): + @abc.abstractmethod + def private_numbers(self): + """ + Returns a DHPrivateNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DHPublicKey(object): + @abc.abstractproperty + def key_size(self): + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def parameters(self): + """ + The DHParameters object associated with this public key. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DHPublicKeyWithSerialization(DHPublicKey): + @abc.abstractmethod + def public_numbers(self): + """ + Returns a DHPublicNumbers. + """ diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 17ef6ddd..a9b6f8bd 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -48,9 +48,24 @@ _OID_NAMES = { "1.3.6.1.5.5.7.3.4": "emailProtection", "1.3.6.1.5.5.7.3.8": "timeStamping", "1.3.6.1.5.5.7.3.9": "OCSPSigning", - "2.5.29.19": "basicConstraints", + "2.5.29.9": "subjectDirectoryAttributes", + "2.5.29.14": "subjectKeyIdentifier", "2.5.29.15": "keyUsage", + "2.5.29.17": "subjectAltName", + "2.5.29.18": "issuerAltName", + "2.5.29.19": "basicConstraints", + "2.5.29.30": "nameConstraints", + "2.5.29.31": "cRLDistributionPoints", + "2.5.29.32": "certificatePolicies", + "2.5.29.33": "policyMappings", + "2.5.29.35": "authorityKeyIdentifier", + "2.5.29.36": "policyConstraints", "2.5.29.37": "extendedKeyUsage", + "2.5.29.46": "freshestCRL", + "2.5.29.54": "inhibitAnyPolicy", + "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", } @@ -175,10 +190,28 @@ class Name(object): def __len__(self): return len(self._attributes) + def __repr__(self): + return "<Name({0!r})>".format(self._attributes) + +OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9") +OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14") OID_KEY_USAGE = ObjectIdentifier("2.5.29.15") -OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37") +OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17") +OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18") OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19") +OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30") +OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31") +OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32") +OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33") +OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35") +OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36") +OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37") +OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46") +OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54") +OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1") +OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11") +OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5") class Extensions(object): @@ -238,6 +271,9 @@ class ExtendedKeyUsage(object): def __len__(self): return len(self._usages) + def __repr__(self): + return "<ExtendedKeyUsage({0})>".format(self._usages) + class BasicConstraints(object): def __init__(self, ca, path_length): @@ -330,6 +366,27 @@ class KeyUsage(object): self, encipher_only, decipher_only) +class SubjectKeyIdentifier(object): + def __init__(self, digest): + self._digest = digest + + digest = utils.read_only_property("_digest") + + def __repr__(self): + return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest) + + def __eq__(self, other): + if not isinstance(other, SubjectKeyIdentifier): + return NotImplemented + + return ( + self.digest == other.digest + ) + + def __ne__(self, other): + return not self == other + + OID_COMMON_NAME = ObjectIdentifier("2.5.4.3") OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6") OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7") |