diff options
Diffstat (limited to 'src/cryptography')
| -rw-r--r-- | src/cryptography/exceptions.py | 1 | ||||
| -rw-r--r-- | src/cryptography/hazmat/backends/interfaces.py | 8 | ||||
| -rw-r--r-- | src/cryptography/hazmat/backends/multibackend.py | 6 | ||||
| -rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 15 | ||||
| -rw-r--r-- | src/cryptography/hazmat/backends/openssl/ec.py | 25 | ||||
| -rw-r--r-- | src/cryptography/hazmat/primitives/asymmetric/ec.py | 11 | ||||
| -rw-r--r-- | src/cryptography/hazmat/primitives/asymmetric/key_exchange.py | 18 | ||||
| -rw-r--r-- | src/cryptography/x509/extensions.py | 5 | 
8 files changed, 68 insertions, 21 deletions
| 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..92d9653a 100644 --- a/src/cryptography/hazmat/backends/interfaces.py +++ b/src/cryptography/hazmat/backends/interfaces.py @@ -212,7 +212,13 @@ 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. +        """ + +    @abc.abstractmethod +    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 cda33145..bbaaf424 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, algorithm, curve): +        return any( +            b.elliptic_curve_exchange_algorithm_supported(algorithm, curve) +            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 06db6f22..58587b94 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1693,6 +1693,13 @@ class Backend(object):          return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) +    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()          self.openssl_assert(evp_pkey != self._ffi.NULL) @@ -1798,9 +1805,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) 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 f1d39eed..c6f83667 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -44,6 +44,13 @@ class EllipticCurvePrivateKey(object):          """      @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):          """          The EllipticCurvePublicKey for this private key. @@ -302,3 +309,7 @@ class EllipticCurvePrivateNumbers(object):      def __ne__(self, other):          return not self == other + + +class ECDH(object): +    pass 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. -        """ 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 ( +            "<Extensions({0})>".format(self._extensions) +        ) +  @utils.register_interface(ExtensionType)  class AuthorityKeyIdentifier(object): | 
