aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py23
-rw-r--r--cryptography/hazmat/bindings/openssl/binding.py1
-rw-r--r--cryptography/hazmat/bindings/openssl/cms.py100
-rw-r--r--cryptography/hazmat/bindings/openssl/err.py1
-rw-r--r--tests/hazmat/primitives/test_rsa.py29
-rw-r--r--tests/test_utils.py11
-rw-r--r--tests/utils.py10
7 files changed, 163 insertions, 12 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 6bf3787a..86fa704b 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -901,10 +901,16 @@ class _RSASignatureContext(object):
if res != 1:
errors = self._backend._consume_errors()
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
- assert (errors[0].reason ==
- self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
- raise ValueError("Salt length too long for key size. Try using "
- "MAX_LENGTH instead.")
+ reason = None
+ if (errors[0].reason ==
+ self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE):
+ reason = ("Salt length too long for key size. Try using "
+ "MAX_LENGTH instead.")
+ elif (errors[0].reason ==
+ self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY):
+ reason = "Digest too large for key size. Use a larger key."
+ assert reason is not None
+ raise ValueError(reason)
return self._backend._ffi.buffer(buf)[:]
@@ -919,7 +925,14 @@ class _RSASignatureContext(object):
)
self._hash_ctx.finalize()
self._hash_ctx = None
- assert res == 1
+ if res == 0:
+ errors = self._backend._consume_errors()
+ assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
+ assert (errors[0].reason ==
+ self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY)
+ raise ValueError("Digest too large for key size. Use a larger "
+ "key.")
+
return self._backend._ffi.buffer(sig_buf)[:sig_len[0]]
def _finalize_pss(self, evp_pkey, pkey_size, evp_md):
diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
index acf9d42c..cc40a108 100644
--- a/cryptography/hazmat/bindings/openssl/binding.py
+++ b/cryptography/hazmat/bindings/openssl/binding.py
@@ -49,6 +49,7 @@ class Binding(object):
"bignum",
"bio",
"cmac",
+ "cms",
"conf",
"crypto",
"dh",
diff --git a/cryptography/hazmat/bindings/openssl/cms.py b/cryptography/hazmat/bindings/openssl/cms.py
new file mode 100644
index 00000000..a3760f2c
--- /dev/null
+++ b/cryptography/hazmat/bindings/openssl/cms.py
@@ -0,0 +1,100 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+INCLUDES = """
+#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
+// The next define should really be in the OpenSSL header, but it is missing.
+// Failing to include this on Windows causes compilation failures.
+#if defined(OPENSSL_SYS_WINDOWS)
+#include <windows.h>
+#endif
+#include <openssl/cms.h>
+#endif
+"""
+
+TYPES = """
+static const long Cryptography_HAS_CMS;
+
+typedef ... CMS_ContentInfo;
+typedef ... CMS_SignerInfo;
+typedef ... CMS_CertificateChoices;
+typedef ... CMS_RevocationInfoChoice;
+typedef ... CMS_RecipientInfo;
+typedef ... CMS_ReceiptRequest;
+typedef ... CMS_Receipt;
+"""
+
+FUNCTIONS = """
+"""
+
+MACROS = """
+BIO *BIO_new_CMS(BIO *, CMS_ContentInfo *);
+int i2d_CMS_bio_stream(BIO *, CMS_ContentInfo *, BIO *, int);
+int PEM_write_bio_CMS_stream(BIO *, CMS_ContentInfo *, BIO *, int);
+int CMS_final(CMS_ContentInfo *, BIO *, BIO *, unsigned int);
+CMS_ContentInfo *CMS_sign(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
+ BIO *, unsigned int);
+int CMS_verify(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *, X509_STORE *,
+ BIO *, BIO *, unsigned int);
+CMS_ContentInfo *CMS_encrypt(Cryptography_STACK_OF_X509 *, BIO *,
+ const EVP_CIPHER *, unsigned int);
+int CMS_decrypt(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
+ unsigned int);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *, X509 *, EVP_PKEY *,
+ const EVP_MD *, unsigned int);
+"""
+
+CUSTOMIZATIONS = """
+#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
+static const long Cryptography_HAS_CMS = 1;
+#else
+static const long Cryptography_HAS_CMS = 0;
+typedef void CMS_ContentInfo;
+typedef void CMS_SignerInfo;
+typedef void CMS_CertificateChoices;
+typedef void CMS_RevocationInfoChoice;
+typedef void CMS_RecipientInfo;
+typedef void CMS_ReceiptRequest;
+typedef void CMS_Receipt;
+BIO *(*BIO_new_CMS)(BIO *, CMS_ContentInfo *) = NULL;
+int (*i2d_CMS_bio_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
+int (*PEM_write_bio_CMS_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
+int (*CMS_final)(CMS_ContentInfo *, BIO *, BIO *, unsigned int) = NULL;
+CMS_ContentInfo *(*CMS_sign)(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
+ BIO *, unsigned int) = NULL;
+int (*CMS_verify)(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *,
+ X509_STORE *, BIO *, BIO *, unsigned int) = NULL;
+CMS_ContentInfo *(*CMS_encrypt)(Cryptography_STACK_OF_X509 *, BIO *,
+ const EVP_CIPHER *, unsigned int) = NULL;
+int (*CMS_decrypt)(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
+ unsigned int) = NULL;
+CMS_SignerInfo *(*CMS_add1_signer)(CMS_ContentInfo *, X509 *, EVP_PKEY *,
+ const EVP_MD *, unsigned int) = NULL;
+#endif
+"""
+
+CONDITIONAL_NAMES = {
+ "Cryptography_HAS_CMS": [
+ "BIO_new_CMS",
+ "i2d_CMS_bio_stream",
+ "PEM_write_bio_CMS_stream",
+ "CMS_final",
+ "CMS_sign",
+ "CMS_verify",
+ "CMS_encrypt",
+ "CMS_decrypt",
+ "CMS_add1_signer",
+ ]
+}
diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py
index 551d8217..f51393aa 100644
--- a/cryptography/hazmat/bindings/openssl/err.py
+++ b/cryptography/hazmat/bindings/openssl/err.py
@@ -215,6 +215,7 @@ static const int PEM_R_UNSUPPORTED_CIPHER;
static const int PEM_R_UNSUPPORTED_ENCRYPTION;
static const int RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
+static const int RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY;
"""
FUNCTIONS = """
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index 236a3bb1..1cbd1636 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -655,6 +655,35 @@ class TestRSASignature(object):
private_key.signer(padding.PSS(mgf=DummyMGF()), hashes.SHA1(),
backend)
+ def test_pkcs1_digest_too_large_for_key_size(self, backend):
+ private_key = rsa.RSAPrivateKey.generate(
+ public_exponent=65537,
+ key_size=599,
+ backend=backend
+ )
+ signer = private_key.signer(
+ padding.PKCS1v15(),
+ hashes.SHA512(),
+ backend
+ )
+ signer.update(b"failure coming")
+ with pytest.raises(ValueError):
+ signer.finalize()
+
+ def test_pkcs1_minimum_key_size(self, backend):
+ private_key = rsa.RSAPrivateKey.generate(
+ public_exponent=65537,
+ key_size=745,
+ backend=backend
+ )
+ signer = private_key.signer(
+ padding.PKCS1v15(),
+ hashes.SHA512(),
+ backend
+ )
+ signer.update(b"no failure")
+ signer.finalize()
+
@pytest.mark.rsa
class TestRSAVerification(object):
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 1f8e86fd..c91efa7f 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -2005,6 +2005,7 @@ eed0785387508877114359cee4a071cf
k = cb0abc7043a10783684556fb12c4154d57bc31a289685f25
R = 6994d962bdd0d793ffddf855ec5bf2f91a9698b46258a63e
S = 02ba6465a234903744ab02bc8521405b73cf5fc00e1a9f41
+ Result = F (3 - S changed)
Msg = 0dcb3e96d77ee64e9d0a350d31563d525755fc675f0c833504e83fc69c030181b42f\
e80c378e86274a93922c570d54a7a358c05755ec3ae91928e02236e81b43e596e4ccbf6a910488\
@@ -2035,6 +2036,7 @@ d3544bc3a666e0014e50030134fe5466a9e4d3911ed580e28851f3747c0010888e819d3d1f
a455579f1ed0517c31822340e4dd3c1f967e1b4b9d071a1072afc1a199f8c548cd449a634
S = 22f97bb48641235826cf4e597fa8de849402d6bd6114ad2d7fbcf53a08247e5ee921f1\
bd5994dffee36eedff5592bb93b8bb148214da3b7baebffbd96b4f86c55b3f6bbac142442
+ Result = P (0 )
Msg = b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c5\
0ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5\
@@ -2069,7 +2071,8 @@ bdcf3035f6829ede041b745955d219dc5d30ddd8b37f6ba0f6d2857504cdc68a1ed812a10
"x": int("7008ea40b08dbe76432096e80a2494c94982d2d5bcf98e6", 16),
"y": int("76fab681d00b414ea636ba215de26d98c41bd7f2e4d65477", 16),
"r": int("6994d962bdd0d793ffddf855ec5bf2f91a9698b46258a63e", 16),
- "s": int("02ba6465a234903744ab02bc8521405b73cf5fc00e1a9f41", 16)
+ "s": int("02ba6465a234903744ab02bc8521405b73cf5fc00e1a9f41", 16),
+ "fail": True
},
{
"curve": "secp192r1",
@@ -2085,7 +2088,7 @@ bdcf3035f6829ede041b745955d219dc5d30ddd8b37f6ba0f6d2857504cdc68a1ed812a10
"x": int("ea3c1fa1f124f26530cbfddeb831eecc67df31e08889d1d", 16),
"y": int("7215a0cce0501b47903bd8fe1179c2dfe07bd076f89f5225", 16),
"r": int("a3ba51c39c43991d87dff0f34d0bec7c883299e04f60f95e", 16),
- "s": int("8a7f9c59c6d65ad390e4c19636ba92b53be5d0f848b4e1f7", 16)
+ "s": int("8a7f9c59c6d65ad390e4c19636ba92b53be5d0f848b4e1f7", 16),
},
{
"curve": "sect571r1",
@@ -2111,7 +2114,8 @@ bdcf3035f6829ede041b745955d219dc5d30ddd8b37f6ba0f6d2857504cdc68a1ed812a10
"071a1072afc1a199f8c548cd449a634", 16),
"s": int("22f97bb48641235826cf4e597fa8de849402d6bd6114ad2d7fbcf53a"
"08247e5ee921f1bd5994dffee36eedff5592bb93b8bb148214da3b7b"
- "aebffbd96b4f86c55b3f6bbac142442", 16)
+ "aebffbd96b4f86c55b3f6bbac142442", 16),
+ "fail": False
},
{
"curve": "sect571r1",
@@ -2140,5 +2144,4 @@ bdcf3035f6829ede041b745955d219dc5d30ddd8b37f6ba0f6d2857504cdc68a1ed812a10
"47a4da7e245ef803e0662e4d2ad721c", 16)
}
]
-
assert expected == load_fips_ecdsa_signing_vectors(vector_data)
diff --git a/tests/utils.py b/tests/utils.py
index 77999955..c38ba7ff 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -431,17 +431,20 @@ def load_fips_dsa_key_pair_vectors(vector_data):
return vectors
+# http://tools.ietf.org/html/rfc4492#appendix-A
_ECDSA_CURVE_NAMES = {
"P-192": "secp192r1",
"P-224": "secp224r1",
- "P-256": "secp192r1",
+ "P-256": "secp256r1",
"P-384": "secp384r1",
"P-521": "secp521r1",
+
"K-163": "sect163k1",
"K-233": "sect233k1",
- "K-283": "sect233k1",
+ "K-283": "sect283k1",
"K-409": "sect409k1",
"K-571": "sect571k1",
+
"B-163": "sect163r2",
"B-233": "sect233r1",
"B-283": "sect283r1",
@@ -531,8 +534,9 @@ def load_fips_ecdsa_signing_vectors(vector_data):
data["s"] = int(line.split("=")[1], 16)
elif line.startswith("d = "):
data["d"] = int(line.split("=")[1], 16)
+ elif line.startswith("Result = "):
+ data["fail"] = line.split("=")[1].strip()[0] == "F"
if data is not None:
vectors.append(data)
-
return vectors