def main(): host = "localhost" port = 4433 num_limit = None run_exclude = set() expected_failures = {} last_exp_tmp = None ext_exclude = set() cookie = False argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:n:", ["help", "cookie", "exc="]) 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 == '--exc': ext_exclude.add(int(arg)) elif opt == '--cookie': cookie = 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 ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] key_shares = [] for group in groups: key_shares.append(key_share_gen(group)) ext[ExtensionType.key_share] = ClientKeyShareExtension().create(key_shares) ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\ .create([TLS_1_3_DRAFT, (3, 3)]) ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) sig_algs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256 ] ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\ .create(sig_algs) ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\ .create(RSA_SIG_ALL) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectEncryptedExtensions()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(FinishedGenerator()) node = node.add_child( ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n"))) # This message is optional and may show up 0 to many times cycle = ExpectNewSessionTicket() node = node.add_child(cycle) node.add_child(cycle) node.next_sibling = ExpectApplicationData() node = node.next_sibling.add_child( AlertGenerator(AlertLevel.warning, AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) node.next_sibling = ExpectClose() conversations["sanity"] = conversation conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = OrderedDict() groups = [GroupName.secp256r1] key_shares = [] ext[ExtensionType.key_share] = ClientKeyShareExtension().create(key_shares) ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\ .create([TLS_1_3_DRAFT, (3, 3)]) ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) sig_algs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256 ] ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\ .create(sig_algs) ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\ .create(RSA_SIG_ALL) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) hrr_ext = OrderedDict() if cookie: hrr_ext[ExtensionType.cookie] = None hrr_ext[ExtensionType.key_share] = None hrr_ext[ExtensionType.supported_versions] = None node = node.add_child(ExpectHelloRetryRequest(extensions=hrr_ext)) node = node.add_child(ExpectChangeCipherSpec()) # Reverse extensions rev_ext = OrderedDict() rev_ext.update(reversed(ext.items())) groups = [GroupName.secp256r1] key_shares = [] for group in groups: key_shares.append(key_share_gen(group)) rev_ext[ExtensionType.key_share] = ClientKeyShareExtension().create( key_shares) if cookie: rev_ext[ExtensionType.cookie] = ch_cookie_handler node = node.add_child(ClientHelloGenerator(ciphers, extensions=rev_ext)) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) node.add_child(ExpectClose()) conversations["HRR reversed order of known extensions"] = conversation unassigned_ext_id = list(range(52, 65279)) # Exclude extensions from a list of unassigned ones unassigned_ext_id = [ ext for ext in unassigned_ext_id if ext not in ext_exclude ] chunk_size = 4096 for ext_chunk in (unassigned_ext_id[j:j + chunk_size] for j in range(0, len(unassigned_ext_id), chunk_size)): conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = OrderedDict() groups = [GroupName.secp256r1] key_shares = [] ext[ExtensionType.key_share] = ClientKeyShareExtension().create( key_shares) ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\ .create([TLS_1_3_DRAFT, (3, 3)]) ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\ .create(groups) sig_algs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256 ] ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\ .create(sig_algs) ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\ .create(RSA_SIG_ALL) for ext_id in ext_chunk: ext[ext_id] = AutoEmptyExtension() node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) hrr_ext = OrderedDict() if cookie: hrr_ext[ExtensionType.cookie] = None hrr_ext[ExtensionType.key_share] = None hrr_ext[ExtensionType.supported_versions] = None node = node.add_child(ExpectHelloRetryRequest(extensions=hrr_ext)) node = node.add_child(ExpectChangeCipherSpec()) # Reverse extensions rev_ext = OrderedDict() rev_ext.update(reversed(ext.items())) groups = [GroupName.secp256r1] key_shares = [] for group in groups: key_shares.append(key_share_gen(group)) rev_ext[ExtensionType.key_share] = ClientKeyShareExtension().create( key_shares) if cookie: rev_ext[ExtensionType.cookie] = ch_cookie_handler node = node.add_child(ClientHelloGenerator(ciphers, extensions=rev_ext)) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) node.add_child(ExpectClose()) conversations[ "HRR reversed order of unassigned extensions, ext_ids in range from {0} to {1}" .format(ext_chunk[0], ext_chunk[-1])] = 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: 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("TLS 1.3 communication with shuffled extensions in CH messages.") print("Verify that server reject second CH message,") print("when the order of extensions in first and second CH is different.") print("Also unassigned extensions are used.\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)
class TestOrderedDict(unittest.TestCase): def setUp(self): self.d = OrderedDict() self.d[1] = "a" self.d[2] = "b" self.d[3] = "c" def test___init__(self): d = OrderedDict() self.assertIsInstance(d, dict) def test___init___with_invalid_params(self): with self.assertRaises(TypeError): OrderedDict(12, "a") def test___init___with_dict(self): d = OrderedDict({12: "a", 14: "b"}) self.assertEqual({12: "a", 14: "b"}, d) def test_add_in_order(self): d = OrderedDict() d[1] = "a" d[2] = "b" d[3] = "c" d[4] = "d" d[5] = "e" d[6] = "f" d[7] = "g" self.assertEqual([1, 2, 3, 4, 5, 6, 7], list(d.keys())) self.assertEqual(["a", "b", "c", "d", "e", "f", "g"], list(d.values())) def test_del(self): del self.d[2] self.assertEqual([1, 3], list(self.d.keys())) self.assertEqual(["a", "c"], list(self.d.values())) def test_iter(self): self.assertEqual([1, 2, 3], list(iter(self.d))) def test_popitem(self): n, v = self.d.popitem() self.assertEqual(n, 3) self.assertEqual(v, "c") self.assertEqual([1, 2], list(self.d.keys())) self.assertEqual(["a", "b"], list(self.d.values())) def test_popitem_on_empty(self): d = OrderedDict() with self.assertRaises(KeyError): d.popitem() def test_popitem_first(self): if type(self.d) is dict: self.skipTest("not popitem(last=False) in dict") else: n, v = self.d.popitem(last=False) self.assertEqual(n, 1) self.assertEqual(v, "a") self.assertEqual([2, 3], list(self.d.keys())) self.assertEqual(["b", "c"], list(self.d.values())) def test_items(self): self.assertEqual([(1, "a"), (2, "b"), (3, "c")], list(self.d.items())) def test_iterkeys(self): if type(self.d) is dict: self.skipTest("no iterkeys in dict") else: self.assertEqual(list(self.d.iterkeys()), list(iter(self.d))) def test_clear(self): self.d.clear() self.assertEqual([], list(self.d.items())) def test_itervalues(self): if type(self.d) is dict: self.skipTest("no itervalues in dict") else: self.assertEqual(list(self.d.itervalues()), self.d.values()) def test_update_with_too_many_args(self): with self.assertRaises(TypeError): self.d.update(0, None) def test_update_with_dict(self): self.d.update({0: None}) self.assertEqual([(1, "a"), (2, "b"), (3, "c"), (0, None)], list(self.d.items())) def test_update_with_list_of_tuples(self): d = OrderedDict() d.update([(3, "c"), (2, "b"), (1, "a")]) self.assertEqual([3, 2, 1], list(d.keys())) self.assertEqual(["c", "b", "a"], list(d.values())) def test_update_with_keyword_args(self): d = OrderedDict() d.update(a='1', b='2', c='3') self.assertEqual(set(['1', '2', '3']), set(d.values())) self.assertEqual(set(['a', 'b', 'c']), set(d.keys())) def test_pop(self): v = self.d.pop(2) self.assertEqual(v, "b") self.assertEqual([(1, "a"), (3, "c")], list(self.d.items())) def test_pop_non_existent(self): with self.assertRaises(KeyError): self.d.pop(4) def test_pop_with_default(self): if type(self.d) is dict: a = self.d.pop(0, "foo") self.assertEqual(a, "foo") else: a = self.d.pop(0, default="foo") self.assertEqual(a, "foo") def test_repr(self): if type(self.d) is dict: self.assertEqual("{1: 'a', 2: 'b', 3: 'c'}", repr(self.d)) else: self.assertEqual("OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])", repr(self.d)) def test_repr_with_circular_dependancy(self): del self.d[2] self.d[2] = self.d if type(self.d) is dict: self.assertEqual("{1: 'a', 3: 'c', 2: {...}}", repr(self.d)) else: self.assertEqual("OrderedDict([(1, 'a'), (3, 'c'), (2, ...)])", repr(self.d)) def test_repr_with_empty(self): d = OrderedDict() if type(self.d) is dict: self.assertEqual("{}", repr(d)) else: self.assertEqual("OrderedDict()", repr(d)) def test_compare_different_order(self): d2 = OrderedDict() d2[1] = "a" d2[3] = "c" d2[2] = "b" self.assertNotEqual(list(self.d.items()), list(d2.items()))
def test_update_with_keyword_args(self): d = OrderedDict() d.update(a='1', b='2', c='3') self.assertEqual(set(['1', '2', '3']), set(d.values())) self.assertEqual(set(['a', 'b', 'c']), set(d.keys()))
def test_update_with_list_of_tuples(self): d = OrderedDict() d.update([(3, "c"), (2, "b"), (1, "a")]) self.assertEqual([3, 2, 1], list(d.keys())) self.assertEqual(["c", "b", "a"], list(d.values()))