diff options
Diffstat (limited to 'src')
23 files changed, 306 insertions, 38 deletions
diff --git a/src/_cffi_src/build_commoncrypto.py b/src/_cffi_src/build_commoncrypto.py index 4e69b6d1..09e020a2 100644 --- a/src/_cffi_src/build_commoncrypto.py +++ b/src/_cffi_src/build_commoncrypto.py @@ -17,10 +17,12 @@ ffi = build_ffi_for_binding( "common_key_derivation", "common_cryptor", "common_symmetric_key_wrap", + "seccertificate", "secimport", "secitem", "seckey", "seckeychain", + "secpolicy", "sectransform", "sectrust", ], diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index ebbe8865..ba6e17b3 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -37,7 +37,11 @@ def _osx_libraries(build_static): return ["ssl", "crypto"] -_OSX_PRE_INCLUDE = """ +_PRE_INCLUDE = """ +#include <openssl/e_os2.h> +#if defined(OPENSSL_SYS_WINDOWS) +#include <windows.h> +#endif #ifdef __APPLE__ #include <AvailabilityMacros.h> #define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \ @@ -47,7 +51,7 @@ _OSX_PRE_INCLUDE = """ #endif """ -_OSX_POST_INCLUDE = """ +_POST_INCLUDE = """ #ifdef __APPLE__ #undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \ @@ -79,6 +83,7 @@ ffi = build_ffi_for_binding( "hmac", "nid", "objects", + "ocsp", "opensslv", "pem", "pkcs12", @@ -92,8 +97,8 @@ ffi = build_ffi_for_binding( "pkcs7", "callbacks", ], - pre_include=_OSX_PRE_INCLUDE, - post_include=_OSX_POST_INCLUDE, + pre_include=_PRE_INCLUDE, + post_include=_POST_INCLUDE, libraries=_get_openssl_libraries(sys.platform), extra_link_args=extra_link_args(compiler_type()), ) diff --git a/src/_cffi_src/commoncrypto/cf.py b/src/_cffi_src/commoncrypto/cf.py index 9d4387e6..02e58d90 100644 --- a/src/_cffi_src/commoncrypto/cf.py +++ b/src/_cffi_src/commoncrypto/cf.py @@ -20,6 +20,7 @@ typedef ... *CFDataRef; typedef signed long long CFIndex; typedef ... *CFStringRef; typedef ... *CFArrayRef; +typedef ... *CFMutableArrayRef; typedef ... *CFBooleanRef; typedef ... *CFErrorRef; typedef ... *CFNumberRef; @@ -35,6 +36,9 @@ typedef struct { typedef struct { ...; } CFRange; +typedef struct { + ...; +} CFArrayCallBacks; typedef UInt32 CFStringEncoding; enum { @@ -65,6 +69,8 @@ typedef int CFNumberType; const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; +const CFArrayCallBacks kCFTypeArrayCallBacks; + const CFBooleanRef kCFBooleanTrue; const CFBooleanRef kCFBooleanFalse; """ @@ -94,6 +100,10 @@ Boolean CFBooleanGetValue(CFBooleanRef); CFNumberRef CFNumberCreate(CFAllocatorRef, CFNumberType, const void *); void CFRelease(CFTypeRef); CFTypeRef CFRetain(CFTypeRef); + +CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef, CFIndex, + const CFArrayCallBacks *); +void CFArrayAppendValue(CFMutableArrayRef, const void *); """ MACROS = """ diff --git a/src/_cffi_src/commoncrypto/seccertificate.py b/src/_cffi_src/commoncrypto/seccertificate.py new file mode 100644 index 00000000..2b54b0ee --- /dev/null +++ b/src/_cffi_src/commoncrypto/seccertificate.py @@ -0,0 +1,23 @@ +# 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 + +INCLUDES = """ +#include <Security/SecCertificate.h> +""" + +TYPES = """ +typedef ... *SecCertificateRef; +""" + +FUNCTIONS = """ +SecCertificateRef SecCertificateCreateWithData(CFAllocatorRef, CFDataRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" diff --git a/src/_cffi_src/commoncrypto/secpolicy.py b/src/_cffi_src/commoncrypto/secpolicy.py new file mode 100644 index 00000000..e132cfae --- /dev/null +++ b/src/_cffi_src/commoncrypto/secpolicy.py @@ -0,0 +1,23 @@ +# 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 + +INCLUDES = """ +#include <Security/SecPolicy.h> +""" + +TYPES = """ +typedef ... *SecPolicyRef; +""" + +FUNCTIONS = """ +SecPolicyRef SecPolicyCreateSSL(Boolean, CFStringRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" diff --git a/src/_cffi_src/commoncrypto/sectrust.py b/src/_cffi_src/commoncrypto/sectrust.py index b787afad..842c36c7 100644 --- a/src/_cffi_src/commoncrypto/sectrust.py +++ b/src/_cffi_src/commoncrypto/sectrust.py @@ -9,13 +9,30 @@ INCLUDES = """ """ TYPES = """ +typedef ... *SecTrustRef; +typedef uint32_t SecTrustResultType; + +enum { + kSecTrustResultInvalid, + kSecTrustResultProceed, + kSecTrustResultDeny, + kSecTrustResultUnspecified, + kSecTrustResultRecoverableTrustFailure, + kSecTrustResultFatalTrustFailure, + kSecTrustResultOtherError +}; """ FUNCTIONS = """ +OSStatus SecTrustEvaluate(SecTrustRef, SecTrustResultType *); OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *); """ MACROS = """ +/* The first argument changed from CFArrayRef to CFTypeRef in 10.8, so this + * has to go here for compatibility. + */ +OSStatus SecTrustCreateWithCertificates(CFTypeRef, CFTypeRef, SecTrustRef *); """ CUSTOMIZATIONS = """ diff --git a/src/_cffi_src/openssl/bio.py b/src/_cffi_src/openssl/bio.py index ac866831..6439e63a 100644 --- a/src/_cffi_src/openssl/bio.py +++ b/src/_cffi_src/openssl/bio.py @@ -99,7 +99,6 @@ BIO *BIO_pop(BIO *); BIO *BIO_next(BIO *); BIO *BIO_find_type(BIO *, int); BIO_METHOD *BIO_s_mem(void); -BIO *BIO_new_mem_buf(void *, int); BIO_METHOD *BIO_s_file(void); BIO *BIO_new_file(const char *, const char *); BIO *BIO_new_fp(FILE *, int); @@ -127,6 +126,8 @@ BIO_METHOD *BIO_f_buffer(void); """ MACROS = """ +/* BIO_new_mem_buf became const void * in 1.0.2g */ +BIO *BIO_new_mem_buf(void *, int); long BIO_set_fd(BIO *, long, int); long BIO_get_fd(BIO *, char *); long BIO_set_mem_eof_return(BIO *, int); diff --git a/src/_cffi_src/openssl/cms.py b/src/_cffi_src/openssl/cms.py index fef7325c..dbe276e9 100644 --- a/src/_cffi_src/openssl/cms.py +++ b/src/_cffi_src/openssl/cms.py @@ -6,11 +6,6 @@ from __future__ import absolute_import, division, print_function INCLUDES = """ #if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL -/* The next define should really be in the OpenSSL header, but it is missing. - Failing to include this on Windows causes compilation failures. */ -#if defined(OPENSSL_SYS_WINDOWS) -#include <windows.h> -#endif #include <openssl/cms.h> #endif """ diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index 9d97be16..4ba90662 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -226,6 +226,7 @@ static const int PKCS12_F_PKCS12_PBE_CRYPT; static const int PKCS12_R_PKCS12_CIPHERFINAL_ERROR; static const int RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; +static const int RSA_R_DATA_TOO_LARGE_FOR_MODULUS; static const int RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY; static const int RSA_R_BLOCK_TYPE_IS_NOT_01; static const int RSA_R_BLOCK_TYPE_IS_NOT_02; diff --git a/src/_cffi_src/openssl/ocsp.py b/src/_cffi_src/openssl/ocsp.py new file mode 100644 index 00000000..5865dba1 --- /dev/null +++ b/src/_cffi_src/openssl/ocsp.py @@ -0,0 +1,67 @@ +# 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 + +INCLUDES = """ +#include <openssl/ocsp.h> +""" + +TYPES = """ +typedef ... OCSP_REQUEST; +typedef ... OCSP_ONEREQ; +typedef ... OCSP_RESPONSE; +typedef ... OCSP_BASICRESP; +typedef ... OCSP_SINGLERESP; +typedef ... OCSP_CERTID; +""" + +FUNCTIONS = """ +int OCSP_response_status(OCSP_RESPONSE *); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *); +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *, int); +int OCSP_resp_count(OCSP_BASICRESP *); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *, int); +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *, int); + +int OCSP_single_get0_status(OCSP_SINGLERESP *, int *, ASN1_GENERALIZEDTIME **, + ASN1_GENERALIZEDTIME **, ASN1_GENERALIZEDTIME **); + +int OCSP_request_onereq_count(OCSP_REQUEST *); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *, int); +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *, int); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *); + + +OCSP_BASICRESP *OCSP_BASICRESP_new(void); +void OCSP_BASICRESP_free(OCSP_BASICRESP *); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *, OCSP_CERTID *, int, + int, ASN1_TIME *, ASN1_TIME *, + ASN1_TIME *); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *, unsigned char *, int); +int OCSP_basic_add1_cert(OCSP_BASICRESP *, X509 *); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *, int, void *, int, + unsigned long); +int OCSP_basic_sign(OCSP_BASICRESP *, X509 *, EVP_PKEY *, const EVP_MD *, + Cryptography_STACK_OF_X509 *, unsigned long); +OCSP_RESPONSE *OCSP_response_create(int, OCSP_BASICRESP *); + +OCSP_REQUEST *OCSP_REQUEST_new(void); +void OCSP_REQUEST_free(OCSP_REQUEST *); +int OCSP_request_add1_nonce(OCSP_REQUEST *, unsigned char *, int); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *, int, void *, int, unsigned long); +""" + +MACROS = """ +OCSP_REQUEST *d2i_OCSP_REQUEST_bio(BIO *, OCSP_REQUEST **); +OCSP_RESPONSE *d2i_OCSP_RESPONSE_bio(BIO *, OCSP_RESPONSE **); +int i2d_OCSP_REQUEST_bio(BIO *, OCSP_REQUEST *); +int i2d_OCSP_RESPONSE_bio(BIO *, OCSP_RESPONSE *); +""" + +CUSTOMIZATIONS = """ +""" diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py index 64e4e2f0..98b396da 100644 --- a/src/_cffi_src/openssl/ssl.py +++ b/src/_cffi_src/openssl/ssl.py @@ -234,6 +234,8 @@ int SSL_CTX_check_private_key(const SSL_CTX *); void SSL_CTX_set_cert_verify_callback(SSL_CTX *, int (*)(X509_STORE_CTX *,void *), void *); +int SSL_CTX_set_session_id_context(SSL_CTX *, const unsigned char *, + unsigned int); void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); @@ -260,6 +262,8 @@ int SSL_set_ex_data(SSL *, int, void *); int SSL_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *, CRYPTO_EX_free *); int SSL_CTX_set_ex_data(SSL_CTX *, int, void *); + +Cryptography_STACK_OF_X509_NAME *SSL_load_client_CA_file(const char *); """ MACROS = """ diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 51c8410a..3612f1c2 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -78,6 +78,11 @@ typedef struct { Cryptography_STACK_OF_GENERAL_SUBTREE *excludedSubtrees; } NAME_CONSTRAINTS; +typedef struct { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + typedef struct { int type; @@ -200,6 +205,9 @@ int Cryptography_i2d_NAME_CONSTRAINTS(NAME_CONSTRAINTS *, unsigned char **); OTHERNAME *OTHERNAME_new(void); void OTHERNAME_free(OTHERNAME *); +POLICY_CONSTRAINTS *POLICY_CONSTRAINTS_new(void); +void POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *); + void *X509V3_set_ctx_nodb(X509V3_CTX *); int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **); diff --git a/src/cryptography/fernet.py b/src/cryptography/fernet.py index 6fbe9f27..99eb10e5 100644 --- a/src/cryptography/fernet.py +++ b/src/cryptography/fernet.py @@ -91,8 +91,10 @@ class Fernet(object): if ttl is not None: if timestamp + ttl < current_time: raise InvalidToken - if current_time + _MAX_CLOCK_SKEW < timestamp: - raise InvalidToken + + if current_time + _MAX_CLOCK_SKEW < timestamp: + raise InvalidToken + h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend) h.update(data[:-32]) try: diff --git a/src/cryptography/hazmat/__init__.py b/src/cryptography/hazmat/__init__.py index 4b540884..9f06a994 100644 --- a/src/cryptography/hazmat/__init__.py +++ b/src/cryptography/hazmat/__init__.py @@ -1,5 +1,11 @@ # 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. +""" +Hazardous Materials +This is a "Hazardous Materials" module. You should ONLY use it if you're +100% absolutely sure that you know what you're doing because this module +is full of land mines, dragons, and dinosaurs with laser guns. +""" from __future__ import absolute_import, division, print_function diff --git a/src/cryptography/hazmat/backends/__init__.py b/src/cryptography/hazmat/backends/__init__.py index 256fee39..96a431dc 100644 --- a/src/cryptography/hazmat/backends/__init__.py +++ b/src/cryptography/hazmat/backends/__init__.py @@ -17,12 +17,7 @@ def _available_backends(): if _available_backends_list is None: _available_backends_list = [ - # setuptools 11.3 deprecated support for the require parameter to - # load(), and introduced the new resolve() method instead. - # This can be removed if/when we can assume setuptools>=11.3. At - # some point we may wish to add a warning, to push people along, - # but at present this would result in too many warnings. - ep.resolve() if hasattr(ep, "resolve") else ep.load(require=False) + ep.resolve() for ep in pkg_resources.iter_entry_points( "cryptography.backends" ) diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py index 42d6c858..5f828c6b 100644 --- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -320,10 +320,9 @@ def _decode_basic_constraints(backend, bc_st): # chooses to just map this to its ordinal value, so true is 255 and # false is 0. ca = basic_constraints.ca == 255 - if basic_constraints.pathlen == backend._ffi.NULL: - path_length = None - else: - path_length = _asn1_integer_to_int(backend, basic_constraints.pathlen) + path_length = _asn1_integer_to_int_or_none( + backend, basic_constraints.pathlen + ) return x509.BasicConstraints(ca, path_length) @@ -343,7 +342,6 @@ def _decode_authority_key_identifier(backend, akid): akid = backend._ffi.gc(akid, backend._lib.AUTHORITY_KEYID_free) key_identifier = None authority_cert_issuer = None - authority_cert_serial_number = None if akid.keyid != backend._ffi.NULL: key_identifier = backend._ffi.buffer( @@ -355,10 +353,9 @@ def _decode_authority_key_identifier(backend, akid): backend, akid.issuer ) - if akid.serial != backend._ffi.NULL: - authority_cert_serial_number = _asn1_integer_to_int( - backend, akid.serial - ) + authority_cert_serial_number = _asn1_integer_to_int_or_none( + backend, akid.serial + ) return x509.AuthorityKeyIdentifier( key_identifier, authority_cert_issuer, authority_cert_serial_number @@ -452,6 +449,22 @@ def _decode_general_subtrees(backend, stack_subtrees): return subtrees +def _decode_policy_constraints(backend, pc): + pc = backend._ffi.cast("POLICY_CONSTRAINTS *", pc) + pc = backend._ffi.gc(pc, backend._lib.POLICY_CONSTRAINTS_free) + + require_explicit_policy = _asn1_integer_to_int_or_none( + backend, pc.requireExplicitPolicy + ) + inhibit_policy_mapping = _asn1_integer_to_int_or_none( + backend, pc.inhibitPolicyMapping + ) + + return x509.PolicyConstraints( + require_explicit_policy, inhibit_policy_mapping + ) + + def _decode_extended_key_usage(backend, sk): sk = backend._ffi.cast("Cryptography_STACK_OF_ASN1_OBJECT *", sk) sk = backend._ffi.gc(sk, backend._lib.sk_ASN1_OBJECT_free) @@ -675,6 +688,13 @@ def _asn1_integer_to_int(backend, asn1_int): return backend._bn_to_int(bn) +def _asn1_integer_to_int_or_none(backend, asn1_int): + if asn1_int == backend._ffi.NULL: + return None + else: + return _asn1_integer_to_int(backend, asn1_int) + + def _asn1_string_to_bytes(backend, asn1_string): return backend._ffi.buffer(asn1_string.data, asn1_string.length)[:] @@ -729,6 +749,7 @@ _EXTENSION_HANDLERS = { ExtensionOID.INHIBIT_ANY_POLICY: _decode_inhibit_any_policy, ExtensionOID.ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name, ExtensionOID.NAME_CONSTRAINTS: _decode_name_constraints, + ExtensionOID.POLICY_CONSTRAINTS: _decode_policy_constraints, } _REVOKED_EXTENSION_HANDLERS = { diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 033cd3b1..ba9c5ab6 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -139,6 +139,10 @@ def _handle_rsa_enc_dec_error(backend, key): backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01, backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02, backend._lib.RSA_R_OAEP_DECODING_ERROR, + # Though this error looks similar to the + # RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE, this occurs on decrypts, + # rather then on encrypts + backend._lib.RSA_R_DATA_TOO_LARGE_FOR_MODULUS, ] if backend._lib.Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR: decoding_errors.append(backend._lib.RSA_R_PKCS_DECODING_ERROR) @@ -534,11 +538,9 @@ class _RSAPrivateKey(object): return _enc_dec_rsa(self._backend, self, ciphertext, padding) def public_key(self): - ctx = self._backend._lib.RSA_new() + ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata) self._backend.openssl_assert(ctx != self._backend._ffi.NULL) ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free) - ctx.e = self._backend._lib.BN_dup(self._rsa_cdata.e) - ctx.n = self._backend._lib.BN_dup(self._rsa_cdata.n) res = self._backend._lib.RSA_blinding_on(ctx, self._backend._ffi.NULL) self._backend.openssl_assert(res == 1) evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 1cfe8162..b2215de3 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -10,6 +10,7 @@ import threading import types import warnings +from cryptography import utils from cryptography.exceptions import InternalError from cryptography.hazmat.bindings._openssl import ffi, lib from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES @@ -204,7 +205,14 @@ class Binding(object): # is per module so this approach will not work. Binding.init_static_locks() -if Binding.lib.SSLeay() < 0x10001000: +if Binding.lib.SSLeay() < 0x10000000: + warnings.warn( + "OpenSSL version 0.9.8 is no longer supported by the OpenSSL project, " + "please upgrade. The next version of cryptography will drop support " + "for it.", + utils.DeprecatedIn12 + ) +elif Binding.lib.SSLeay() < 0x10001000: warnings.warn( "OpenSSL versions less than 1.0.1 are no longer supported by the " "OpenSSL project, please upgrade. A future version of cryptography " diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index dae93655..496975ae 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -185,7 +185,7 @@ class _AEADCipherContext(object): self._aad_bytes_processed += len(data) if self._aad_bytes_processed > self._ctx._mode._MAX_AAD_BYTES: raise ValueError( - "{0} has a maximum AAD byte limit of {0}".format( + "{0} has a maximum AAD byte limit of {1}".format( self._ctx._mode.name, self._ctx._mode._MAX_AAD_BYTES ) ) diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index b85d50d3..53795732 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -15,7 +15,7 @@ import warnings # the functions deprecated in 1.0 are on an arbitrarily extended deprecation # cycle and should not be removed until we agree on when that cycle ends. DeprecatedIn10 = DeprecationWarning -DeprecatedIn12 = PendingDeprecationWarning +DeprecatedIn12 = DeprecationWarning def read_only_property(name): @@ -45,6 +45,7 @@ else: while len(data) > 0: digit, = struct.unpack('>I', data[:4]) result = (result << 32) + digit + # TODO: this is quadratic in the length of data data = data[4:] return result diff --git a/src/cryptography/x509/__init__.py b/src/cryptography/x509/__init__.py index a1deb7f4..8d7bad27 100644 --- a/src/cryptography/x509/__init__.py +++ b/src/cryptography/x509/__init__.py @@ -4,6 +4,7 @@ from __future__ import absolute_import, division, print_function +from cryptography import utils from cryptography.x509.base import ( Certificate, CertificateBuilder, CertificateRevocationList, CertificateRevocationListBuilder, @@ -19,9 +20,10 @@ from cryptography.x509.extensions import ( DistributionPoint, DuplicateExtension, ExtendedKeyUsage, Extension, ExtensionNotFound, ExtensionType, Extensions, GeneralNames, InhibitAnyPolicy, InvalidityDate, IssuerAlternativeName, KeyUsage, - NameConstraints, NoticeReference, OCSPNoCheck, PolicyInformation, - ReasonFlags, SubjectAlternativeName, SubjectKeyIdentifier, - UnrecognizedExtension, UnsupportedExtension, UserNotice + NameConstraints, NoticeReference, OCSPNoCheck, PolicyConstraints, + PolicyInformation, ReasonFlags, SubjectAlternativeName, + SubjectKeyIdentifier, UnrecognizedExtension, UnsupportedExtension, + UserNotice ) from cryptography.x509.general_name import ( DNSName, DirectoryName, GeneralName, IPAddress, OtherName, RFC822Name, @@ -30,12 +32,19 @@ from cryptography.x509.general_name import ( ) from cryptography.x509.name import Name, NameAttribute from cryptography.x509.oid import ( - AuthorityInformationAccessOID, CRLEntryExtensionOID, CRLExtensionOID, + AuthorityInformationAccessOID, CRLEntryExtensionOID, CertificatePoliciesOID, ExtendedKeyUsageOID, ExtensionOID, NameOID, ObjectIdentifier, SignatureAlgorithmOID, _SIG_OIDS_TO_HASH ) +CRLExtensionOID = utils.deprecated( + CRLEntryExtensionOID, + __name__, + "CRLExtensionOID has been renamed to CRLEntryExtensionOID", + utils.DeprecatedIn12 +) + OID_AUTHORITY_INFORMATION_ACCESS = ExtensionOID.AUTHORITY_INFORMATION_ACCESS OID_AUTHORITY_KEY_IDENTIFIER = ExtensionOID.AUTHORITY_KEY_IDENTIFIER OID_BASIC_CONSTRAINTS = ExtensionOID.BASIC_CONSTRAINTS @@ -170,4 +179,5 @@ __all__ = [ "CRLReason", "InvalidityDate", "UnrecognizedExtension", + "PolicyConstraints", ] diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index 3e6fc3b3..0aa67212 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -313,6 +313,9 @@ class AccessDescription(object): def __ne__(self, other): return not self == other + def __hash__(self): + return hash((self.access_method, self.access_location)) + access_method = utils.read_only_property("_access_method") access_location = utils.read_only_property("_access_location") @@ -487,6 +490,62 @@ class ReasonFlags(Enum): @utils.register_interface(ExtensionType) +class PolicyConstraints(object): + oid = ExtensionOID.POLICY_CONSTRAINTS + + def __init__(self, require_explicit_policy, inhibit_policy_mapping): + if require_explicit_policy is not None and not isinstance( + require_explicit_policy, six.integer_types + ): + raise TypeError( + "require_explicit_policy must be a non-negative integer or " + "None" + ) + + if inhibit_policy_mapping is not None and not isinstance( + inhibit_policy_mapping, six.integer_types + ): + raise TypeError( + "inhibit_policy_mapping must be a non-negative integer or None" + ) + + if inhibit_policy_mapping is None and require_explicit_policy is None: + raise ValueError( + "At least one of require_explicit_policy and " + "inhibit_policy_mapping must not be None" + ) + + self._require_explicit_policy = require_explicit_policy + self._inhibit_policy_mapping = inhibit_policy_mapping + + def __repr__(self): + return ( + u"<PolicyConstraints(require_explicit_policy={0.require_explicit" + u"_policy}, inhibit_policy_mapping={0.inhibit_policy_" + u"mapping})>".format(self) + ) + + def __eq__(self, other): + if not isinstance(other, PolicyConstraints): + return NotImplemented + + return ( + self.require_explicit_policy == other.require_explicit_policy and + self.inhibit_policy_mapping == other.inhibit_policy_mapping + ) + + def __ne__(self, other): + return not self == other + + require_explicit_policy = utils.read_only_property( + "_require_explicit_policy" + ) + inhibit_policy_mapping = utils.read_only_property( + "_inhibit_policy_mapping" + ) + + +@utils.register_interface(ExtensionType) class CertificatePolicies(object): oid = ExtensionOID.CERTIFICATE_POLICIES @@ -690,6 +749,9 @@ class InhibitAnyPolicy(object): def __ne__(self, other): return not self == other + def __hash__(self): + return hash(self.skip_certs) + skip_certs = utils.read_only_property("_skip_certs") diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 9d93ece1..d62341d7 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function import six from cryptography import utils -from cryptography.x509.oid import ObjectIdentifier +from cryptography.x509.oid import NameOID, ObjectIdentifier class NameAttribute(object): @@ -22,6 +22,11 @@ class NameAttribute(object): "value argument must be a text type." ) + if oid == NameOID.COUNTRY_NAME and len(value.encode("utf8")) != 2: + raise ValueError( + "Country name must be a 2 character country code" + ) + self._oid = oid self._value = value |