Wire TLS keys in Python for cross-tests

Configure Python test client/server to use shared test keys and CA for SSL.
Remove Python SSL entries from known failures to re-enable SSL coverage.
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index da73ba5..6afe00c 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -171,26 +171,18 @@
   "cpp-php_multi-accel_framed-ip",
   "cpp-php_multij-json_buffered-ip",
   "cpp-php_multij-json_framed-ip",
-  "cpp-py_binary-accel_buffered-ip-ssl",
-  "cpp-py_binary-accel_framed-ip-ssl",
   "cpp-py_binary-accel_http-domain",
   "cpp-py_binary-accel_http-ip",
   "cpp-py_binary-accel_http-ip-ssl",
   "cpp-py_binary-accel_zlib-ip-ssl",
-  "cpp-py_binary_buffered-ip-ssl",
-  "cpp-py_binary_framed-ip-ssl",
   "cpp-py_binary_http-domain",
   "cpp-py_binary_http-ip",
   "cpp-py_binary_http-ip-ssl",
   "cpp-py_binary_zlib-ip-ssl",
-  "cpp-py_compact-accelc_buffered-ip-ssl",
-  "cpp-py_compact-accelc_framed-ip-ssl",
   "cpp-py_compact-accelc_http-domain",
   "cpp-py_compact-accelc_http-ip",
   "cpp-py_compact-accelc_http-ip-ssl",
   "cpp-py_compact-accelc_zlib-ip-ssl",
-  "cpp-py_compact_buffered-ip-ssl",
-  "cpp-py_compact_framed-ip-ssl",
   "cpp-py_compact_http-domain",
   "cpp-py_compact_http-ip",
   "cpp-py_compact_http-ip-ssl",
@@ -201,12 +193,9 @@
   "cpp-py_header_http-ip",
   "cpp-py_header_http-ip-ssl",
   "cpp-py_header_zlib-ip-ssl",
-  "cpp-py_json_buffered-ip-ssl",
-  "cpp-py_json_framed-ip-ssl",
   "cpp-py_json_http-domain",
   "cpp-py_json_http-ip",
   "cpp-py_json_http-ip-ssl",
-  "cpp-py_json_zlib-ip-ssl",
   "cpp-py_multi-accel_buffered-ip-ssl",
   "cpp-py_multi-accel_framed-ip-ssl",
   "cpp-py_multi-accel_http-domain",
@@ -455,24 +444,8 @@
   "go-netstd_json_buffered-ip-ssl",
   "go-netstd_json_framed-ip",
   "go-netstd_json_framed-ip-ssl",
-  "go-py_binary-accel_buffered-ip-ssl",
-  "go-py_binary-accel_framed-ip-ssl",
   "go-py_binary-accel_zlib-ip-ssl",
-  "go-py_binary_buffered-ip-ssl",
-  "go-py_binary_framed-ip-ssl",
-  "go-py_binary_zlib-ip-ssl",
-  "go-py_compact-accelc_buffered-ip-ssl",
-  "go-py_compact-accelc_framed-ip-ssl",
   "go-py_compact-accelc_zlib-ip-ssl",
-  "go-py_compact_buffered-ip-ssl",
-  "go-py_compact_framed-ip-ssl",
-  "go-py_compact_zlib-ip-ssl",
-  "go-py_header_buffered-ip-ssl",
-  "go-py_header_framed-ip-ssl",
-  "go-py_header_zlib-ip-ssl",
-  "go-py_json_buffered-ip-ssl",
-  "go-py_json_framed-ip-ssl",
-  "go-py_json_zlib-ip-ssl",
   "hs-netstd_binary_buffered-ip",
   "hs-netstd_binary_framed-ip",
   "hs-netstd_compact_buffered-ip",
@@ -543,66 +516,6 @@
   "java-php_multij-json_buffered-ip",
   "java-php_multij-json_fastframed-framed-ip",
   "java-php_multij-json_framed-ip",
