def setUp(self): cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.clnt_pub_key = cert_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA self.clnt_private_key = parsePEMKey(srv_raw_key, private=True) self.handshake_hashes = HandshakeHashes() self.handshake_hashes.update(bytearray(b'\xab'*32))
def test_process_with_not_matching_signature_algorithms(self): exp = ExpectServerKeyExchange( valid_sig_algs=[(HashAlgorithm.sha256, SignatureAlgorithm.rsa)]) state = ConnectionState() state.cipher = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA cert = Certificate(CertificateType.x509).\ create(X509CertChain([X509().parse(srv_raw_certificate)])) private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() client_hello.client_version = (3, 3) client_hello.random = bytearray(32) state.client_random = client_hello.random state.handshake_messages.append(client_hello) server_hello = ServerHello() server_hello.server_version = (3, 3) server_hello.random = bytearray(32) state.server_random = server_hello.random # server hello is not necessary for the test to work #state.handshake_messages.append(server_hello) state.handshake_messages.append(cert) srv_key_exchange = DHE_RSAKeyExchange(\ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, client_hello, server_hello, private_key) msg = srv_key_exchange.makeServerKeyExchange('sha1') with self.assertRaises(TLSIllegalParameterException): exp.process(state, msg)
def test_server_with_client_proposing_SHA256_on_TLSv1_1(self): gen_sock = MockSocket(bytearray(0)) gen_record_layer = RecordLayer(gen_sock) gen_record_layer.version = (3, 0) ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, 0x88, # TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, ] client_hello = ClientHello().create( version=(3, 2), random=bytearray(32), session_id=bytearray(0), cipher_suites=ciphers ) for res in gen_record_layer.sendRecord(client_hello): if res in (0, 1): self.assertTrue(False, "Blocking socket") else: break # test proper sock = MockSocket(gen_sock.sent[0]) conn = TLSConnection(sock) srv_private_key = parsePEMKey(self.srv_raw_key, private=True) srv_cert_chain = X509CertChain([X509().parse(self.srv_raw_certificate)]) with self.assertRaises(TLSLocalAlert) as err: conn.handshakeServer(certChain=srv_cert_chain, privateKey=srv_private_key) self.assertEqual(err.exception.description, AlertDescription.handshake_failure)
def test_key_parse_using_openssl(self): # XXX doesn't handle files without newlines with self.assertRaises(SyntaxError): key = parsePEMKey(self.privKey_str, private=True, implementations=["openssl"])
def test_process_with_unknown_key_exchange(self): exp = ExpectServerKeyExchange() state = ConnectionState() state.cipher = CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA cert = Certificate(CertificateType.x509).\ create(X509CertChain([X509().parse(srv_raw_certificate)])) private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() client_hello.client_version = (3, 3) client_hello.random = bytearray(32) client_hello.extensions = [ SignatureAlgorithmsExtension().create([(HashAlgorithm.sha256, SignatureAlgorithm.rsa)]) ] state.client_random = client_hello.random state.handshake_messages.append(client_hello) server_hello = ServerHello() server_hello.server_version = (3, 3) state.version = server_hello.server_version server_hello.random = bytearray(32) state.server_random = server_hello.random state.handshake_messages.append(cert) msg = ServerKeyExchange(state.cipher, state.version) msg.createSRP(1, 2, bytearray(3), 5) msg.signAlg = SignatureAlgorithm.rsa msg.hashAlg = HashAlgorithm.sha256 hash_bytes = msg.hash(client_hello.random, server_hello.random) hash_bytes = private_key.addPKCS1Prefix(hash_bytes, 'sha256') msg.signature = private_key.sign(hash_bytes) with self.assertRaises(AssertionError): exp.process(state, msg)
def setUp(self): self.srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.srv_pub_key = srv_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA self.client_hello = ClientHello().create((3, 3), bytearray(32), bytearray(0), [], srpUsername='******') self.server_hello = ServerHello().create((3, 3), bytearray(32), bytearray(0), self.cipher_suite) verifierDB = VerifierDB() verifierDB.create() entry = verifierDB.makeVerifier('user', 'password', 2048) verifierDB['user'] = entry self.keyExchange = SRPKeyExchange(self.cipher_suite, self.client_hello, self.server_hello, self.srv_private_key, verifierDB)
def test_process_with_ECDHE_RSA(self): exp = ExpectServerKeyExchange() state = ConnectionState() state.cipher = CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA cert = Certificate(CertificateType.x509).\ create(X509CertChain([X509().parse(srv_raw_certificate)])) private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() client_hello.client_version = (3, 3) client_hello.random = bytearray(32) client_hello.extensions = [ SignatureAlgorithmsExtension().create([(HashAlgorithm.sha256, SignatureAlgorithm.rsa)]), SupportedGroupsExtension().create([GroupName.secp256r1]) ] state.client_random = client_hello.random state.handshake_messages.append(client_hello) server_hello = ServerHello() server_hello.server_version = (3, 3) server_hello.random = bytearray(32) state.server_random = server_hello.random # server hello is not necessary for the test to work #state.handshake_messages.append(server_hello) state.handshake_messages.append(cert) srv_key_exchange = ECDHE_RSAKeyExchange( CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, client_hello, server_hello, private_key, [GroupName.secp256r1]) msg = srv_key_exchange.makeServerKeyExchange('sha256') exp.process(state, msg)
def test_server_with_client_proposing_SHA256_on_TLSv1_1(self): gen_sock = MockSocket(bytearray(0)) gen_record_layer = RecordLayer(gen_sock) gen_record_layer.version = (3, 0) ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, 0x88, # TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] client_hello = ClientHello().create(version=(3, 2), random=bytearray(32), session_id=bytearray(0), cipher_suites=ciphers) for res in gen_record_layer.sendRecord(client_hello): if res in (0, 1): self.assertTrue(False, "Blocking socket") else: break # test proper sock = MockSocket(gen_sock.sent[0]) conn = TLSConnection(sock) srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) with self.assertRaises(TLSLocalAlert) as err: conn.handshakeServer(certChain=srv_cert_chain, privateKey=srv_private_key) self.assertEqual(err.exception.description, AlertDescription.handshake_failure)
def test_process_with_not_matching_signature_algorithms(self): exp = ExpectServerKeyExchange(valid_sig_algs=[(HashAlgorithm.sha256, SignatureAlgorithm.rsa)]) state = ConnectionState() state.cipher = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA cert = Certificate(CertificateType.x509).\ create(X509CertChain([X509().parse(srv_raw_certificate)])) private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() client_hello.client_version = (3, 3) client_hello.random = bytearray(32) state.client_random = client_hello.random state.handshake_messages.append(client_hello) server_hello = ServerHello() server_hello.server_version = (3, 3) server_hello.random = bytearray(32) state.server_random = server_hello.random # server hello is not necessary for the test to work #state.handshake_messages.append(server_hello) state.handshake_messages.append(cert) srv_key_exchange = DHE_RSAKeyExchange(\ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, client_hello, server_hello, private_key) msg = srv_key_exchange.makeServerKeyExchange('sha1') with self.assertRaises(TLSIllegalParameterException): exp.process(state, msg)
def test_process_with_rcf7919_groups_required_not_provided(self): exp = ExpectServerKeyExchange(valid_groups=[256]) state = ConnectionState() state.cipher = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA cert = Certificate(CertificateType.x509).\ create(X509CertChain([X509().parse(srv_raw_certificate)])) private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() client_hello.client_version = (3, 3) client_hello.random = bytearray(32) client_hello.extensions = [SupportedGroupsExtension().create([256])] state.client_random = client_hello.random state.handshake_messages.append(client_hello) server_hello = ServerHello() server_hello.server_version = (3, 3) server_hello.random = bytearray(32) state.server_random = server_hello.random # server hello is not necessary for the test to work #state.handshake_messages.append(server_hello) state.handshake_messages.append(cert) srv_key_exchange = DHE_RSAKeyExchange(\ CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, client_hello, server_hello, private_key, dhGroups=None) msg = srv_key_exchange.makeServerKeyExchange('sha1') with self.assertRaises(AssertionError): exp.process(state, msg)
def setUp(self): self.srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.srv_pub_key = srv_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA self.client_hello = ClientHello().create((3, 3), bytearray(32), bytearray(0), [], srpUsername=bytearray(b'user') ) self.server_hello = ServerHello().create((3, 3), bytearray(32), bytearray(0), self.cipher_suite) verifierDB = VerifierDB() verifierDB.create() entry = verifierDB.makeVerifier('user', 'password', 2048) verifierDB[b'user'] = entry self.keyExchange = SRPKeyExchange(self.cipher_suite, self.client_hello, self.server_hello, self.srv_private_key, verifierDB)
def test_signServerKeyExchange_with_sha1_in_TLS1_2(self): def m(leght): return bytearray(leght) with mock.patch('tlslite.utils.rsakey.getRandomBytes', m): srv_private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA server_hello = ServerHello().create((3, 3), bytearray(32), bytearray(0), cipher_suite) keyExchange = KeyExchange(cipher_suite, client_hello, server_hello, srv_private_key) server_key_exchange = ServerKeyExchange(cipher_suite, (3, 3)) \ .createDH(5, 2, 3) keyExchange.clientHello.random = bytearray(len(keyExchange.clientHello.random)) keyExchange.serverHello.random = bytearray(len(keyExchange.clientHello.random)) getRandomBytes = mock.Mock( return_value=bytearray(b'0')) keyExchange.signServerKeyExchange(server_key_exchange, 'rsa_pss_sha256') print(repr(server_key_exchange.signature)) self.assertEqual(server_key_exchange.signature,bytearray(b'E\xae\x8e\xbe~RU\n\xab4\x8e\x10y\x94\x01\xdfVr\x8b\x03\xa4\xb7\x9dI\xf1\xb7\x16\xfa\xa0-\x9a\x16^pZ\x979\xc2&\xa5\xfcU\x9a"\xc7~u\x1e_y\xc1w\x91\x98L\x10\xb4\xed\x103\xdf\xac\xba\x19Q\x0e\x8an\x13\x99\x8d1\x17XK\x9a\x00\xcdno\xc7\xae\x92:pU\xf8\xfbl\xeeg\xe0s\x03\xc8\xcb\xe5\xc4\xb9z\xcf\nv\xca\x80`\xbe\xc9\x85\xcfM\x89\xaeE\xf0\xa1\xd8`\x99\x93\xa0Bp\x1cwW\xce\x8e'))
def test_rsa_key_parse_with_new_lines_using_openssl(self): key = parsePEMKey(self.privRSAKey_str_newLines, private=True, implementations=["openssl"]) self.assertIsInstance(key, RSAKey) self.assertEqual(1024, len(key)) self.assertTrue(key.hasPrivateKey())
def test_rsa_pss_key_parse_using_python(self): key = parsePEMKey(self.privRSAPSSKey_str, private=True, implementations=["python"]) self.assertIsInstance(key, RSAKey) self.assertEqual(1024, len(key)) self.assertTrue(key.hasPrivateKey())
def signWithPEM(self, data, key_file): file = open(os.path.join(self.key_location,key_file)) pem = file.read() file.close() key = keyfactory.parsePEMKey(pem, private=True) signature = key.hashAndSign(compat.stringToBytes(data)) return cryptomath.bytesToBase64(signature)
def check_signature(self, oauth_request, consumer, token, signature): decoded_sig = base64.b64decode(signature) base_string = self.build_signature_base_string(oauth_request, consumer, token) # Fetch the public key cert based on the request cert = self._fetch_public_cert(oauth_request) # Pull the public key from the certificate publickey = keyfactory.parsePEMKey(cert, public=True) # Check the signature valid = publickey.hashAndVerify(decoded_sig, base_string) return valid
def test_rsa_pss_key_parse_using_openssl(self): try: key = parsePEMKey(self.privRSAPSSKey_str, private=True, implementations=["openssl"]) except SyntaxError: self.fail("Unexpected exception raised") self.assertIsInstance(key, RSAKey) self.assertEqual(1024, len(key)) self.assertTrue(key.hasPrivateKey())
def test_key_parse_using_openssl(self): # XXX doesn't handle files without newlines # old version of M2Crypto return a Null, in Python3 it raises exception if M2Crypto.version_info >= (0, 28, 0): exp = M2Crypto.EVP.EVPError else: exp = SyntaxError with self.assertRaises(exp): key = parsePEMKey(self.privKey_str, private=True, implementations=["openssl"])
def hs_parse_client_key_exchange(self, ssl_convo, record, handshake, bytes): """Parse ClientKeyExchange handshake message.""" # TODO: Where the heck did these 2 extra bytes come from? ssl_convo.encrypted_pre_master_secret = bytes[2:] if ssl_convo.suite_props['key_exchange'] == 'RSA': private_key = self.cfg.get('ssl', 'private_key') rsa_key = parsePEMKey(open(private_key).read()) array = byteArray(bytes[2:]) ssl_convo.pre_master_secret = rsa_key.decrypt(array) assert len(ssl_convo.pre_master_secret) == 48 else: pass # TODO: Something. Logging.
def check_signature(self, oauth_request, consumer, token, signature): decoded_sig = base64.b64decode(signature) key, base_string = self.build_signature_base_string( oauth_request, consumer, token) # Fetch the public key cert based on the request cert = self._fetch_public_cert(oauth_request) # Pull the public key from the certificate publickey = keyfactory.parsePEMKey(cert, public=True) # Check the signature ok = publickey.hashAndVerify(decoded_sig, base_string) return ok
def setUp(self): self.srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.srv_pub_key = srv_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA self.client_hello = ClientHello().create((3, 3), bytearray(32), bytearray(0), []) self.server_hello = ServerHello().create((3, 3), bytearray(32), bytearray(0), self.cipher_suite) self.keyExchange = DHE_RSAKeyExchange(self.cipher_suite, self.client_hello, self.server_hello, self.srv_private_key)
def setUp(self): self.srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.srv_pub_key = srv_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA self.client_hello = ClientHello().create((3, 3), bytearray(32), bytearray(0), []) self.server_hello = ServerHello().create((3, 2), bytearray(32), bytearray(0), self.cipher_suite) self.keyExchange = RSAKeyExchange(self.cipher_suite, self.client_hello, self.server_hello, self.srv_private_key)
def test_signServerKeyExchange_in_TLS1_1(self): srv_private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA server_hello = ServerHello().create((3, 2), bytearray(32), bytearray(0), cipher_suite) keyExchange = KeyExchange(cipher_suite, client_hello, server_hello, srv_private_key) server_key_exchange = ServerKeyExchange(cipher_suite, (3, 2))\ .createDH(5, 2, 3) keyExchange.signServerKeyExchange(server_key_exchange) self.assertEqual(server_key_exchange.write(), self.expected_tls1_1_SKE)
def test_signServerKeyExchange_in_TLS1_1_signature_invalid(self): srv_private_key = parsePEMKey(srv_raw_key, private=True) client_hello = ClientHello() cipher_suite = CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA server_hello = ServerHello().create((3, 2), bytearray(32), bytearray(0), cipher_suite) keyExchange = KeyExchange(cipher_suite, client_hello, server_hello, srv_private_key) server_key_exchange = ServerKeyExchange(cipher_suite, (3, 2)) \ .createDH(5, 2, 3) with self.assertRaises(TLSInternalError): keyExchange.privateKey.sign = mock.Mock( return_value=bytearray(b'wrong')) keyExchange.signServerKeyExchange(server_key_exchange)
def setUp(self): self.srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_chain = X509CertChain([X509().parse(srv_raw_certificate)]) self.srv_pub_key = srv_chain.getEndEntityPublicKey() self.cipher_suite = CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ext = [SupportedGroupsExtension().create([GroupName.secp256r1])] self.client_hello = ClientHello().create((3, 3), bytearray(32), bytearray(0), [], extensions=ext) self.server_hello = ServerHello().create((3, 3), bytearray(32), bytearray(0), self.cipher_suite) self.keyExchange = ECDHE_RSAKeyExchange(self.cipher_suite, self.client_hello, self.server_hello, self.srv_private_key, [GroupName.secp256r1])
def test_server_with_client_not_using_required_EMS(self): gen_sock = MockSocket(bytearray(0)) gen_record_layer = RecordLayer(gen_sock) gen_record_layer.version = (3, 0) ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] client_hello = ClientHello().create(version=(3, 3), random=bytearray(32), session_id=bytearray(0), cipher_suites=ciphers) for res in gen_record_layer.sendRecord(client_hello): if res in (0, 1): self.assertTrue(False, "Blocking socket") else: break # test proper sock = MockSocket(gen_sock.sent[0]) conn = TLSConnection(sock) hs = HandshakeSettings() hs.requireExtendedMasterSecret = True srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) with self.assertRaises(TLSLocalAlert) as err: conn.handshakeServer(certChain=srv_cert_chain, privateKey=srv_private_key, settings=hs) self.assertEqual(err.exception.description, AlertDescription.insufficient_security)
def test_server_with_client_not_using_required_EMS(self): gen_sock = MockSocket(bytearray(0)) gen_record_layer = RecordLayer(gen_sock) gen_record_layer.version = (3, 0) ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] client_hello = ClientHello().create(version=(3, 3), random=bytearray(32), session_id=bytearray(0), cipher_suites=ciphers) for res in gen_record_layer.sendRecord(client_hello): if res in (0, 1): self.assertTrue(False, "Blocking socket") else: break # test proper sock = MockSocket(gen_sock.sent[0]) conn = TLSConnection(sock) hs = HandshakeSettings() hs.requireExtendedMasterSecret = True srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) with self.assertRaises(TLSLocalAlert) as err: conn.handshakeServer(certChain=srv_cert_chain, privateKey=srv_private_key, settings=hs) self.assertEqual(err.exception.description, AlertDescription.insufficient_security)
def main(): """Check that server propoerly rejects pkcs1 signatures in TLS 1.3""" hostname = "localhost" port = 4433 num_limit = None run_exclude = set() expected_failures = {} last_exp_tmp = None cert = None private_key = None # algorithms to expect from server in Certificate Request cr_sigalgs = [ SignatureScheme.ecdsa_secp521r1_sha512, SignatureScheme.ecdsa_secp384r1_sha384, SignatureScheme.ecdsa_secp256r1_sha256, (HashAlgorithm.sha224, SignatureAlgorithm.ecdsa), (HashAlgorithm.sha1, SignatureAlgorithm.ecdsa), SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha512, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pkcs1_sha512, SignatureScheme.rsa_pkcs1_sha384, SignatureScheme.rsa_pkcs1_sha256, SignatureScheme.rsa_pkcs1_sha224, SignatureScheme.rsa_pkcs1_sha1 ] # algorithms to advertise in ClientHello sig_algs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_pss_sha384 ] hashalgs = hashes_to_list("sha256 sha384 sha512") argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:n:s:k:c:", ["help", "hash-order="]) 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 == '--help': help_msg() sys.exit(0) elif opt == '-s': cr_sigalgs = sig_algs_to_ids(arg) elif opt == '--hash-order': hashalgs = hashes_to_list(arg) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None if not cert or not private_key: raise Exception("A Client certificate and a private key are required") certType = cert.certAlg conversations = {} conversations_long = {} # sanity check for Client Certificates conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(CertificateVerifyGenerator(private_key)) 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 # verify the advertised hashes conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest(cr_sigalgs)) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator()) 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["check sigalgs in cert request"] = conversation for sigalg in RSA_SIG_ALL: # set if test should succeed or fail based on cert type, # advertisement and forbidden algorithms expectPass = True if certType == "rsa" and sigalg in ( SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512): expectPass = False elif certType == "rsa-pss" and sigalg in ( SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512): expectPass = False # also verify that pkcs1 signatures are unconditionally refused if sigalg in ((HashAlgorithm.md5, SignatureAlgorithm.rsa), SignatureScheme.rsa_pkcs1_sha1, SignatureScheme.rsa_pkcs1_sha224, SignatureScheme.rsa_pkcs1_sha256, SignatureScheme.rsa_pkcs1_sha384, SignatureScheme.rsa_pkcs1_sha512): expectPass = False # also expect failure if an algorithm is not advertized if sigalg not in cr_sigalgs: expectPass = False conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) # force sigalg node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=sigalg)) node = node.add_child(FinishedGenerator()) result = "works" # only signatures of matching certificate type should work if expectPass: 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() else: node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) node.add_child(ExpectClose()) result = "is refused" conversations["check {0} signature {1}".format( SignatureScheme.toStr(sigalg), result)] = conversation # verify that rsa-pss signatures with empty, too short or too long # salt fail msgalg = sigalg_select("rsa_pss", hashalgs, cr_sigalgs, certType) hash_name = SignatureScheme.getHash(SignatureScheme.toRepr(msgalg)) digest_len = getattr(tlshashlib, hash_name)().digest_size for saltlen in (0, digest_len - 1, digest_len + 1): conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) # force salt length node = node.add_child( CertificateVerifyGenerator(private_key, rsa_pss_salt_len=saltlen)) node = node.add_child(FinishedGenerator()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node.add_child(ExpectClose()) conversations["check signature with salt length {0}".format( saltlen)] = conversation # verify that a rsa-pkcs1 signature in a rsa-pss ID envelope fails sigalg = sigalg_select("rsa_pkcs1", hashalgs) msgalg = sigalg_select("rsa_pss", hashalgs, cr_sigalgs, certType) conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child( CertificateVerifyGenerator(private_key, sig_alg=sigalg, msg_alg=msgalg)) node = node.add_child(FinishedGenerator()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node.add_child(ExpectClose()) scheme = SignatureScheme.toRepr(sigalg) conversations["check pkcs1 signature with rsa-pss envelope fails"] = \ conversation # verify that a rsa-pss signature with mismatched message hash fails msgalg = sigalg_select("rsa_pss", hashalgs, cr_sigalgs, certType) # choose a similar scheme with just a different hash, doesn't need to be # a server supported sigalg hash_name = SignatureScheme.getHash(SignatureScheme.toRepr(msgalg)) _hashalgs = [x for x in hashalgs if x != hash_name] sigalg = sigalg_select("rsa_pss", _hashalgs, cert_type=certType) conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child( CertificateVerifyGenerator(private_key, sig_alg=sigalg, msg_alg=msgalg)) node = node.add_child(FinishedGenerator()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node.add_child(ExpectClose()) conversations["check rsa-pss signature with mismatched hash fails"] = \ conversation # verify that a rsa-pss signature with mismatched MGF1 hash fails sigalg = sigalg_select("rsa_pss", hashalgs, cr_sigalgs, certType) # choose a different hash to cause mismtach hash_name = SignatureScheme.getHash(SignatureScheme.toRepr(msgalg)) mgf1_hash = [x for x in hashalgs if x != hash_name][0] conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child( CertificateVerifyGenerator(private_key, mgf1_hash=mgf1_hash, msg_alg=sigalg)) node = node.add_child(FinishedGenerator()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node.add_child(ExpectClose()) conversations["check rsa-pss signature with mismatched mgf1 fails"] = \ conversation # check that fuzzed signatures are rejected for pos in range(numBytes(private_key.n)): for xor in [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]: conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_AES_128_GCM_SHA256, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = {} groups = [GroupName.secp256r1] ext[ExtensionType.key_share] = key_share_ext_gen(groups) ext[ExtensionType.supported_versions] = \ SupportedVersionsExtension().create([(3, 4), (3, 3)]) ext[ExtensionType.supported_groups] = \ SupportedGroupsExtension().create(groups) 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(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child( CertificateVerifyGenerator(private_key, padding_xors={pos: xor})) node = node.add_child(FinishedGenerator()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node.add_child(ExpectClose()) scheme = SignatureScheme.toRepr(sigalg) conversations_long["check that fuzzed signatures are rejected." + " Malformed {0} - xor {1} at {2}".format( certType, hex(xor), pos)] = conversation # run the conversation good = 0 bad = 0 xfail = 0 xpass = 0 failed = [] xpassed = [] if not num_limit: num_limit = len(conversations_long) # 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'])] short_tests = [(k, v) for k, v in conversations.items() if k != 'sanity'] long_tests = list(conversations_long.items()) long_sampled_tests = sample(long_tests, min(num_limit, len(long_tests))) regular_tests = sample(long_sampled_tests + short_tests, len(long_sampled_tests) + len(short_tests)) ordered_tests = chain(sanity_tests, regular_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("Test to verify that server properly accepts or refuses") print("signatures in TLS1.3; PKCS1 signatures are always refused.") print("Other signatures are accepted or refused accordingly to") print("the certificate type provided ('rsa' vs 'rsa-pss').\n") print("version: {0}\n".format(version)) print("Test end") print(20 * '=') print("TOTAL: {0}".format(len(regular_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(): """Check if malformed signatures in Certificate Verify are rejected""" host = "localhost" port = 4433 num_limit = None run_exclude = set() private_key = None cert = None argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:n:k:c:", ["help"]) 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 == '-n': num_limit = int(arg) elif opt == '--help': help_msg() sys.exit(0) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") if args: run_only = set(args) else: run_only = None conversations = {} # sanity check for Client Certificates sanity_hash_alg = ("sha1", "sha256") for hash_alg in sanity_hash_alg: conversation = Connect(host, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']]), ExtensionType.signature_algorithms_cert : SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL)} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) sig_type = (getattr(HashAlgorithm, hash_alg), SignatureAlgorithm.rsa) node = node.add_child(CertificateVerifyGenerator(private_key, msg_alg=sig_type )) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity - {0}".format(hash_alg)] = conversation # place SHA-1 sig with SHA-256 indicator conversation = Connect(host, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']]), ExtensionType.signature_algorithms_cert : SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL)} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) sig_type = (HashAlgorithm.sha1, SignatureAlgorithm.rsa) msg_type = (HashAlgorithm.sha256, SignatureAlgorithm.rsa) node = node.add_child(CertificateVerifyGenerator(private_key, msg_alg=msg_type, sig_alg=sig_type )) # the other side can close connection right away, add options to handle it node.next_sibling = ExpectClose() node = node.add_child(ChangeCipherSpecGenerator()) node.next_sibling = ExpectClose() node = node.add_child(FinishedGenerator()) node.next_sibling = ExpectClose() # we expect closure or Alert and then closure of socket node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["SHA-1 signature in SHA-256 envelope"] = conversation # because the TLSv1.1 signatures are concatenation of MD5 and SHA1 # implementation that just checks the hash, without verifying the Hash # Info structure in signature, will accept a TLSv1.1 signature # in a TLSv1.2 SHA-1 envelope conversation = Connect(host, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']]), ExtensionType.signature_algorithms_cert : SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL)} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) msg_alg = (HashAlgorithm.sha1, SignatureAlgorithm.rsa) node = node.add_child(CertificateVerifyGenerator(private_key, msg_alg=msg_alg, sig_version=(3, 2) )) # the other side can close connection right away, add options to handle it node.next_sibling = ExpectClose() node = node.add_child(ChangeCipherSpecGenerator()) node.next_sibling = ExpectClose() node = node.add_child(FinishedGenerator()) node.next_sibling = ExpectClose() # we expect closure or Alert and then closure of socket node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["TLSv1.1 signature in SHA-1 TLSv1.2 envelope"] = conversation # run the conversation good = 0 bad = 0 failed = [] 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 throught sanity_tests = [] for hash_alg in sanity_hash_alg: sanity_test_name = 'sanity - {0}'.format(hash_alg) sanity_tests.append((sanity_test_name, conversations[sanity_test_name])) ordered_tests = chain(sanity_tests, islice(filter(lambda x: not 'sanity' in x[0], conversations.items()), num_limit), 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 try: runner.run() except Exception: print("Error while processing") print(traceback.format_exc()) res = False if res: good += 1 print("OK\n") else: bad += 1 failed.append(c_name) print("CertificateVerify malformed signatures test version 1\n") 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(): """check if obsolete signature algorithm is rejected by server""" conversations = {} hostname = "localhost" port = 4433 run_exclude = set() private_key = None cert = None argv = sys.argv[1:] opts, argv = getopt.getopt(argv, "h:p:e:k:c:", ["help"]) for opt, arg in opts: if opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) elif opt == '-h': host = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '--help': help_msg() sys.exit(0) else: raise ValueError("Unknown option: {0}".format(opt)) if argv: run_only = set(argv) else: run_only = None if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity"] = conversation for prf in ['sha256', 'sha384']: for md in ['sha1', 'sha256', 'sha384', 'sha512']: conversation = Connect(hostname, port) node = conversation if prf == 'sha256': ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=(getattr(HashAlgorithm, md), SignatureAlgorithm.rsa))) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator( AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["check {0} w/{1} PRF".format(md, prf)] = \ conversation # run the conversation good = 0 bad = 0 failed = [] print("Certificate Verify test version 4") 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 #because we don't want to abort the testing and we are reporting #the errors to the user, using a bare except is OK #pylint: disable=bare-except try: runner.run() except: print("Error while processing") print(traceback.format_exc()) res = False #pylint: enable=bare-except if res: good += 1 print("OK\n") 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(): """Check if malformed messages related to client certs are rejected.""" conversations = {} host = "localhost" port = 4433 run_exclude = set() private_key = None cert = None argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:k:c:", ["help"]) 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 == '--help': help_msg() sys.exit(0) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") if args: run_only = set(args) else: run_only = None # sanity check for Client Certificates conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity"] = conversation # sanity check for no client certificate conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(None)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity - no client cert"] = conversation for i in range(1, 0x100): conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child( fuzz_message(CertificateGenerator(X509CertChain([cert])), xors={7: i})) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decode_error)) node = node.add_child(ExpectClose()) conversations["fuzz certificates length with {0}".format( i)] = conversation for i in range(1, 0x100): conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child( fuzz_message(CertificateGenerator(X509CertChain([cert])), xors={9: i})) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decode_error)) node = node.add_child(ExpectClose()) conversations["fuzz first certificate length with {0}".format( i)] = conversation # fuzz empty certificates message for i in range(1, 0x100): conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child( fuzz_message(CertificateGenerator(None), xors={-1: i})) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decode_error)) node = node.add_child(ExpectClose()) conversations["fuzz empty certificates length - {0}".format( i)] = conversation # sanity check for no client certificate conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) # technically, it's an invalid encoding as the items are defined as # <1..2^24-1>, but some implementations, like OpenSSL, accept it; # don't be too precise for now msg = CertificateGenerator() msg = pad_handshake(msg, 3) msg = fuzz_message(msg, substitutions={-4: 3}) node = node.add_child(msg) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child(ExpectChangeCipherSpec()) # if the implementation is proper, it will reject the message node.next_sibling = ExpectAlert(AlertLevel.fatal, AlertDescription.decode_error) node.next_sibling.add_child(ExpectClose()) node = node.add_child(ExpectFinished()) node = node.add_child(ApplicationDataGenerator(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity - empty client cert"] = conversation # fuzz empty certificate message for i, j, k in ((i, j, k) for i in range(8) for j in range(8) for k in range(6)): if i == 3 and j == 0 or k == 0 and i == 0: continue conversation = Connect(host, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) msg = CertificateGenerator() msg = pad_handshake(msg, k) subs = {6: i} if k >= 3: subs[9] = j msg = fuzz_message(msg, substitutions=subs) node = node.add_child(msg) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decode_error)) node = node.add_child(ExpectClose()) conversations[ "fuzz empty certificate - overall {2}, certs {0}, cert {1}".format( i, j, k + 3)] = 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\n") else: bad += 1 failed.append(c_name) print("Malformed Certificate test version 1\n") 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 setUpClass(cls): cls.cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) cls.certKey = parsePEMKey(srv_raw_key, private=True)
def main(): host = "localhost" port = 4433 num_limit = 15 run_exclude = set() expected_failures = {} last_exp_tmp = None private_key = None cert = None exp_illeg_param = False sigalgs = [ SignatureScheme.ecdsa_secp521r1_sha512, SignatureScheme.ecdsa_secp384r1_sha384, SignatureScheme.ecdsa_secp256r1_sha256, (HashAlgorithm.sha224, SignatureAlgorithm.ecdsa), (HashAlgorithm.sha1, SignatureAlgorithm.ecdsa), SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha512, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa) ] argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:n:k:c:s:", ["help", "illegpar"]) for opt, arg in opts: if opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True, implementations=["python"]) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) elif opt == '-s': sigalgs = sig_algs_to_ids(arg) elif 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 == '--illegpar': exp_illeg_param = 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 if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") conversations = {} conversations_long = {} conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa) ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) algs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] node = node.add_child(ExpectServerKeyExchange(valid_sig_algs=algs)) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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() node = node.add_child(ExpectClose()) conversations["sanity"] = conversation # check if RSA-PSS can be the only one conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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() node = node.add_child(ExpectClose()) conversations["RSA-PSS only"] = conversation # check if algs in CertificateRequest are expected conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest(sig_algs=sigalgs)) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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() node = node.add_child(ExpectClose()) conversations["check CertificateRequest sigalgs"] = conversation if cert.certAlg == "rsa": schemes = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512 ] invalid_schemes = [ SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] else: schemes = [ SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] invalid_schemes = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512 ] for scheme in invalid_schemes: conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=scheme)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) if exp_illeg_param: node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) else: node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations["{0} in CertificateVerify with {1} key".format( SignatureScheme.toRepr(scheme), cert.certAlg)] = conversation # check if CertificateVerify can be signed with any algorithm for scheme in schemes: conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator(private_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( 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() node = node.add_child(ExpectClose()) conversations["{0} in CertificateVerify with {1} key".format( SignatureScheme.toRepr(scheme), cert.certAlg)] = conversation # check if CertificateVerify with wrong salt size is rejected for scheme in schemes: conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=scheme, rsa_pss_salt_len=20)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations[ "{0} in CertificateVerify with incorrect salt len".format( SignatureScheme.toRepr(scheme))] = conversation # check if CertificateVerify with wrong salt size is rejected for pos in range(numBytes(private_key.n)): for xor in [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]: conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) if cert.certAlg == "rsa": scheme = SignatureScheme.rsa_pss_rsae_sha256 else: scheme = SignatureScheme.rsa_pss_pss_sha256 node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=scheme, padding_xors={pos: xor})) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations_long[ "malformed {0} in CertificateVerify - xor {1} at {2}".format( cert.certAlg, hex(xor), pos)] = conversation if cert.certAlg == "rsa-pss": conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator( private_key, msg_alg=SignatureScheme.rsa_pkcs1_sha256, sig_alg=SignatureScheme.rsa_pkcs1_sha256)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) if exp_illeg_param: node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) else: node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations["rsa_pkcs1_sha256 signature in CertificateVerify " "with rsa-pss key"] = conversation conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) if cert.certAlg == "rsa": sig_alg = SignatureScheme.rsa_pss_rsae_sha256 else: sig_alg = SignatureScheme.rsa_pss_pss_sha256 node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=SignatureScheme.rsa_pkcs1_sha256, sig_alg=sig_alg)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) if exp_illeg_param and cert.certAlg != "rsa": node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter)) else: # with rsaEncryption key in certificate, there is nothing the TLS # layer can inspect to decide if the signature is valid before actually # verifying it # for rsassa-pss, rsa_pkcs1 signature is illegal node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations[ "{0} signature in CertificateVerify with rsa_pkcs1_sha256 id".format( SignatureScheme.toRepr(sig_alg))] = conversation conversation = Connect(host, port) node = conversation sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512 ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), 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 ] node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(TCPBufferingEnable()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) if cert.certAlg == "rsa": scheme = SignatureScheme.rsa_pss_rsae_sha256 else: scheme = SignatureScheme.rsa_pss_pss_sha256 sig = bytearray(b'\xfa\xbc\x0f\x4c') node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=scheme, signature=sig)) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(TCPBufferingDisable()) node = node.add_child(TCPBufferingFlush()) node = node.add_child( ExpectAlert(AlertLevel.fatal, AlertDescription.decrypt_error)) node = node.add_child(ExpectClose()) conversations["short sig with {0} id".format( SignatureScheme.toRepr(scheme))] = conversation # run the conversation good = 0 bad = 0 xfail = 0 xpass = 0 failed = [] xpassed = [] if not num_limit: num_limit = len(conversations_long) # 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) long_tests = [(k, v) for k, v in conversations_long.items() if k in run_only] short_tests = [(k, v) for k, v in conversations.items() if (k != 'sanity') and k in run_only] else: long_tests = [(k, v) for k, v in conversations_long.items() if k not in run_exclude] short_tests = [(k, v) for k, v in conversations.items() if (k != 'sanity') and k not in run_exclude] sampled_tests = sample(long_tests, min(num_limit, len(long_tests))) ordered_tests = chain(sanity_tests, short_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("Check handling of rsa-pss signatures") print("Test should be run twice, once with certificate with") print("rsaEncryption key and once with certificate with rsassa-pss key.") print("Implementations that inspect certificate type and check signature") print("scheme in CertificateVerify before verifying signature need to use") print("--illegpar option") print("Test end") print(20 * '=') print("version: {0}".format(version)) print(20 * '=') print("TOTAL: {0}".format( len(sampled_tests) + len(short_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 validate_signature(self, signature): decoded_sig = base64.b64decode(signature) publickey = keyfactory.parsePEMKey(self.public_cert, public=True) if not publickey.hashAndVerify(decoded_sig, self.base_string): raise OAuthError('Invalid Signature')
def test_rsa_key_parse_using_openssl(self): # XXX doesn't handle files without newlines with self.assertRaises(SyntaxError): key = parsePEMKey(self.privRSAKey_str, private=True, implementations=["openssl"])
def __init__(self, rsa_key, token_string=None, scopes=None): self.rsa_key = keyfactory.parsePEMKey(rsa_key) self.token_string = token_string or '' self.scopes = scopes or []
def test_with_missing_m2crypto(self): with self.assertRaises(ValueError): key = parsePEMKey(self.privKey_str, private=True, implementations=["openssl"])
def main(): """Check if malformed signatures in Certificate Verify are rejected""" conversations = {} hostname = "localhost" port = 4433 argv = sys.argv[1:] if len(argv) != 4: raise ValueError("You need to specify key (-k file.pem) and " "certificate (-c file.pem)") opts, argv = getopt.getopt(argv, "k:c:") for opt, arg in opts: if opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) if opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") # sanity check for Client Certificates for hash_alg in ("sha1", "sha256"): conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) sig_type = (getattr(HashAlgorithm, hash_alg), SignatureAlgorithm.rsa) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=sig_type)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["Sanity check - {0}".format(hash_alg)] = conversation # place SHA-1 sig with SHA-256 indicator conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) sig_type = (HashAlgorithm.sha1, SignatureAlgorithm.rsa) msg_type = (HashAlgorithm.sha256, SignatureAlgorithm.rsa) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=msg_type, sig_alg=sig_type)) # the other side can close connection right away, add options to handle it node.next_sibling = ExpectClose() node = node.add_child(ChangeCipherSpecGenerator()) node.next_sibling = ExpectClose() node = node.add_child(FinishedGenerator()) node.next_sibling = ExpectClose() # we expect closure or Alert and then closure of socket node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["SHA-1 signature in SHA-256 envelope"] = conversation # because the TLSv1.1 signatures are concatenation of MD5 and SHA1 # implementation that just checks the hash, without verifying the Hash # Info structure in signature, will accept a TLSv1.1 signature # in a TLSv1.2 SHA-1 envelope conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) msg_alg = (HashAlgorithm.sha1, SignatureAlgorithm.rsa) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=msg_alg, sig_version=(3, 2))) # the other side can close connection right away, add options to handle it node.next_sibling = ExpectClose() node = node.add_child(ChangeCipherSpecGenerator()) node.next_sibling = ExpectClose() node = node.add_child(FinishedGenerator()) node.next_sibling = ExpectClose() # we expect closure or Alert and then closure of socket node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["TLSv1.1 signature in SHA-1 TLSv1.2 envelope"] = conversation # run the conversation good = 0 bad = 0 print("CertificateVerify malformed signatures test version 1") for conversation_name in conversations: conversation = conversations[conversation_name] print(conversation_name + "...") runner = Runner(conversation) res = True #because we don't want to abort the testing and we are reporting #the errors to the user, using a bare except is OK #pylint: disable=bare-except try: runner.run() except: print("Error while processing") print(traceback.format_exc()) res = False #pylint: enable=bare-except if res: good += 1 print("OK") else: bad += 1 print("Test end") print("successful: {0}".format(good)) print("failed: {0}".format(bad)) if bad > 0: sys.exit(1)
def main(): """Check if EMS with client certificates is supported""" hostname = "localhost" port = 4433 run_exclude = set() sigalgs = [(HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa)] cert = None private_key = None argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:s:k:c:", ["help"]) for opt, arg in opts: if opt == '-h': hostname = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '--help': help_msg() sys.exit(0) elif opt == '-s': sigalgs = sig_algs_to_ids(arg) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} # sanity check for Client Certificates conversation = Connect(hostname, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']])} ext[ExtensionType.extended_master_secret] = None node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = {ExtensionType.renegotiation_info:None, ExtensionType.extended_master_secret:None} node = node.add_child(ExpectServerHello(version=(3, 3), extensions=ext)) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator()) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity"] = conversation if cert and private_key: # sanity check for Client Certificates conversation = Connect(hostname, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']])} ext[ExtensionType.extended_master_secret] = None node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = {ExtensionType.renegotiation_info:None, ExtensionType.extended_master_secret:None} node = node.add_child(ExpectServerHello(version=(3, 3), extensions=ext)) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["with certificate"] = conversation # resume session with client certificates conversation = Connect(hostname, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']])} ext[ExtensionType.extended_master_secret] = None node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = {ExtensionType.renegotiation_info:None, ExtensionType.extended_master_secret:None} node = node.add_child(ExpectServerHello(version=(3, 3), extensions=ext)) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectAlert()) close = ExpectClose() node.next_sibling = close node = node.add_child(ExpectClose()) node = node.add_child(Close()) node = node.add_child(Connect(hostname, port)) close.add_child(node) node = node.add_child(ResetHandshakeHashes()) node = node.add_child(ResetRenegotiationInfo()) ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']])} ext[ExtensionType.extended_master_secret] = None ext[ExtensionType.renegotiation_info] = None node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = {ExtensionType.renegotiation_info:None, ExtensionType.extended_master_secret:None} node = node.add_child(ExpectServerHello(version=(3, 3), extensions=ext, resume=True)) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) 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() node.add_child(Close()) conversations["resume with certificate and EMS"] = 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\n") else: bad += 1 failed.append(c_name) print("Test to verify if server supports extended master secret with ") print("client certificates.\n") print("Test version 1\n") 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 test_full_connection_with_RSA_kex(self): clnt_sock, srv_sock = socket.socketpair() # # client part # record_layer = TLSRecordLayer(clnt_sock) record_layer._handshakeStart(client=True) record_layer.version = (3, 3) client_hello = ClientHello() client_hello = client_hello.create( (3, 3), bytearray(32), bytearray(0), [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA], None, None, False, False, None, ) for result in record_layer._sendMsg(client_hello): if result in (0, 1): raise Exception("blocking socket") # # server part # srv_record_layer = TLSRecordLayer(srv_sock) srv_raw_certificate = str( "-----BEGIN CERTIFICATE-----\n" "MIIB9jCCAV+gAwIBAgIJAMyn9DpsTG55MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV\n" "BAMMCWxvY2FsaG9zdDAeFw0xNTAxMjExNDQzMDFaFw0xNTAyMjAxNDQzMDFaMBQx\n" "EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\n" "0QkEeakSyV/LMtTeARdRtX5pdbzVuUuqOIdz3lg7YOyRJ/oyLTPzWXpKxr//t4FP\n" "QvYsSJiVOlPk895FNu6sNF/uJQyQGfFWYKkE6fzFifQ6s9kssskFlL1DVI/dD/Zn\n" "7sgzua2P1SyLJHQTTs1MtMb170/fX2EBPkDz+2kYKN0CAwEAAaNQME4wHQYDVR0O\n" "BBYEFJtvXbRmxRFXYVMOPH/29pXCpGmLMB8GA1UdIwQYMBaAFJtvXbRmxRFXYVMO\n" "PH/29pXCpGmLMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAkOgC7LP/\n" "Rd6uJXY28HlD2K+/hMh1C3SRT855ggiCMiwstTHACGgNM+AZNqt6k8nSfXc6k1gw\n" "5a7SGjzkWzMaZC3ChBeCzt/vIAGlMyXeqTRhjTCdc/ygRv3NPrhUKKsxUYyXRk5v\n" "g/g6MwxzXfQP3IyFu3a9Jia/P89Z1rQCNRY=\n" "-----END CERTIFICATE-----\n" ) srv_raw_key = str( "-----BEGIN RSA PRIVATE KEY-----\n" "MIICXQIBAAKBgQDRCQR5qRLJX8sy1N4BF1G1fml1vNW5S6o4h3PeWDtg7JEn+jIt\n" "M/NZekrGv/+3gU9C9ixImJU6U+Tz3kU27qw0X+4lDJAZ8VZgqQTp/MWJ9Dqz2Syy\n" "yQWUvUNUj90P9mfuyDO5rY/VLIskdBNOzUy0xvXvT99fYQE+QPP7aRgo3QIDAQAB\n" "AoGAVSLbE8HsyN+fHwDbuo4I1Wa7BRz33xQWLBfe9TvyUzOGm0WnkgmKn3LTacdh\n" "GxgrdBZXSun6PVtV8I0im5DxyVaNdi33sp+PIkZU386f1VUqcnYnmgsnsUQEBJQu\n" "fUZmgNM+bfR+Rfli4Mew8lQ0sorZ+d2/5fsM0g80Qhi5M3ECQQDvXeCyrcy0u/HZ\n" "FNjIloyXaAIvavZ6Lc6gfznCSfHc5YwplOY7dIWp8FRRJcyXkA370l5dJ0EXj5Gx\n" "udV9QQ43AkEA34+RxjRk4DT7Zo+tbM/Fkoi7jh1/0hFkU5NDHweJeH/mJseiHtsH\n" "KOcPGtEGBBqT2KNPWVz4Fj19LiUmmjWXiwJBAIBs49O5/+ywMdAAqVblv0S0nweF\n" "4fwne4cM+5ZMSiH0XsEojGY13EkTEon/N8fRmE8VzV85YmkbtFWgmPR85P0CQQCs\n" "elWbN10EZZv3+q1wH7RsYzVgZX3yEhz3JcxJKkVzRCnKjYaUi6MweWN76vvbOq4K\n" "G6Tiawm0Duh/K4ZmvyYVAkBppE5RRQqXiv1KF9bArcAJHvLm0vnHPpf1yIQr5bW6\n" "njBuL4qcxlaKJVGRXT7yFtj2fj0gv3914jY2suWqp8XJ\n" "-----END RSA PRIVATE KEY-----\n" ) srv_private_key = parsePEMKey(srv_raw_key, private=True) srv_cert_chain = X509CertChain([X509().parse(srv_raw_certificate)]) srv_record_layer._handshakeStart(client=False) srv_record_layer.version = (3, 3) for result in srv_record_layer._getMsg(ContentType.handshake, HandshakeType.client_hello): if result in (0, 1): raise Exception("blocking socket") else: break srv_client_hello = result self.assertEqual(ClientHello, type(srv_client_hello)) srv_cipher_suite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA srv_session_id = bytearray(0) srv_server_hello = ServerHello().create( (3, 3), bytearray(32), srv_session_id, srv_cipher_suite, CertificateType.x509, None, None ) srv_msgs = [] srv_msgs.append(srv_server_hello) srv_msgs.append(Certificate(CertificateType.x509).create(srv_cert_chain)) srv_msgs.append(ServerHelloDone()) for result in srv_record_layer._sendMsgs(srv_msgs): if result in (0, 1): raise Exception("blocking socket") else: break srv_record_layer._versionCheck = True # # client part # for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello): if result in (0, 1): raise Exception("blocking socket") else: break server_hello = result self.assertEqual(ServerHello, type(server_hello)) for result in record_layer._getMsg(ContentType.handshake, HandshakeType.certificate, CertificateType.x509): if result in (0, 1): raise Exception("blocking socket") else: break server_certificate = result self.assertEqual(Certificate, type(server_certificate)) for result in record_layer._getMsg(ContentType.handshake, HandshakeType.server_hello_done): if result in (0, 1): raise Exception("blocking socket") else: break server_hello_done = result self.assertEqual(ServerHelloDone, type(server_hello_done)) public_key = server_certificate.certChain.getEndEntityPublicKey() premasterSecret = bytearray(48) premasterSecret[0] = 3 # 'cause we negotiatied TLSv1.2 premasterSecret[1] = 3 encryptedPreMasterSecret = public_key.encrypt(premasterSecret) client_key_exchange = ClientKeyExchange(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, (3, 3)) client_key_exchange.createRSA(encryptedPreMasterSecret) for result in record_layer._sendMsg(client_key_exchange): if result in (0, 1): raise Exception("blocking socket") else: break master_secret = calcMasterSecret( (3, 3), CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, premasterSecret, client_hello.random, server_hello.random ) record_layer._calcPendingStates( CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, master_secret, client_hello.random, server_hello.random, None ) for result in record_layer._sendMsg(ChangeCipherSpec()): if result in (0, 1): raise Exception("blocking socket") else: break record_layer._changeWriteState() handshake_hashes = record_layer._handshake_hash.digest("sha256") verify_data = PRF_1_2(master_secret, b"client finished", handshake_hashes, 12) finished = Finished((3, 3)).create(verify_data) for result in record_layer._sendMsg(finished): if result in (0, 1): raise Exception("blocking socket") else: break # # server part # for result in srv_record_layer._getMsg( ContentType.handshake, HandshakeType.client_key_exchange, srv_cipher_suite ): if result in (0, 1): raise Exception("blocking socket") else: break srv_client_key_exchange = result srv_premaster_secret = srv_private_key.decrypt(srv_client_key_exchange.encryptedPreMasterSecret) self.assertEqual(bytearray(b"\x03\x03" + b"\x00" * 46), srv_premaster_secret) srv_master_secret = calcMasterSecret( srv_record_layer.version, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, srv_premaster_secret, srv_client_hello.random, srv_server_hello.random, ) srv_record_layer._calcPendingStates( srv_cipher_suite, srv_master_secret, srv_client_hello.random, srv_server_hello.random, None ) for result in srv_record_layer._getMsg(ContentType.change_cipher_spec): if result in (0, 1): raise Exception("blocking socket") else: break srv_change_cipher_spec = result self.assertEqual(ChangeCipherSpec, type(srv_change_cipher_spec)) srv_record_layer._changeReadState() srv_handshakeHashes = srv_record_layer._handshake_hash.digest("sha256") srv_verify_data = PRF_1_2(srv_master_secret, b"client finished", srv_handshakeHashes, 12) for result in srv_record_layer._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0, 1): raise Exception("blocking socket") else: break srv_finished = result self.assertEqual(Finished, type(srv_finished)) self.assertEqual(srv_verify_data, srv_finished.verify_data) for result in srv_record_layer._sendMsg(ChangeCipherSpec()): if result in (0, 1): raise Exception("blocking socket") else: break srv_record_layer._changeWriteState() srv_handshakeHashes = srv_record_layer._handshake_hash.digest("sha256") srv_verify_data = PRF_1_2(srv_master_secret, b"server finished", srv_handshakeHashes, 12) for result in srv_record_layer._sendMsg(Finished((3, 3)).create(srv_verify_data)): if result in (0, 1): raise Exception("blocking socket") else: break srv_record_layer._handshakeDone(resumed=False) # # client part # for result in record_layer._getMsg(ContentType.change_cipher_spec): if result in (0, 1): raise Exception("blocking socket") else: break change_cipher_spec = result self.assertEqual(ChangeCipherSpec, type(change_cipher_spec)) record_layer._changeReadState() handshake_hashes = record_layer._handshake_hash.digest("sha256") server_verify_data = PRF_1_2(master_secret, b"server finished", handshake_hashes, 12) for result in record_layer._getMsg(ContentType.handshake, HandshakeType.finished): if result in (0, 1): raise Exception("blocking socket") else: break server_finished = result self.assertEqual(Finished, type(server_finished)) self.assertEqual(server_verify_data, server_finished.verify_data) record_layer._handshakeDone(resumed=False) # try sending data record_layer.write(bytearray(b"text\n")) # try recieving data data = srv_record_layer.read(10) self.assertEqual(data, bytearray(b"text\n")) record_layer.close() srv_record_layer.close()
def main(): """check if obsolete signature algorithm is rejected by server""" conversations = {} hostname = "localhost" port = 4433 run_exclude = set() expected_failures = {} last_exp_tmp = None private_key = None cert = None argv = sys.argv[1:] opts, argv = getopt.getopt(argv, "h:p:e:x:X:k:c:", ["help"]) for opt, arg in opts: if opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) elif 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 == '--help': help_msg() sys.exit(0) else: raise ValueError("Unknown option: {0}".format(opt)) if argv: run_only = set(argv) else: run_only = None if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity"] = conversation for prf in ['sha256', 'sha384']: for md in ['sha1', 'sha256', 'sha384', 'sha512']: conversation = Connect(hostname, port) node = conversation if prf == 'sha256': ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] else: ciphers = [ CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] ]), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child( CertificateVerifyGenerator(private_key, msg_alg=(getattr(HashAlgorithm, md), SignatureAlgorithm.rsa))) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator( AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["check {0} w/{1} PRF".format(md, prf)] = \ conversation # run the conversation good = 0 bad = 0 xfail = 0 xpass = 0 failed = [] xpassed = [] print("Certificate Verify test version 4") 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 #because we don't want to abort the testing and we are reporting #the errors to the user, using a bare except is OK #pylint: disable=bare-except try: runner.run() except Exception as exp: exception = exp print("Error while processing") print(traceback.format_exc()) res = False #pylint: enable=bare-except 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 end") 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(): """Check what signature algorithms server advertises""" hostname = "localhost" port = 4433 run_exclude = set() cert = None private_key = None sigalgs = [ SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha512, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa) ] argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:s:k:c:", ["help"]) 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 == '--help': help_msg() sys.exit(0) elif opt == '-s': sigalgs = sig_algs_to_ids(arg) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} # sanity check for Client Certificates conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa), (HashAlgorithm.md5, SignatureAlgorithm.rsa) ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator()) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["sanity"] = conversation if cert and private_key: # sanity check for Client Certificates conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa), (HashAlgorithm.md5, SignatureAlgorithm.rsa) ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator(private_key)) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["with certificate"] = conversation # verify the advertised hashes conversation = Connect(hostname, port) node = conversation ciphers = [ CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV ] sigs = [ SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_pss_sha512, (HashAlgorithm.sha512, SignatureAlgorithm.rsa), (HashAlgorithm.sha384, SignatureAlgorithm.rsa), (HashAlgorithm.sha256, SignatureAlgorithm.rsa), (HashAlgorithm.sha224, SignatureAlgorithm.rsa), (HashAlgorithm.sha1, SignatureAlgorithm.rsa), (HashAlgorithm.md5, SignatureAlgorithm.rsa) ] ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigs), ExtensionType.signature_algorithms_cert: SignatureAlgorithmsCertExtension().create(RSA_SIG_ALL) } node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest(sigalgs)) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator()) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["check sigalgs in cert request"] = 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\n") else: bad += 1 failed.append(c_name) print("Test to verify if server accepts empty certificate messages and") print("advertises only expected signature algotithms in Certificate") print("Request message\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 main(): """check if obsolete signature algorithm is rejected by server""" conversations = {} hostname = "localhost" port = 4433 argv = sys.argv[1:] if len(argv) != 4: raise ValueError("You need to specify key (-k file.pem) and " "certificate (-c file.pem)") opts, argv = getopt.getopt(argv, "k:c:") for opt, arg in opts: if opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) if opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) if not private_key: raise ValueError("Specify private key file using -k") if not cert: raise ValueError("Specify certificate file using -c") for md in ['sha1', 'sha256', 'sha384', 'sha512']: conversation = Connect(hostname, port) node = conversation ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] ext = {ExtensionType.signature_algorithms : SignatureAlgorithmsExtension().create([ (getattr(HashAlgorithm, x), SignatureAlgorithm.rsa) for x in ['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5']])} node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) node = node.add_child(ExpectServerHello(version=(3, 3))) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(CertificateVerifyGenerator( private_key, sig_type=(getattr(HashAlgorithm, md), SignatureAlgorithm.rsa))) 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(b"GET / HTTP/1.0\n\n")) node = node.add_child(ExpectApplicationData()) node = node.add_child(AlertGenerator(AlertDescription.close_notify)) node = node.add_child(ExpectClose()) node.next_sibling = ExpectAlert() node.next_sibling.add_child(ExpectClose()) conversations["check " + md] = conversation # run the conversation good = 0 bad = 0 print("Certificate Verify test version 2") for conversation_name in conversations: conversation = conversations[conversation_name] print(conversation_name + "...") runner = Runner(conversation) res = True #because we don't want to abort the testing and we are reporting #the errors to the user, using a bare except is OK #pylint: disable=bare-except try: runner.run() except: print("Error while processing") print(traceback.format_exc()) res = False #pylint: enable=bare-except if res: good+=1 print("OK") else: bad+=1 print("Test end") print("successful: {0}".format(good)) print("failed: {0}".format(bad)) if bad > 0: sys.exit(1)
def main(): """Check what signature algorithms server advertises""" hostname = "localhost" port = 4433 num_limit = None run_exclude = set() expected_failures = {} last_exp_tmp = None cert = None private_key = None ext_spec = { 'CH': None, 'SH': None, 'EE': None, 'CT': None, 'CR': None, 'NST': None, 'HRR': None } sigalgs = [ SignatureScheme.ed25519, SignatureScheme.ed448, SignatureScheme.ecdsa_secp521r1_sha512, SignatureScheme.ecdsa_secp384r1_sha384, SignatureScheme.ecdsa_secp256r1_sha256, (HashAlgorithm.sha224, SignatureAlgorithm.ecdsa), (HashAlgorithm.sha1, SignatureAlgorithm.ecdsa), SignatureScheme.rsa_pss_rsae_sha512, SignatureScheme.rsa_pss_pss_sha512, SignatureScheme.rsa_pss_rsae_sha384, SignatureScheme.rsa_pss_pss_sha384, SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256, SignatureScheme.rsa_pkcs1_sha512, SignatureScheme.rsa_pkcs1_sha384, SignatureScheme.rsa_pkcs1_sha256, SignatureScheme.rsa_pkcs1_sha224, SignatureScheme.rsa_pkcs1_sha1 ] argv = sys.argv[1:] opts, args = getopt.getopt(argv, "h:p:e:x:X:s:k:c:E:", ["help"]) for opt, arg in opts: if opt == '-h': hostname = arg elif opt == '-p': port = int(arg) elif opt == '-e': run_exclude.add(arg) elif opt == '-n': num_limit = int(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 == '--help': help_msg() sys.exit(0) elif opt == '-s': sigalgs = sig_algs_to_ids(arg) elif opt == '-E': ext_spec = expected_ext_parser(arg) elif opt == '-k': text_key = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_key = str(text_key, 'utf-8') private_key = parsePEMKey(text_key, private=True) elif opt == '-c': text_cert = open(arg, 'rb').read() if sys.version_info[0] >= 3: text_cert = str(text_cert, 'utf-8') cert = X509() cert.parse(text_cert) else: raise ValueError("Unknown option: {0}".format(opt)) if args: run_only = set(args) else: run_only = None conversations = {} # sanity check for Client Certificates conversation = Connect(hostname, 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([(3, 4), (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) ext = dict_update_non_present(ext, ext_spec['CH']) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = dict_update_non_present(None, ext_spec['SH']) node = node.add_child(ExpectServerHello(extensions=ext)) node = node.add_child(ExpectChangeCipherSpec()) ext = dict_update_non_present(None, ext_spec['EE']) node = node.add_child(ExpectEncryptedExtensions(extensions=ext)) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator()) 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 if cert and private_key: # sanity check for Client Certificates conversation = Connect(hostname, 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([(3, 4), (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) ext = dict_update_non_present(ext, ext_spec['CH']) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = dict_update_non_present(None, ext_spec['SH']) node = node.add_child(ExpectServerHello(extensions=ext)) node = node.add_child(ExpectChangeCipherSpec()) ext = dict_update_non_present(None, ext_spec['EE']) node = node.add_child(ExpectEncryptedExtensions(extensions=ext)) node = node.add_child(ExpectCertificateRequest()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator(X509CertChain([cert]))) node = node.add_child(CertificateVerifyGenerator(private_key)) 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["with certificate"] = conversation # verify the advertised hashes conversation = Connect(hostname, 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([(3, 4), (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) ext = dict_update_non_present(ext, ext_spec['CH']) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = dict_update_non_present(None, ext_spec['SH']) node = node.add_child(ExpectServerHello(extensions=ext)) node = node.add_child(ExpectChangeCipherSpec()) ext = dict_update_non_present(None, ext_spec['EE']) node = node.add_child(ExpectEncryptedExtensions(extensions=ext)) node = node.add_child(ExpectCertificateRequest(sigalgs)) # extensions are not yet supported in Certificate messages node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator()) 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["check sigalgs in cert request"] = conversation # verify the sent extensions conversation = Connect(hostname, 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([(3, 4), (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) ext = dict_update_non_present(ext, ext_spec['CH']) node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext)) ext = dict_update_non_present(None, ext_spec['SH']) node = node.add_child(ExpectServerHello(extensions=ext)) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectEncryptedExtensions()) ext = { ExtensionType.signature_algorithms: SignatureAlgorithmsExtension().create(sigalgs) } ext = dict_update_non_present(ext, ext_spec['CR']) node = node.add_child(ExpectCertificateRequest(extensions=ext)) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectCertificateVerify()) node = node.add_child(ExpectFinished()) node = node.add_child(CertificateGenerator()) 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["verify extensions in CertificateRequest"] = 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("Test to verify if server accepts empty certificate messages and") print("advertises only expected signature algotithms and extensions in ") print("Certificate Request message\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 or xpass: sys.exit(1)