adds supported curves to context; fixes compatibility issues with py27

This commit is contained in:
Moisés Guimarães
2016-12-13 13:57:24 -03:00
parent 9b58ab0211
commit 1c9147a41e
4 changed files with 59 additions and 15 deletions

View File

@@ -25,7 +25,7 @@
import unittest import unittest
import socket import socket
import ssl import ssl
# import wolfssl import wolfssl
class SSLClientTest(unittest.TestCase): class SSLClientTest(unittest.TestCase):
ssl_provider = ssl ssl_provider = ssl
@@ -37,14 +37,14 @@ class SSLClientTest(unittest.TestCase):
def test_wrap_socket(self): def test_wrap_socket(self):
secure_sock = self.ssl_provider.wrap_socket( secure_sock = self.ssl_provider.wrap_socket(
self.sock, ssl_version=ssl.PROTOCOL_SSLv23) self.sock, ssl_version=self.ssl_provider.PROTOCOL_SSLv23)
secure_sock.connect((self.host, self.port)) secure_sock.connect((self.host, self.port))
secure_sock.send(b"GET / HTTP/1.1\n\n") secure_sock.write(b"GET / HTTP/1.1\n\n")
self.assertEqual(b"HTTP", secure_sock.recv(4)) self.assertEqual(b"HTTP", secure_sock.read(4))
secure_sock.close() secure_sock.close()
#class TestWolfSSL(SSLClientTest): class TestWolfSSL(SSLClientTest):
# ssl_provider = wolfssl ssl_provider = wolfssl

View File

@@ -136,7 +136,7 @@ class TestSSLContext(unittest.TestCase):
self.assertEqual(self.ctx.verify_mode, self.provider.CERT_REQUIRED) self.assertEqual(self.ctx.verify_mode, self.provider.CERT_REQUIRED)
def test_set_ciphers(self): def test_set_ciphers(self):
self.ctx.set_ciphers("DHE-RSA-AES256-SHA256:AES256-SHA256") self.ctx.set_ciphers("DHE-RSA-AES256-SHA256")
def test_load_cert_chain_raises(self): def test_load_cert_chain_raises(self):
self.assertRaises(TypeError, self.ctx.load_cert_chain, None) self.assertRaises(TypeError, self.ctx.load_cert_chain, None)

View File

@@ -19,8 +19,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
import sys
import errno import errno
from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_TYPE from socket import (
socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_TYPE, error as socket_error
)
try: try:
from wolfssl._ffi import ffi as _ffi from wolfssl._ffi import ffi as _ffi
@@ -57,6 +60,32 @@ _SSL_SUCCESS = 1
_SSL_FILETYPE_PEM = 1 _SSL_FILETYPE_PEM = 1
_SSL_ERROR_WANT_READ = 2 _SSL_ERROR_WANT_READ = 2
_WOLFSSL_ECC_SECP160K1 = 15
_WOLFSSL_ECC_SECP160R1 = 16
_WOLFSSL_ECC_SECP160R2 = 17
_WOLFSSL_ECC_SECP192K1 = 18
_WOLFSSL_ECC_SECP192R1 = 19
_WOLFSSL_ECC_SECP224K1 = 20
_WOLFSSL_ECC_SECP224R1 = 21
_WOLFSSL_ECC_SECP256K1 = 22
_WOLFSSL_ECC_SECP256R1 = 23
_WOLFSSL_ECC_SECP384R1 = 24
_WOLFSSL_ECC_SECP521R1 = 25
_WOLFSSL_ECC_BRAINPOOLP256R1 = 26
_WOLFSSL_ECC_BRAINPOOLP384R1 = 27
_WOLFSSL_ECC_BRAINPOOLP512R1 = 28
_SUPPORTED_CURVES = [
_WOLFSSL_ECC_SECP160K1, _WOLFSSL_ECC_SECP160R1, _WOLFSSL_ECC_SECP160R2,
_WOLFSSL_ECC_SECP192K1, _WOLFSSL_ECC_SECP192R1, _WOLFSSL_ECC_SECP224K1,
_WOLFSSL_ECC_SECP224R1, _WOLFSSL_ECC_SECP256K1, _WOLFSSL_ECC_SECP256R1,
_WOLFSSL_ECC_SECP384R1, _WOLFSSL_ECC_SECP521R1,
_WOLFSSL_ECC_BRAINPOOLP256R1, _WOLFSSL_ECC_BRAINPOOLP384R1,
_WOLFSSL_ECC_BRAINPOOLP512R1
]
_PY3 = sys.version_info[0] == 3
class SSLContext(object): class SSLContext(object):
""" """
An SSLContext holds various SSL-related configuration options and An SSLContext holds various SSL-related configuration options and
@@ -82,6 +111,13 @@ class SSLContext(object):
# verify_mode initialization needs a valid native_object. # verify_mode initialization needs a valid native_object.
self.verify_mode = CERT_NONE self.verify_mode = CERT_NONE
if not server_side:
for curve in _SUPPORTED_CURVES:
ret = _lib.wolfSSL_CTX_UseSupportedCurve(self.native_object,
curve)
if ret != _SSL_SUCCESS:
raise SSLError("unnable to set curve (%d)" % curve)
def __del__(self): def __del__(self):
if getattr(self, 'native_object', _ffi.NULL) != _ffi.NULL: if getattr(self, 'native_object', _ffi.NULL) != _ffi.NULL:
@@ -262,12 +298,18 @@ class SSLSocket(socket):
if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM: if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
raise NotImplementedError("only stream sockets are supported") raise NotImplementedError("only stream sockets are supported")
if _PY3:
socket.__init__(self, socket.__init__(self,
family=sock.family, family=sock.family,
type=sock.type, type=sock.type,
proto=sock.proto, proto=sock.proto,
fileno=sock.fileno()) fileno=sock.fileno())
else:
socket.__init__(self, _sock=sock._sock)
self.settimeout(sock.gettimeout()) self.settimeout(sock.gettimeout())
if _PY3:
sock.detach() sock.detach()
elif fileno is not None: elif fileno is not None:
@@ -280,7 +322,7 @@ class SSLSocket(socket):
# see if we are connected # see if we are connected
try: try:
self.getpeername() self.getpeername()
except OSError as exception: except socket_error as exception:
if exception.errno != errno.ENOTCONN: if exception.errno != errno.ENOTCONN:
raise raise
connected = False connected = False

View File

@@ -60,6 +60,8 @@ ffi.cdef(
int wolfSSL_CTX_load_verify_locations(void*, const char*, const char*); int wolfSSL_CTX_load_verify_locations(void*, const char*, const char*);
int wolfSSL_CTX_load_verify_buffer(void*, const unsigned char*, long, int); int wolfSSL_CTX_load_verify_buffer(void*, const unsigned char*, long, int);
int wolfSSL_CTX_use_certificate_chain_file(void*, const char *); int wolfSSL_CTX_use_certificate_chain_file(void*, const char *);
int wolfSSL_CTX_UseSupportedCurve(void*, short);
void* wolfSSL_new(void*); void* wolfSSL_new(void*);
void wolfSSL_free(void*); void wolfSSL_free(void*);