-  "java-py_binary-accel_buffered-ip-ssl",
-  "java-py_binary-accel_fastframed-framed-ip-ssl",
-  "java-py_binary-accel_framed-ip-ssl",
-  "java-py_binary-accel_zlib-ip-ssl",
-  "java-py_binary_buffered-ip-ssl",
-  "java-py_binary_fastframed-framed-ip-ssl",
-  "java-py_binary_framed-ip-ssl",
-  "java-py_binary_zlib-ip-ssl",
-  "java-py_compact-accelc_buffered-ip-ssl",
-  "java-py_compact-accelc_fastframed-framed-ip-ssl",
-  "java-py_compact-accelc_framed-ip-ssl",
-  "java-py_compact-accelc_zlib-ip-ssl",
-  "java-py_compact_buffered-ip-ssl",
-  "java-py_compact_fastframed-framed-ip-ssl",
-  "java-py_compact_framed-ip-ssl",
-  "java-py_compact_zlib-ip-ssl",
-  "java-py_json_buffered-ip-ssl",
-  "java-py_json_fastframed-framed-ip-ssl",
-  "java-py_json_framed-ip-ssl",
-  "java-py_json_zlib-ip-ssl",
-  "java-py_multi-accel_buffered-ip-ssl",
-  "java-py_multi-accel_fastframed-framed-ip-ssl",
-  "java-py_multi-accel_framed-ip-ssl",
-  "java-py_multi-accel_zlib-ip-ssl",
-  "java-py_multi-binary_buffered-ip-ssl",
-  "java-py_multi-binary_fastframed-framed-ip-ssl",
-  "java-py_multi-binary_framed-ip-ssl",
-  "java-py_multi-binary_zlib-ip-ssl",
-  "java-py_multi-multia_buffered-ip-ssl",
-  "java-py_multi-multia_fastframed-framed-ip-ssl",
-  "java-py_multi-multia_framed-ip-ssl",
-  "java-py_multi-multia_zlib-ip-ssl",
-  "java-py_multi_buffered-ip-ssl",
-  "java-py_multi_fastframed-framed-ip-ssl",
-  "java-py_multi_framed-ip-ssl",
-  "java-py_multi_zlib-ip-ssl",
-  "java-py_multic-accelc_buffered-ip-ssl",
-  "java-py_multic-accelc_fastframed-framed-ip-ssl",
-  "java-py_multic-accelc_framed-ip-ssl",
-  "java-py_multic-accelc_zlib-ip-ssl",
-  "java-py_multic-compact_buffered-ip-ssl",
-  "java-py_multic-compact_fastframed-framed-ip-ssl",
-  "java-py_multic-compact_framed-ip-ssl",
-  "java-py_multic-compact_zlib-ip-ssl",
-  "java-py_multic-multiac_buffered-ip-ssl",
-  "java-py_multic-multiac_fastframed-framed-ip-ssl",
-  "java-py_multic-multiac_framed-ip-ssl",
-  "java-py_multic-multiac_zlib-ip-ssl",
-  "java-py_multic_buffered-ip-ssl",
-  "java-py_multic_fastframed-framed-ip-ssl",
-  "java-py_multic_framed-ip-ssl",
-  "java-py_multic_zlib-ip-ssl",
-  "java-py_multij-json_buffered-ip-ssl",
-  "java-py_multij-json_fastframed-framed-ip-ssl",
-  "java-py_multij-json_framed-ip-ssl",
-  "java-py_multij-json_zlib-ip-ssl",
-  "java-py_multij_buffered-ip-ssl",
-  "java-py_multij_fastframed-framed-ip-ssl",
-  "java-py_multij_framed-ip-ssl",
-  "java-py_multij_zlib-ip-ssl",
   "kotlin-netstd_binary_framed-ip",
   "kotlin-netstd_compact_framed-ip",
   "kotlin-netstd_json_framed-ip",
@@ -1315,11 +1228,6 @@
   "py-java_multij_http-ip-ssl",
   "py-java_multij_zlib-ip",
   "py-java_multij_zlib-ip-ssl",
-  "py-kotlin_accel-binary_framed-ip-ssl",
-  "py-kotlin_accelc-compact_framed-ip-ssl",
-  "py-kotlin_binary_framed-ip-ssl",
-  "py-kotlin_compact_framed-ip-ssl",
-  "py-kotlin_json_framed-ip-ssl",
   "py-lua_accel-binary_http-ip",
   "py-lua_accelc-compact_http-ip",
   "py-lua_binary_http-ip",
@@ -1357,86 +1265,6 @@
   "py-php_binary-accel_framed-ip",
   "py-php_json_buffered-ip",
   "py-php_json_framed-ip",
