Skip to content

Instantly share code, notes, and snippets.

@bplaat
Last active June 18, 2024 09:29
Show Gist options
  • Save bplaat/a48baa736807477a9ce6cfa33399236b to your computer and use it in GitHub Desktop.
Save bplaat/a48baa736807477a9ce6cfa33399236b to your computer and use it in GitHub Desktop.
Python TLS Client Auth Example

Python TLS Client Auth Example

Generate certs

openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/CN=ca" -keyout ca.key -out ca.crt

openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/CN=localhost" -config <(cat <<EOF
[req]
x509_extensions = v3_req
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
EOF
) -CA ca.crt -CAkey ca.key -keyout server.key -out server.crt

openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/CN=localhost" -config <(cat <<EOF
[req]
x509_extensions = v3_req
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
EOF
) -CA ca.crt -CAkey ca.key -keyout client.key -out client.crt

Inspect certs

openssl x509 -in ca.crt -text
openssl x509 -in server.crt -text
openssl x509 -in client.crt -text
#!/usr/bin/python3
import socket
import ssl
host_addr = '127.0.0.1'
host_port = 8082
server_hostname = 'localhost'
ca_cert = 'ca.crt'
client_cert = 'client.crt'
client_key = 'client.key'
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
context.load_cert_chain(certfile=client_cert, keyfile=client_key)
context.load_verify_locations(cafile=ca_cert)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn = context.wrap_socket(s, server_hostname=server_hostname)
conn.connect((host_addr, host_port))
print("SSL established. Peer: {}".format(conn.getpeercert()))
print("Sending: 'Hello, world!")
conn.send(b"Hello, world!")
print("Closing connection")
conn.close()
#!/usr/bin/python3
import socket
import ssl
listen_addr = '127.0.0.1'
listen_port = 8082
server_cert = 'server.crt'
server_key = 'server.key'
ca_cert = 'ca.crt'
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.verify_mode = ssl.CERT_REQUIRED
context.load_cert_chain(certfile=server_cert, keyfile=server_key)
context.load_verify_locations(cafile=ca_cert)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((listen_addr, listen_port))
s.listen()
while True:
print("Waiting for client")
newsocket, fromaddr = s.accept()
print("Client connected: {}:{}".format(fromaddr[0], fromaddr[1]))
conn = context.wrap_socket(newsocket, server_side=True)
print("SSL established. Peer: {}".format(conn.getpeercert()))
buf = b''
try:
while True:
data = conn.recv(4096)
if data:
buf += data
else:
print("Received:", buf)
break
finally:
print("Closing connection")
conn.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment