diff options
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 23 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/binding.py | 1 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/cms.py | 100 | ||||
-rw-r--r-- | cryptography/hazmat/bindings/openssl/err.py | 1 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_rsa.py | 29 | ||||
-rw-r--r-- | tests/test_utils.py | 11 | ||||
-rw-r--r-- | tests/utils.py | 10 |
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 |