-  "py-py_accel-binary_buffered-ip-ssl",
-  "py-py_accel-binary_framed-ip-ssl",
-  "py-py_accel-binary_http-ip-ssl",
-  "py-py_accel-binary_zlib-ip-ssl",
-  "py-py_accel_buffered-ip-ssl",
-  "py-py_accel_framed-ip-ssl",
-  "py-py_accel_http-ip-ssl",
-  "py-py_accel_zlib-ip-ssl",
-  "py-py_accelc-compact_buffered-ip-ssl",
-  "py-py_accelc-compact_framed-ip-ssl",
-  "py-py_accelc-compact_http-ip-ssl",
-  "py-py_accelc-compact_zlib-ip-ssl",
-  "py-py_accelc_buffered-ip-ssl",
-  "py-py_accelc_framed-ip-ssl",
-  "py-py_accelc_http-ip-ssl",
-  "py-py_accelc_zlib-ip-ssl",
-  "py-py_binary-accel_buffered-ip-ssl",
-  "py-py_binary-accel_framed-ip-ssl",
-  "py-py_binary-accel_http-ip-ssl",
-  "py-py_binary-accel_zlib-ip-ssl",
-  "py-py_binary_buffered-ip-ssl",
-  "py-py_binary_framed-ip-ssl",
-  "py-py_binary_http-ip-ssl",
-  "py-py_binary_zlib-ip-ssl",
-  "py-py_compact-accelc_buffered-ip-ssl",
-  "py-py_compact-accelc_framed-ip-ssl",
-  "py-py_compact-accelc_http-ip-ssl",
-  "py-py_compact-accelc_zlib-ip-ssl",
-  "py-py_compact_buffered-ip-ssl",
-  "py-py_compact_framed-ip-ssl",
-  "py-py_compact_http-ip-ssl",
-  "py-py_compact_zlib-ip-ssl",
-  "py-py_header_buffered-ip-ssl",
-  "py-py_header_framed-ip-ssl",
-  "py-py_header_http-ip-ssl",
-  "py-py_header_zlib-ip-ssl",
-  "py-py_json_buffered-ip-ssl",
-  "py-py_json_framed-ip-ssl",
-  "py-py_json_http-ip-ssl",
-  "py-py_json_zlib-ip-ssl",
-  "py-py_multi-multia_buffered-ip-ssl",
-  "py-py_multi-multia_framed-ip-ssl",
-  "py-py_multi-multia_http-ip-ssl",
-  "py-py_multi-multia_zlib-ip-ssl",
-  "py-py_multi_buffered-ip-ssl",
-  "py-py_multi_framed-ip-ssl",
-  "py-py_multi_http-ip-ssl",
-  "py-py_multi_zlib-ip-ssl",
-  "py-py_multia-multi_buffered-ip-ssl",
-  "py-py_multia-multi_framed-ip-ssl",
-  "py-py_multia-multi_http-ip-ssl",
-  "py-py_multia-multi_zlib-ip-ssl",
-  "py-py_multia_buffered-ip-ssl",
-  "py-py_multia_framed-ip-ssl",
-  "py-py_multia_http-ip-ssl",
-  "py-py_multia_zlib-ip-ssl",
-  "py-py_multiac-multic_buffered-ip-ssl",
-  "py-py_multiac-multic_framed-ip-ssl",
-  "py-py_multiac-multic_http-ip-ssl",
-  "py-py_multiac-multic_zlib-ip-ssl",
-  "py-py_multiac_buffered-ip-ssl",
-  "py-py_multiac_framed-ip-ssl",
-  "py-py_multiac_http-ip-ssl",
-  "py-py_multiac_zlib-ip-ssl",
-  "py-py_multic-multiac_buffered-ip-ssl",
-  "py-py_multic-multiac_framed-ip-ssl",
-  "py-py_multic-multiac_http-ip-ssl",
-  "py-py_multic-multiac_zlib-ip-ssl",
-  "py-py_multic_buffered-ip-ssl",
-  "py-py_multic_framed-ip-ssl",
-  "py-py_multic_http-ip-ssl",
-  "py-py_multic_zlib-ip-ssl",
-  "py-py_multih_buffered-ip-ssl",
-  "py-py_multih_framed-ip-ssl",
-  "py-py_multih_http-ip-ssl",
-  "py-py_multih_zlib-ip-ssl",
-  "py-py_multij_buffered-ip-ssl",
-  "py-py_multij_framed-ip-ssl",
-  "py-py_multij_http-ip-ssl",
-  "py-py_multij_zlib-ip-ssl",
   "py-rb_accel-binary_buffered-domain",
   "py-rb_accel-binary_buffered-ip",
   "py-rb_accel-binary_buffered-ip-ssl",
