diff options
Diffstat (limited to 'tests/hazmat/backends/test_openssl.py')
-rw-r--r-- | tests/hazmat/backends/test_openssl.py | 147 |
1 files changed, 117 insertions, 30 deletions
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index bba7d758..bfcdf14a 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -13,6 +13,8 @@ from __future__ import absolute_import, division, print_function +import pretend + import pytest from cryptography import utils @@ -22,7 +24,7 @@ from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import dsa, padding, rsa from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.algorithms import AES -from cryptography.hazmat.primitives.ciphers.modes import CBC +from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR from cryptography.hazmat.primitives.interfaces import BlockCipherAlgorithm from ...utils import raises_unsupported_algorithm @@ -41,11 +43,20 @@ class DummyCipher(object): name = "dummy-cipher" +@utils.register_interface(interfaces.AsymmetricPadding) +class DummyPadding(object): + name = "dummy-cipher" + + @utils.register_interface(interfaces.HashAlgorithm) class DummyHash(object): name = "dummy-hash" +class DummyMGF(object): + _salt_length = 0 + + class TestOpenSSL(object): def test_backend_exists(self): assert backend @@ -64,6 +75,11 @@ class TestOpenSSL(object): def test_supports_cipher(self): assert backend.cipher_supported(None, None) is False + def test_aes_ctr_always_available(self): + # AES CTR should always be available in both 0.9.8 and 1.0.0+ + assert backend.cipher_supported(AES(b"\x00" * 16), + CTR(b"\x00" * 16)) is True + def test_register_duplicate_cipher_adapter(self): with pytest.raises(ValueError): backend.register_cipher_adapter(AES, CBC, None) @@ -144,15 +160,6 @@ class TestOpenSSL(object): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): backend.derive_pbkdf2_hmac(hashes.SHA256(), 10, b"", 1000, b"") - # This test is not in the TestOpenSSLRandomEngine class because to check - # if it's really default we don't want to run the setup_method before it - def test_osrandom_engine_is_default(self): - e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name - res = backend._lib.ENGINE_free(e) - assert res == 1 - @pytest.mark.skipif( backend._lib.OPENSSL_VERSION_NUMBER >= 0x1000000f, reason="Requires an older OpenSSL. Must be < 1.0.0" @@ -174,6 +181,25 @@ class TestOpenSSL(object): parameters = dsa.DSAParameters.generate(3072, backend) assert utils.bit_length(parameters.p) == 3072 + def test_int_to_bn(self): + value = (2 ** 4242) - 4242 + bn = backend._int_to_bn(value) + assert bn != backend._ffi.NULL + bn = backend._ffi.gc(bn, backend._lib.BN_free) + + assert bn + assert backend._bn_to_int(bn) == value + + def test_int_to_bn_inplace(self): + value = (2 ** 4242) - 4242 + bn_ptr = backend._lib.BN_new() + assert bn_ptr != backend._ffi.NULL + bn_ptr = backend._ffi.gc(bn_ptr, backend._lib.BN_free) + bn = backend._int_to_bn(value, bn_ptr) + + assert bn == bn_ptr + assert backend._bn_to_int(bn_ptr) == value + class TestOpenSSLRandomEngine(object): def teardown_method(self, method): @@ -184,6 +210,15 @@ class TestOpenSSLRandomEngine(object): name = backend._lib.ENGINE_get_name(current_default) assert name == backend._lib.Cryptography_osrandom_engine_name + # This must be the first test in the class so that the teardown method + # has not (potentially) altered the default engine. + def test_osrandom_engine_is_default(self): + e = backend._lib.ENGINE_get_default_RAND() + name = backend._lib.ENGINE_get_name(e) + assert name == backend._lib.Cryptography_osrandom_engine_name + res = backend._lib.ENGINE_free(e) + assert res == 1 + def test_osrandom_sanity_check(self): # This test serves as a check against catastrophic failure. buf = backend._ffi.new("char[]", 500) @@ -234,27 +269,30 @@ class TestOpenSSLRandomEngine(object): e = backend._lib.ENGINE_get_default_RAND() assert e == backend._ffi.NULL - def test_int_to_bn(self): - value = (2 ** 4242) - 4242 - bn = backend._int_to_bn(value) - assert bn != backend._ffi.NULL - bn = backend._ffi.gc(bn, backend._lib.BN_free) - assert bn - assert backend._bn_to_int(bn) == value +class TestOpenSSLRSA(object): + def test_generate_rsa_parameters_supported(self): + assert backend.generate_rsa_parameters_supported(1, 1024) is False + assert backend.generate_rsa_parameters_supported(4, 1024) is False + assert backend.generate_rsa_parameters_supported(3, 1024) is True + assert backend.generate_rsa_parameters_supported(3, 511) is False - def test_int_to_bn_inplace(self): - value = (2 ** 4242) - 4242 - bn_ptr = backend._lib.BN_new() - assert bn_ptr != backend._ffi.NULL - bn_ptr = backend._ffi.gc(bn_ptr, backend._lib.BN_free) - bn = backend._int_to_bn(value, bn_ptr) + def test_generate_bad_public_exponent(self): + with pytest.raises(ValueError): + backend.generate_rsa_private_key(public_exponent=1, key_size=2048) - assert bn == bn_ptr - assert backend._bn_to_int(bn_ptr) == value + with pytest.raises(ValueError): + backend.generate_rsa_private_key(public_exponent=4, key_size=2048) + def test_cant_generate_insecure_tiny_key(self): + with pytest.raises(ValueError): + backend.generate_rsa_private_key(public_exponent=65537, + key_size=511) + + with pytest.raises(ValueError): + backend.generate_rsa_private_key(public_exponent=65537, + key_size=256) -class TestOpenSSLRSA(object): @pytest.mark.skipif( backend._lib.OPENSSL_VERSION_NUMBER >= 0x1000100f, reason="Requires an older OpenSSL. Must be < 1.0.1" @@ -270,8 +308,8 @@ class TestOpenSSLRSA(object): padding.PSS( mgf=padding.MGF1( algorithm=hashes.SHA256(), - salt_length=padding.MGF1.MAX_LENGTH - ) + ), + salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA1(), backend @@ -283,8 +321,8 @@ class TestOpenSSLRSA(object): padding.PSS( mgf=padding.MGF1( algorithm=hashes.SHA256(), - salt_length=padding.MGF1.MAX_LENGTH - ) + ), + salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA1(), backend @@ -293,6 +331,44 @@ class TestOpenSSLRSA(object): def test_unsupported_mgf1_hash_algorithm(self): assert backend.mgf1_hash_supported(DummyHash()) is False + def test_rsa_padding_unsupported_pss_mgf1_hash(self): + assert backend.rsa_padding_supported( + padding.PSS(mgf=padding.MGF1(DummyHash()), salt_length=0) + ) is False + + def test_rsa_padding_unsupported(self): + assert backend.rsa_padding_supported(DummyPadding()) is False + + def test_rsa_padding_supported_pkcs1v15(self): + assert backend.rsa_padding_supported(padding.PKCS1v15()) is True + + def test_rsa_padding_supported_pss(self): + assert backend.rsa_padding_supported( + padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0) + ) is True + + def test_rsa_padding_supported_oaep(self): + assert backend.rsa_padding_supported( + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA1()), + algorithm=hashes.SHA1(), + label=None + ), + ) is True + + def test_rsa_padding_unsupported_mgf(self): + assert backend.rsa_padding_supported( + padding.OAEP( + mgf=DummyMGF(), + algorithm=hashes.SHA1(), + label=None + ), + ) is False + + assert backend.rsa_padding_supported( + padding.PSS(mgf=DummyMGF(), salt_length=0) + ) is False + def test_unsupported_mgf1_hash_algorithm_decrypt(self): private_key = rsa.RSAPrivateKey.generate( public_exponent=65537, @@ -358,3 +434,14 @@ class TestOpenSSLCMAC(object): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER): backend.create_cmac_ctx(FakeAlgorithm()) + + +class TestOpenSSLSerialisationWithOpenSSL(object): + def test_password_too_long(self): + ffi_cb, cb = backend._pem_password_cb(b"aa") + assert cb(None, 1, False, None) == 0 + + def test_unsupported_evp_pkey_type(self): + key = pretend.stub(type="unsupported") + with raises_unsupported_algorithm(None): + backend._evp_pkey_to_private_key(key) |