-
- -
-
-

Welcome

-

wolfssl Python is a Python module that encapsulates wolfssl C, a lightweight C-language-based SSL/TLS library targeted for embedded, RTOS, or -resource-constrained environments primarily because of its small size, speed, -and portability.

-
-
-

Installation

-

In order to use wolfssl Python, you’ll also need to install wolfssl C.

-
-

Mac OSX

-

Installing from homebrew and pip package managers:

-
# wolfssl C installation
-brew install wolfssl
-
-# wolfssl Python installation
-sudo -H pip install wolfssl
-
-
-

Installing from source code:

-
# wolfssl C installation
-git clone https://github.com/wolfssl/wolfssl.git
-cd wolfssl/
-./autogen.sh
-./configure --enable-sha512
-make
-sudo make install
-
-# wolfssl Python installation
-cd wrapper/python/wolfssl
-sudo make install
-
-
-
-
-

Linux

-
# dependencies installation
-sudo apt-get update
-sudo apt-get install -y git autoconf libtool
-sudo apt-get install -y python-dev python3-dev python-pip libffi-dev
-
-# wolfssl C installation
-git clone https://github.com/wolfssl/wolfssl.git
-cd wolfssl/
-./autogen.sh
-./configure --enable-sha512
-make
-sudo make install
-
-sudo ldconfig
-
-# wolfssl Python installation
-sudo -H pip install wolfssl
-
-
-
-
-
-

Testing

-

To run the tox tests in the source code, you’ll need tox and a few other -requirements. The source code relies at WOLFSSL_DIR/wrapper/python/wolfssl -where WOLFSSL_DIR is the path of wolfssl C‘s source code.

-
    -
  1. Make sure that the testing requirements are installed:
  2. -
-
sudo -H pip install -r requirements-testing.txt
-
-
-
    -
  1. Run make check:
  2. -
-
$ make check
-...
-_________________________________ summary _________________________________
-py27: commands succeeded
-SKIPPED: py34: InterpreterNotFound: python3.4
-py35: commands succeeded
-py36: commands succeeded
-congratulations :)
-
-
-

Note: the test is performed using multiple versions of python. If you are -missing a version the test will be skipped with an InterpreterNotFound -error.

-
-
-

Basic Usage

-

The SSL/TLS protocol works securing an underlying TCP connection, this module -adds the secure layer around the Python standard library -socket module.

-

There are three different paths to secure a socket in this module:

-
    -
  • Using the top level function wolfssl.wrap_socket();
  • -
  • Using the method wrap_socket() from a SSLContext instance;
  • -
  • Creating an SSLSocket object from the scratch.
  • -
-
-
Note 1:
-
It is possible to use the same SSLContext for multiple SSLSockets to save -time and resources.
-
Note 2:
-
Each path provides its own options for fine-tuning the securint parameters. -Check them out in the API documentation.
-
-
-

Using the top level function wolfssl.wrap_socket()

-
>>> import socket
->>> import wolfssl
->>>
->>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
->>>
->>> secure_socket = wolfssl.wrap_socket(sock)
->>>
->>> secure_socket.connect(("www.python.org", 443))
->>>
->>> secure_socket.write(b"GET / HTTP/1.1\n\n")
->>>
->>> print(secure_socket.read())
-b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
->>>
->>> secure_socket.close()
-
-
-
-
-

Using the method wrap_socket() from a SSLContext instance

-
>>> import socket
->>> import wolfssl
->>>
->>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
->>>
->>> context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
->>>
->>> secure_socket = context.wrap_socket(sock)
->>>
->>> secure_socket.connect(("www.python.org", 443))
->>>
->>> secure_socket.write(b"GET / HTTP/1.1\n\n")
->>>
->>> print(secure_socket.read())
-b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
->>>
->>> secure_socket.close()
-
-
-
-
-

Creating an SSLSocket object from the scratch

-
>>> import socket
->>> import wolfssl
->>>
->>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
->>>
->>> secure_socket = wolfssl.SSLSocket(sock)
->>>
->>> secure_socket.connect(("www.python.org", 443))
->>>
->>> secure_socket.write(b"GET / HTTP/1.1\n\n")
->>>
->>> print(secure_socket.read())
-b'HTTP/1.1 500 Domain Not Found\r\nServer: Varnish\r\nRetry-After: 0\r\ncontent-type: text/html\r\nCache-Control: private, no-cache\r\nconnection: keep-alive\r\nContent-Length: 179\r\nAccept-Ranges: bytes\r\nDate: Sun, 05 Feb 2017 21:26:48 GMT\r\nVia: 1.1 varnish\r\nConnection: keep-alive\r\n\r\n\n<html>\n<head>\n<title>Fastly error: unknown domain </title>\n</head>\n<body>\nFastly error: unknown domain: . Please check that this domain has been added to a service.</body></html>'
->>>
->>> secure_socket.close()
-
-
-
-
-
-

API Documentation

-
-

wrap_socket

-
-
-wolfssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=0, ssl_version=1, 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, wraping the underlying socket in an SSL context.

-

The sock parameter must be a SOCK_STREAM socket; other socket types are -unsupported.

-

