From 00f94097219d14036d7172994e54dc6a6d2fa8f3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 10 Oct 2015 15:42:17 -0400 Subject: Catch Invalid X or Y points and raise a ValueError Signed-off-by: Simo Sorce --- src/cryptography/hazmat/backends/openssl/backend.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index ac025e95..0d3b3dd4 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1776,9 +1776,13 @@ class Backend(object): self.openssl_assert(res == 1) res = self._lib.BN_cmp(bn_x, check_x) - self.openssl_assert(res == 0) + if res != 0: + self._consume_errors() + raise ValueError("Invalid EC Key X point.") res = self._lib.BN_cmp(bn_y, check_y) - self.openssl_assert(res == 0) + if res != 0: + self._consume_errors() + raise ValueError("Invalid EC Key Y point.") res = self._lib.EC_KEY_set_public_key(ctx, point) self.openssl_assert(res == 1) -- cgit v1.2.3 From 90ddd354784ffcf8723d4a7b81e9b399bc2a6c9c Mon Sep 17 00:00:00 2001 From: Dominic Chen Date: Mon, 12 Oct 2015 18:50:21 +0000 Subject: extend pkcs7 openssl bindings --- src/_cffi_src/build_openssl.py | 4 ++-- src/_cffi_src/openssl/pkcs7.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index defa69d3..c856e3d9 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -79,7 +79,6 @@ ffi = build_ffi_for_binding( "objects", "opensslv", "pem", - "pkcs7", "pkcs12", "rand", "rsa", @@ -87,7 +86,8 @@ ffi = build_ffi_for_binding( "x509", "x509name", "x509v3", - "x509_vfy" + "x509_vfy", + "pkcs7", ], pre_include=_OSX_PRE_INCLUDE, post_include=_OSX_POST_INCLUDE, diff --git a/src/_cffi_src/openssl/pkcs7.py b/src/_cffi_src/openssl/pkcs7.py index 5d6ee45f..0dd89582 100644 --- a/src/_cffi_src/openssl/pkcs7.py +++ b/src/_cffi_src/openssl/pkcs7.py @@ -9,8 +9,34 @@ INCLUDES = """ """ TYPES = """ +typedef struct { + Cryptography_STACK_OF_X509 *cert; + Cryptography_STACK_OF_X509_CRL *crl; + ...; +} PKCS7_SIGNED; + +typedef struct { + Cryptography_STACK_OF_X509 *cert; + Cryptography_STACK_OF_X509_CRL *crl; + ...; +} PKCS7_SIGN_ENVELOPE; + +typedef ... PKCS7_DIGEST; +typedef ... PKCS7_ENCRYPT; +typedef ... PKCS7_ENVELOPE; + typedef struct { ASN1_OBJECT *type; + union { + char *ptr; + ASN1_OCTET_STRING *data; + PKCS7_SIGNED *sign; + PKCS7_ENVELOPE *enveloped; + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + PKCS7_DIGEST *digest; + PKCS7_ENCRYPT *encrypted; + ASN1_TYPE *other; + } d; ...; } PKCS7; @@ -44,13 +70,17 @@ Cryptography_STACK_OF_X509 *PKCS7_get0_signers(PKCS7 *, PKCS7 *PKCS7_encrypt(Cryptography_STACK_OF_X509 *, BIO *, const EVP_CIPHER *, int); int PKCS7_decrypt(PKCS7 *, EVP_PKEY *, X509 *, BIO *, int); + +BIO *PKCS7_dataInit(PKCS7 *, BIO *); """ MACROS = """ +int PKCS7_type_is_encrypted(PKCS7 *); int PKCS7_type_is_signed(PKCS7 *); int PKCS7_type_is_enveloped(PKCS7 *); int PKCS7_type_is_signedAndEnveloped(PKCS7 *); int PKCS7_type_is_data(PKCS7 *); +int PKCS7_type_is_digest(PKCS7 *); """ CUSTOMIZATIONS = "" -- cgit v1.2.3 From f115e0548001452de7d2ffc81fdbac1d5ec8b418 Mon Sep 17 00:00:00 2001 From: Erik Trauschke Date: Thu, 15 Oct 2015 15:30:55 -0700 Subject: add binding for d2i_GENERAL_NAMES() --- src/_cffi_src/openssl/x509v3.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/_cffi_src/openssl/x509v3.py b/src/_cffi_src/openssl/x509v3.py index 84e49640..8e163dc2 100644 --- a/src/_cffi_src/openssl/x509v3.py +++ b/src/_cffi_src/openssl/x509v3.py @@ -202,6 +202,8 @@ void OTHERNAME_free(OTHERNAME *); void *X509V3_set_ctx_nodb(X509V3_CTX *); int i2d_GENERAL_NAMES(GENERAL_NAMES *, unsigned char **); +GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **, const unsigned char **, + long); int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *, unsigned char **); -- cgit v1.2.3 From e6abbfd2ad055b8be81c49a1d9cd4c01a890dd55 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 15 Oct 2015 22:58:52 -0400 Subject: Kill Key Exchange as a separate interface Ultimately it was decided that ECDH and the others can be implemented as simple classes without the overhead of an interface. So ... let's kill it, it was a fun process. Signed-off-by: Simo Sorce --- .../hazmat/primitives/asymmetric/key_exchange.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/cryptography/hazmat/primitives/asymmetric/key_exchange.py (limited to 'src') diff --git a/src/cryptography/hazmat/primitives/asymmetric/key_exchange.py b/src/cryptography/hazmat/primitives/asymmetric/key_exchange.py deleted file mode 100644 index a9846e28..00000000 --- a/src/cryptography/hazmat/primitives/asymmetric/key_exchange.py +++ /dev/null @@ -1,18 +0,0 @@ -# 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 - - -@six.add_metaclass(abc.ABCMeta) -class KeyExchangeContext(object): - @abc.abstractmethod - def agree(self, public_key): - """ - Returns the agreed key material. - """ -- cgit v1.2.3 From 9aaeee0dc62189204f38097c815a0913fabe006c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 30 Apr 2015 14:06:47 -0400 Subject: Add an Elliptic Curve Key Exchange Algorithm(ECDH) The ECDH Key Exchange algorithm as standardized in NIST publication 800-56A Revision 2 Includes tests with vectors from NIST. Signed-off-by: Simo Sorce --- src/cryptography/exceptions.py | 1 + src/cryptography/hazmat/backends/interfaces.py | 6 ++++++ src/cryptography/hazmat/backends/multibackend.py | 6 ++++++ .../hazmat/backends/openssl/backend.py | 20 +++++++++++++++++ .../hazmat/primitives/asymmetric/ec.py | 25 ++++++++++++++++++++++ 5 files changed, 58 insertions(+) (limited to 'src') diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py index 29be22be..3bf8a75b 100644 --- a/src/cryptography/exceptions.py +++ b/src/cryptography/exceptions.py @@ -20,6 +20,7 @@ class _Reasons(Enum): UNSUPPORTED_ELLIPTIC_CURVE = 6 UNSUPPORTED_SERIALIZATION = 7 UNSUPPORTED_X509 = 8 + UNSUPPORTED_EXCHANGE_ALGORITHM = 9 class UnsupportedAlgorithm(Exception): diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py index a43621a7..faa0b313 100644 --- a/src/cryptography/hazmat/backends/interfaces.py +++ b/src/cryptography/hazmat/backends/interfaces.py @@ -215,6 +215,12 @@ class EllipticCurveBackend(object): Return an EllipticCurvePublicKey provider using the given numbers. """ + @abc.abstractmethod + def elliptic_curve_exchange_algorithm_supported(self): + """ + Returns whether the exchange algorithm is supported by this backend. + """ + @six.add_metaclass(abc.ABCMeta) class PEMSerializationBackend(object): diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py index 9db32aa5..77a45ccd 100644 --- a/src/cryptography/hazmat/backends/multibackend.py +++ b/src/cryptography/hazmat/backends/multibackend.py @@ -271,6 +271,12 @@ class MultiBackend(object): _Reasons.UNSUPPORTED_ELLIPTIC_CURVE ) + def elliptic_curve_exchange_algorithm_supported(self): + return any( + b.elliptic_curve_exchange_algorithm_supported() + for b in self._filtered_backends(EllipticCurveBackend) + ) + def load_pem_private_key(self, data, password): for b in self._filtered_backends(PEMSerializationBackend): return b.load_pem_private_key(data, password) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 0d3b3dd4..d82f3834 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1671,6 +1671,26 @@ class Backend(object): return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) + def elliptic_curve_exchange_algorithm_supported(self): + return (self._lib.Cryptography_HAS_EC == 1 and + self._lib.Cryptography_HAS_ECDH == 1) + + def ecdh_compute_key(self, private_key, peer_public_key): + pri_key = private_key._ec_key + pub_key = peer_public_key._ec_key + + group = self._lib.EC_KEY_get0_group(pri_key) + z_len = (self._lib.EC_GROUP_get_degree(group) + 7) // 8 + self.openssl_assert(z_len > 0) + z_buf = self._ffi.new("uint8_t[]", z_len) + peer_key = self._lib.EC_KEY_get0_public_key(pub_key) + + r = self._lib.ECDH_compute_key(z_buf, z_len, + peer_key, pri_key, + self._ffi.NULL) + self.openssl_assert(r > 0) + return self._ffi.buffer(z_buf)[:z_len] + def _ec_cdata_to_evp_pkey(self, ec_cdata): evp_pkey = self._lib.EVP_PKEY_new() self.openssl_assert(evp_pkey != self._ffi.NULL) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index f1d39eed..978a7c41 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -8,6 +8,7 @@ import abc import six +from cryptography import exceptions from cryptography import utils @@ -302,3 +303,27 @@ class EllipticCurvePrivateNumbers(object): def __ne__(self, other): return not self == other + + +class ECDH(object): + def __init__(self, private_key): + if not isinstance(private_key, EllipticCurvePrivateKey): + raise TypeError("Private Key must be a EllipticCurvePrivateKey") + self._private_key = private_key + self._backend = private_key._backend + if not self._backend.elliptic_curve_exchange_algorithm_supported(): + raise exceptions.UnsupportedAlgorithm( + "This backend does not support the ECDH algorithm.", + exceptions._Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM + ) + + private_key = utils.read_only_property("_private_key") + + def public_key(self): + return self._private_key.public_key() + + def compute_key(self, peer_public_key): + if not isinstance(peer_public_key, EllipticCurvePublicKey): + raise TypeError("Peer Public Key must be a EllipticCurvePublicKey") + return self._backend.ecdh_compute_key(self._private_key, + peer_public_key) -- cgit v1.2.3 From 5cdfba5c8d06ed10510310de03e1df0265a89bcc Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 17 Oct 2015 16:33:04 -0400 Subject: a refactor to the API --- src/cryptography/hazmat/backends/interfaces.py | 2 +- src/cryptography/hazmat/backends/multibackend.py | 4 ++-- .../hazmat/backends/openssl/backend.py | 25 ++++++---------------- src/cryptography/hazmat/backends/openssl/ec.py | 25 ++++++++++++++++++++++ .../hazmat/primitives/asymmetric/ec.py | 22 +------------------ 5 files changed, 35 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py index faa0b313..dbebc883 100644 --- a/src/cryptography/hazmat/backends/interfaces.py +++ b/src/cryptography/hazmat/backends/interfaces.py @@ -216,7 +216,7 @@ class EllipticCurveBackend(object): """ @abc.abstractmethod - def elliptic_curve_exchange_algorithm_supported(self): + def elliptic_curve_exchange_algorithm_supported(self, algorithm, curve): """ Returns whether the exchange algorithm is supported by this backend. """ diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py index 77a45ccd..c4d2c133 100644 --- a/src/cryptography/hazmat/backends/multibackend.py +++ b/src/cryptography/hazmat/backends/multibackend.py @@ -271,9 +271,9 @@ class MultiBackend(object): _Reasons.UNSUPPORTED_ELLIPTIC_CURVE ) - def elliptic_curve_exchange_algorithm_supported(self): + def elliptic_curve_exchange_algorithm_supported(self, algorithm, curve): return any( - b.elliptic_curve_exchange_algorithm_supported() + b.elliptic_curve_exchange_algorithm_supported(algorithm, curve) for b in self._filtered_backends(EllipticCurveBackend) ) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index d82f3834..f86c3aa1 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1671,25 +1671,12 @@ class Backend(object): return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) - def elliptic_curve_exchange_algorithm_supported(self): - return (self._lib.Cryptography_HAS_EC == 1 and - self._lib.Cryptography_HAS_ECDH == 1) - - def ecdh_compute_key(self, private_key, peer_public_key): - pri_key = private_key._ec_key - pub_key = peer_public_key._ec_key - - group = self._lib.EC_KEY_get0_group(pri_key) - z_len = (self._lib.EC_GROUP_get_degree(group) + 7) // 8 - self.openssl_assert(z_len > 0) - z_buf = self._ffi.new("uint8_t[]", z_len) - peer_key = self._lib.EC_KEY_get0_public_key(pub_key) - - r = self._lib.ECDH_compute_key(z_buf, z_len, - peer_key, pri_key, - self._ffi.NULL) - self.openssl_assert(r > 0) - return self._ffi.buffer(z_buf)[:z_len] + def elliptic_curve_exchange_algorithm_supported(self, algorithm, curve): + return ( + self.elliptic_curve_supported(curve) and + self._lib.Cryptography_HAS_ECDH == 1 and + isinstance(algorithm, ec.ECDH) + ) def _ec_cdata_to_evp_pkey(self, ec_cdata): evp_pkey = self._lib.EVP_PKEY_new() diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 939a3f90..cfd559ae 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -171,6 +171,31 @@ class _EllipticCurvePrivateKey(object): "Unsupported elliptic curve signature algorithm.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + def exchange(self, algorithm, peer_public_key): + if not ( + self._backend.elliptic_curve_exchange_algorithm_supported( + algorithm, self.curve + ) + ): + raise UnsupportedAlgorithm( + "This backend does not support the ECDH algorithm.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM + ) + + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + z_len = (self._backend._lib.EC_GROUP_get_degree(group) + 7) // 8 + self._backend.openssl_assert(z_len > 0) + z_buf = self._backend._ffi.new("uint8_t[]", z_len) + peer_key = self._backend._lib.EC_KEY_get0_public_key( + peer_public_key._ec_key + ) + + r = self._backend._lib.ECDH_compute_key( + z_buf, z_len, peer_key, self._ec_key, self._backend._ffi.NULL + ) + self._backend.openssl_assert(r > 0) + return self._backend._ffi.buffer(z_buf)[:z_len] + def public_key(self): group = self._backend._lib.EC_KEY_get0_group(self._ec_key) self._backend.openssl_assert(group != self._backend._ffi.NULL) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 978a7c41..544894a9 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -306,24 +306,4 @@ class EllipticCurvePrivateNumbers(object): class ECDH(object): - def __init__(self, private_key): - if not isinstance(private_key, EllipticCurvePrivateKey): - raise TypeError("Private Key must be a EllipticCurvePrivateKey") - self._private_key = private_key - self._backend = private_key._backend - if not self._backend.elliptic_curve_exchange_algorithm_supported(): - raise exceptions.UnsupportedAlgorithm( - "This backend does not support the ECDH algorithm.", - exceptions._Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM - ) - - private_key = utils.read_only_property("_private_key") - - def public_key(self): - return self._private_key.public_key() - - def compute_key(self, peer_public_key): - if not isinstance(peer_public_key, EllipticCurvePublicKey): - raise TypeError("Peer Public Key must be a EllipticCurvePublicKey") - return self._backend.ecdh_compute_key(self._private_key, - peer_public_key) + pass -- cgit v1.2.3 From 91113b9c37fbaeeb55a2486313d8314ecdc8dfbf Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 17 Oct 2015 16:35:05 -0400 Subject: unused import --- src/cryptography/hazmat/primitives/asymmetric/ec.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 544894a9..052ae742 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -8,7 +8,6 @@ import abc import six -from cryptography import exceptions from cryptography import utils -- cgit v1.2.3 From 68b3441d90fa4230b62d19a43c49dd2aa155db47 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 17 Oct 2015 18:09:03 -0400 Subject: better document hte iface --- 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 052ae742..c6f83667 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -43,6 +43,13 @@ class EllipticCurvePrivateKey(object): Returns an AsymmetricSignatureContext used for signing data. """ + @abc.abstractmethod + def exchange(self, algorithm, peer_public_key): + """ + Performs a key exchange operation using the provided algorithm with the + provided peer's public key. + """ + @abc.abstractmethod def public_key(self): """ -- cgit v1.2.3 From b5f1f7235f69dd56038ce8240bed6c08a5977b45 Mon Sep 17 00:00:00 2001 From: Terry Chia Date: Sun, 18 Oct 2015 10:12:13 +0800 Subject: Fix wrong mention of class in docstring. --- src/cryptography/hazmat/backends/interfaces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py index a43621a7..d93968cf 100644 --- a/src/cryptography/hazmat/backends/interfaces.py +++ b/src/cryptography/hazmat/backends/interfaces.py @@ -212,7 +212,7 @@ class EllipticCurveBackend(object): @abc.abstractmethod def load_elliptic_curve_private_numbers(self, numbers): """ - Return an EllipticCurvePublicKey provider using the given numbers. + Return an EllipticCurvePrivateKey provider using the given numbers. """ -- cgit v1.2.3 From afbe75bf4fb6c288a7e25b2c58a72ec7049f3f64 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Tue, 20 Oct 2015 08:08:43 -0500 Subject: add __repr__ to x509.Extensions fix #2434 --- src/cryptography/x509/extensions.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py index cd75ecdc..46ba5a28 100644 --- a/src/cryptography/x509/extensions.py +++ b/src/cryptography/x509/extensions.py @@ -104,6 +104,11 @@ class Extensions(object): def __len__(self): return len(self._extensions) + def __repr__(self): + return ( + "".format(self._extensions) + ) + @utils.register_interface(ExtensionType) class AuthorityKeyIdentifier(object): -- cgit v1.2.3