diff --git a/tests/conftest.py b/tests/conftest.py index 851d910..748b141 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,7 @@ import pytest import wolfssl from wolfssl._ffi import lib as _lib +from wolfssltestserver import wolfSSLTestServer @pytest.fixture def tcp_socket(): @@ -61,3 +62,15 @@ def ssl_context(ssl_provider, request): return ssl_provider.SSLContext(ssl_provider.PROTOCOL_TLSv1_3) if request.param == "SSLv23": return ssl_provider.SSLContext(ssl_provider.PROTOCOL_SSLv23) + +port = 1110 +@pytest.fixture +def ssl_server(): + from threading import Thread + global port + port += 1 + with wolfSSLTestServer(('localhost', port)) as server: + t = Thread(target=server.handle_request) + t.daemon = True + t.start() + yield server diff --git a/tests/test_client.py b/tests/test_client.py index 2cccc22..9e265c3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -24,6 +24,7 @@ # pylint: disable=redefined-outer-name import pytest +import wolfssl HOST = "www.python.org" PORT = 443 @@ -70,3 +71,21 @@ def test_secure_connection(secure_socket): secure_socket.write(b"GET / HTTP/1.1\n\n") assert secure_socket.read(4) == b"HTTP" + +@pytest.mark.parametrize("ssl_version", + [pytest.param((wolfssl.PROTOCOL_TLSv1_1, "TLSv1.1"), id="TLSv1.1"), + pytest.param((wolfssl.PROTOCOL_TLSv1_2, "TLSv1.2"), id="TLSv1.2"), + pytest.param((wolfssl.PROTOCOL_TLSv1_3, "TLSv1.3"), id="TLSv1.3")]) +def test_get_version(ssl_server, ssl_version, tcp_socket): + protocol = ssl_version[0] + protocol_name = ssl_version[1] + try: + ssl_context = wolfssl.SSLContext(protocol) + except ValueError: + pytest.skip("Protocol {} not supported".format(protocol_name)) + return + secure_socket = ssl_context.wrap_socket(tcp_socket) + secure_socket.connect(('127.0.0.1', ssl_server.port)) + assert secure_socket.version() == protocol_name + secure_socket.write(b'hello wolfssl') + secure_socket.read(1024) diff --git a/tests/wolfssltestserver.py b/tests/wolfssltestserver.py new file mode 100644 index 0000000..7284269 --- /dev/null +++ b/tests/wolfssltestserver.py @@ -0,0 +1,25 @@ +from wolfssl import SSLContext, PROTOCOL_TLS, CERT_NONE +from socketserver import TCPServer, BaseRequestHandler + +ca_path = './certs/client-cert.pem' +cert_path = './certs/server-cert.pem' +key_path = './certs/server-key.pem' + +class wolfSSLTestServer(TCPServer): + class wolfSSLRequestHandler(BaseRequestHandler): + def handle(self): + ssl_socket = self.server.ctx.wrap_socket(self.request, server_side=True) + ssl_socket.recv(1024) + ssl_socket.sendall(b'I hear you fa shizzle!') + ctx = None + def __init__(self, address, version=PROTOCOL_TLS, ca=ca_path, cert=cert_path, key=key_path, verify=CERT_NONE): + TCPServer.__init__(self, address, self.wolfSSLRequestHandler, bind_and_activate=False) + self.allow_reuse_address = self.allow_reuse_port = True + self.ctx = SSLContext(version, server_side=True) + self.ctx.verify_mode = verify + self.ctx.load_verify_locations(ca) + self.ctx.load_cert_chain(cert, key) + self.port = address[1] + self.version = version + self.server_bind() + self.server_activate() diff --git a/wolfssl/__init__.py b/wolfssl/__init__.py index f92b38b..fbb28f0 100644 --- a/wolfssl/__init__.py +++ b/wolfssl/__init__.py @@ -857,6 +857,11 @@ def getpeercert(self, binary_form=False): return {'subject': ((('commonName', x509.get_subject_cn()),),), 'subjectAltName': x509.get_altnames() } + def version(self): + """ + Returns the version of the protocol used in the connection. + """ + return _ffi.string(_lib.wolfSSL_get_version(self.native_object)).decode("ascii") # The following functions expose functionality of the underlying # Socket object. These are also exposed through Python's ssl module diff --git a/wolfssl/_build_ffi.py b/wolfssl/_build_ffi.py index c02551a..00d8991 100644 --- a/wolfssl/_build_ffi.py +++ b/wolfssl/_build_ffi.py @@ -485,6 +485,7 @@ def generate_libwolfssl(): void* wolfSSL_dtls_create_peer(int, char*); int wolfSSL_dtls_free_peer(void*); int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int); + const char* wolfSSL_get_version(const WOLFSSL*); /* * WOLFSSL_X509 functions