diff options
Diffstat (limited to 'scripts/codegen')
-rwxr-xr-x | scripts/codegen/fuzzing_include_am.py | 160 | ||||
-rwxr-xr-x | scripts/codegen/gen_server_ciphers.py | 64 | ||||
-rwxr-xr-x[-rw-r--r--] | scripts/codegen/get_mozilla_ciphers.py | 15 | ||||
-rw-r--r-- | scripts/codegen/makedesc.py | 2 | ||||
-rwxr-xr-x | scripts/codegen/run_trunnel.sh | 10 |
5 files changed, 218 insertions, 33 deletions
diff --git a/scripts/codegen/fuzzing_include_am.py b/scripts/codegen/fuzzing_include_am.py new file mode 100755 index 0000000000..fda57d2ae8 --- /dev/null +++ b/scripts/codegen/fuzzing_include_am.py @@ -0,0 +1,160 @@ +#!/usr/bin/python + +FUZZERS = """ + consensus + descriptor + diff + diff-apply + extrainfo + hsdescv2 + hsdescv3 + http + http-connect + iptsv2 + microdesc + vrs +""" + + +PREAMBLE = r""" +FUZZING_CPPFLAGS = \ + $(src_test_AM_CPPFLAGS) $(TEST_CPPFLAGS) +FUZZING_CFLAGS = \ + $(AM_CFLAGS) $(TEST_CFLAGS) +FUZZING_LDFLAG = \ + @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ +FUZZING_LIBS = \ + src/or/libtor-testing.a \ + src/common/libor-crypto-testing.a \ + $(LIBKECCAK_TINY) \ + $(LIBDONNA) \ + src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ + src/common/libor-event-testing.a \ + src/trunnel/libor-trunnel-testing.a \ + $(rust_ldadd) \ + @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \ + @TOR_LIBEVENT_LIBS@ \ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ + @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ \ + @TOR_LZMA_LIBS@ \ + @TOR_ZSTD_LIBS@ + +oss-fuzz-prereqs: \ + src/or/libtor-testing.a \ + src/common/libor-crypto-testing.a \ + $(LIBKECCAK_TINY) \ + $(LIBDONNA) \ + src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ + src/common/libor-event-testing.a \ + src/trunnel/libor-trunnel-testing.a + +noinst_HEADERS += \ + src/test/fuzz/fuzzing.h + +LIBFUZZER = -lFuzzer +LIBFUZZER_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ +LIBFUZZER_CFLAGS = $(FUZZING_CFLAGS) +LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG) +LIBFUZZER_LIBS = $(FUZZING_LIBS) $(LIBFUZZER) -lstdc++ + +LIBOSS_FUZZ_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ +LIBOSS_FUZZ_CFLAGS = $(FUZZING_CFLAGS) +""" + +POSTAMBLE = r""" +noinst_PROGRAMS += $(FUZZERS) $(LIBFUZZER_FUZZERS) +noinst_LIBRARIES += $(OSS_FUZZ_FUZZERS) +oss-fuzz-fuzzers: oss-fuzz-prereqs $(OSS_FUZZ_FUZZERS) +fuzzers: $(FUZZERS) $(LIBFUZZER_FUZZERS) + +test-fuzz-corpora: $(FUZZERS) + $(top_srcdir)/src/test/fuzz_static_testcases.sh +""" + +########### No user serviceable parts will follow. + +PREAMBLE = PREAMBLE.strip() +POSTAMBLE = POSTAMBLE.strip() # If I use it, it's a word! +FUZZERS = FUZZERS.split() +FUZZERS.sort() + +WARNING = """ +# This file was generated by fuzzing_include_am.py; do not hand-edit unless +# you enjoy having your changes erased. +""".strip() + +print(WARNING) + +print(PREAMBLE) + +print("\n# ===== AFL fuzzers") + +def get_id_name(s): + return s.replace("-", "_") + +for fuzzer in FUZZERS: + idname = get_id_name(fuzzer) + print("""\ +src_test_fuzz_fuzz_{name}_SOURCES = \\ + src/test/fuzz/fuzzing_common.c \\ + src/test/fuzz/fuzz_{name}.c +src_test_fuzz_fuzz_{name}_CPPFLAGS = $(FUZZING_CPPFLAGS) +src_test_fuzz_fuzz_{name}_CFLAGS = $(FUZZING_CFLAGS) +src_test_fuzz_fuzz_{name}_LDFLAGS = $(FUZZING_LDFLAG) +src_test_fuzz_fuzz_{name}_LDADD = $(FUZZING_LIBS) +""".format(name=idname)) + +print("FUZZERS = \\") +print(" \\\n".join("\tsrc/test/fuzz/fuzz-{name}".format(name=fuzzer) + for fuzzer in FUZZERS)) + +print("\n# ===== libfuzzer") +print("\nif LIBFUZZER_ENABLED") + +for fuzzer in FUZZERS: + idname = get_id_name(fuzzer) + print("""\ +src_test_fuzz_lf_fuzz_{name}_SOURCES = \\ + $(src_test_fuzz_fuzz_{name}_SOURCES) +src_test_fuzz_lf_fuzz_{name}_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) +src_test_fuzz_lf_fuzz_{name}_CFLAGS = $(LIBFUZZER_CFLAGS) +src_test_fuzz_lf_fuzz_{name}_LDFLAGS = $(LIBFUZZER_LDFLAG) +src_test_fuzz_lf_fuzz_{name}_LDADD = $(LIBFUZZER_LIBS) +""".format(name=idname)) + +print("LIBFUZZER_FUZZERS = \\") +print(" \\\n".join("\tsrc/test/fuzz/lf-fuzz-{name}".format(name=fuzzer) + for fuzzer in FUZZERS)) + +print(""" +else +LIBFUZZER_FUZZERS = +endif""") + +print("\n# ===== oss-fuzz\n") +print("if OSS_FUZZ_ENABLED") + +for fuzzer in FUZZERS: + idname = get_id_name(fuzzer) + print("""\ +src_test_fuzz_liboss_fuzz_{name}_a_SOURCES = \\ + $(src_test_fuzz_fuzz_{name}_SOURCES) +src_test_fuzz_liboss_fuzz_{name}_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) +src_test_fuzz_liboss_fuzz_{name}_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) +""".format(name=idname)) + +print("OSS_FUZZ_FUZZERS = \\") +print(" \\\n".join("\tsrc/test/fuzz/liboss-fuzz-{name}.a".format(name=fuzzer) + for fuzzer in FUZZERS)) + +print(""" +else +OSS_FUZZ_FUZZERS = +endif""") + +print("") + +print(POSTAMBLE) diff --git a/scripts/codegen/gen_server_ciphers.py b/scripts/codegen/gen_server_ciphers.py index 0dca8a6734..7ea39c540d 100755 --- a/scripts/codegen/gen_server_ciphers.py +++ b/scripts/codegen/gen_server_ciphers.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2014-2015, The Tor Project, Inc +# Copyright 2014-2017, The Tor Project, Inc # See LICENSE for licensing information # This script parses openssl headers to find ciphersuite names, determines @@ -13,13 +13,13 @@ import sys EPHEMERAL_INDICATORS = [ "_EDH_", "_DHE_", "_ECDHE_" ] BAD_STUFF = [ "_DES_40_", "MD5", "_RC4_", "_DES_64_", - "_SEED_", "_CAMELLIA_", "_NULL" ] + "_SEED_", "_CAMELLIA_", "_NULL", + "_CCM_8", "_DES_", ] # these never get #ifdeffed. MANDATORY = [ "TLS1_TXT_DHE_RSA_WITH_AES_256_SHA", "TLS1_TXT_DHE_RSA_WITH_AES_128_SHA", - "SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA", ] def find_ciphers(filename): @@ -48,15 +48,23 @@ def usable_cipher(ciph): # All fields we sort on, in order of priority. FIELDS = [ 'cipher', 'fwsec', 'mode', 'digest', 'bitlength' ] # Map from sorted fields to recognized value in descending order of goodness -FIELD_VALS = { 'cipher' : [ 'AES', 'DES'], +FIELD_VALS = { 'cipher' : [ 'AES', 'CHACHA20' ], 'fwsec' : [ 'ECDHE', 'DHE' ], - 'mode' : [ 'GCM', 'CBC' ], - 'digest' : [ 'SHA384', 'SHA256', 'SHA' ], + 'mode' : [ 'POLY1305', 'GCM', 'CCM', 'CBC', ], + 'digest' : [ 'n/a', 'SHA384', 'SHA256', 'SHA', ], 'bitlength' : [ '256', '128', '192' ], } class Ciphersuite(object): def __init__(self, name, fwsec, cipher, bitlength, mode, digest): + if fwsec == 'EDH': + fwsec = 'DHE' + + if mode in [ '_CBC3', '_CBC', '' ]: + mode = 'CBC' + elif mode == '_GCM': + mode = 'GCM' + self.name = name self.fwsec = fwsec self.cipher = cipher @@ -74,42 +82,50 @@ class Ciphersuite(object): def parse_cipher(ciph): m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)(|_CBC|_CBC3|_GCM)_(SHA|SHA256|SHA384)$', ciph) - if not m: - print "/* Couldn't parse %s ! */"%ciph - return None + if m: + fwsec, cipher, bits, mode, digest = m.groups() + return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest) - fwsec, cipher, bits, mode, digest = m.groups() - if fwsec == 'EDH': - fwsec = 'DHE' + m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)_CCM', ciph) + if m: + fwsec, cipher, bits = m.groups() + return Ciphersuite(ciph, fwsec, cipher, bits, "CCM", "n/a") - if mode in [ '_CBC3', '_CBC', '' ]: - mode = 'CBC' - elif mode == '_GCM': - mode = 'GCM' + m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_CHACHA20_POLY1305', ciph) + if m: + fwsec, = m.groups() + return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a") + + print "/* Couldn't parse %s ! */"%ciph + return None - return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest) ALL_CIPHERS = [] for fname in sys.argv[1:]: - ALL_CIPHERS += (parse_cipher(c) - for c in find_ciphers(fname) - if usable_cipher(c) ) + for c in find_ciphers(fname): + if usable_cipher(c): + parsed = parse_cipher(c) + if parsed != None: + ALL_CIPHERS.append(parsed) ALL_CIPHERS.sort(key=Ciphersuite.sort_key) +indent = " "*7 + for c in ALL_CIPHERS: if c is ALL_CIPHERS[-1]: - colon = ';' + colon = '' else: colon = ' ":"' if c.name in MANDATORY: - print " /* Required */" - print ' %s%s'%(c.name,colon) + print "%s/* Required */"%indent + print '%s%s%s'%(indent,c.name,colon) else: print "#ifdef %s"%c.name - print ' %s%s'%(c.name,colon) + print '%s%s%s'%(indent,c.name,colon) print "#endif" +print '%s;'%indent diff --git a/scripts/codegen/get_mozilla_ciphers.py b/scripts/codegen/get_mozilla_ciphers.py index e673ec7dc6..946957ac77 100644..100755 --- a/scripts/codegen/get_mozilla_ciphers.py +++ b/scripts/codegen/get_mozilla_ciphers.py @@ -1,6 +1,6 @@ #!/usr/bin/python # coding=utf-8 -# Copyright 2011-2015, The Tor Project, Inc +# Copyright 2011-2017, The Tor Project, Inc # original version by Arturo Filastò # See LICENSE for licensing information @@ -127,9 +127,9 @@ for k, v in enabled_ciphers.items(): #oSSLinclude = ('/usr/include/openssl/ssl3.h', '/usr/include/openssl/ssl.h', # '/usr/include/openssl/ssl2.h', '/usr/include/openssl/ssl23.h', # '/usr/include/openssl/tls1.h') -oSSLinclude = ('ssl/ssl3.h', 'ssl/ssl.h', - 'ssl/ssl2.h', 'ssl/ssl23.h', - 'ssl/tls1.h') +oSSLinclude = ['ssl3.h', 'ssl.h' + 'ssl2.h', 'ssl23.h', + 'tls1.h'] ##### # This reads the hex code for the ciphers that are used by firefox. @@ -155,9 +155,12 @@ for x in used_ciphers: openssl_macro_by_hex = {} all_openssl_macros = {} for fl in oSSLinclude: - fp = open(ossl(fl), 'r') + fname = ossl("include/openssl/"+fl) + if not os.path.exists(fname): + continue + fp = open(fname, 'r') for line in fp.readlines(): - m = re.match('#define\s+(\S+)\s+(\S+)', line) + m = re.match('# *define\s+(\S+)\s+(\S+)', line) if m: value,key = m.groups() if key.startswith('0x') and "_CK_" in value: diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py index d4ba21efae..8d9d4edaaf 100644 --- a/scripts/codegen/makedesc.py +++ b/scripts/codegen/makedesc.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright 2014-2015, The Tor Project, Inc. +# Copyright 2014-2017, The Tor Project, Inc. # See LICENSE for license information # This is a kludgey python script that uses ctypes and openssl to sign diff --git a/scripts/codegen/run_trunnel.sh b/scripts/codegen/run_trunnel.sh index d2669931e9..428804342a 100755 --- a/scripts/codegen/run_trunnel.sh +++ b/scripts/codegen/run_trunnel.sh @@ -5,7 +5,13 @@ if test "x$TRUNNEL_PATH" != "x"; then export PYTHONPATH fi -python -m trunnel --require-version=1.4 ./src/trunnel/*.trunnel +OPTIONS="--require-version=1.5.1" -python -m trunnel --require-version=1.4 --write-c-files --target-dir=./src/ext/trunnel/ +# Get all .trunnel files recursively from that directory so we can support +# multiple sub-directories. +for file in `find ./src/trunnel/ -name '*.trunnel'`; do + python -m trunnel ${OPTIONS} $file +done + +python -m trunnel ${OPTIONS} --write-c-files --target-dir=./src/ext/trunnel/ |