aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography/hazmat
diff options
context:
space:
mode:
Diffstat (limited to 'cryptography/hazmat')
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py67
1 files changed, 51 insertions, 16 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 1495e75c..d7c0f882 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function
import collections
import itertools
+import math
import six
@@ -695,11 +696,24 @@ class _HMACContext(object):
return self._backend._ffi.buffer(buf)[:outlen[0]]
+def _get_rsa_pss_salt_length(mgf, key_size, digest_size):
+ if mgf._salt_length is MGF1.MAX_LENGTH:
+ # bit length - 1 per RFC 3447
+ emlen = int(math.ceil((key_size - 1) / 8.0))
+ salt_length = emlen - digest_size - 2
+ assert salt_length >= 0
+ return salt_length
+ else:
+ return mgf._salt_length
+
+
@utils.register_interface(interfaces.AsymmetricSignatureContext)
class _RSASignatureContext(object):
def __init__(self, backend, private_key, padding, algorithm):
self._backend = backend
self._private_key = private_key
+ key_size_bytes = int(math.ceil(private_key.key_size / 8.0))
+
if not isinstance(padding, interfaces.AsymmetricPadding):
raise TypeError(
"Expected provider of interfaces.AsymmetricPadding")
@@ -716,6 +730,11 @@ class _RSASignatureContext(object):
"Only MGF1 is supported by this backend"
)
+ # Size of key in bytes - 2 is the maximum
+ # PSS signature length (salt length is checked later)
+ if key_size_bytes - algorithm.digest_size - 2 < 0:
+ raise ValueError("Digest too large for key size.")
+
if not self._backend.mgf1_hash_supported(padding._mgf._algorithm):
raise UnsupportedHash(
"When OpenSSL is older than 1.0.1 then only SHA1 is "
@@ -773,8 +792,15 @@ class _RSASignatureContext(object):
assert res > 0
if isinstance(self._padding, PSS):
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
- pkey_ctx, self._get_salt_length())
+ pkey_ctx,
+ _get_rsa_pss_salt_length(
+ self._padding._mgf,
+ self._private_key.key_size,
+ self._hash_ctx.algorithm.digest_size
+ )
+ )
assert res > 0
+
if self._backend._lib.Cryptography_HAS_MGF1_MD:
# MGF1 MD is configurable in OpenSSL 1.0.1+
mgf1_md = self._backend._lib.EVP_get_digestbyname(
@@ -834,7 +860,11 @@ class _RSASignatureContext(object):
padded,
data_to_sign,
evp_md,
- self._get_salt_length()
+ _get_rsa_pss_salt_length(
+ self._padding._mgf,
+ self._private_key.key_size,
+ len(data_to_sign)
+ )
)
if res != 1:
errors = self._backend._consume_errors()
@@ -854,12 +884,6 @@ class _RSASignatureContext(object):
assert sig_len != -1
return self._backend._ffi.buffer(sig_buf)[:sig_len]
- def _get_salt_length(self):
- if self._padding._mgf._salt_length is MGF1.MAX_LENGTH:
- return -2
- else:
- return self._padding._mgf._salt_length
-
@utils.register_interface(interfaces.AsymmetricVerificationContext)
class _RSAVerificationContext(object):
@@ -867,6 +891,8 @@ class _RSAVerificationContext(object):
self._backend = backend
self._public_key = public_key
self._signature = signature
+ key_size_bytes = int(math.ceil(public_key.key_size / 8.0))
+
if not isinstance(padding, interfaces.AsymmetricPadding):
raise TypeError(
"Expected provider of interfaces.AsymmetricPadding")
@@ -883,6 +909,11 @@ class _RSAVerificationContext(object):
"Only MGF1 is supported by this backend"
)
+ # Size of key in bytes - 2 is the maximum
+ # PSS signature length (salt length is checked later)
+ if key_size_bytes - algorithm.digest_size - 2 < 0:
+ raise ValueError("Digest too large for key size.")
+
if not self._backend.mgf1_hash_supported(padding._mgf._algorithm):
raise UnsupportedHash(
"When OpenSSL is older than 1.0.1 then only SHA1 is "
@@ -936,7 +967,13 @@ class _RSAVerificationContext(object):
assert res > 0
if isinstance(self._padding, PSS):
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
- pkey_ctx, self._get_salt_length())
+ pkey_ctx,
+ _get_rsa_pss_salt_length(
+ self._padding._mgf,
+ self._public_key.key_size,
+ self._hash_ctx.algorithm.digest_size
+ )
+ )
assert res > 0
if self._backend._lib.Cryptography_HAS_MGF1_MD:
# MGF1 MD is configurable in OpenSSL 1.0.1+
@@ -1011,18 +1048,16 @@ class _RSAVerificationContext(object):
data_to_verify,
evp_md,
buf,
- self._get_salt_length()
+ _get_rsa_pss_salt_length(
+ self._padding._mgf,
+ self._public_key.key_size,
+ len(data_to_verify)
+ )
)
if res != 1:
errors = self._backend._consume_errors()
assert errors
raise InvalidSignature
- def _get_salt_length(self):
- if self._padding._mgf._salt_length is MGF1.MAX_LENGTH:
- return -2
- else:
- return self._padding._mgf._salt_length
-
backend = Backend()