Skip to main content

Adds TLS-PSK support to the Python ssl package

Project description

sslpsk3

PyPI version

This module adds TLS-PSK support to the Python 2.7 and 3.x ssl package. Simply use

sslpsk3.wrap_socket(sock, psk=b'...', ...)

instead of

ssl.wrap_socket(sock, ...)

Backstory

There were two published versions on PyPI, both without Python 3.11 support.

Additionally, for whatever reason, the Windows build of sslpsk2 for Python 3.10 has been linked against OpenSSL 3, while Python 3.10 on Windows uses OpenSSL 1.1.1, which causes run-time crashes (Python started using OpenSSL 3 in 3.11.5).

This fork aims to fix the incompatibility between OpenSSL versions.

Availability of binary wheels for Windows:

  sslpsk sslpsk2 sslpsk3
Python 2.7 1.0.0 - -
Python 3.3 1.0.0 - -
Python 3.4 1.0.0 - -
Python 3.5 1.0.0 - -
Python 3.6 1.0.0 - -
Python 3.7 - 1.0.1 -
Python 3.8 - 1.0.1 1.1.0
Python 3.9 - 1.0.1 1.1.0
Python 3.10 - 1.0.2 1.1.0
Python 3.11 - - 1.1.0

Installation

pip install sslpsk3

pip builds from source for Linux and Mac OSX, so a C compiler, the Python development headers, and the openSSL development headers are required. For Microsoft Windows, pre-built binaries are available so there are no such prerequisites.

Usage

sslpsk3.wrap_socket(...) is a drop-in replacement for ssl.wrap_socket(...) that supports two additional arguments, psk and hint.

psk sets the preshared key and, optionally, the identity for a client connection. hint sets the identity hint for a server connection and is optional.

For client connections, psk can be one of four things:

  1. Just the preshared key.
sslpsk3.wrap_socket(sock, psk=b'mypsk')
  1. A tuple of the preshared key and client identity.
sslpsk3.wrap_socket(sock, psk=(b'mypsk', b'myidentity'))
  1. A function mapping the server identity hint to the preshared key.
PSK_FOR = {b'server1' : b'abcdef',
           b'server2' : b'123456'}

sslpsk3.wrap_socket(sock, psk=lambda hint: PSK_FOR[hint])
  1. A function mapping the server identity hint to a tuple of the preshared key and client identity.
PSK_FOR = {b'server1' : b'abcdef',
           b'server2' : b'123456'}

ID_FOR  = {b'server1' : b'clientA',
           b'server2' : b'clientB'}

sslpsk3.wrap_socket(sock, psk=lambda hint: (PSK_FOR[hint], ID_FOR[hint]))

For server connections, psk can be one of two things:

  1. Just the preshared key.
sslpsk3.wrap_socket(sock, server_side=True, psk=b'mypsk')
  1. A function mapping the client identity to the preshared key.
PSK_FOR = {b'clientA' : b'abcdef',
           b'clientB' : b'123456'}

sslpsk3.wrap_socket(sock, server_side=True, psk=lambda identity: PSK_FOR[identity])

Additionally for server connections, the optional server identity hint is specified using the hint argument.

sslpsk3.wrap_socket(sock, server_side=True, hint=b'myidentity', psk=b'mypsk')

If hint is not specified, None, or the empty string, the identity hint will not be sent to the client.

Example Server

from __future__ import print_function
import socket
import ssl
import sslpsk3

PSKS = {'client1' : 'abcdef',
        'client2' : '123456'}

def server(host, port):
    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcp_sock.bind((host, port))
    tcp_sock.listen(1)

    sock, _ = tcp_sock.accept()
    ssl_sock = sslpsk3.wrap_socket(sock,
                                  server_side = True,
                                  ssl_version=ssl.PROTOCOL_TLSv1,
                                  ciphers='ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH',
                                  psk=lambda identity: PSKS[identity],
                                  hint=b'server1')

    msg = ssl_sock.recv(4).decode()
    print('Server received: %s'%(msg))
    msg = "pong"
    ssl_sock.sendall(msg.encode())

    ssl_sock.shutdown(socket.SHUT_RDWR)
    ssl_sock.close()

def main():
    host = '127.0.0.1'
    port = 6000
    server(host, port)

if __name__ == '__main__':
    main()

Example Client

from __future__ import print_function
import socket
import ssl
import sslpsk3

PSKS = {b'server1' : b'abcdef',
        b'server2' : b'uvwxyz'}

def client(host, port, psk):
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_socket.connect((host, port))

    ssl_sock = sslpsk3.wrap_socket(tcp_socket,
                                  ssl_version=ssl.PROTOCOL_TLSv1,
                                  ciphers='ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH',
                                  psk=lambda hint: (PSKS[hint], b'client1'))

    msg = "ping"
    ssl_sock.sendall(msg.encode())
    msg = ssl_sock.recv(4).decode()
    print('Client received: %s'%(msg))

    ssl_sock.shutdown(socket.SHUT_RDWR)
    ssl_sock.close()

