diff --git a/wrapper/python/wolfssl/requirements-testing.txt b/wrapper/python/wolfssl/requirements-testing.txt index 61def5278..9a277b876 100644 --- a/wrapper/python/wolfssl/requirements-testing.txt +++ b/wrapper/python/wolfssl/requirements-testing.txt @@ -1,3 +1,3 @@ -pytest>=2.9.1 -cffi>=1.6.0 -tox>=2.3.1 +pytest>=3.0.5 +cffi>=1.9.1 +tox>=2.5.0 diff --git a/wrapper/python/wolfssl/src/wolfssl/__init__.py b/wrapper/python/wolfssl/src/wolfssl/__init__.py index d637c164e..929674152 100644 --- a/wrapper/python/wolfssl/src/wolfssl/__init__.py +++ b/wrapper/python/wolfssl/src/wolfssl/__init__.py @@ -582,7 +582,17 @@ class SSLSocket(socket): containing that new connection wrapped with a server-side secure channel, and the address of the remote client. """ - pass + if not self.server_side: + raise ValueError("can't accept in client-side mode") + + newsock, addr = socket.accept(self) + newsock = self.context.wrap_socket( + newsock, + do_handshake_on_connect=self.do_handshake_on_connect, + suppress_ragged_eofs=self.suppress_ragged_eofs, + server_side=True) + + return newsock, addr def wrap_socket(sock, keyfile=None, certfile=None, server_side=False, diff --git a/wrapper/python/wolfssl/test/conftest.py b/wrapper/python/wolfssl/test/conftest.py new file mode 100644 index 000000000..1128f4448 --- /dev/null +++ b/wrapper/python/wolfssl/test/conftest.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# +# conftest.py +# +# Copyright (C) 2006-2016 wolfSSL Inc. +# +# This file is part of wolfSSL. (formerly known as CyaSSL) +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +# pylint: disable=missing-docstring, redefined-outer-name + +import socket +import ssl +import wolfssl +import pytest + +@pytest.fixture +def tcp_socket(): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + yield sock + sock.close() + +@pytest.fixture(params=[ssl, wolfssl], ids=["ssl", "wolfssl"]) +def ssl_provider(request): + return request.param + +@pytest.fixture +def ssl_context(ssl_provider): + return ssl_provider.SSLContext(ssl_provider.PROTOCOL_SSLv23) diff --git a/wrapper/python/wolfssl/test/test_client.py b/wrapper/python/wolfssl/test/test_client.py index 2a7c02104..5a55d47b6 100644 --- a/wrapper/python/wolfssl/test/test_client.py +++ b/wrapper/python/wolfssl/test/test_client.py @@ -21,67 +21,45 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # pylint: disable=missing-docstring, invalid-name, import-error +# pylint: disable=redefined-outer-name -import unittest -import socket -import ssl -import wolfssl +import pytest -class SSLClientTest(unittest.TestCase): - provider = ssl - host = "www.globalsign.com" - port = 443 +HOST = "www.python.org" +PORT = 443 +CA_CERTS = "/etc/ssl/cert.pem" - def setUp(self): - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +@pytest.fixture( + params=["wrap_socket", "wrap_socket_with_ca", + "wrap_socket_from_context", "ssl_socket"]) +def secure_socket(request, ssl_provider, tcp_socket): + sock = None - def test_wrap_socket(self): - secure_sock = self.provider.wrap_socket(self.sock) - secure_sock.connect((self.host, self.port)) + if request.param == "wrap_socket": + sock = ssl_provider.wrap_socket(tcp_socket) - secure_sock.write(b"GET / HTTP/1.1\n\n") - self.assertEqual(b"HTTP", secure_sock.read(4)) + elif request.param == "wrap_socket_with_ca": + sock = ssl_provider.wrap_socket( + tcp_socket, cert_reqs=ssl_provider.CERT_REQUIRED, ca_certs=CA_CERTS) - secure_sock.close() + elif request.param == "wrap_socket_from_context": + ctx = ssl_provider.SSLContext(ssl_provider.PROTOCOL_TLSv1_2) - def test_wrap_socket_with_ca(self): - secure_sock = self.provider.wrap_socket( - self.sock, cert_reqs=self.provider.CERT_REQUIRED, - ca_certs="../../../certs/external/ca-globalsign-root-r2.pem") - secure_sock.connect((self.host, self.port)) + ctx.verify_mode = ssl_provider.CERT_REQUIRED + ctx.load_verify_locations(CA_CERTS) - secure_sock.write(b"GET / HTTP/1.1\n\n") - self.assertEqual(b"HTTP", secure_sock.read(4)) + sock = ctx.wrap_socket(tcp_socket) - secure_sock.close() + elif request.param == "ssl_socket": + sock = ssl_provider.SSLSocket( + tcp_socket, cert_reqs=ssl_provider.CERT_REQUIRED, ca_certs=CA_CERTS) - def test_wrap_socket_from_context(self): - ctx = self.provider.SSLContext(self.provider.PROTOCOL_TLSv1_2) + if sock: + yield sock + sock.close() - ctx.verify_mode = self.provider.CERT_REQUIRED - ctx.load_verify_locations( - "../../../certs/external/ca-globalsign-root-r2.pem") +def test_secure_connection(secure_socket): + secure_socket.connect((HOST, PORT)) - secure_sock = ctx.wrap_socket(self.sock) - secure_sock.connect((self.host, self.port)) - - secure_sock.write(b"GET / HTTP/1.1\n\n") - self.assertEqual(b"HTTP", secure_sock.read(4)) - - secure_sock.close() - - def test_ssl_socket(self): - secure_sock = self.provider.SSLSocket( - self.sock, - cert_reqs=self.provider.CERT_REQUIRED, - ca_certs="../../../certs/external/ca-globalsign-root-r2.pem") - - secure_sock.connect((self.host, self.port)) - - secure_sock.write(b"GET / HTTP/1.1\n\n") - self.assertEqual(b"HTTP", secure_sock.read(4)) - - secure_sock.close() - -class TestWolfSSL(SSLClientTest): - provider = wolfssl + secure_socket.write(b"GET / HTTP/1.1\n\n") + assert secure_socket.read(4) == b"HTTP" diff --git a/wrapper/python/wolfssl/test/test_context.py b/wrapper/python/wolfssl/test/test_context.py index 2c1a0920b..b8692781d 100644 --- a/wrapper/python/wolfssl/test/test_context.py +++ b/wrapper/python/wolfssl/test/test_context.py @@ -21,11 +21,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # pylint: disable=missing-docstring, invalid-name, import-error +# pylint: disable=redefined-outer-name import sys -import unittest import ssl -import wolfssl +import pytest _CADATA = """" Certificate: @@ -117,43 +117,36 @@ Lkp2vSl/HFM3Bq3pW2rWt06UonzorE6mUD4rMp5oQhvkWWdh6seaUZwcVaN3dg== -----END CERTIFICATE----- """ -class TestSSLContext(unittest.TestCase): - provider = ssl +def test_context_creation(ssl_context): + assert ssl_context != None - def setUp(self): - self.ctx = self.provider.SSLContext(self.provider.PROTOCOL_SSLv23) +def test_verify_mode(ssl_provider, ssl_context): + assert ssl_context.verify_mode == ssl_provider.CERT_NONE - def test_context_creation(self): - self.assertIsNotNone(self.ctx) + ssl_context.verify_mode = ssl_provider.CERT_REQUIRED + assert ssl_context.verify_mode == ssl_provider.CERT_REQUIRED - def test_verify_mode(self): - self.assertEqual(self.ctx.verify_mode, self.provider.CERT_NONE) +def test_set_ciphers(ssl_context): + ssl_context.set_ciphers("DHE-RSA-AES256-SHA256") - self.ctx.verify_mode = self.provider.CERT_REQUIRED - self.assertEqual(self.ctx.verify_mode, self.provider.CERT_REQUIRED) +def test_load_cert_chain_raises(ssl_context): + with pytest.raises(TypeError): + ssl_context.load_cert_chain(None) - def test_set_ciphers(self): - self.ctx.set_ciphers("DHE-RSA-AES256-SHA256") +def test_load_cert_chain(ssl_context): + ssl_context.load_cert_chain("../../../certs/client-cert.pem", + "../../../certs/client-key.pem") - def test_load_cert_chain_raises(self): - self.assertRaises(TypeError, self.ctx.load_cert_chain, None) +def test_load_verify_locations_raises(ssl_context): + with pytest.raises(TypeError): + ssl_context.load_verify_locations(None) - def test_load_cert_chain(self): - self.ctx.load_cert_chain("../../../certs/client-cert.pem", - "../../../certs/client-key.pem") +def test_load_verify_locations_with_cafile(ssl_context): + ssl_context.load_verify_locations(cafile="../../../certs/ca-cert.pem") - def test_load_verify_locations_raises(self): - self.assertRaises(TypeError, self.ctx.load_verify_locations, None) +def test_load_verify_locations_with_cadata(ssl_provider, ssl_context): + if ssl_provider is ssl and sys.version_info[0] == 2: + # this test doesn't works for provider ssl in python 2 + return - def test_load_verify_locations_with_cafile(self): - self.ctx.load_verify_locations(cafile="../../../certs/ca-cert.pem") - - def test_load_verify_locations_with_cadata(self): - if self.provider is ssl and sys.version_info[0] == 2: - # this test doesn't works for provider ssl in python 2 - return - - self.ctx.load_verify_locations(cadata=_CADATA) - -class TestWolfSSLContext(TestSSLContext): - provider = wolfssl + ssl_context.load_verify_locations(cadata=_CADATA) diff --git a/wrapper/python/wolfssl/test/test_methods.py b/wrapper/python/wolfssl/test/test_methods.py index dc902db36..21fede687 100644 --- a/wrapper/python/wolfssl/test/test_methods.py +++ b/wrapper/python/wolfssl/test/test_methods.py @@ -20,59 +20,39 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -# pylint: disable=missing-docstring, invalid-name, import-error +# pylint: disable=missing-docstring, redefined-outer-name, import-error -import unittest +import pytest from wolfssl._methods import (WolfSSLMethod, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLS, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2) from wolfssl._ffi import ffi as _ffi +@pytest.fixture( + params=[PROTOCOL_SSLv3, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1], + ids=["SSLv3", "TLSv1", "TLSv1_1"]) +def unsupported_method(request): + yield request.param -class TestMethods(unittest.TestCase): - def test_SSLv3_raises(self): - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_SSLv3, False) - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_SSLv3, True) +@pytest.fixture( + params=[PROTOCOL_SSLv23, PROTOCOL_TLS, PROTOCOL_TLSv1_2], + ids=["SSLv23", "TLS", "TLSv1_2"]) +def supported_method(request): + yield request.param - def test_TLSv1_raises(self): - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_TLSv1, False) - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_TLSv1, True) +def test_unsupported_method(unsupported_method): + with pytest.raises(ValueError): + WolfSSLMethod(unsupported_method, False) + with pytest.raises(ValueError): + WolfSSLMethod(unsupported_method, True) - def test_TLSv1_1_raises(self): - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_TLSv1_1, False) - self.assertRaises(ValueError, WolfSSLMethod, PROTOCOL_TLSv1_1, True) +def test_supported_method(supported_method): + client = WolfSSLMethod(supported_method, False) + server = WolfSSLMethod(supported_method, True) - - def test_SSLv23_doesnt_raises(self): - client = WolfSSLMethod(PROTOCOL_SSLv23, False) - server = WolfSSLMethod(PROTOCOL_SSLv23, True) - - self.assertIsInstance(client, WolfSSLMethod) - self.assertIsInstance(server, WolfSSLMethod) - - self.assertNotEqual(client.native_object, _ffi.NULL) - self.assertNotEqual(server.native_object, _ffi.NULL) - - - def test_TLS_doesnt_raises(self): - client = WolfSSLMethod(PROTOCOL_TLS, False) - server = WolfSSLMethod(PROTOCOL_TLS, True) - - self.assertIsInstance(client, WolfSSLMethod) - self.assertIsInstance(server, WolfSSLMethod) - - self.assertNotEqual(client.native_object, _ffi.NULL) - self.assertNotEqual(server.native_object, _ffi.NULL) - - - def test_TLSv1_2_doesnt_raises(self): - client = WolfSSLMethod(PROTOCOL_TLSv1_2, False) - server = WolfSSLMethod(PROTOCOL_TLSv1_2, True) - - self.assertIsInstance(client, WolfSSLMethod) - self.assertIsInstance(server, WolfSSLMethod) - - self.assertNotEqual(client.native_object, _ffi.NULL) - self.assertNotEqual(server.native_object, _ffi.NULL) + assert isinstance(client, WolfSSLMethod) + assert isinstance(server, WolfSSLMethod) + assert client.native_object != _ffi.NULL + assert server.native_object != _ffi.NULL