aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography/hazmat
diff options
context:
space:
mode:
Diffstat (limited to 'cryptography/hazmat')
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py395
-rw-r--r--cryptography/hazmat/bindings/openssl/ssl.py45
-rw-r--r--cryptography/hazmat/primitives/asymmetric/ec.py186
-rw-r--r--cryptography/hazmat/primitives/interfaces.py94
-rw-r--r--cryptography/hazmat/primitives/serialization.py8
5 files changed, 628 insertions, 100 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index ffe09663..7746dafb 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -25,13 +25,13 @@ from cryptography.exceptions import (
UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import (
- CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
- PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
+ CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend,
+ HashBackend, PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
TraditionalOpenSSLSerializationBackend
)
from cryptography.hazmat.bindings.openssl.binding import Binding
from cryptography.hazmat.primitives import hashes, interfaces
-from cryptography.hazmat.primitives.asymmetric import dsa, rsa
+from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
from cryptography.hazmat.primitives.asymmetric.padding import (
MGF1, OAEP, PKCS1v15, PSS
)
@@ -51,12 +51,13 @@ _OpenSSLError = collections.namedtuple("_OpenSSLError",
@utils.register_interface(CipherBackend)
@utils.register_interface(CMACBackend)
@utils.register_interface(DSABackend)
+@utils.register_interface(EllipticCurveBackend)
@utils.register_interface(HashBackend)
@utils.register_interface(HMACBackend)
@utils.register_interface(PBKDF2HMACBackend)
+@utils.register_interface(PKCS8SerializationBackend)
@utils.register_interface(RSABackend)
@utils.register_interface(TraditionalOpenSSLSerializationBackend)
-@utils.register_interface(PKCS8SerializationBackend)
class Backend(object):
"""
OpenSSL API binding interfaces.
@@ -425,8 +426,8 @@ class Backend(object):
The char* is the storage for the BIO and it must stay alive until the
BIO is finished with.
"""
- data_char_p = backend._ffi.new("char[]", data)
- bio = backend._lib.BIO_new_mem_buf(
+ data_char_p = self._ffi.new("char[]", data)
+ bio = self._lib.BIO_new_mem_buf(
data_char_p, len(data)
)
assert bio != self._ffi.NULL
@@ -890,6 +891,236 @@ class Backend(object):
return self._evp_pkey_to_private_key(evp_pkey)
+ def elliptic_curve_supported(self, curve):
+ if self._lib.Cryptography_HAS_EC != 1:
+ return False
+
+ curves = self._supported_curves()
+ return curve.name.encode("ascii") in curves
+
+ def elliptic_curve_signature_algorithm_supported(
+ self, signature_algorithm, curve
+ ):
+ if self._lib.Cryptography_HAS_EC != 1:
+ return False
+
+ # We only support ECDSA right now.
+ if isinstance(signature_algorithm, ec.ECDSA) is False:
+ return False
+
+ # Before 0.9.8m OpenSSL can't cope with digests longer than the curve.
+ if (
+ self._lib.OPENSSL_VERSION_NUMBER < 0x009080df and
+ curve.key_size < signature_algorithm.algorithm.digest_size * 8
+ ):
+ return False
+
+ return self.elliptic_curve_supported(curve)
+
+ def _supported_curves(self):
+ if self._lib.Cryptography_HAS_EC != 1:
+ return []
+
+ num_curves = self._lib.EC_get_builtin_curves(self._ffi.NULL, 0)
+ curve_array = self._ffi.new("EC_builtin_curve[]", num_curves)
+ num_curves_assigned = self._lib.EC_get_builtin_curves(
+ curve_array, num_curves)
+ assert num_curves == num_curves_assigned
+
+ curves = [
+ self._ffi.string(self._lib.OBJ_nid2sn(curve.nid)).decode()
+ for curve in curve_array
+ ]
+
+ curve_aliases = {
+ "prime192v1": "secp192r1",
+ "prime256v1": "secp256r1"
+ }
+ return [
+ curve_aliases.get(curve, curve)
+ for curve in curves
+ ]
+
+ def _create_ecdsa_signature_ctx(self, private_key, ecdsa):
+ return _ECDSASignatureContext(self, private_key, ecdsa.algorithm)
+
+ def _create_ecdsa_verification_ctx(self, public_key, signature, ecdsa):
+ return _ECDSAVerificationContext(self, public_key, signature,
+ ecdsa.algorithm)
+
+ def generate_elliptic_curve_private_key(self, curve):
+ """
+ Generate a new private key on the named curve.
+ """
+
+ curve_nid = self._elliptic_curve_to_nid(curve)
+
+ ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
+ assert ctx != self._ffi.NULL
+ ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free)
+
+ res = self._lib.EC_KEY_generate_key(ctx)
+ assert res == 1
+
+ res = self._lib.EC_KEY_check_key(ctx)
+ assert res == 1
+
+ return _EllipticCurvePrivateKey(self, ctx, curve)
+
+ def elliptic_curve_private_key_from_numbers(self, numbers):
+ ec_key = self._ec_key_cdata_from_private_numbers(numbers)
+ return _EllipticCurvePrivateKey(self, ec_key,
+ numbers.public_numbers.curve)
+
+ def elliptic_curve_public_key_from_numbers(self, numbers):
+ ec_key = self._ec_key_cdata_from_public_numbers(numbers)
+ return _EllipticCurvePublicKey(self, ec_key, numbers.curve)
+
+ def _elliptic_curve_to_nid(self, curve):
+ """
+ Get the NID for a curve name.
+ """
+
+ curve_aliases = {
+ "secp192r1": "prime192v1",
+ "secp256r1": "prime256v1"
+ }
+
+ curve_name = curve_aliases.get(curve.name, curve.name)
+
+ curve_nid = self._lib.OBJ_sn2nid(curve_name.encode())
+ if curve_nid == self._lib.NID_undef:
+ raise UnsupportedAlgorithm(
+ "{0} is not a supported elliptic curve".format(curve.name),
+ _Reasons.UNSUPPORTED_ELLIPTIC_CURVE
+ )
+ return curve_nid
+
+ def _ec_key_cdata_from_private_numbers(self, numbers):
+ """
+ Build an EC_KEY from a private key object.
+ """
+
+ public = numbers.public_numbers
+
+ curve_nid = self._elliptic_curve_to_nid(public.curve)
+
+ ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
+ assert ctx != self._ffi.NULL
+ ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free)
+
+ ctx = self._ec_key_set_public_key_affine_coordinates(
+ ctx, public.x, public.y)
+
+ res = self._lib.EC_KEY_set_private_key(
+ ctx, self._int_to_bn(numbers.private_value))
+ assert res == 1
+
+ return ctx
+
+ def _ec_key_cdata_from_public_numbers(self, numbers):
+ """
+ Build an EC_KEY from a public key object.
+ """
+
+ curve_nid = self._elliptic_curve_to_nid(numbers.curve)
+
+ ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
+ assert ctx != self._ffi.NULL
+ ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free)
+
+ ctx = self._ec_key_set_public_key_affine_coordinates(
+ ctx, numbers.x, numbers.y)
+
+ return ctx
+
+ def _public_ec_key_from_private_ec_key(self, private_key_cdata):
+ """
+ Copy the public portions out of one EC key into a new one.
+ """
+
+ group = self._lib.EC_KEY_get0_group(private_key_cdata)
+ assert group != self._ffi.NULL
+
+ curve_nid = self._lib.EC_GROUP_get_curve_name(group)
+
+ ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
+ assert ctx != self._ffi.NULL
+ ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free)
+
+ point = self._lib.EC_KEY_get0_public_key(private_key_cdata)
+ assert point != self._ffi.NULL
+
+ res = self._lib.EC_KEY_set_public_key(ctx, point)
+ assert res == 1
+
+ return ctx
+
+ def _ec_key_set_public_key_affine_coordinates(self, ctx, x, y):
+ """
+ This is a port of EC_KEY_set_public_key_affine_coordinates that was
+ added in 1.0.1.
+
+ Sets the public key point in the EC_KEY context to the affine x and y
+ values.
+ """
+
+ assert ctx != self._ffi.NULL
+
+ bn_x = self._int_to_bn(x)
+ bn_y = self._int_to_bn(y)
+
+ nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field")
+ assert nid_two_field != self._lib.NID_undef
+
+ bn_ctx = self._lib.BN_CTX_new()
+ assert bn_ctx != self._ffi.NULL
+ bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free)
+
+ group = self._lib.EC_KEY_get0_group(ctx)
+ assert group != self._ffi.NULL
+
+ point = self._lib.EC_POINT_new(group)
+ assert point != self._ffi.NULL
+ point = self._ffi.gc(point, self._lib.EC_POINT_free)
+
+ method = self._lib.EC_GROUP_method_of(group)
+ assert method != self._ffi.NULL
+
+ nid = self._lib.EC_METHOD_get_field_type(method)
+ assert nid != self._lib.NID_undef
+
+ check_x = self._lib.BN_CTX_get(bn_ctx)
+ check_y = self._lib.BN_CTX_get(bn_ctx)
+
+ if nid == nid_two_field and self._lib.Cryptography_HAS_EC2M:
+ set_func = self._lib.EC_POINT_set_affine_coordinates_GF2m
+ get_func = self._lib.EC_POINT_get_affine_coordinates_GF2m
+ else:
+ set_func = self._lib.EC_POINT_set_affine_coordinates_GFp
+ get_func = self._lib.EC_POINT_get_affine_coordinates_GFp
+
+ assert set_func and get_func
+
+ res = set_func(group, point, bn_x, bn_y, bn_ctx)
+ assert res == 1
+
+ res = get_func(group, point, check_x, check_y, bn_ctx)
+ assert res == 1
+
+ assert (
+ self._lib.BN_cmp(bn_x, check_x) == 0 and
+ self._lib.BN_cmp(bn_y, check_y) == 0
+ )
+
+ res = self._lib.EC_KEY_set_public_key(ctx, point)
+ assert res == 1
+
+ res = self._lib.EC_KEY_check_key(ctx)
+ assert res == 1
+
+ return ctx
+
class GetCipherByName(object):
def __init__(self, fmt):
@@ -1727,4 +1958,156 @@ class _CMACContext(object):
)
+def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):
+ _lib = backend._lib
+ _ffi = backend._ffi
+
+ digest_len = len(digest)
+
+ group = _lib.EC_KEY_get0_group(ec_key_cdata)
+
+ bn_ctx = _lib.BN_CTX_new()
+ assert bn_ctx != _ffi.NULL
+ bn_ctx = _ffi.gc(bn_ctx, _lib.BN_CTX_free)
+
+ order = _lib.BN_CTX_get(bn_ctx)
+ assert order != _ffi.NULL
+
+ res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
+ assert res == 1
+
+ order_bits = _lib.BN_num_bits(order)
+
+ if 8 * digest_len > order_bits:
+ digest_len = (order_bits + 7) // 8
+ digest = digest[:digest_len]
+
+ if 8 * digest_len > order_bits:
+ rshift = 8 - (order_bits & 0x7)
+ assert rshift > 0 and rshift < 8
+
+ mask = 0xFF >> rshift << rshift
+
+ # Set the bottom rshift bits to 0
+ digest = digest[:-1] + six.int2byte(six.byte2int(digest[-1]) & mask)
+
+ return digest
+
+
+@utils.register_interface(interfaces.AsymmetricSignatureContext)
+class _ECDSASignatureContext(object):
+ def __init__(self, backend, private_key, algorithm):
+ self._backend = backend
+ self._private_key = private_key
+ self._digest = hashes.Hash(algorithm, backend)
+
+ def update(self, data):
+ self._digest.update(data)
+
+ def finalize(self):
+ ec_key = self._private_key._ec_key
+
+ digest = self._digest.finalize()
+
+ digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
+
+ max_size = self._backend._lib.ECDSA_size(ec_key)
+ assert max_size > 0
+
+ sigbuf = self._backend._ffi.new("char[]", max_size)
+ siglen_ptr = self._backend._ffi.new("unsigned int[]", 1)
+ res = self._backend._lib.ECDSA_sign(
+ 0,
+ digest,
+ len(digest),
+ sigbuf,
+ siglen_ptr,
+ ec_key
+ )
+ assert res == 1
+ return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]]
+
+
+@utils.register_interface(interfaces.AsymmetricVerificationContext)
+class _ECDSAVerificationContext(object):
+ def __init__(self, backend, public_key, signature, algorithm):
+ self._backend = backend
+ self._public_key = public_key
+ self._signature = signature
+ self._digest = hashes.Hash(algorithm, backend)
+
+ def update(self, data):
+ self._digest.update(data)
+
+ def verify(self):
+ ec_key = self._public_key._ec_key
+
+ digest = self._digest.finalize()
+
+ digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
+
+ res = self._backend._lib.ECDSA_verify(
+ 0,
+ digest,
+ len(digest),
+ self._signature,
+ len(self._signature),
+ ec_key
+ )
+ if res != 1:
+ self._backend._consume_errors()
+ raise InvalidSignature
+ return True
+
+
+@utils.register_interface(interfaces.EllipticCurvePrivateKey)
+class _EllipticCurvePrivateKey(object):
+ def __init__(self, backend, ec_key_cdata, curve):
+ self._backend = backend
+ self._ec_key = ec_key_cdata
+ self._curve = curve
+
+ @property
+ def curve(self):
+ return self._curve
+
+ def signer(self, signature_algorithm):
+ if isinstance(signature_algorithm, ec.ECDSA):
+ return self._backend._create_ecdsa_signature_ctx(
+ self, signature_algorithm)
+ else:
+ raise UnsupportedAlgorithm(
+ "Unsupported elliptic curve signature algorithm.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
+ def public_key(self):
+ public_ec_key = self._backend._public_ec_key_from_private_ec_key(
+ self._ec_key
+ )
+
+ return _EllipticCurvePublicKey(
+ self._backend, public_ec_key, self._curve)
+
+
+@utils.register_interface(interfaces.EllipticCurvePublicKey)
+class _EllipticCurvePublicKey(object):
+ def __init__(self, backend, ec_key_cdata, curve):
+ self._backend = backend
+ self._ec_key = ec_key_cdata
+ self._curve = curve
+
+ @property
+ def curve(self):
+ return self._curve
+
+ def verifier(self, signature, signature_algorithm):
+ if isinstance(signature_algorithm, ec.ECDSA):
+ return self._backend._create_ecdsa_verification_ctx(
+ self, signature, signature_algorithm)
+ else:
+ raise UnsupportedAlgorithm(
+ "Unsupported elliptic curve signature algorithm.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
+
backend = Backend()
diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py
index 94b96d98..165bc7a1 100644
--- a/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/cryptography/hazmat/bindings/openssl/ssl.py
@@ -46,6 +46,7 @@ static const long Cryptography_HAS_SSL_SET_SSL_CTX;
static const long Cryptography_HAS_SSL_OP_NO_TICKET;
static const long Cryptography_HAS_NETBSD_D1_METH;
static const long Cryptography_HAS_NEXTPROTONEG;
+static const long Cryptography_HAS_ALPN;
static const long SSL_FILETYPE_PEM;
static const long SSL_FILETYPE_ASN1;
@@ -367,6 +368,21 @@ void SSL_get0_next_proto_negotiated(const SSL *,
int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *);
SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int);
+
+/* ALPN APIs were introduced in OpenSSL 1.0.2. To continue to support earlier
+ * versions some special handling of these is necessary.
+ */
+int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char*, unsigned);
+int SSL_set_alpn_protos(SSL *, const unsigned char*, unsigned);
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *,
+ int (*) (SSL *,
+ const unsigned char **,
+ unsigned char *,
+ const unsigned char *,
+ unsigned int,
+ void *),
+ void *);
+void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *);
"""
CUSTOMIZATIONS = """
@@ -515,6 +531,28 @@ void (*SSL_get0_next_proto_negotiated)(const SSL *,
#else
static const long Cryptography_HAS_NEXTPROTONEG = 1;
#endif
+
+// ALPN was added in OpenSSL 1.0.2.
+#if OPENSSL_VERSION_NUMBER < 0x10002001L
+int (*SSL_CTX_set_alpn_protos)(SSL_CTX *,
+ const unsigned char*,
+ unsigned) = NULL;
+int (*SSL_set_alpn_protos)(SSL *, const unsigned char*, unsigned) = NULL;
+void (*SSL_CTX_set_alpn_select_cb)(SSL_CTX *,
+ int (*) (SSL *,
+ const unsigned char **,
+ unsigned char *,
+ const unsigned char *,
+ unsigned int,
+ void *),
+ void *) = NULL;
+void (*SSL_get0_alpn_selected)(const SSL *,
+ const unsigned char **,
+ unsigned *) = NULL;
+static const long Cryptography_HAS_ALPN = 0;
+#else
+static const long Cryptography_HAS_ALPN = 1;
+#endif
"""
CONDITIONAL_NAMES = {
@@ -585,4 +623,11 @@ CONDITIONAL_NAMES = {
"SSL_OP_LEGACY_SERVER_CONNECT",
"SSL_get_secure_renegotiation_support",
],
+
+ "Cryptography_HAS_ALPN": [
+ "SSL_CTX_set_alpn_protos",
+ "SSL_set_alpn_protos",
+ "SSL_CTX_set_alpn_select_cb",
+ "SSL_get0_alpn_selected",
+ ]
}
diff --git a/cryptography/hazmat/primitives/asymmetric/ec.py b/cryptography/hazmat/primitives/asymmetric/ec.py
index 1e49ad7b..220a419c 100644
--- a/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -15,9 +15,189 @@ from __future__ import absolute_import, division, print_function
import six
+from cryptography import utils
from cryptography.hazmat.primitives import interfaces
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT571R1(object):
+ @property
+ def name(self):
+ return "sect571r1"
+
+ @property
+ def key_size(self):
+ return 571
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT409R1(object):
+ @property
+ def name(self):
+ return "sect409r1"
+
+ @property
+ def key_size(self):
+ return 409
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT283R1(object):
+ @property
+ def name(self):
+ return "sect283r1"
+
+ @property
+ def key_size(self):
+ return 283
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT233R1(object):
+ @property
+ def name(self):
+ return "sect233r1"
+
+ @property
+ def key_size(self):
+ return 233
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT163R2(object):
+ @property
+ def name(self):
+ return "sect163r2"
+
+ @property
+ def key_size(self):
+ return 163
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT571K1(object):
+ @property
+ def name(self):
+ return "sect571k1"
+
+ @property
+ def key_size(self):
+ return 571
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT409K1(object):
+ @property
+ def name(self):
+ return "sect409k1"
+
+ @property
+ def key_size(self):
+ return 409
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT283K1(object):
+ @property
+ def name(self):
+ return "sect283k1"
+
+ @property
+ def key_size(self):
+ return 283
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT233K1(object):
+ @property
+ def name(self):
+ return "sect233k1"
+
+ @property
+ def key_size(self):
+ return 233
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECT163K1(object):
+ @property
+ def name(self):
+ return "sect163k1"
+
+ @property
+ def key_size(self):
+ return 163
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECP521R1(object):
+ @property
+ def name(self):
+ return "secp521r1"
+
+ @property
+ def key_size(self):
+ return 521
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECP384R1(object):
+ @property
+ def name(self):
+ return "secp384r1"
+
+ @property
+ def key_size(self):
+ return 384
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECP256R1(object):
+ @property
+ def name(self):
+ return "secp256r1"
+
+ @property
+ def key_size(self):
+ return 256
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECP224R1(object):
+ @property
+ def name(self):
+ return "secp224r1"
+
+ @property
+ def key_size(self):
+ return 224
+
+
+@utils.register_interface(interfaces.EllipticCurve)
+class SECP192R1(object):
+ @property
+ def name(self):
+ return "secp192r1"
+
+ @property
+ def key_size(self):
+ return 192
+
+
+@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm)
+class ECDSA(object):
+ def __init__(self, algorithm):
+ self._algorithm = algorithm
+
+ @property
+ def algorithm(self):
+ return self._algorithm
+
+
+def generate_private_key(curve, backend):
+ return backend.generate_elliptic_curve_private_key(curve)
+
+
class EllipticCurvePublicNumbers(object):
def __init__(self, x, y, curve):
if (
@@ -33,6 +213,9 @@ class EllipticCurvePublicNumbers(object):
self._x = x
self._curve = curve
+ def public_key(self, backend):
+ return backend.elliptic_curve_public_key_from_numbers(self)
+
@property
def curve(self):
return self._curve
@@ -60,6 +243,9 @@ class EllipticCurvePrivateNumbers(object):
self._private_value = private_value
self._public_numbers = public_numbers
+ def private_key(self, backend):
+ return backend.elliptic_curve_private_key_from_numbers(self)
+
@property
def private_value(self):
return self._private_value
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index 0dd1d01a..d805bd1a 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -192,24 +192,6 @@ class RSAPrivateKey(object):
"""
@abc.abstractproperty
- def modulus(self):
- """
- The public modulus of the RSA key.
- """
-
- @abc.abstractproperty
- def public_exponent(self):
- """
- The public exponent of the RSA key.
- """
-
- @abc.abstractproperty
- def private_exponent(self):
- """
- The private exponent of the RSA key.
- """
-
- @abc.abstractproperty
def key_size(self):
"""
The bit length of the public modulus.
@@ -221,58 +203,6 @@ class RSAPrivateKey(object):
The RSAPublicKey associated with this private key.
"""
- @abc.abstractproperty
- def n(self):
- """
- The public modulus of the RSA key. Alias for modulus.
- """
-
- @abc.abstractproperty
- def p(self):
- """
- One of the two primes used to generate d.
- """
-
- @abc.abstractproperty
- def q(self):
- """
- One of the two primes used to generate d.
- """
-
- @abc.abstractproperty
- def d(self):
- """
- The private exponent. This can be calculated using p and q. Alias for
- private_exponent.
- """
-
- @abc.abstractproperty
- def dmp1(self):
- """
- A Chinese remainder theorem coefficient used to speed up RSA
- calculations. Calculated as: d mod (p-1)
- """
-
- @abc.abstractproperty
- def dmq1(self):
- """
- A Chinese remainder theorem coefficient used to speed up RSA
- calculations. Calculated as: d mod (q-1)
- """
-
- @abc.abstractproperty
- def iqmp(self):
- """
- A Chinese remainder theorem coefficient used to speed up RSA
- calculations. The modular inverse of q modulo p
- """
-
- @abc.abstractproperty
- def e(self):
- """
- The public exponent of the RSA key. Alias for public_exponent.
- """
-
@six.add_metaclass(abc.ABCMeta)
class RSAPublicKey(object):
@@ -283,35 +213,11 @@ class RSAPublicKey(object):
"""
@abc.abstractproperty
- def modulus(self):
- """
- The public modulus of the RSA key.
- """
-
- @abc.abstractproperty
- def public_exponent(self):
- """
- The public exponent of the RSA key.
- """
-
- @abc.abstractproperty
def key_size(self):
"""
The bit length of the public modulus.
"""
- @abc.abstractproperty
- def n(self):
- """
- The public modulus of the RSA key. Alias for modulus.
- """
-
- @abc.abstractproperty
- def e(self):
- """
- The public exponent of the RSA key. Alias for public_exponent.
- """
-
@six.add_metaclass(abc.ABCMeta)
class DSAParameters(object):
diff --git a/cryptography/hazmat/primitives/serialization.py b/cryptography/hazmat/primitives/serialization.py
index ed73c4c4..056d4a06 100644
--- a/cryptography/hazmat/primitives/serialization.py
+++ b/cryptography/hazmat/primitives/serialization.py
@@ -24,3 +24,11 @@ def load_pem_pkcs8_private_key(data, password, backend):
return backend.load_pkcs8_pem_private_key(
data, password
)
+
+
+def load_rsa_private_numbers(numbers, backend):
+ return backend.load_rsa_private_numbers(numbers)
+
+
+def load_rsa_public_numbers(numbers, backend):
+ return backend.load_rsa_public_numbers(numbers)