@@ -1555,22 +1383,8 @@
   "rb-netstd_json_buffered-ip-ssl",
   "rb-netstd_json_framed-ip",
   "rb-netstd_json_framed-ip-ssl",
-  "rb-py_accel-binary_buffered-ip-ssl",
-  "rb-py_accel-binary_framed-ip-ssl",
-  "rb-py_accel_buffered-ip-ssl",
-  "rb-py_accel_framed-ip-ssl",
-  "rb-py_binary-accel_buffered-ip-ssl",
-  "rb-py_binary-accel_framed-ip-ssl",
-  "rb-py_binary_buffered-ip-ssl",
-  "rb-py_binary_framed-ip-ssl",
-  "rb-py_compact-accelc_buffered-ip-ssl",
-  "rb-py_compact-accelc_framed-ip-ssl",
-  "rb-py_compact_buffered-ip-ssl",
-  "rb-py_compact_framed-ip-ssl",
   "rb-py_header_framed-ip-ssl",
   "rb-py_header_buffered-ip-ssl",
-  "rb-py_json_buffered-ip-ssl",
-  "rb-py_json_framed-ip-ssl",
   "rs-netstd_binary_buffered-ip",
   "rs-netstd_binary_framed-ip",
   "rs-netstd_compact_buffered-ip",
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index d80ddf4..9971e42 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -20,6 +20,7 @@
 #
 
 import os
+import ssl
 import sys
 import time
 import unittest
@@ -40,7 +41,7 @@
                                             options.port,
                                             (options.http_path if options.http_path else '/'))
             if options.ssl:
-                __cafile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "CA.pem")
+                __cafile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "server.pem")
                 __certfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.crt")
                 __keyfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.key")
                 self.transport = THttpClient.THttpClient(uri, cafile=__cafile, cert_file=__certfile, key_file=__keyfile)
@@ -49,7 +50,20 @@
         else:
             if options.ssl:
                 from thrift.transport import TSSLSocket
-                socket = TSSLSocket.TSSLSocket(options.host, options.port, validate=False)
+                keys_dir = os.path.join(os.path.dirname(SCRIPT_DIR), "keys")
+                ca_certs = os.path.join(keys_dir, "server.pem")
+                certfile = os.path.join(keys_dir, "client.crt")
+                keyfile = os.path.join(keys_dir, "client.key")
+                ssl_version = getattr(ssl, "PROTOCOL_TLS_CLIENT", ssl.PROTOCOL_TLSv1)
+                socket = TSSLSocket.TSSLSocket(
+                    options.host,
+                    options.port,
+                    certfile=certfile,
+                    keyfile=keyfile,
+                    ca_certs=ca_certs,
+                    cert_reqs=ssl.CERT_REQUIRED,
+                    ssl_version=ssl_version,
+                )
             else:
                 socket = TSocket.TSocket(options.host, options.port, options.domain_socket)
             # frame or buffer depending upon args
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index c2723e5..3b93841 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -21,6 +21,7 @@
 import logging
 import os
 import signal
+import ssl
 import sys
 import time
 from optparse import OptionParser
@@ -310,12 +311,23 @@
 
     # set up server transport and transport factory
 
-    abs_key_path = os.path.join(os.path.dirname(SCRIPT_DIR), 'keys', 'server.pem')
-
     host = None
     if options.ssl:
         from thrift.transport import TSSLSocket
-        transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile=abs_key_path)
+        keys_dir = os.path.join(os.path.dirname(SCRIPT_DIR), 'keys')
+        ca_certs = os.path.join(keys_dir, 'client.pem')
+        certfile = os.path.join(keys_dir, 'server.crt')
+        keyfile = os.path.join(keys_dir, 'server.key')
+        ssl_version = getattr(ssl, 'PROTOCOL_TLS_SERVER', ssl.PROTOCOL_TLSv1)
+        transport = TSSLSocket.TSSLServerSocket(
+            host,
+            options.port,
+            certfile=certfile,
+            keyfile=keyfile,
+            ca_certs=ca_certs,
+            cert_reqs=ssl.CERT_REQUIRED,
+            ssl_version=ssl_version,
+        )
     else:
         transport = TSocket.TServerSocket(host, options.port, options.domain_socket)
     tfactory = TTransport.TBufferedTransportFactory()