aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2019-01-17 09:43:47 -0600
committerAlex Gaynor <alex.gaynor@gmail.com>2019-01-17 10:43:47 -0500
commit5b4c81e39622fc13895bf5df7d0f4f6bd067e7a0 (patch)
tree70ae40472a57cad2b25d9fba7044f3a719e7c05f
parent8d9ea52be9e7de1373641d3afaed9b292cb03f43 (diff)
downloadplatform_external_python_cryptography-5b4c81e39622fc13895bf5df7d0f4f6bd067e7a0.tar.gz
platform_external_python_cryptography-5b4c81e39622fc13895bf5df7d0f4f6bd067e7a0.tar.bz2
platform_external_python_cryptography-5b4c81e39622fc13895bf5df7d0f4f6bd067e7a0.zip
x448 and x25519 should enforce key lengths in backend (#4703)
* x448 and x25519 should enforce key lengths in from_private_bytes they should also check if the algorithm is supported like the public bytes class methods do * oops * move the checks
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py9
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/x25519.py9
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/x448.py6
-rw-r--r--tests/hazmat/primitives/test_x25519.py10
-rw-r--r--tests/hazmat/primitives/test_x448.py12
5 files changed, 42 insertions, 4 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index fd6057f8..8cec64d6 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -2081,6 +2081,9 @@ class Backend(object):
def x25519_load_public_bytes(self, data):
# When we drop support for CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 we can
# switch this to EVP_PKEY_new_raw_public_key
+ if len(data) != 32:
+ raise ValueError("An X25519 public key is 32 bytes long")
+
evp_pkey = self._create_evp_pkey_gc()
res = self._lib.EVP_PKEY_set_type(evp_pkey, self._lib.NID_X25519)
backend.openssl_assert(res == 1)
@@ -2106,6 +2109,9 @@ class Backend(object):
# Of course there's a bit more complexity. In reality OCTET STRING
# contains an OCTET STRING of length 32! So the last two bytes here
# are \x04\x20, which is an OCTET STRING of length 32.
+ if len(data) != 32:
+ raise ValueError("An X25519 private key is 32 bytes long")
+
pkcs8_prefix = b'0.\x02\x01\x000\x05\x06\x03+en\x04"\x04 '
bio = self._bytes_to_bio(pkcs8_prefix + data)
evp_pkey = backend._lib.d2i_PrivateKey_bio(bio.bio, self._ffi.NULL)
@@ -2148,6 +2154,9 @@ class Backend(object):
return _X448PublicKey(self, evp_pkey)
def x448_load_private_bytes(self, data):
+ if len(data) != 56:
+ raise ValueError("An X448 private key is 56 bytes long")
+
data_ptr = self._ffi.from_buffer(data)
evp_pkey = self._lib.EVP_PKEY_new_raw_private_key(
self._lib.NID_X448, self._ffi.NULL, data_ptr, len(data)
diff --git a/src/cryptography/hazmat/primitives/asymmetric/x25519.py b/src/cryptography/hazmat/primitives/asymmetric/x25519.py
index 94602261..4e8badf4 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/x25519.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/x25519.py
@@ -22,9 +22,6 @@ class X25519PublicKey(object):
_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM
)
- if len(data) != 32:
- raise ValueError("An X25519 public key is 32 bytes long")
-
return backend.x25519_load_public_bytes(data)
@abc.abstractmethod
@@ -49,6 +46,12 @@ class X25519PrivateKey(object):
@classmethod
def from_private_bytes(cls, data):
from cryptography.hazmat.backends.openssl.backend import backend
+ if not backend.x25519_supported():
+ raise UnsupportedAlgorithm(
+ "X25519 is not supported by this version of OpenSSL.",
+ _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM
+ )
+
return backend.x25519_load_private_bytes(data)
@abc.abstractmethod
diff --git a/src/cryptography/hazmat/primitives/asymmetric/x448.py b/src/cryptography/hazmat/primitives/asymmetric/x448.py
index 992ec0fd..475e678f 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/x448.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/x448.py
@@ -46,6 +46,12 @@ class X448PrivateKey(object):
@classmethod
def from_private_bytes(cls, data):
from cryptography.hazmat.backends.openssl.backend import backend
+ if not backend.x448_supported():
+ raise UnsupportedAlgorithm(
+ "X448 is not supported by this version of OpenSSL.",
+ _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM
+ )
+
return backend.x448_load_private_bytes(data)
@abc.abstractmethod
diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py
index 682c3125..f412f2e8 100644
--- a/tests/hazmat/primitives/test_x25519.py
+++ b/tests/hazmat/primitives/test_x25519.py
@@ -32,6 +32,9 @@ def test_x25519_unsupported(backend):
X25519PublicKey.from_public_bytes(b"0" * 32)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
+ X25519PrivateKey.from_private_bytes(b"0" * 32)
+
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
X25519PrivateKey.generate()
@@ -166,6 +169,13 @@ class TestX25519Exchange(object):
with pytest.raises(ValueError):
X25519PublicKey.from_public_bytes(b"a" * 33)
+ def test_invalid_length_from_private_bytes(self, backend):
+ with pytest.raises(ValueError):
+ X25519PrivateKey.from_private_bytes(b"a" * 31)
+
+ with pytest.raises(ValueError):
+ X25519PrivateKey.from_private_bytes(b"a" * 33)
+
def test_invalid_private_bytes(self, backend):
key = X25519PrivateKey.generate()
with pytest.raises(ValueError):
diff --git a/tests/hazmat/primitives/test_x448.py b/tests/hazmat/primitives/test_x448.py
index 51be0e10..817de76f 100644
--- a/tests/hazmat/primitives/test_x448.py
+++ b/tests/hazmat/primitives/test_x448.py
@@ -28,7 +28,10 @@ from ...utils import (
@pytest.mark.requires_backend_interface(interface=DHBackend)
def test_x448_unsupported(backend):
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
- X448PublicKey.from_public_bytes(b"0" * 32)
+ X448PublicKey.from_public_bytes(b"0" * 56)
+
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
+ X448PrivateKey.from_private_bytes(b"0" * 56)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM):
X448PrivateKey.generate()
@@ -176,6 +179,13 @@ class TestX448Exchange(object):
with pytest.raises(ValueError):
X448PublicKey.from_public_bytes(b"a" * 57)
+ def test_invalid_length_from_private_bytes(self, backend):
+ with pytest.raises(ValueError):
+ X448PrivateKey.from_private_bytes(b"a" * 55)
+
+ with pytest.raises(ValueError):
+ X448PrivateKey.from_private_bytes(b"a" * 57)
+
def test_invalid_private_bytes(self, backend):
key = X448PrivateKey.generate()
with pytest.raises(ValueError):