def main():
    host = '127.0.0.1'
    port = 6000
    client(host, port, PSKS)

if __name__ == '__main__':
    main()

Changelog

  • 0.1.0 (July 31, 2017)
    • initial release
  • 1.0.0 (August 2, 2017)
    • include tests in pip distribution
    • add support for Windows
  • 1.0.1 (August 11, 2020)
    • OpenSSL 1.1.1
    • Fix with _sslobj
    • Build from source in Windows with error description, when OpenSSL files are not present
  • 1.1.0 (September 13, 2023)
    • Migrate to GitHub actions
    • Reformat code
    • Support OpenSSL v1 and v3

Acknowledgments

Fork of drbild/sslpsk.

The main approach was borrowed from webgravel/common-ssl.

Version from autinerd/sslpsk2 updated to work with OpenSSL v1 and v3.

Contributing

Please submit bugs, questions, suggestions, or (ideally) contributions as issues and pull requests on GitHub.

License

Copyright 2017 David R. Bild, 2020 Sidney Kuyateh, 2023 Kuba Szczodrzyński

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License from the LICENSE.txt file or at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

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

sslpsk3-1.1.0.tar.gz (13.9 kB view details)

Uploaded Source

Built Distributions

sslpsk3-1.1.0-cp311-cp311-win_amd64.whl (27.0 kB view details)

Uploaded CPython 3.11 Windows x86-64

sslpsk3-1.1.0-cp310-cp310-win_amd64.whl (27.0 kB view details)

Uploaded CPython 3.10 Windows x86-64

sslpsk3-1.1.0-cp39-cp39-win_amd64.whl (27.0 kB view details)

Uploaded CPython 3.9 Windows x86-64

sslpsk3-1.1.0-cp38-cp38-win_amd64.whl (27.0 kB view details)

Uploaded CPython 3.8 Windows x86-64

File details

Details for the file sslpsk3-1.1.0.tar.gz.

File metadata

  • Download URL: sslpsk3-1.1.0.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.13 Linux/6.2.0-1011-azure

File hashes

Hashes for sslpsk3-1.1.0.tar.gz
Algorithm Hash digest
SHA256 5e28266a24a126b4e74201c238cec72dff686aa64e0c85f602d66d14945e559a
MD5 9654d12a951b257117aba4fadced3124
BLAKE2b-256 9af40798d205f164e79861f367d87135b81de76ce47e73933855c7bcdd82d82f

See more details on using hashes here.

File details

Details for the file sslpsk3-1.1.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: sslpsk3-1.1.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.13 Linux/6.2.0-1011-azure

File hashes

Hashes for sslpsk3-1.1.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 b0ee42b96a2ae85b88a5f0d658b73c3adcb57b01dbd13a90602a334cc6bdde4f
MD5 a38c0e67ae6707fadd4f1cfe94b043da
BLAKE2b-256 2886f328837e625a93cce6112681e4bba0d7f0d142a2741575bdc7bc4c0669cb

See more details on using hashes here.

File details

Details for the file sslpsk3-1.1.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: sslpsk3-1.1.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.13 Linux/6.2.0-1011-azure

File hashes

Hashes for sslpsk3-1.1.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c45e01c776a5b97bf03bc7198fb5efed255895698231c6141ee7b35cde219641
MD5 b51ce9f207abeacc85118d5a443b6f7b
BLAKE2b-256 1642ebf2f39473d7f61e21fdbfc6e476d74e5ed180852c22adbb594a462e442b

See more details on using hashes here.

File details

Details for the file sslpsk3-1.1.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: sslpsk3-1.1.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.13 Linux/6.2.0-1011-azure

File hashes

Hashes for sslpsk3-1.1.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 bd7122cc64de73d1247d0034b827fac478bfa2924292bbac7472a5cffecb12c6
MD5 e5006020b4aa043c1152e071c31c51ec
BLAKE2b-256 12d936d789a39dbe1bfab9ed4e7819d23936f15fbd626995c48668e0f891bcc5

See more details on using hashes here.

File details

Details for the file sslpsk3-1.1.0-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: sslpsk3-1.1.0-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.13 Linux/6.2.0-1011-azure

File hashes

Hashes for sslpsk3-1.1.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 10162d6e7bf63696e71bea3a0bde85181ca43ff44ea89c52efb82c2296bf6129
MD5 f0a7a6352824d2c15d45a604bbcb2530
BLAKE2b-256 0e108dd355e166e47dae98e80fe1ea3dbaff19b4c419a129f0372ec4cfdb0518

See more details on using hashes here.

Supported by

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