aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst4
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py6
-rw-r--r--src/cryptography/hazmat/backends/openssl/rsa.py18
-rw-r--r--tests/hazmat/backends/test_openssl.py12
-rw-r--r--tests/hazmat/primitives/test_rsa.py131
5 files changed, 153 insertions, 18 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 48dd0bf4..32560318 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -38,6 +38,10 @@ Changelog
* Support :class:`~cryptography.hazmat.primitives.hashes.BLAKE2b` and
:class:`~cryptography.hazmat.primitives.hashes.BLAKE2s` with
:class:`~cryptography.hazmat.primitives.hmac.HMAC`.
+* Added support for using labels with
+ :class:`~cryptography.hazmat.primitives.asymmetric.padding.OAEP` when using
+ OpenSSL 1.0.2 or greater.
+
.. _v2-0-3:
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 6c9ef84f..d9a5bdf2 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -547,7 +547,11 @@ class Backend(object):
elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1):
return (
self._oaep_hash_supported(padding._mgf._algorithm) and
- self._oaep_hash_supported(padding._algorithm)
+ self._oaep_hash_supported(padding._algorithm) and
+ (
+ (padding._label is None or len(padding._label) == 0) or
+ self._lib.Cryptography_HAS_RSA_OAEP_LABEL == 1
+ )
)
else:
return False
diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py
index 839ef147..05b4e9dc 100644
--- a/src/cryptography/hazmat/backends/openssl/rsa.py
+++ b/src/cryptography/hazmat/backends/openssl/rsa.py
@@ -57,9 +57,6 @@ def _enc_dec_rsa(backend, key, data, padding):
_Reasons.UNSUPPORTED_PADDING
)
- if padding._label is not None and padding._label != b"":
- raise ValueError("This backend does not support OAEP labels.")
-
else:
raise UnsupportedAlgorithm(
"{0} is not supported by this backend.".format(
@@ -106,6 +103,21 @@ def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md)
backend.openssl_assert(res > 0)
+ if (
+ isinstance(padding, OAEP) and
+ padding._label is not None and
+ len(padding._label) > 0
+ ):
+ # set0_rsa_oaep_label takes ownership of the char * so we need to
+ # copy it into some new memory
+ labelptr = backend._lib.OPENSSL_malloc(len(padding._label))
+ backend.openssl_assert(labelptr != backend._ffi.NULL)
+ backend._ffi.memmove(labelptr, padding._label, len(padding._label))
+ res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label(
+ pkey_ctx, labelptr, len(padding._label)
+ )
+ backend.openssl_assert(res == 1)
+
outlen = backend._ffi.new("size_t *", buf_size)
buf = backend._ffi.new("unsigned char[]", buf_size)
res = crypt(pkey_ctx, buf, outlen, data, len(data))
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 3a847cd2..40e92853 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -422,18 +422,6 @@ class TestOpenSSLRSA(object):
)
)
- def test_unsupported_oaep_label_decrypt(self):
- private_key = RSA_KEY_512.private_key(backend)
- with pytest.raises(ValueError):
- private_key.decrypt(
- b"0" * 64,
- padding.OAEP(
- mgf=padding.MGF1(algorithm=hashes.SHA1()),
- algorithm=hashes.SHA1(),
- label=b"label"
- )
- )
-
class TestOpenSSLCMAC(object):
def test_unsupported_cipher(self):
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index 627248fd..fc956ecb 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -38,8 +38,8 @@ from ...doubles import (
DummyAsymmetricPadding, DummyHashAlgorithm, DummyKeySerializationEncryption
)
from ...utils import (
- load_pkcs1_vectors, load_rsa_nist_vectors, load_vectors_from_file,
- raises_unsupported_algorithm
+ load_nist_vectors, load_pkcs1_vectors, load_rsa_nist_vectors,
+ load_vectors_from_file, raises_unsupported_algorithm
)
@@ -218,6 +218,133 @@ class TestRSA(object):
assert public_num.n == public_num2.n
assert public_num.e == public_num2.e
+ @pytest.mark.parametrize(
+ "vector",
+ load_vectors_from_file(
+ os.path.join("asymmetric", "RSA", "oaep-label.txt"),
+ load_nist_vectors)
+ )
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=b"label"
+ )
+ ),
+ skip_message="Does not support RSA OAEP labels"
+ )
+ def test_oaep_label_decrypt(self, vector, backend):
+ private_key = serialization.load_der_private_key(
+ binascii.unhexlify(vector["key"]), None, backend
+ )
+ assert vector["oaepdigest"] == b"SHA512"
+ decrypted = private_key.decrypt(
+ binascii.unhexlify(vector["input"]),
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA512()),
+ algorithm=hashes.SHA512(),
+ label=binascii.unhexlify(vector["oaeplabel"])
+ )
+ )
+ assert vector["output"][1:-1] == decrypted
+
+ @pytest.mark.parametrize(
+ ("msg", "label"),
+ [
+ (b"amazing encrypted msg", b"some label"),
+ (b"amazing encrypted msg", b""),
+ ]
+ )
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=b"label"
+ )
+ ),
+ skip_message="Does not support RSA OAEP labels"
+ )
+ def test_oaep_label_roundtrip(self, msg, label, backend):
+ private_key = RSA_KEY_2048.private_key(backend)
+ ct = private_key.public_key().encrypt(
+ msg,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=label
+ )
+ )
+ pt = private_key.decrypt(
+ ct,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=label
+ )
+ )
+ assert pt == msg
+
+ @pytest.mark.parametrize(
+ ("enclabel", "declabel"),
+ [
+ (b"label1", b"label2"),
+ (b"label3", b""),
+ (b"", b"label4"),
+ ]
+ )
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=b"label"
+ )
+ ),
+ skip_message="Does not support RSA OAEP labels"
+ )
+ def test_oaep_wrong_label(self, enclabel, declabel, backend):
+ private_key = RSA_KEY_2048.private_key(backend)
+ msg = b"test"
+ ct = private_key.public_key().encrypt(
+ msg, padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=enclabel
+ )
+ )
+ with pytest.raises(ValueError):
+ private_key.decrypt(
+ ct, padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=declabel
+ )
+ )
+
+ @pytest.mark.supported(
+ only_if=lambda backend: not backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=b"label"
+ )
+ ),
+ skip_message="Requires backend without RSA OAEP label support"
+ )
+ def test_unsupported_oaep_label_decrypt(self, backend):
+ private_key = RSA_KEY_512.private_key(backend)
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):
+ private_key.decrypt(
+ b"0" * 64,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ algorithm=hashes.SHA1(),
+ label=b"label"
+ )
+ )
+
def test_rsa_generate_invalid_backend():
pretend_backend = object()