From 8eec3cb8745fc115ff611484653014327f8148bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moise=CC=81s=20Guimara=CC=83es?= Date: Tue, 22 Nov 2016 11:56:39 -0300 Subject: [PATCH] adds initial code for SSLSocket --- wrapper/python/wolfssl/test/test_client.py | 2 + wrapper/python/wolfssl/test/test_methods.py | 2 + wrapper/python/wolfssl/wolfssl/__init__.py | 123 ++++++++++++++++++ wrapper/python/wolfssl/wolfssl/_exceptions.py | 7 + wrapper/python/wolfssl/wolfssl/_memory.py | 2 +- wrapper/python/wolfssl/wolfssl/_socket.py | 30 +++++ 6 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 wrapper/python/wolfssl/wolfssl/__init__.py create mode 100644 wrapper/python/wolfssl/wolfssl/_socket.py diff --git a/wrapper/python/wolfssl/test/test_client.py b/wrapper/python/wolfssl/test/test_client.py index 2ee5c0e96..254f84427 100644 --- a/wrapper/python/wolfssl/test/test_client.py +++ b/wrapper/python/wolfssl/test/test_client.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +# # test_client.py # # Copyright (C) 2006-2016 wolfSSL Inc. diff --git a/wrapper/python/wolfssl/test/test_methods.py b/wrapper/python/wolfssl/test/test_methods.py index f49de4648..dc902db36 100644 --- a/wrapper/python/wolfssl/test/test_methods.py +++ b/wrapper/python/wolfssl/test/test_methods.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +# # test_methods.py # # Copyright (C) 2006-2016 wolfSSL Inc. diff --git a/wrapper/python/wolfssl/wolfssl/__init__.py b/wrapper/python/wolfssl/wolfssl/__init__.py new file mode 100644 index 000000000..2a526a888 --- /dev/null +++ b/wrapper/python/wolfssl/wolfssl/__init__.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +# +# __init__.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 + +from wolfssl._methods import ( + PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLSv1, + PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2, PROTOCOL_TLS +) + +from wolfssl._context import ( + SSLContext, CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED +) + +from wolfssl._socket import SSLSocket + +from wolfssl._exceptions import ( + CertificateError, SSLError, SSLEOFError, SSLSyscallError, + SSLWantReadError, SSLWantWriteError, SSLZeroReturnError +) + +from wolfssl.__about__ import ( + __all__, METADATA +) + +globals().update(METADATA) + +def wrap_socket(sock, keyfile=None, certfile=None, server_side=False, + cert_reqs=CERT_NONE, ssl_version=PROTOCOL_TLS, ca_certs=None, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + ciphers=None): + """ + Takes an instance sock of socket.socket, and returns an instance of + wolfssl.SSLSocket, a subtype of socket.socket, which wraps the underlying + socket in an SSL context. sock must be a SOCK_STREAM socket; other socket + types are unsupported. + + For client-side sockets, the context construction is lazy; if the underlying + socket isn’t connected yet, the context construction will be performed after + connect() is called on the socket. For server-side sockets, if the socket + has no remote peer, it is assumed to be a listening socket, and the + server-side SSL wrapping is automatically performed on client connections + accepted via the accept() method. wrap_socket() may raise SSLError. + + The keyfile and certfile parameters specify optional files which contain a + certificate to be used to identify the local side of the connection. + + The parameter server_side is a boolean which identifies whether server-side + or client-side behavior is desired from this socket. + + The parameter cert_reqs specifies whether a certificate is required from the + other side of the connection, and whether it will be validated if provided. + It must be one of the three values: + CERT_NONE (certificates ignored) + CERT_OPTIONAL (not required, but validated if provided) + CERT_REQUIRED (required and validated) + + If the value of this parameter is not CERT_NONE, then the ca_certs parameter + must point to a file of CA certificates. + + The ca_certs file contains a set of concatenated “certification authority” + certificates, which are used to validate certificates passed from the other + end of the connection. + + The parameter ssl_version specifies which version of the SSL protocol to + use. Typically, the server chooses a particular protocol version, and the + client must adapt to the server’s choice. Most of the versions are not + interoperable with the other versions. If not specified, the default is + PROTOCOL_TLS; it provides the most compatibility with other versions. + + Here’s a table showing which versions in a client (down the side) can + connect to which versions in a server (along the top): + + | client \\ server | SSLv3 | TLS | TLSv1 | TLSv1.1 | TLSv1.2 | + | SSLv3 | yes | yes | no | no | no | + | TLS (SSLv23) | yes | yes | yes | yes | yes | + | TLSv1 | no | yes | yes | no | no | + | TLSv1.1 | no | yes | no | yes | no | + | TLSv1.2 | no | yes | no | no | yes | + + Note: + Which connections succeed will vary depending on the versions of the ssl + providers on both sides of the communication. + + The ciphers parameter sets the available ciphers for this SSL object. It + should be a string in the wolfSSL cipher list format. + + The parameter do_handshake_on_connect specifies whether to do the SSL + handshake automatically after doing a socket.connect(), or whether the + application program will call it explicitly, by invoking the + SSLSocket.do_handshake() method. Calling SSLSocket.do_handshake() explicitly + gives the program control over the blocking behavior of the socket I/O + involved in the handshake. + + The parameter suppress_ragged_eofs specifies how the SSLSocket.recv() method + should signal unexpected EOF from the other end of the connection. If + specified as True (the default), it returns a normal EOF (an empty bytes + object) in response to unexpected EOF errors raised from the underlying + socket; if False, it will raise the exceptions back to the caller. + """ + return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile, + server_side=server_side, cert_reqs=cert_reqs, + ssl_version=ssl_version, ca_certs=ca_certs, + do_handshake_on_connect=do_handshake_on_connect, + suppress_ragged_eofs=suppress_ragged_eofs, + ciphers=ciphers) diff --git a/wrapper/python/wolfssl/wolfssl/_exceptions.py b/wrapper/python/wolfssl/wolfssl/_exceptions.py index 1af6a76ba..87e38dccc 100644 --- a/wrapper/python/wolfssl/wolfssl/_exceptions.py +++ b/wrapper/python/wolfssl/wolfssl/_exceptions.py @@ -77,3 +77,10 @@ class SSLEOFError(SSLError): when this error is encountered. """ pass + +class CertificateError(ValueError): + """ + Raised to signal an error with a certificate (such as mismatching hostname). + Certificate errors detected by wolfSSL, though, raise an SSLError. + """ + pass diff --git a/wrapper/python/wolfssl/wolfssl/_memory.py b/wrapper/python/wolfssl/wolfssl/_memory.py index 7fd541cd3..e272b7ac8 100644 --- a/wrapper/python/wolfssl/wolfssl/_memory.py +++ b/wrapper/python/wolfssl/wolfssl/_memory.py @@ -28,4 +28,4 @@ except ImportError: _DYNAMIC_TYPE_METHOD = 11 def _native_free(native_object, dynamic_type): - _lib.wolfSSL_Free(native_object, _ffi.NULL, dynamic_type) \ No newline at end of file + _lib.wolfSSL_Free(native_object, _ffi.NULL, dynamic_type) diff --git a/wrapper/python/wolfssl/wolfssl/_socket.py b/wrapper/python/wolfssl/wolfssl/_socket.py new file mode 100644 index 000000000..d6a7cf166 --- /dev/null +++ b/wrapper/python/wolfssl/wolfssl/_socket.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# +# _socket.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 +import socket + +class SSLSocket(socket.socket): + """ + This class implements a subtype of socket.socket that wraps + the underlying OS socket in an SSL context when necessary, and + provides read and write methods over that channel. + """ + pass