The keyfile and certfile parameters specify optional files whith proper -key and the certificates 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 serverSSLv3TLSTLSv1TLSv1.1TLSv1.2
SSLv3yesyesnonono
TLS (SSLv23)yesyesyesyesyes
TLSv1noyesyesnono
TLSv1.1noyesnoyesno
TLSv1.2noyesnonoyes
-
-
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 is not supported yet.

-
- -
-
-

SSL/TLS Context

-
-
-class wolfssl.SSLContext(protocol, server_side=False)
-

An SSLContext holds various SSL-related configuration options and -data, such as certificates and possibly a private key.

-
-
-verify_mode
-

Whether to try to verify other peers’ certificates and how to behave -if verification fails. This attribute must be one of CERT_NONE, -CERT_OPTIONAL or CERT_REQUIRED.

-
- -
-
-wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True)
-

Wrap an existing Python socket sock and return an SSLSocket object. -sock must be a SOCK_STREAM socket; other socket types are unsupported.

-

The returned SSL socket is tied to the context, its settings and -certificates. The parameters server_side, do_handshake_on_connect and -suppress_ragged_eofs have the same meaning as in the top-level -wrap_socket() function.

-
- -
-
-set_ciphers(ciphers)
-

Set the available ciphers for sockets created with this context. It -should be a string in the wolfSSL cipher list format. If no cipher can -be selected (because compile-time options or other configuration forbids -use of all the specified ciphers), an SSLError will be raised.

-
- -
-
-load_cert_chain(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.

-

The password parameter is not supported yet.

-
- -
-
-load_verify_locations(cafile=None, capath=None, cadata=None)
-

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.

-
- -
- -
-
-

SSL/TLS Socket

-
-
-class wolfssl.SSLSocket(sock=None, keyfile=None, certfile=None, server_side=False, cert_reqs=0, ssl_version=1, ca_certs=None, do_handshake_on_connect=True, family=<AddressFamily.AF_INET: 2>, sock_type=<SocketKind.SOCK_STREAM: 1>, proto=0, fileno=None, suppress_ragged_eofs=True, ciphers=None, _context=None)
-

This class implements a subtype of socket.socket that wraps the -underlying OS socket in an SSL/TLS connection, providing secure -read and write methods over that channel.

-
-
-context
-

Returns the context used by this object.

-
- -
-
-write(data)
-

Write DATA to the underlying secure channel. -Returns number of bytes of DATA actually transmitted.

-
- -
-
-read(length=1024, buffer=None)
-

Read up to LENGTH bytes and return them. -Return zero-length string on EOF.

-
- -
-
-unwrap()
-

Unwraps the underlying OS socket from the SSL/TLS connection. -Returns the wrapped OS socket.

-
- -
-
-do_handshake(block=False)
-

Perform a TLS/SSL handshake.

-
- -
-
-connect(addr)
-

Connects to remote ADDR, and then wraps the connection in a secure -channel.

-
- -
-
-connect_ex(addr)
-

Connects to remote ADDR, and then wraps the connection in a secure -channel.

-
- -
-
-accept()
-

Accepts a new connection from a remote client, and returns a tuple -containing that new connection wrapped with a server-side secure -channel, and the address of the remote client.

-
- -
- -
-
-
-

Client and Server Examples

-
-

SSL/TLS Client Example

-
import socket
-import wolfssl
-
-CA_DATA = \
-"""
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
-"""
-
-bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
-
-context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
-
-context.verify_mode = wolfssl.CERT_REQUIRED
-context.load_verify_locations(cadata=CA_DATA)
-
-secure_socket = context.wrap_socket(bind_socket)
-
-secure_socket.connect(("www.python.org", 443))
-
-secure_socket.write(b"GET / HTTP/1.1\n\n")
-
-print(secure_socket.read())
-
-secure_socket.close()
-
-
-
-
-

SSL/TLS Server Example

-
import socket
-import wolfssl
-
-bind_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
-
-bind_socket.bind(("", 4433))
-bind_socket.listen(5)
-
-context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2, server_side=True)
-
-context.load_cert_chain("certs/server-cert.pem", "certs/server-key.pem")
-
-while True:
-    try:
-        secure_socket = None
-
-        new_socket, from_addr = bind_socket.accept()
-
-        secure_socket = context.wrap_socket(new_socket)
-
-        print("Connection received from", from_addr)
-
-        print("\n", secure_socket.read(), "\n")
-        secure_socket.write(b"I hear you fa shizzle!")
-
-    except KeyboardInterrupt:
-        print()
-        break
-
-    finally:
-        if secure_socket:
-            secure_socket.close()
-
-bind_socket.close()
-
-
-
-
-
-

Licensing

-

wolfSSL’s software is available under two distinct licensing models: -open source and standard commercial licensing. Please see the relevant -section below for information on each type of license.

-
-

Open Source

-

wolfCrypt and wolfSSL software are free software downloads and may be modified -to the needs of the user as long as the user adheres to version two of the GPL -License. The GPLv2 license can be found on the gnu.org website.

-
-
-

Commercial Licensing

-

Businesses and enterprises who wish to incorporate wolfSSL products into -proprietary appliances or other commercial software products for -re-distribution must license commercial versions. Licenses are generally -issued for one product and include unlimited royalty-free distribution. -Custom licensing terms are also available at licensing@wolfssl.com.

-
-
-
- - -
-