Adding DTLS support
parent
94f7769d6e
commit
3adf33d460
|
|
@ -59,6 +59,11 @@ def build_arg_parser():
|
|||
"(SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3, SSLv23)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-u", action="store_true",
|
||||
help="Use UDP DTLS, add -v 0 for DTLSv1, -v 1 for DTLSv1.2 (default)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-l", metavar="ciphers", type=str, default="",
|
||||
help="Cipher suite list (: delimited)"
|
||||
|
|
@ -103,7 +108,7 @@ def build_arg_parser():
|
|||
return parser
|
||||
|
||||
|
||||
def get_method(index):
|
||||
def get_SSLmethod(index):
|
||||
return (
|
||||
wolfssl.PROTOCOL_SSLv3,
|
||||
wolfssl.PROTOCOL_TLSv1,
|
||||
|
|
@ -113,17 +118,27 @@ def get_method(index):
|
|||
wolfssl.PROTOCOL_SSLv23
|
||||
)[index]
|
||||
|
||||
def get_DTLSmethod(index):
|
||||
return (
|
||||
wolfssl.PROTOCOL_DTLSv1,
|
||||
wolfssl.PROTOCOL_DTLSv1_2
|
||||
)[index]
|
||||
|
||||
def main():
|
||||
args = build_arg_parser().parse_args()
|
||||
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
||||
# DTLS connection over UDP
|
||||
if args.u:
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
|
||||
context = wolfssl.SSLContext(get_DTLSmethod(args.v))
|
||||
# SSL/TLS connection over TCP
|
||||
else:
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
||||
context = wolfssl.SSLContext(get_SSLmethod(args.v))
|
||||
|
||||
# enable debug, if native wolfSSL has been compiled with '--enable-debug'
|
||||
wolfssl.WolfSSL.enable_debug()
|
||||
|
||||
context = wolfssl.SSLContext(get_method(args.v))
|
||||
|
||||
context.load_cert_chain(args.c, args.k)
|
||||
|
||||
if args.d:
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ def build_arg_parser():
|
|||
"(SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1_3, SSLv23)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-u", action="store_true",
|
||||
help="Use UDP DTLS, add -v 0 for DTLSv1, -v 1 for DTLSv1.2"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-l", metavar="ciphers", type=str, default="",
|
||||
help="Cipher suite list (: delimited)"
|
||||
|
|
@ -92,7 +97,7 @@ def build_arg_parser():
|
|||
return parser
|
||||
|
||||
|
||||
def get_method(index):
|
||||
def get_SSLmethod(index):
|
||||
return (
|
||||
wolfssl.PROTOCOL_SSLv3,
|
||||
wolfssl.PROTOCOL_TLSv1,
|
||||
|
|
@ -102,21 +107,36 @@ def get_method(index):
|
|||
wolfssl.PROTOCOL_SSLv23
|
||||
)[index]
|
||||
|
||||
def get_DTLSmethod(index):
|
||||
return (
|
||||
wolfssl.PROTOCOL_DTLSv1,
|
||||
wolfssl.PROTOCOL_DTLSv1_2
|
||||
)[index]
|
||||
|
||||
|
||||
def main():
|
||||
args = build_arg_parser().parse_args()
|
||||
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
||||
bind_socket.bind(("" if args.b else "localhost", args.p))
|
||||
bind_socket.listen(5)
|
||||
# DTLS connection over UDP
|
||||
if args.u:
|
||||
# Set DTLSv1.2 as default if unspecified
|
||||
if args.v == 5:
|
||||
args.v = 1
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
|
||||
bind_socket.bind(("" if args.b else "localhost", args.p))
|
||||
data, from_addr = bind_socket.recvfrom(1)
|
||||
context = wolfssl.SSLContext(get_DTLSmethod(args.v), server_side=True)
|
||||
# SSL/TLS connection over TCP
|
||||
else:
|
||||
bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
|
||||
bind_socket.bind(("" if args.b else "localhost", args.p))
|
||||
bind_socket.listen(5)
|
||||
context = wolfssl.SSLContext(get_SSLmethod(args.v), server_side=True)
|
||||
|
||||
print("Server listening on port", bind_socket.getsockname()[1])
|
||||
|
||||
# enable debug, if native wolfSSL has been compiled with '--enable-debug'
|
||||
wolfssl.WolfSSL.enable_debug()
|
||||
|
||||
context = wolfssl.SSLContext(get_method(args.v), server_side=True)
|
||||
|
||||
context.load_cert_chain(args.c, args.k)
|
||||
|
||||
if args.d:
|
||||
|
|
@ -131,10 +151,11 @@ def main():
|
|||
while True:
|
||||
try:
|
||||
secure_socket = None
|
||||
|
||||
new_socket, from_addr = bind_socket.accept()
|
||||
|
||||
secure_socket = context.wrap_socket(new_socket)
|
||||
if args.u:
|
||||
secure_socket = context.wrap_socket(bind_socket)
|
||||
else:
|
||||
new_socket, from_addr = bind_socket.accept()
|
||||
secure_socket = context.wrap_socket(new_socket)
|
||||
|
||||
print("Connection received from", from_addr)
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ from wolfssl.exceptions import ( # noqa: F401
|
|||
from wolfssl._methods import ( # noqa: F401
|
||||
PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLSv1,
|
||||
PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2, PROTOCOL_TLSv1_3,
|
||||
PROTOCOL_TLS, WolfSSLMethod as _WolfSSLMethod
|
||||
PROTOCOL_TLS, PROTOCOL_DTLSv1, PROTOCOL_DTLSv1_2,
|
||||
WolfSSLMethod as _WolfSSLMethod
|
||||
)
|
||||
|
||||
CERT_NONE = 0
|
||||
|
|
@ -64,6 +65,8 @@ _SSL_FILETYPE_PEM = 1
|
|||
_SSL_ERROR_WANT_READ = 2
|
||||
_SSL_ERROR_WANT_WRITE = 3
|
||||
|
||||
_SOCKADDR_SZ = 16
|
||||
|
||||
_PY3 = sys.version_info[0] == 3
|
||||
|
||||
|
||||
|
|
@ -519,7 +522,6 @@ class SSLSocket(object):
|
|||
"""
|
||||
Enables CRL certificate revocation
|
||||
"""
|
||||
|
||||
ret = _lib.wolfSSL_EnableCRL(self.native_object, options)
|
||||
|
||||
if ret != _SSL_SUCCESS:
|
||||
|
|
@ -529,7 +531,6 @@ class SSLSocket(object):
|
|||
"""
|
||||
Load CRL certificate revocation
|
||||
"""
|
||||
|
||||
ret = _lib.wolfSSL_LoadCRLFile(self.native_object,
|
||||
t2b(path) if path else _ffi.NULL,
|
||||
filetype)
|
||||
|
|
@ -543,7 +544,12 @@ class SSLSocket(object):
|
|||
Returns number of bytes of DATA actually transmitted.
|
||||
"""
|
||||
self._check_closed("write")
|
||||
self._check_connected()
|
||||
# Check connected if not DTLS
|
||||
if self._context.protocol < PROTOCOL_DTLSv1:
|
||||
self._check_connected()
|
||||
# Complete handshake if DTLS connection
|
||||
else:
|
||||
self.do_handshake()
|
||||
|
||||
data = t2b(data)
|
||||
|
||||
|
|
@ -599,7 +605,12 @@ class SSLSocket(object):
|
|||
Return zero-length string on EOF.
|
||||
"""
|
||||
self._check_closed("read")
|
||||
self._check_connected()
|
||||
# Check connected if not DTLS
|
||||
if self._context.protocol < PROTOCOL_DTLSv1:
|
||||
self._check_connected()
|
||||
# Complete handshake if DTLS connection
|
||||
else:
|
||||
self.do_handshake()
|
||||
|
||||
if buffer is not None:
|
||||
raise ValueError("buffer not allowed in calls to "
|
||||
|
|
@ -630,7 +641,8 @@ class SSLSocket(object):
|
|||
to full size of buffer.
|
||||
"""
|
||||
self._check_closed("read")
|
||||
self._check_connected()
|
||||
if self._context.protocol < PROTOCOL_DTLSv1:
|
||||
self._check_connected()
|
||||
|
||||
if buffer is None:
|
||||
raise ValueError("buffer cannot be None")
|
||||
|
|
@ -678,7 +690,8 @@ class SSLSocket(object):
|
|||
if self.native_object != _ffi.NULL:
|
||||
_lib.wolfSSL_shutdown(self.native_object)
|
||||
self._release_native_object()
|
||||
self._sock.shutdown(how)
|
||||
if self._context.protocol < PROTOCOL_DTLSv1:
|
||||
self._sock.shutdown(how)
|
||||
|
||||
def unwrap(self):
|
||||
"""
|
||||
|
|
@ -698,12 +711,23 @@ class SSLSocket(object):
|
|||
|
||||
return sock
|
||||
|
||||
def add_peer(self, addr):
|
||||
peerAddr = _lib.wolfSSL_dtls_create_peer(addr[1],t2b(addr[0]))
|
||||
if peerAddr == _ffi.NULL:
|
||||
raise SSLError("Failed to create peer")
|
||||
ret = _lib.wolfSSL_dtls_set_peer(self.native_object, peerAddr,
|
||||
_SOCKADDR_SZ)
|
||||
if ret != _SSL_SUCCESS:
|
||||
raise SSLError("Unable to set dtls peer. E(%d)" % ret)
|
||||
_lib.wolfSSL_dtls_free_peer(peerAddr)
|
||||
|
||||
def do_handshake(self, block=False): # pylint: disable=unused-argument
|
||||
"""
|
||||
Perform a TLS/SSL handshake.
|
||||
"""
|
||||
self._check_closed("do_handshake")
|
||||
self._check_connected()
|
||||
if self._context.protocol < PROTOCOL_DTLSv1:
|
||||
self._check_connected()
|
||||
|
||||
if self._server_side:
|
||||
ret = _lib.wolfSSL_accept(self.native_object)
|
||||
|
|
@ -756,13 +780,19 @@ class SSLSocket(object):
|
|||
if self._connected:
|
||||
raise ValueError("attempt to connect already-connected SSLSocket!")
|
||||
|
||||
if connect_ex:
|
||||
err = self._sock.connect_ex(addr)
|
||||
err = 0
|
||||
ret = _SSL_SUCCESS
|
||||
|
||||
if self._context.protocol >= PROTOCOL_DTLSv1:
|
||||
self.add_peer(addr)
|
||||
else:
|
||||
err = 0
|
||||
self._sock.connect(addr)
|
||||
if connect_ex:
|
||||
err = self._sock.connect_ex(addr)
|
||||
else:
|
||||
err = 0
|
||||
self._sock.connect(addr)
|
||||
|
||||
if err == 0:
|
||||
if err == 0 and ret == _SSL_SUCCESS:
|
||||
self._connected = True
|
||||
if self.do_handshake_on_connect:
|
||||
self.do_handshake()
|
||||
|
|
|
|||
|
|
@ -156,9 +156,15 @@ def make_flags(prefix, debug):
|
|||
# tls 1.3
|
||||
flags.append("--enable-tls13")
|
||||
|
||||
# dtls
|
||||
flags.append("--enable-dtls")
|
||||
|
||||
# crl
|
||||
flags.append("--enable-crl")
|
||||
|
||||
# wrapper allocators
|
||||
cflags.append("-DWOLFSSL_WRAPPER_ALLOCATORS")
|
||||
|
||||
# for urllib3 - requires SNI (tlsx), options (openssl compat), peer cert
|
||||
flags.append("--enable-tlsx")
|
||||
flags.append("--enable-opensslextra")
|
||||
|
|
@ -202,7 +208,7 @@ def make(configure_flags):
|
|||
call("make install")
|
||||
|
||||
|
||||
def build_wolfssl(ref, debug=False):
|
||||
def build_wolfssl(ref, debug=True):
|
||||
prefix = local_path("lib/wolfssl/{}/{}".format(
|
||||
get_platform(), ref))
|
||||
libfile = os.path.join(prefix, 'lib/libwolfssl.la')
|
||||
|
|
@ -394,6 +400,12 @@ cdef += """
|
|||
WOLFSSL_METHOD* wolfSSLv23_client_method(void);
|
||||
|
||||
WOLFSSL_METHOD* wolfSSLv23_method(void);
|
||||
|
||||
WOLFSSL_METHOD* wolfDTLSv1_server_method(void);
|
||||
WOLFSSL_METHOD* wolfDTLSv1_client_method(void);
|
||||
|
||||
WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void);
|
||||
WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void);
|
||||
"""
|
||||
if OLDTLS_ENABLED:
|
||||
cdef += """
|
||||
|
|
@ -453,6 +465,9 @@ cdef += """
|
|||
void wolfSSL_set_connect_state(WOLFSSL*);
|
||||
int wolfSSL_EnableCRL(WOLFSSL*, int);
|
||||
int wolfSSL_LoadCRLFile(WOLFSSL*, const char*, int);
|
||||
void* wolfSSL_dtls_create_peer(int, char*);
|
||||
int wolfSSL_dtls_free_peer(void*);
|
||||
int wolfSSL_dtls_set_peer(WOLFSSL*, void*, unsigned int);
|
||||
|
||||
/**
|
||||
* WOLFSSL_X509 functions
|
||||
|
|
|
|||
|
|
@ -36,10 +36,12 @@ PROTOCOL_TLSv1 = 3
|
|||
PROTOCOL_TLSv1_1 = 4
|
||||
PROTOCOL_TLSv1_2 = 5
|
||||
PROTOCOL_TLSv1_3 = 6
|
||||
PROTOCOL_DTLSv1 = 7
|
||||
PROTOCOL_DTLSv1_2 = 8
|
||||
|
||||
_PROTOCOL_LIST = [PROTOCOL_SSLv23, PROTOCOL_SSLv3, PROTOCOL_TLS,
|
||||
PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2,
|
||||
PROTOCOL_TLSv1_3]
|
||||
PROTOCOL_TLSv1_3, PROTOCOL_DTLSv1, PROTOCOL_DTLSv1_2]
|
||||
|
||||
_DYNAMIC_TYPE_METHOD = 11
|
||||
|
||||
|
|
@ -86,6 +88,17 @@ class WolfSSLMethod(object): # pylint: disable=too-few-public-methods
|
|||
_lib.wolfSSLv23_server_method() if server_side else \
|
||||
_lib.wolfSSLv23_client_method()
|
||||
|
||||
elif protocol == PROTOCOL_DTLSv1:
|
||||
self.native_object = \
|
||||
_lib.wolfDTLSv1_server_method() if server_side else \
|
||||
_lib.wolfDTLSv1_client_method()
|
||||
|
||||
elif protocol == PROTOCOL_DTLSv1_2:
|
||||
self.native_object = \
|
||||
_lib.wolfDTLSv1_2_server_method() if server_side else \
|
||||
_lib.wolfDTLSv1_2_client_method()
|
||||
|
||||
|
||||
if self.native_object == _ffi.NULL:
|
||||
raise MemoryError("Unnable to allocate method object")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue