diff --git a/wrapper/python/wolfcrypt/wolfcrypt/utils.py b/wrapper/python/wolfcrypt/wolfcrypt/utils.py index 34646ff8a..9f7369cb2 100644 --- a/wrapper/python/wolfcrypt/wolfcrypt/utils.py +++ b/wrapper/python/wolfcrypt/wolfcrypt/utils.py @@ -17,22 +17,20 @@ # 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=unused-import, undefined-variable + import sys from binascii import hexlify as b2h, unhexlify as h2b +_PY3 = sys.version_info[0] == 3 +_TEXT_TYPE = str if _PY3 else unicode +_BINARY_TYPE = bytes if _PY3 else str -if sys.version_info[0] == 3: - _text_type = str - _binary_type = bytes -else: - _text_type = unicode - _binary_type = str - - -def t2b(s): +def t2b(string): """ Converts text to bynary. """ - if isinstance(s, _binary_type): - return s - return _text_type(s).encode("utf-8") + if isinstance(string, _BINARY_TYPE): + return string + return _TEXT_TYPE(string).encode("utf-8") diff --git a/wrapper/python/wolfssl/test/test_client.py b/wrapper/python/wolfssl/test/test_client.py index e41e9df75..2ee5c0e96 100644 --- a/wrapper/python/wolfssl/test/test_client.py +++ b/wrapper/python/wolfssl/test/test_client.py @@ -17,28 +17,31 @@ # 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, invalid-name, import-error + import unittest import socket -import wolfssl import ssl +# import wolfssl class SSLClientTest(unittest.TestCase): ssl_provider = ssl host = "www.google.com" port = 443 - + def setUp(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) def test_wrap_socket(self): - self.secure_sock = self.ssl_provider.wrap_socket( - self.sock, ssl_version=ssl.PROTOCOL_SSLv23) - self.secure_sock.connect((self.host, self.port)) + secure_sock = self.ssl_provider.wrap_socket( + self.sock, ssl_version=ssl.PROTOCOL_SSLv23) + secure_sock.connect((self.host, self.port)) - self.secure_sock.send(b"GET / HTTP/1.1\n\n") - self.assertEquals(b"HTTP", self.secure_sock.recv(4)) + secure_sock.send(b"GET / HTTP/1.1\n\n") + self.assertEqual(b"HTTP", secure_sock.recv(4)) - self.secure_sock.close() + secure_sock.close() #class TestWolfSSL(SSLClientTest): diff --git a/wrapper/python/wolfssl/test/test_context.py b/wrapper/python/wolfssl/test/test_context.py index 0b2aaf0cc..6e931b8fd 100644 --- a/wrapper/python/wolfssl/test/test_context.py +++ b/wrapper/python/wolfssl/test/test_context.py @@ -17,9 +17,12 @@ # 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, invalid-name, import-error + import unittest -import wolfssl import ssl +import wolfssl class TestSSLContext(unittest.TestCase): @@ -34,8 +37,11 @@ class TestSSLContext(unittest.TestCase): def test_load_cert_chain(self): self.assertRaises(TypeError, self.ctx.load_cert_chain, None) - def test_load_verify_locations(self): + def test_load_verify_locations_raises(self): self.assertRaises(TypeError, self.ctx.load_verify_locations, None) + def test_load_verify_locations_with_cafile(self): + self.ctx.load_verify_locations(cafile="../../../certs/ca-cert.pem") + class TestWolfSSLContext(TestSSLContext): - provider = wolfssl \ No newline at end of file + provider = wolfssl diff --git a/wrapper/python/wolfssl/test/test_methods.py b/wrapper/python/wolfssl/test/test_methods.py index 7548ed6f6..f49de4648 100644 --- a/wrapper/python/wolfssl/test/test_methods.py +++ b/wrapper/python/wolfssl/test/test_methods.py @@ -17,8 +17,13 @@ # 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, invalid-name, import-error + import unittest -from wolfssl._methods import * +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 @@ -41,31 +46,31 @@ class TestMethods(unittest.TestCase): 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.assertNotEquals(client.native_object, _ffi.NULL) - self.assertNotEquals(server.native_object, _ffi.NULL) + 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.assertNotEquals(client.native_object, _ffi.NULL) - self.assertNotEquals(server.native_object, _ffi.NULL) + 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.assertNotEquals(client.native_object, _ffi.NULL) - self.assertNotEquals(server.native_object, _ffi.NULL) + self.assertNotEqual(client.native_object, _ffi.NULL) + self.assertNotEqual(server.native_object, _ffi.NULL) diff --git a/wrapper/python/wolfssl/wolfssl/_context.py b/wrapper/python/wolfssl/wolfssl/_context.py index 4b318ff6e..1662aace2 100644 --- a/wrapper/python/wolfssl/wolfssl/_context.py +++ b/wrapper/python/wolfssl/wolfssl/_context.py @@ -24,26 +24,29 @@ except ImportError: pass from wolfssl._methods import WolfSSLMethod -from wolfssl._exceptions import * +from wolfssl._exceptions import SSLError +from wolfssl.utils import t2b -CERT_NONE = 0 +CERT_NONE = 0 CERT_OPTIONAL = 1 CERT_REQUIRED = 2 +_SSL_SUCCESS = 1 _SSL_FILETYPE_PEM = 1 class SSLContext: - """An SSLContext holds various SSL-related configuration options and - data, such as certificates and possibly a private key.""" - + """ + An SSLContext holds various SSL-related configuration options and + data, such as certificates and possibly a private key. + """ def __init__(self, protocol, server_side=False): method = WolfSSLMethod(protocol, server_side) - - self.protocol = protocol - self._side = server_side + + self.protocol = protocol + self._side = server_side self.native_object = _lib.wolfSSL_CTX_new(method.native_object) - + # wolfSSL_CTX_new() takes ownership of the method. # the method is freed later inside wolfSSL_CTX_free() # or if wolfSSL_CTX_new() failed to allocate the context object. @@ -70,29 +73,51 @@ class SSLContext: # # def load_cert_chain(self, certfile, keyfile=None, password=None): + """ + Load a private key and the corresponding certificate. The certfile + string must be the path to a single file in PEM format containing + the certificate as well as any number of CA certificates needed to + establish the certificate’s authenticity. + + The keyfile string, if present, must point to a file containing the + private key in. + """ + if certfile: ret = _lib.wolfSSL_CTX_use_certificate_chain_file( - self.native_object, certfile) - if ret != 0: + self.native_object, t2b(certfile)) + if ret != _SSL_SUCCESS: raise SSLError("Unnable to load certificate chain") else: raise TypeError("certfile should be a valid filesystem path") if keyfile: ret = _lib.wolfSSL_CTX_use_PrivateKey_file( - self.native_object, keyfile, _SSL_FILETYPE_PEM) - if ret != 0: + self.native_object, t2b(keyfile), _SSL_FILETYPE_PEM) + if ret != _SSL_SUCCESS: raise SSLError("Unnable to load private key") def load_verify_locations(self, cafile=None, capath=None, cadata=None): - if cafile is None and capath is None and cadata is None: - raise TypeError("cafile, capath and cadata cannot be all omitted") + """ + Load a set of “certification authority” (CA) certificates used to + validate other peers’ certificates when verify_mode is other than + CERT_NONE. At least one of cafile or capath must be specified. + + The cafile string, if present, is the path to a file of concatenated + CA certificates in PEM format. + + The capath string, if present, is the path to a directory containing + several CA certificates in PEM format. + """ + + if cafile is None and capath is None: + raise TypeError("cafile and capath cannot be all omitted") ret = _lib.wolfSSL_CTX_load_verify_locations( self.native_object, - cafile if cafile else _ffi.NULL, - capath if capath else _ffi.NULL) + t2b(cafile) if cafile else _ffi.NULL, + t2b(capath) if capath else _ffi.NULL) - if ret != 0: - raise SSLError("Unnable to load verify locations") + if ret != _SSL_SUCCESS: + raise SSLError("Unnable to load verify locations. Error: %d" % ret) diff --git a/wrapper/python/wolfssl/wolfssl/_methods.py b/wrapper/python/wolfssl/wolfssl/_methods.py index ae0a03d9f..0d929aa9d 100644 --- a/wrapper/python/wolfssl/wolfssl/_methods.py +++ b/wrapper/python/wolfssl/wolfssl/_methods.py @@ -28,10 +28,10 @@ from wolfssl._memory import ( ) -PROTOCOL_SSLv23 = 1 -PROTOCOL_SSLv3 = 2 -PROTOCOL_TLS = 1 -PROTOCOL_TLSv1 = 3 +PROTOCOL_SSLv23 = 1 +PROTOCOL_SSLv3 = 2 +PROTOCOL_TLS = 1 +PROTOCOL_TLSv1 = 3 PROTOCOL_TLSv1_1 = 4 PROTOCOL_TLSv1_2 = 5 @@ -40,6 +40,10 @@ _PROTOCOL_LIST = [PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLS, class WolfSSLMethod: + """ + An SSLMethod holds SSL-related configuration options such as + protocol version and communication side. + """ def __init__(self, protocol, server_side): if protocol not in _PROTOCOL_LIST: diff --git a/wrapper/python/wolfssl/wolfssl/utils.py b/wrapper/python/wolfssl/wolfssl/utils.py new file mode 100644 index 000000000..9f7369cb2 --- /dev/null +++ b/wrapper/python/wolfssl/wolfssl/utils.py @@ -0,0 +1,36 @@ +# utils.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=unused-import, undefined-variable + +import sys +from binascii import hexlify as b2h, unhexlify as h2b + +_PY3 = sys.version_info[0] == 3 +_TEXT_TYPE = str if _PY3 else unicode +_BINARY_TYPE = bytes if _PY3 else str + +def t2b(string): + """ + Converts text to bynary. + """ + if isinstance(string, _BINARY_TYPE): + return string + return _TEXT_TYPE(string).encode("utf-8")