Skip to main content

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

Project description

pypi version 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 has 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.4a0.tar.gz (134.1 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.4a0-py3-none-any.whl (133.0 kB view details)

Uploaded Python 3

File details

Details for the file siotls-0.0.4a0.tar.gz.

File metadata

  • Download URL: siotls-0.0.4a0.tar.gz
  • Upload date:
  • Size: 134.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for siotls-0.0.4a0.tar.gz
Algorithm Hash digest
SHA256 300a2d8c35d0b9f8bf3ec1857f02e5bd6e814a9c8ecbd710ebd5ab221d2b5883
MD5 ef1e1357eb3315af8d4db29e6223dc2c
BLAKE2b-256 0c87191ce582db80d1032392f4170c19561882f71eb37322f0b23a7f1fc3be5c

See more details on using hashes here.

File details

Details for the file siotls-0.0.4a0-py3-none-any.whl.

File metadata

  • Download URL: siotls-0.0.4a0-py3-none-any.whl
  • Upload date:
  • Size: 133.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.8

File hashes

Hashes for siotls-0.0.4a0-py3-none-any.whl
Algorithm Hash digest
SHA256 1cf8d1659f5eed78a4f4b69769f54d40414fa5490900756f1e5a0246fb73c199
MD5 481f40602181eb226a4b84bfbc2af101
BLAKE2b-256 fc43d7b1ff4747f917db220b05bf2ed4b3f9c3841596047b2379c74797db61e1

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