1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7import binascii 8 9import pytest 10 11from cryptography.exceptions import InvalidSignature 12from cryptography.hazmat.backends.interfaces import RSABackend 13from cryptography.hazmat.primitives import hashes, serialization 14from cryptography.hazmat.primitives.asymmetric import padding 15 16 17_DIGESTS = { 18 "SHA-1": hashes.SHA1(), 19 "SHA-224": hashes.SHA224(), 20 "SHA-256": hashes.SHA256(), 21 "SHA-384": hashes.SHA384(), 22 "SHA-512": hashes.SHA512(), 23} 24 25 26def should_verify(backend, wycheproof): 27 if wycheproof.valid: 28 return True 29 30 if wycheproof.acceptable: 31 if ( 32 backend._lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER and 33 wycheproof.has_flag("MissingNull") 34 ): 35 return False 36 return True 37 38 return False 39 40 41@pytest.mark.requires_backend_interface(interface=RSABackend) 42@pytest.mark.supported( 43 only_if=lambda backend: ( 44 # TODO: this also skips on LibreSSL, which is ok for now, since these 45 # don't pass on Libre, but we'll need to fix this when LibreSSL 2.8 is 46 # released. 47 not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 48 ), 49 skip_message=( 50 "Many of these tests fail on OpenSSL < 1.0.2 and since upstream isn't" 51 " maintaining it, they'll never be fixed." 52 ), 53) 54@pytest.mark.wycheproof_tests( 55 "rsa_signature_test.json", 56 "rsa_signature_2048_sha224_test.json", 57 "rsa_signature_2048_sha256_test.json", 58 "rsa_signature_2048_sha512_test.json", 59 "rsa_signature_3072_sha256_test.json", 60 "rsa_signature_3072_sha384_test.json", 61 "rsa_signature_3072_sha512_test.json", 62 "rsa_signature_4096_sha384_test.json", 63 "rsa_signature_4096_sha512_test.json", 64) 65def test_rsa_pkcs1v15_signature(backend, wycheproof): 66 key = serialization.load_der_public_key( 67 binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend 68 ) 69 digest = _DIGESTS[wycheproof.testgroup["sha"]] 70 71 if should_verify(backend, wycheproof): 72 key.verify( 73 binascii.unhexlify(wycheproof.testcase["sig"]), 74 binascii.unhexlify(wycheproof.testcase["msg"]), 75 padding.PKCS1v15(), 76 digest, 77 ) 78 else: 79 with pytest.raises(InvalidSignature): 80 key.verify( 81 binascii.unhexlify(wycheproof.testcase["sig"]), 82 binascii.unhexlify(wycheproof.testcase["msg"]), 83 padding.PKCS1v15(), 84 digest, 85 ) 86 87 88@pytest.mark.requires_backend_interface(interface=RSABackend) 89@pytest.mark.wycheproof_tests( 90 "rsa_pss_2048_sha1_mgf1_20_test.json", 91 "rsa_pss_2048_sha256_mgf1_0_test.json", 92 "rsa_pss_2048_sha256_mgf1_32_test.json", 93 "rsa_pss_3072_sha256_mgf1_32_test.json", 94 "rsa_pss_4096_sha256_mgf1_32_test.json", 95 "rsa_pss_4096_sha512_mgf1_32_test.json", 96 "rsa_pss_misc_test.json", 97) 98def test_rsa_pss_signature(backend, wycheproof): 99 key = serialization.load_der_public_key( 100 binascii.unhexlify(wycheproof.testgroup["keyDer"]), backend 101 ) 102 digest = _DIGESTS[wycheproof.testgroup["sha"]] 103 mgf_digest = _DIGESTS[wycheproof.testgroup["mgfSha"]] 104 105 if wycheproof.valid or wycheproof.acceptable: 106 key.verify( 107 binascii.unhexlify(wycheproof.testcase["sig"]), 108 binascii.unhexlify(wycheproof.testcase["msg"]), 109 padding.PSS( 110 mgf=padding.MGF1(mgf_digest), 111 salt_length=wycheproof.testgroup["sLen"] 112 ), 113 digest 114 ) 115 else: 116 with pytest.raises(InvalidSignature): 117 key.verify( 118 binascii.unhexlify(wycheproof.testcase["sig"]), 119 binascii.unhexlify(wycheproof.testcase["msg"]), 120 padding.PSS( 121 mgf=padding.MGF1(mgf_digest), 122 salt_length=wycheproof.testgroup["sLen"] 123 ), 124 digest 125 ) 126