diff options
-rw-r--r-- | src/lib/math/numbertheory/pow_mod.cpp | 4 | ||||
-rw-r--r-- | src/lib/tls/msg_client_kex.cpp | 4 | ||||
-rw-r--r-- | src/lib/tls/tls_callbacks.cpp | 2 | ||||
-rw-r--r-- | src/lib/tls/tls_handshake_io.cpp | 3 | ||||
-rwxr-xr-x | src/scripts/run_tls_fuzzer.py | 97 | ||||
-rw-r--r-- | src/tests/data/tls-policy/compat.txt | 7 |
6 files changed, 111 insertions, 6 deletions
diff --git a/src/lib/math/numbertheory/pow_mod.cpp b/src/lib/math/numbertheory/pow_mod.cpp index 00917a5f9..02434fe68 100644 --- a/src/lib/math/numbertheory/pow_mod.cpp +++ b/src/lib/math/numbertheory/pow_mod.cpp @@ -65,8 +65,8 @@ void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints, bool disable_mon */ void Power_Mod::set_base(const BigInt& b) const { - if(b.is_zero() || b.is_negative()) - throw Invalid_Argument("Power_Mod::set_base: arg must be > 0"); + if(b.is_negative()) + throw Invalid_Argument("Power_Mod::set_base: arg must be non-negative"); if(!m_core) throw Internal_Error("Power_Mod::set_base: m_core was NULL"); diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index f55568c8e..9cb92447b 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -377,6 +377,10 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, else m_pre_master = shared_secret; } + catch(Invalid_Argument& e) + { + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, e.what()); + } catch(std::exception &) { /* diff --git a/src/lib/tls/tls_callbacks.cpp b/src/lib/tls/tls_callbacks.cpp index 28884c1e2..bcd3aa39b 100644 --- a/src/lib/tls/tls_callbacks.cpp +++ b/src/lib/tls/tls_callbacks.cpp @@ -119,7 +119,7 @@ std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_dh_a * advantage to bogus keys anyway. */ if(Y <= 1 || Y >= p - 1) - throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, + throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Server sent bad DH key for DHE exchange"); DL_Group group(p, g); diff --git a/src/lib/tls/tls_handshake_io.cpp b/src/lib/tls/tls_handshake_io.cpp index acc30b102..7ac868612 100644 --- a/src/lib/tls/tls_handshake_io.cpp +++ b/src/lib/tls/tls_handshake_io.cpp @@ -78,6 +78,9 @@ Stream_Handshake_IO::get_next_record(bool) { Handshake_Type type = static_cast<Handshake_Type>(m_queue[0]); + if(type == HANDSHAKE_NONE) + throw Decoding_Error("Invalid handshake message type"); + std::vector<uint8_t> contents(m_queue.begin() + 4, m_queue.begin() + length); diff --git a/src/scripts/run_tls_fuzzer.py b/src/scripts/run_tls_fuzzer.py new file mode 100755 index 000000000..4754480a6 --- /dev/null +++ b/src/scripts/run_tls_fuzzer.py @@ -0,0 +1,97 @@ +#!/usr/bin/python + +import argparse +import subprocess +import logging +import sys +import os +import time + +def script_is_disabled(script_name): + if script_name.find('tls13') >= 0: + return True + if script_name.find('sslv2') >= 0: + return True + + disabled = { + 'test-SSLv3-padding.py', + 'test-serverhello-random.py', # assumes support for SSLv2 hello + 'test-x25519.py', # assumes support for X448 (!) + } + + if script_name in disabled: + return True + + slow = { + 'test-bleichenbacher-workaround.py', + 'test-client-compatibility.py', + 'test-dhe-key-share-random.py', + 'test-dhe-no-shared-secret-padding.py', + 'test-ecdhe-padded-shared-secret.py', + 'test-ecdhe-rsa-key-share-random.py', + 'test-fuzzed-plaintext.py', + 'test-invalid-client-hello-w-record-overflow.py', + 'test-invalid-client-hello.py', + 'test-large-hello.py', + } + if script_name in slow: + return True + + return False + +def main(args = None): + if args is None: + args = sys.argv[1:] + + parser = argparse.ArgumentParser() + + # TODO generate key and spawn the server on some random port in tmp dir + # TODO support running tls_server binary under valgrind + + parser.add_argument('--verbose', action='store_true', default=False) + parser.add_argument('tls-fuzzer-dir') + + args = vars(parser.parse_args(args)) + + tlsfuzzer_dir = args['tls-fuzzer-dir'] + + if not os.access(tlsfuzzer_dir, os.X_OK): + raise Exception("Unable to read TLS fuzzer dir") + + tls_scripts_dir = os.path.join(tlsfuzzer_dir, 'scripts') + if not os.access(tlsfuzzer_dir, os.X_OK): + raise Exception("Unable to read TLS fuzzer scripts dir") + + scripts = sorted(os.listdir(tls_scripts_dir)) + + procs = {} + + for script in scripts: + if script_is_disabled(script): + logging.debug('Skipping %s' % (script)) + continue + + procs[script] = subprocess.Popen([sys.executable, os.path.join(tls_scripts_dir, script)], + cwd=tlsfuzzer_dir, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + results = {} + + while len(results) != len(procs): + time.sleep(.5) + for (script, proc) in procs.items(): + + if script in results: + continue + + if proc.poll() != None: + rv = proc.returncode + results[script] = rv + if rv == 0: + print("PASS %s" % (script)) + else: + print("FAIL %s" % (script)) + sys.stdout.flush() + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/tests/data/tls-policy/compat.txt b/src/tests/data/tls-policy/compat.txt index 2fb831f44..4de9a60a6 100644 --- a/src/tests/data/tls-policy/compat.txt +++ b/src/tests/data/tls-policy/compat.txt @@ -2,7 +2,8 @@ # for interop testing and fuzz testing # It is based on the default policy, but allows 3DES, SHA-1 signatures, -# static RSA, and reduces the ephemeral key sizes +# static RSA, reduces the ephemeral key sizes, and removes some +# non-standard ciphersuites allow_tls10 = true allow_tls11 = true @@ -13,8 +14,8 @@ ciphers = ChaCha20Poly1305 AES-256/GCM AES-128/GCM AES-256 AES-128 3DES macs = AEAD SHA-256 SHA-384 SHA-1 signature_hashes = SHA-512 SHA-384 SHA-256 SHA-1 signature_methods = ECDSA RSA IMPLICIT -key_exchange_methods = CECPQ1 ECDH DH RSA -key_exchange_groups = x25519 secp256r1 secp521r1 secp384r1 brainpool256r1 brainpool384r1 brainpool512r1 ffdhe/ietf/2048 +key_exchange_methods = ECDH DH RSA +key_exchange_groups = x25519 secp256r1 secp521r1 secp384r1 brainpool256r1 brainpool384r1 brainpool512r1 ffdhe/ietf/2048 ffdhe/ietf/3072 ffdhe/ietf/4096 ffdhe/ietf/6144 ffdhe/ietf/8192 allow_insecure_renegotiation = false include_time_in_hello_random = true allow_client_initiated_renegotiation = true |