def main(): host = "localhost" port = 4433 run_exclude = set() renego = 1 status = True argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:r:", ["help", "no-status"]) for opt, arg in opts: if opt == '-h': host = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '-r': renego = int(arg) elif opt == '--no-status': status = False elif opt == '--help': help_msg() sys.exit(0) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} # check if status_request is recognized and supported conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ocsp = StatusRequestExtension().create() ext = {ExtensionType.status_request: ocsp} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\n\n"))) node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["sanity"] = conversation # check if status_request is recognized and supported conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ocsp = StatusRequestExtension().create() ext = {ExtensionType.status_request: ocsp} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA] ext = { ExtensionType.status_request: ocsp, ExtensionType.renegotiation_info: None } # renegotiate node = node.add_child(ResetHandshakeHashes()) node = node.add_child( ClientHelloGenerator(ciphers, extensions=ext, session_id=bytearray())) node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) #node = node.add_child(ApplicationDataGenerator( # bytearray(b"GET / HTTP/1.0\n\n"))) #node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["renegotiate"] = conversation # check if responder_id_list is supported conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] # DER encoding of CHOICE[1] OCTETSTRING (20) ocsp = StatusRequestExtension().create(responder_id_list=[ bytearray(b'\xa2\x16\x04\x14') + bytearray([(i + 2) % 256] * 20) for i in range(625) ]) ocsp.responder_id_list += [ bytearray(b'\xa2\x16\x04\x14') + bytearray( b'\x18\x70\x95\x0B\xE0\x8E\x49\x98\x76\x23\x54\xE7\xD1\xFB\x4E\x9B\xB6\x67\x5E\x2B' ) ] ext = {ExtensionType.status_request: ocsp} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA] ext = { ExtensionType.status_request: ocsp, ExtensionType.renegotiation_info: None } # renegotiate for _ in range(renego): node = node.add_child(ResetHandshakeHashes()) node = node.add_child( ClientHelloGenerator(ciphers, extensions=ext, session_id=bytearray())) node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) #node = node.add_child(ApplicationDataGenerator( # bytearray(b"GET / HTTP/1.0\n\n"))) #node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["renegotiate with large responder_id_list"] = conversation # run the conversation good = 0 bad = 0 failed = [] # make sure that sanity test is run first and last # to verify that server was running and kept running throught sanity_test = ('sanity', conversations['sanity']) ordered_tests = chain([sanity_test], filter(lambda x: x[0] != 'sanity', conversations.items()), [sanity_test]) for c_name, c_test in ordered_tests: if run_only and c_name not in run_only or c_name in run_exclude: continue print("{0} ...".format(c_name)) runner = Runner(c_test) res = True try: runner.run() except: print("Error while processing") print(traceback.format_exc()) res = False if res: good += 1 print("OK") else: bad += 1 failed.append(c_name) print("Test end") print("successful: {0}".format(good)) print("failed: {0}".format(bad)) failed_sorted = sorted(failed, key=natural_sort_keys) print(" {0}".format('\n '.join(repr(i) for i in failed_sorted))) if bad > 0: sys.exit(1)
def main(): host = "localhost" port = 4433 num_limit = None run_exclude = set() expected_failures = {} last_exp_tmp = None dhe = False ocsp = False argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:n:d", ["help", "ocsp-enabled"]) for opt, arg in opts: if opt == '-h': host = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '-x': expected_failures[arg] = None last_exp_tmp = str(arg) elif opt == '-X': if not last_exp_tmp: raise ValueError("-x has to be specified before -X") expected_failures[last_exp_tmp] = str(arg) elif opt == '-n': num_limit = int(arg) elif opt == '-d': dhe = True elif opt == '--ocsp-enabled': ocsp = True elif opt == '--help': help_msg() sys.exit(0) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} conversation = Connect(host, port) node = conversation if dhe: ext = {} groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ext = None ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(description="first")) node = node.add_child(ExpectCertificate()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n"))) node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["sanity"] = conversation # sanity renegotiation test case conversation = Connect(host, port) node = conversation ext = OrderedDict() # TODO add session_ticket ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(SIG_ALL) groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.extended_master_secret] = AutoEmptyExtension() ext[ExtensionType.key_share] = key_share_ext_gen([GroupName.secp256r1]) ext[ExtensionType.alpn] = \ ALPNExtension().create([bytearray(b'http/1.1')]) ext[ExtensionType.ec_point_formats] = \ ECPointFormatsExtension().create([ ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, ECPointFormat.uncompressed]) # 18 - signed_certificate_timestamp ext[18] = AutoEmptyExtension() ext[ExtensionType.status_request] = \ StatusRequestExtension().create() ext[ExtensionType.post_handshake_auth] = AutoEmptyExtension() # yes, don't include TLS 1.3, as we want to be able to renegotiate... ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\ .create([(3, 3), (3, 2)]) ext[ExtensionType.psk_key_exchange_modes] = \ PskKeyExchangeModesExtension().create( [PskKeyExchangeMode.psk_dhe_ke, PskKeyExchangeMode.psk_ke]) psk_settings = [(b'test', b'pre-shared key', 'sha256')] ext[ExtensionType.pre_shared_key] = psk_ext_gen(psk_settings) mods = [] mods.append(psk_ext_updater(psk_settings)) if dhe: ciphers = [ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child( ClientHelloGenerator(ciphers, extensions=ext, modifiers=mods)) node = node.add_child(ExpectServerHello(description="first handshake")) node = node.add_child(ExpectCertificate()) if ocsp: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child(ResetHandshakeHashes()) renego_exts = OrderedDict(ext) # use None for autogeneration of the renegotiation_info with correct # payload renego_exts[ExtensionType.renegotiation_info] = None if ExtensionType.pre_shared_key in renego_exts: # make sure the PSK is the last extension tmp = renego_exts[ExtensionType.pre_shared_key] del renego_exts[ExtensionType.pre_shared_key] renego_exts[ExtensionType.pre_shared_key] = tmp renego_ciphers = list(ciphers) renego_ciphers.remove(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) node = node.add_child( ClientHelloGenerator(renego_ciphers, extensions=renego_exts, session_id=bytearray(0), modifiers=mods)) node = node.add_child(ExpectServerHello(description="second handshake")) node = node.add_child(ExpectCertificate()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n"))) node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["sanity - renegotiation"] = conversation # drop specific extensions in the renegotiated client hello # signature_algorithms and signature_algorithms_cert are covered # by the test-sig-algs-renegotiation-resumption.py for drop_ext, exp_result in [ (ExtensionType.supported_groups, None), (ExtensionType.extended_master_secret, AlertDescription.handshake_failure), (ExtensionType.key_share, None), (ExtensionType.alpn, None), (ExtensionType.ec_point_formats, None), (18, None), # signed_certificate_timestamp (ExtensionType.status_request, None), (ExtensionType.post_handshake_auth, None), (ExtensionType.supported_versions, None), (ExtensionType.psk_key_exchange_modes, None), (ExtensionType.pre_shared_key, None) ]: conversation = Connect(host, port) node = conversation ext = OrderedDict() ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(SIG_ALL) groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.extended_master_secret] = AutoEmptyExtension() ext[ExtensionType.key_share] = key_share_ext_gen([GroupName.secp256r1]) ext[ExtensionType.alpn] = \ ALPNExtension().create([bytearray(b'http/1.1')]) ext[ExtensionType.ec_point_formats] = \ ECPointFormatsExtension().create([ ECPointFormat.ansiX962_compressed_prime, ECPointFormat.ansiX962_compressed_char2, ECPointFormat.uncompressed]) # 18 - signed_certificate_timestamp ext[18] = AutoEmptyExtension() ext[ExtensionType.status_request] = \ StatusRequestExtension().create() ext[ExtensionType.post_handshake_auth] = AutoEmptyExtension() # yes, don't include TLS 1.3, as we want to be able to renegotiate... ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\ .create([(3, 3), (3, 2)]) ext[ExtensionType.psk_key_exchange_modes] = \ PskKeyExchangeModesExtension().create( [PskKeyExchangeMode.psk_dhe_ke, PskKeyExchangeMode.psk_ke]) ext[ExtensionType.pre_shared_key] = psk_ext_gen([(b'test', b'pre-shared key')]) if dhe: ciphers = [ CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(description="first handshake")) node = node.add_child(ExpectCertificate()) if ocsp: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child(ResetHandshakeHashes()) renego_exts = OrderedDict(ext) del renego_exts[drop_ext] # use None for autogeneration of the renegotiation_info with correct # payload renego_exts[ExtensionType.renegotiation_info] = None if ExtensionType.pre_shared_key in renego_exts: # make sure the PSK is the last extension tmp = renego_exts[ExtensionType.pre_shared_key] del renego_exts[ExtensionType.pre_shared_key] renego_exts[ExtensionType.pre_shared_key] = tmp renego_ciphers = list(ciphers) renego_ciphers.remove(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) node = node.add_child( ClientHelloGenerator(renego_ciphers, extensions=renego_exts, session_id=bytearray(0))) if exp_result is not None: node = node.add_child(ExpectAlert(AlertLevel.fatal, exp_result)) node.add_child(ExpectClose()) else: node = node.add_child( ExpectServerHello(description="second handshake")) node = node.add_child(ExpectCertificate()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n"))) node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["drop {0} in renegotiation".format( ExtensionType.toStr(drop_ext))] = conversation # run the conversation good = 0 bad = 0 xfail = 0 xpass = 0 failed = [] xpassed = [] if not num_limit: num_limit = len(conversations) # make sure that sanity test is run first and last # to verify that server was running and kept running throughout sanity_tests = [('sanity', conversations['sanity'])] if run_only: if num_limit > len(run_only): num_limit = len(run_only) regular_tests = [(k, v) for k, v in conversations.items() if k in run_only] else: regular_tests = [(k, v) for k, v in conversations.items() if (k != 'sanity') and k not in run_exclude] sampled_tests = sample(regular_tests, min(num_limit, len(regular_tests))) ordered_tests = chain(sanity_tests, sampled_tests, sanity_tests) for c_name, c_test in ordered_tests: print("{0} ...".format(c_name)) runner = Runner(c_test) res = True exception = None try: runner.run() except Exception as exp: exception = exp print("Error while processing") print(traceback.format_exc()) res = False if c_name in expected_failures: if res: xpass += 1 xpassed.append(c_name) print("XPASS-expected failure but test passed\n") else: if expected_failures[c_name] is not None and \ expected_failures[c_name] not in str(exception): bad += 1 failed.append(c_name) print("Expected error message: {0}\n".format( expected_failures[c_name])) else: xfail += 1 print("OK-expected failure\n") else: if res: good += 1 print("OK\n") else: bad += 1 failed.append(c_name) print("Test how server behaves when the renegotiation Client Hello is") print("changed compared to the initial ClientHello.\n") print("If the renegotiation is supposed to be disabled use the") print("test-renegotiation-disabled.py or") print("test-renegotiation-disabled-client-cert.py scripts to verify") print("that.\n") print("Test end") print(20 * '=') print("version: {0}".format(version)) print(20 * '=') print("TOTAL: {0}".format(len(sampled_tests) + 2 * len(sanity_tests))) print("SKIP: {0}".format( len(run_exclude.intersection(conversations.keys())))) print("PASS: {0}".format(good)) print("XFAIL: {0}".format(xfail)) print("FAIL: {0}".format(bad)) print("XPASS: {0}".format(xpass)) print(20 * '=') sort = sorted(xpassed, key=natural_sort_keys) if len(sort): print("XPASSED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort))) sort = sorted(failed, key=natural_sort_keys) if len(sort): print("FAILED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort))) if bad > 0: sys.exit(1)
def main(): host = "localhost" port = 4433 run_exclude = set() expected_failures = {} last_exp_tmp = None dhe = False renego = 1 status = True argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:r:d", ["help", "no-status"]) for opt, arg in opts: if opt == '-h': host = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '-x': expected_failures[arg] = None last_exp_tmp = str(arg) elif opt == '-X': if not last_exp_tmp: raise ValueError("-x has to be specified before -X") expected_failures[last_exp_tmp] = str(arg) elif opt == '-d': dhe = True elif opt == '-r': renego = int(arg) elif opt == '--no-status': status = False elif opt == '--help': help_msg() sys.exit(0) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} # check if status_request is recognized and supported conversation = Connect(host, port) node = conversation ocsp = StatusRequestExtension().create() ext = {ExtensionType.status_request: ocsp} if dhe: groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(RSA_SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n"))) node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["sanity"] = conversation # check if status_request is recognized and supported conversation = Connect(host, port) node = conversation ocsp = StatusRequestExtension().create() ext = {ExtensionType.status_request: ocsp} if dhe: groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(RSA_SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) ext = { ExtensionType.status_request: ocsp, ExtensionType.renegotiation_info: None } if dhe: groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(RSA_SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA ] else: ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA] # renegotiate node = node.add_child(ResetHandshakeHashes()) node = node.add_child( ClientHelloGenerator(ciphers, extensions=ext, session_id=bytearray())) node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) #node = node.add_child(ApplicationDataGenerator( # bytearray(b"GET / HTTP/1.0\n\n"))) #node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["renegotiate"] = conversation # check if responder_id_list is supported conversation = Connect(host, port) node = conversation # DER encoding of CHOICE[1] OCTETSTRING (20) ocsp = StatusRequestExtension().create(responder_id_list=[ bytearray(b'\xa2\x16\x04\x14') + bytearray([(i + 2) % 256] * 20) for i in range(625) ]) ocsp.responder_id_list += [ bytearray(b'\xa2\x16\x04\x14') + bytearray( b'\x18\x70\x95\x0B\xE0\x8E\x49\x98\x76\x23\x54\xE7\xD1\xFB\x4E\x9B\xB6\x67\x5E\x2B' ) ] ext = {ExtensionType.status_request: ocsp} if dhe: groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(RSA_SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext_srv = {ExtensionType.renegotiation_info: None} if status: ext_srv[ExtensionType.status_request] = None node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) ext = { ExtensionType.status_request: ocsp, ExtensionType.renegotiation_info: None } if dhe: groups = [GroupName.secp256r1, GroupName.ffdhe2048] ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension().create(RSA_SIG_ALL) ext[ExtensionType.signature_algorithms_cert] = \ SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) ciphers = [ CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA ] else: ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA] # renegotiate for _ in range(renego): node = node.add_child(ResetHandshakeHashes()) node = node.add_child( ClientHelloGenerator(ciphers, extensions=ext, session_id=bytearray())) node = node.add_child(ExpectServerHello(extensions=ext_srv)) node = node.add_child(ExpectCertificate()) if status: node = node.add_child(ExpectCertificateStatus()) if dhe: node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) #node = node.add_child(ApplicationDataGenerator( # bytearray(b"GET / HTTP/1.0\n\n"))) #node = node.add_child(ExpectApplicationData()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["renegotiate with large responder_id_list"] = conversation # run the conversation good = 0 bad = 0 xfail = 0 xpass = 0 failed = [] xpassed = [] # make sure that sanity test is run first and last # to verify that server was running and kept running throughout sanity_tests = [('sanity', conversations['sanity'])] regular_tests = [(k, v) for k, v in conversations.items() if k != 'sanity'] sampled_tests = sample(regular_tests, len(regular_tests)) ordered_tests = chain(sanity_tests, sampled_tests, sanity_tests) for c_name, c_test in ordered_tests: if run_only and c_name not in run_only or c_name in run_exclude: continue print("{0} ...".format(c_name)) runner = Runner(c_test) res = True exception = None try: runner.run() except Exception as exp: exception = exp print("Error while processing") print(traceback.format_exc()) res = False if c_name in expected_failures: if res: xpass += 1 xpassed.append(c_name) print("XPASS: expected failure but test passed\n") else: if expected_failures[c_name] is not None and \ expected_failures[c_name] not in str(exception): bad += 1 failed.append(c_name) print("Expected error message: {0}\n".format( expected_failures[c_name])) else: xfail += 1 print("OK-expected failure\n") else: if res: good += 1 print("OK\n") else: bad += 1 failed.append(c_name) print("Script to verify that OCSP stapling support is implemented in " "server") print("Also can be used to reproduce CVE-2016-6304 with the use of -r " "option\n") print("version: {0}\n".format(version)) print("Test end") print("successful: {0}".format(good)) print("failed: {0}".format(bad)) failed_sorted = sorted(failed, key=natural_sort_keys) print(" {0}".format('\n '.join(repr(i) for i in failed_sorted))) if bad > 0: sys.exit(1)
def conv_generator(conf, host, port, sni_hostname, cert=None, key=None): """Generate a conversation based on dict with configuration.""" root = Connect(host, port) hs = HandshakeSettings() # only RSA is supported if conf['Server_authentication'] != "RSA" and \ conf['Server_authentication'] != "anon": print("Substituting {0} to RSA for server auth".format( conf['Server_authentication']), file=sys.stderr) # get the cipher that matches the imposed restrictions cipher_trans = { "AES_128_CBC": "aes128", "AES_256_CBC": "aes256", "AES_128_GCM": "aes128gcm", "AES_256_GCM": "aes256gcm", "3DES_EDE_CBC": "3des", "RC4": "rc4", "Chacha20_Poly1305": "chacha20-poly1305" } hs.cipherNames = [cipher_trans.get(conf['Cipher'], None)] if hs.cipherNames == [None]: raise ValueError("Unknown cipher type: {0}".format(conf['Cipher'])) mac_trans = { "AEAD": "aead", "MD5_HMAC": "md5", "SHA1_HMAC": "sha", "SHA256_HMAC": "sha256", "SHA384_HMAC": "sha384" } hs.macNames = [mac_trans.get(conf['Integrity'], None)] if hs.macNames == [None]: raise ValueError("Unknown integrity type: {0}".format( conf['Integrity'])) if conf['Key_exchange'] == 'DHE' and \ conf['Server_authentication'] == "anon": suites = CipherSuite.getAnonSuites(hs) elif conf['Key_exchange'] == 'ECDHE' and \ conf['Server_authentication'] == "anon": suites = CipherSuite.getEcdhAnonSuites(hs) elif conf['Key_exchange'] == 'RSA': suites = CipherSuite.getCertSuites(hs) elif conf['Key_exchange'] == 'DHE': suites = CipherSuite.getDheCertSuites(hs) elif conf['Key_exchange'] == 'ECDHE': suites = CipherSuite.getEcdheCertSuites(hs) else: raise ValueError("Unknown key exchange type: {0}".format( conf['Key_exchange'])) if not suites: raise ValueError( "Couldn't find matching cipher for {0} {3} {1} {2}".format( conf['Key_exchange'], conf['Cipher'], conf['Integrity'], conf['Server_authentication'])) # session ID/resumption handling if conf['CH_SessionID'] == 'random': sess_ID = getRandomBytes(16) elif conf['CH_SessionID'] == 'empty': sess_ID = bytearray() else: raise ValueError("Unknown CH_SessionID value".format( conf['CH_SessionID'])) # compression if conf['CH_compression'] == 'null_only': compress = [0] elif conf['CH_compression'] == 'null_and_deflate': compress = [0, 1] else: raise ValueError("Unknown CH_compression value: {0}".format( conf['CH_compression'])) # Renegotiation Info if conf['CH_renegotiation_info_SCSV'] == "first": suites.insert(0, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) elif conf['CH_renegotiation_info_SCSV'] == "last": suites.append(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) elif conf['CH_renegotiation_info_SCSV'] == "absent": pass elif conf['CH_renegotiation_info_SCSV'] == "second": suites.append(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) suites.append(0xeaea) # GREASE else: raise ValueError( "Unexpected CH_renegotiation_info_SCSV value: {0}".format( conf['CH_renegotiation_info_SCSV'])) # whether to send extensions if conf['CH_extensions_present'] == "false": ext = None elif conf['CH_extensions_present'] != "true": raise ValueError("Unexpected CH_extensions_present value: {0}".format( conf['CH_extensions_present'])) else: ext = dict() # session ticket if conf['CH_session_ticket'] != "no_ext": print("Not generating session ticket extension", file=sys.stderr) # renegotiation info if conf['CH_renegotiation_info_ext'] == "true": ext[ExtensionType.renegotiation_info] = \ RenegotiationInfoExtension().create(bytearray()) elif conf['CH_renegotiation_info_ext'] == "false": pass else: raise ValueError( "Unknown option in CH_renegotiation_info_ext: {0}".format( conf['CH_renegotiation_info_ext'])) # signature algorithms if conf['CH_signature_algorithms_ext'] == "false": pass elif conf['CH_signature_algorithms_ext'] != "true": raise ValueError( "Unknown option CH_signature_algorithms_ext: {0}".format( conf["CH_signature_algorithms_ext"])) else: sig = conf['SKE_signature_scheme'] if sig == "none" or sig == "no_message": # enter some random ones: ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension()\ .create([SignatureScheme.rsa_pkcs1_sha256, SignatureScheme.rsa_pss_sha256]) else: if "dsa" in sig: print("Changing {0} to RSA scheme".format(sig)) sig = sig.replace("ecdsa", "rsa") sig = sig.replace("dsa", "rsa") sig = sig.replace("rsa_sha", "rsa_pkcs1_sha") sig = sig.replace("rsapss", "rsa_pss") if "sha224" in sig: scheme = (HashAlgorithm.sha224, SignatureAlgorithm.rsa) else: scheme = getattr(SignatureScheme, sig) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension()\ .create([scheme]) # supported groups extension if conf['CH_supported_groups_ext'] == "false": groups = [ GroupName.ffdhe2048, GroupName.secp256r1, GroupName.x25519 ] ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) pass elif conf['CH_supported_groups_ext'] != "true": raise ValueError( "Unknown option in CH_supported_groups_ext: {0}".format( conf['CH_supported_groups_ext'])) else: if conf['SKE_dh_group'] == "no_message": groups = [ GroupName.ffdhe2048, GroupName.secp256r1, GroupName.x25519 ] elif conf['SKE_dh_group'] == "ffdhe1024": groups = [GroupName.secp256r1, GroupName.x25519] else: groups = [getattr(GroupName, conf['SKE_dh_group'])] ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) ext[ExtensionType.ec_point_formats] = \ ECPointFormatsExtension()\ .create([ECPointFormat.uncompressed, ECPointFormat.ansiX962_compressed_char2, ECPointFormat.ansiX962_compressed_prime]) # encrypt then MAC if conf['CH_encrypt_then_mac_ext'] == "false": pass elif conf['CH_encrypt_then_mac_ext'] != "true": raise ValueError( "Unknown option in CH_encrypt_then_mac_ext: {0}".format( conf['CH_encrypt_then_mac_ext'])) else: ext[ExtensionType.encrypt_then_mac] = \ TLSExtension(extType=ExtensionType.encrypt_then_mac)\ .create(bytearray(0)) # server name if conf['CH_server_name'] == "no_ext": pass elif conf['CH_server_name'] == "correct": ext[ExtensionType.server_name] = \ SNIExtension().create(sni_hostname) elif conf['CH_server_name'] == "mismatch": ext[ExtensionType.server_name] = \ SNIExtension().create(sni_hostname + b'.www') else: raise ValueError("Unknown option in CH_server_name: {0}".format( conf['CH_server_name'])) # OCSP staple if conf['CH_status_request_ext'] == "false": pass elif conf['CH_status_request_ext'] != "true": raise ValueError( "Unknown option in CH_status_request_ext: {0}".format( conf['CH_status_request_ext'])) else: ext[ExtensionType.status_request] = \ StatusRequestExtension().create() # Extended Master Secret ext if conf['CH_extended_master_secret_ext'] == "false": pass elif conf['CH_extended_master_secret_ext'] != "true": raise ValueError( ("Unknown value in CH_extended_master_secret_ext" ": {0}").format(conf['CH_extended_master_secret_ext'])) else: ext[ExtensionType.extended_master_secret] = \ TLSExtension(extType=ExtensionType.extended_master_secret)\ .create(bytearray()) # # node = root.add_child( ClientHelloGenerator(suites, session_id=sess_ID, compression=compress, extensions=ext)) if conf['CH_server_name'] == "mismatch": node = node.add_child( ExpectAlert(AlertLevel.warning, AlertDescription.unrecognized_name)) al_node = node node = node.add_child(ExpectServerHello()) if conf['CH_server_name'] == "mismatch": # make the sending of warning alert node optional al_node.next_sibling = node node = node.add_child(ExpectCertificate()) # TODO if conf['Certificate_Status_msg'] if conf['SKE_dh_group'] != "no_message": node = node.add_child(ExpectServerKeyExchange()) if conf['CR_sent'] == "true": node = node.add_child(ExpectCertificateRequest()) elif conf['CR_sent'] != "false": raise ValueError("Unknown option in CR_sent: {0}".format( conf['CR_sent'])) node = node.add_child(ExpectServerHelloDone()) if conf['CR_sent'] == "true": if conf['CV_signature_scheme'] == "no_message": node = node.add_child(CertificateGenerator()) else: node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) if conf['CV_signature_scheme'] != "no_message": sig = conf['CV_signature_scheme'] if "dsa" in sig: print("Changing {0} to RSA scheme in CV".format(sig)) sig = sig.replace("ecdsa", "rsa") sig = sig.replace("dsa", "rsa") sig = sig.replace("rsa_sha", "rsa_pkcs1_sha") sig = sig.replace("rsapss", "rsa_pss") if "sha224" in sig: scheme = (HashAlgorithm.sha224, SignatureAlgorithm.rsa) else: scheme = getattr(SignatureScheme, sig) node = node.add_child(CertificateVerifyGenerator(key, msg_alg=scheme)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) if conf['Disconnect'] == "true": node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child( ExpectAlert(AlertLevel.warning, AlertDescription.close_notify)) node.next_sibling = ExpectClose() node = node.add_child(node.next_sibling) node = node.add_child(Connect(host, port)) node = node.add_child(ResetRenegotiationInfo()) node = node.add_child(ResetHandshakeHashes()) hs = HandshakeSettings() hs.cipherNames = [cipher_trans.get(conf['H2Cipher'], None)] if hs.cipherNames == [None]: raise ValueError("Unknown cipher type: {0}".format(conf['H2Cipher'])) hs.macNames = [mac_trans.get(conf["H2Integrity"], None)] if hs.macNames == [None]: raise ValueError("Unknown integrity type: {0}".format( conf['H2Integrity'])) if conf['H2Key_exchange'] == 'DHE' and \ conf['H2Server_authentication'] == "anon": suites = CipherSuite.getAnonSuites(hs) elif conf['H2Key_exchange'] == "ECDHE" and \ conf['H2Server_authentication'] == "anon": suites = CipherSuite.getEcdhAnonSuites(hs) elif conf['H2Key_exchange'] == "RSA": suites = CipherSuite.getCertSuites(hs) elif conf['H2Key_exchange'] == "DHE": suites = CipherSuite.getDheCertSuites(hs) elif conf['H2Key_exchange'] == "ECDHE": suites = CipherSuite.getEcdheCertSuites(hs) else: raise ValueError("Unknown key exchange type: {0}".format( conf['H2Key_exchange'])) if not suites: raise ValueError( "Couldn't find matching cipher for {0} {3} {1} {2}".format( conf['H2Key_exchange'], conf['H2Cipher'], conf['H2Integrity'], conf['H2Server_authentication'])) if conf['H2CH_SessionID'] == 'random': sess_ID = getRandomBytes(16) elif conf['H2CH_SessionID'] == 'empty': sess_ID = bytearray() elif conf['H2CH_SessionID'] == "resume": sess_ID = None else: raise ValueError("Unknown session id value: {0}".format( conf['H2CH_SessionID'])) # compression if conf['H2CH_compression'] == 'null_only': compress = [0] elif conf['H2CH_compression'] == 'null_and_deflate': compress = [0, 1] else: raise ValueError("Unknown H2CH_compression value: {0}".format( conf['H2CH_compression'])) # Renegotiation Info if conf['H2CH_renegotiation_info_SCSV'] == "first": suites.insert(0, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) elif conf['H2CH_renegotiation_info_SCSV'] == "last": suites.append(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) elif conf['H2CH_renegotiation_info_SCSV'] == "absent": pass elif conf['H2CH_renegotiation_info_SCSV'] == "second": suites.append(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) suites.append(0xeaea) # GREASE else: raise ValueError( "Unexpected H2CH_renegotiation_info_SCSV value: {0}".format( conf['H2CH_renegotiation_info_SCSV'])) # whether to send extensions if conf['H2CH_extensions_present'] == "false": ext = None elif conf['H2CH_extensions_present'] != "true": raise ValueError("Unexpected CH_extensions_present value: {0}".format( conf['H2CH_extensions_present'])) else: ext = dict() # session ticket if conf['H2CH_session_ticket'] != "no_ext": print("Not generating session ticket extension", file=sys.stderr) # renegotiation info if conf['H2CH_renegotiation_info_ext'] == "true": ext[ExtensionType.renegotiation_info] = None elif conf['H2CH_renegotiation_info_ext'] == "false": pass else: raise ValueError("Unknown option in H2CH_renegotiation_info_ext: " "{0}".format(conf['H2CH_renegotiation_info_ext'])) # signature algorithms if conf['H2CH_signature_algorithms_ext'] == "false": pass elif conf['H2CH_signature_algorithms_ext'] != "true": raise ValueError("Unknown option H2CH_signature_algorithms_ext: " "{0}".format( conf["H2CH_signature_algorithms_ext"])) else: sig = conf['H2SKE_signature_scheme'] if sig == "none" or sig == "no_message": # enter some random ones: ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension()\ .create([SignatureScheme.rsa_pkcs1_sha256, SignatureScheme.rsa_pss_sha256]) else: if "dsa" in sig: print("Changing {0} to RSA scheme".format(sig)) sig = sig.replace("ecdsa", "rsa") sig = sig.replace("dsa", "rsa") sig = sig.replace("rsa_sha", "rsa_pkcs1_sha") sig = sig.replace("rsapss", "rsa_pss") if "sha224" in sig: scheme = (HashAlgorithm.sha224, SignatureAlgorithm.rsa) else: scheme = getattr(SignatureScheme, sig) ext[ExtensionType.signature_algorithms] = \ SignatureAlgorithmsExtension()\ .create([scheme]) # supported groups extension if conf['H2CH_supported_groups_ext'] == "false": groups = [ GroupName.ffdhe2048, GroupName.secp256r1, GroupName.x25519 ] ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) pass elif conf['H2CH_supported_groups_ext'] != "true": raise ValueError( "Unknown option in H2CH_supported_groups_ext: {0}".format( conf['H2CH_supported_groups_ext'])) else: if conf['H2SKE_dh_group'] == "no_message": groups = [ GroupName.ffdhe2048, GroupName.secp256r1, GroupName.x25519 ] elif conf['H2SKE_dh_group'] == "ffdhe1024": groups = [GroupName.secp256r1, GroupName.x25519] else: groups = [getattr(GroupName, conf['H2SKE_dh_group'])] ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) ext[ExtensionType.ec_point_formats] = \ ECPointFormatsExtension()\ .create([ECPointFormat.uncompressed, ECPointFormat.ansiX962_compressed_char2, ECPointFormat.ansiX962_compressed_prime]) # encrypt then MAC if conf['H2CH_encrypt_then_mac_ext'] == "false": pass elif conf['H2CH_encrypt_then_mac_ext'] != "true": raise ValueError( "Unknown option in H2CH_encrypt_then_mac_ext: {0}".format( conf['H2CH_encrypt_then_mac_ext'])) else: ext[ExtensionType.encrypt_then_mac] = \ TLSExtension(extType=ExtensionType.encrypt_then_mac)\ .create(bytearray(0)) # server name if conf['H2CH_server_name'] == "no_ext": pass elif conf['H2CH_server_name'] == "correct": ext[ExtensionType.server_name] = \ SNIExtension().create(sni_hostname) elif conf['H2CH_server_name'] == "mismatch": ext[ExtensionType.server_name] = \ SNIExtension().create(sni_hostname + b'.www') else: raise ValueError("Unknown option in H2CH_server_name: {0}".format( conf['H2CH_server_name'])) # OCSP staple if conf['H2CH_status_request_ext'] == "false": pass elif conf['H2CH_status_request_ext'] != "true": raise ValueError( "Unknown option in H2CH_status_request_ext: {0}".format( conf['H2CH_status_request_ext'])) else: ext[ExtensionType.status_request] = \ StatusRequestExtension().create() # Extended Master Secret ext if conf['H2CH_extended_master_secret_ext'] == "false": pass elif conf['H2CH_extended_master_secret_ext'] != "true": raise ValueError( ("Unknown value in H2CH_extended_master_secret_ext" ": {0}").format(conf['H2CH_extended_master_secret_ext'])) else: ext[ExtensionType.extended_master_secret] = \ TLSExtension(extType=ExtensionType.extended_master_secret)\ .create(bytearray()) node = node.add_child( ClientHelloGenerator(suites, session_id=sess_ID, compression=compress, extensions=ext)) if conf['H2CH_server_name'] == "mismatch": node = node.add_child( ExpectAlert(AlertLevel.warning, AlertDescription.unrecognized_name)) al_node = node if conf['H2SH_SessionID'] == "resume": print("doing resumption") node = node.add_child(ExpectServerHello(resume=True)) if conf['H2CH_server_name'] == "mismatch": # make the sending of warning alert node optional al_node.next_sibling = node node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child( ExpectAlert(AlertLevel.warning, AlertDescription.close_notify)) node.next_sibling = ExpectClose() else: node = node.add_child(ExpectServerHello()) if conf['H2CH_server_name'] == "mismatch": # make the sending of warning alert node optional al_node.next_sibling = node node = node.add_child(ExpectCertificate()) # TODO if conf['Certificate_Status_msg'] if conf['H2SKE_dh_group'] != "no_message": node = node.add_child(ExpectServerKeyExchange()) if conf['H2CR_sent'] == "true": node = node.add_child(ExpectCertificateRequest()) elif conf['H2CR_sent'] != "false": raise ValueError("Unknown option in H2CR_sent: {0}".format( conf['H2CR_sent'])) node = node.add_child(ExpectServerHelloDone()) if conf['H2CR_sent'] == "true": if conf['H2CV_signature_scheme'] == "no_message": node = node.add_child(CertificateGenerator()) else: node = node.add_child( CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) if conf['H2CV_signature_scheme'] != "no_message": sig = conf['H2CV_signature_scheme'] if "dsa" in sig: print("Changing {0} to RSA scheme in CV".format(sig)) sig = sig.replace("ecdsa", "rsa") sig = sig.replace("dsa", "rsa") sig = sig.replace("rsa_sha", "rsa_pkcs1_sha") sig = sig.replace("rsapss", "rsa_pss") if "sha224" in sig: scheme = (HashAlgorithm.sha224, SignatureAlgorithm.rsa) else: scheme = getattr(SignatureScheme, sig) node = node.add_child( CertificateVerifyGenerator(key, msg_alg=scheme)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child( ExpectAlert(AlertLevel.warning, AlertDescription.close_notify)) node.next_sibling = ExpectClose() return root