Skip to main content

Sans-IO Python implementation of the TLS 1.3 (RFC 8446) protocol stack

Project description

pypi version badge doc stable badge coverage badge

siotls

Sans-IO Python implementation of the TLS 1.3 (RFC 8446) protocol stack.

Quick Start

Install the library and select a cryptographic backend, openssl is a sane choice.

pip install siotls[openssl]

Use siotls.crypto.install to load the cryptography backend you installed.

import siotls

siotls.crypto.install('openssl')

Client config

Create a client-side TLSConfiguration object.

A truststore is required to verify the server certificates, leaving it out makes the configuration insecure (as no certificate will be verified). The get_truststore function attempts to locate and load the truststore of the operating system, and fallbacks on using certifi (Mozilla's bundled root CA certificates) if installed.

from siotls import TLSConfiguration
from siotls.trust import get_truststore

tls_client_config = TLSConfiguration(
    side='client',
    truststore=get_truststore(),
)

Server config

Create a server-side TLSConfiguration object.

Bth a private_key and certificate_chain are required, they must be in DER-format, the siotls.pem module offers utilities to convert PEM to DER.

from siotls import TLSConfiguration
from siotls.pem import decode_pem_certificate_chain, decode_pem_private_key

with open('/path/to/private_key.pem', 'rb') as file:
    der_private_key = decode_pem_private_key(file.read())
with open('/path/to/certificate_chain.pem', 'rb') as file:
    der_certificate_chain = decode_pem_certificate_chain(file.read())

tls_server_config = TLSConfiguration(
    side='server',
    private_key=der_private_key,
    certificate_chain=der_certificate,
)

Connection

Then establish a connection using your favorite network library and create a TLSConnection object for that connection. The following examples show a plain blocking socket client. A server connection would be very similar.

import socket
from siotls import TLSConnection

tls_client_config = ...  # above snippet

sock = socket.create_connection(('example.com', 443))
conn = TLSConnection(tls_client_config, server_hostname='example.com')

The next step is to exchange messages with the peer to secure the connection.

conn.initiate_connection()
if conn.config.side == 'client':
    sock.sendall(conn.data_to_send())
while not conn.is_post_handshake():
    if input_data := sock.recv(4096):
        try:
            conn.receive_data(input_data)
        finally:
            if output_data := conn.data_to_send():
                sock.sendall(output_data)
    else:
        conn.close_receiving_end()  # it goes post handshake

Exchange

The above while loop stops once the connection has been secured (or closed). At this moment it is safe to exchange data, the following example sends a basic HTTP request and prints the result.

req = """\
GET / HTTP/1.1\r
Host: example.com\r
Connection: close\r
\r
"""
res = bytearray()

if conn.is_connected():
    conn.send_data(req.encode())
    sock.sendall(conn.data_to_send())

    while conn.is_connected():
        if input_data := sock.recv(4096):
            try:
                conn.receive_data(input_data)
            finally:
                if output_data := conn.data_to_send():
                    sock.sendall(output_data)
            res += conn.data_to_read()
        else:
            conn.close_receiving_end()  # it disconnects

    conn.close_sending_end()
    sock.sendall(conn.data_to_send())

sock.close()

print(res.decode())

Documentation

Available online at readthedocs.io.

Contribute

The same as usual: fork, branch, pull request.

We are using uv and pre-commit:

# make sure to be in the right directory
cd path/to/siotls

# install dependencies in a venv
uv venv
uv sync --group precommit --group tests --group docs --extra hacl --extra openssl
uv run pre-commit install

# run tests
SIOTLS_INTEGRATION=1 uv run python -m unittest -v

# build docs
uv run sphinx-build -j auto docs/source/ docs/build/

Not all tests run by default, only the fast unittests do. Enable more test suites setting the below environment variables to 1.

  • SIOTLS_INTEGRATION: tests that test more than a single function at a time.
  • SIOTLS_SLOW: tests that make heavy use of the CPU.
  • SIOTLS_EXTERNAL: tests that connect to remote servers on the internet.

The code is linted using ruff and isort, the typehints are validated using mypy. All of them run automatically with pre-commit, so you don't have any command to know.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

siotls-0.0.5.tar.gz (129.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

siotls-0.0.5-py3-none-any.whl (128.2 kB view details)

Uploaded Python 3

File details

Details for the file siotls-0.0.5.tar.gz.

File metadata

  • Download URL: siotls-0.0.5.tar.gz
  • Upload date:
  • Size: 129.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.17

File hashes

Hashes for siotls-0.0.5.tar.gz
Algorithm Hash digest
SHA256 a3b6c901c793e6c9411a557751c9444b37c8b6625304759615c1be0d50fdf65c
MD5 e8bdfc9dd41c21d528af97ad9841c0f0
BLAKE2b-256 83d4d4cb607793ccd0bd1a37c292fba9a027d8926d07cfa630af0edff171ac0e

See more details on using hashes here.

File details

Details for the file siotls-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: siotls-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 128.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.17

File hashes

Hashes for siotls-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c08c21decb766101df475b1d361406638699604ae9f27bbad99afe9d339a4046
MD5 320573c810eb80ccb5e7a0ccc220e944
BLAKE2b-256 edb9a7dd6d7f5c327113036ac289eb82dc5c81cd90e527f9a9e32479e0ef8c26

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page