sample client/server webapp in python using mtls where the client key is resident on a trusted platform module
# on debian 12
apt-get update
apt -y install autoconf-archive libcmocka0 libcmocka-dev procps iproute2 build-essential git pkg-config gcc libtool automake libssl-dev uthash-dev autoconf doxygen libcurl4-openssl-dev dbus-x11 libglib2.0-dev libjson-c-dev acl swtpm swtpm-tools python3-pip python3-requests python3-flask
cd
git clone https://github.com/tpm2-software/tpm2-tss.git
cd tpm2-tss
./bootstrap
./configure --with-udevrulesdir=/etc/udev/rules.d
make -j$(nproc)
make install
udevadm control --reload-rules && sudo udevadm trigger
ldconfig
cd
git clone https://github.com/tpm2-software/tpm2-tools.git
cd tpm2-tools
./bootstrap
./configure
make install
cd
git clone https://github.com/tpm2-software/tpm2-openssl.git
cd tpm2-openssl
./bootstrap
./configure
make install
### if you want to use softwaretpm
# mkdir /tmp/myvtpm
# swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert
# swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2
# export TPM2TOOLS_TCTI="swtpm:port=2321"
# export TPM2OPENSSL_TCTI="swtpm:port=2321"
export TPM2OPENSSL_TCTI="device:/dev/tpmrm0"
export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/
export TSS2_LOG=esys+debug
$ openssl version
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
git clone https://github.com/salrashid123/ca_scratchpad.git
cd ca_scratchpad
mkdir -p ca/root-ca/private ca/root-ca/db crl certs
chmod 700 ca/root-ca/private
cp /dev/null ca/root-ca/db/root-ca.db
cp /dev/null ca/root-ca/db/root-ca.db.attr
echo 01 > ca/root-ca/db/root-ca.crt.srl
echo 01 > ca/root-ca/db/root-ca.crl.srl
export SAN=single-root-ca
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 \
-pkeyopt rsa_keygen_pubexp:65537 -out ca/root-ca/private/root-ca.key
openssl req -new -config single-root-ca.conf -key ca/root-ca/private/root-ca.key \
-out ca/root-ca.csr
openssl ca -selfsign -config single-root-ca.conf \
-in ca/root-ca.csr -out ca/root-ca.crt \
-extensions root_ca_ext
### create a server cert
export NAME=server
export SAN="DNS:localhost"
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 \
-pkeyopt rsa_keygen_pubexp:65537 -out certs/$NAME.key
openssl req -new -config single-root-ca.conf \
-out certs/$NAME.csr \
-key certs/$NAME.key -reqexts server_reqext \
-subj "/C=US/O=Google/OU=Enterprise/CN=server.domain.com"
openssl ca \
-config single-root-ca.conf \
-in certs/$NAME.csr \
-out certs/$NAME.crt \
-extensions server_ext
### create a client cert
export NAME=tpmc
export SAN="DNS:client.domain.com"
openssl genpkey -provider tpm2 -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-pkeyopt rsa_keygen_pubexp:65537 -out certs/$NAME.key
openssl req -new -provider tpm2 -provider default \
-config single-root-ca.conf -out certs/$NAME.csr \
-key certs/$NAME.key -subj "/C=US/O=Google/OU=Enterprise/CN=client.domain.com"
openssl ca \
-config single-root-ca.conf \
-in certs/$NAME.csr \
-out certs/$NAME.crt \
-policy extern_pol \
-extensions client_ext
$ cat tpmc.key
-----BEGIN TSS2 PRIVATE KEY-----
MIICEgYGZ4EFCgEDoAMBAQECBEAAAAEEggEYARYAAQALAAYAcgAAABAAEAgAAAEA
AQEAyDaWiSc/cRZjXVuL8R3YzzysqhvcXSsabO2NQKR73EJ4NxKG1Q9QmOfnay+E
p1Op2EIEdy3L2Ev43IC9cVwojPkp4UNTj0RPBEGfUoy4pCcxSqdRCTWD5jB5DUG8
KMz6lkhdY39+DsXgieUkkVuWgouMAUEYND9ypHc9kb7N9R1L/TfYkUjohWPnew8w
6WF0gQaZOiZUG+753biUx0xrXQi92fsMNlpcBo6+vWTZjtKzohRbFgBC6RL/yzcC
CtcjZYfUp2XHLR7pGrP+lTwF6T30vpF2VJ4rUSd90f7M9oI+8YhCD3lB2RrRyTe4
7UhVcYFS21OkhmQ3ibZEnOdi/wSB4ADeACAapjcmn7+dwAxM7z57LMl3/pAytfhe
K7cLu0hhWlx1wwAQARrbrL3kKtkIy19XH1wYOS7ypZ66hqU0JkmonptTq0xelguy
v3ak/SMfls2Vrrq6+20W0boQPdVAHl6KoUky4xwDA+fzSvW9tQurhZXkbe6M7yAF
nUBdl+uwZR/e9E+6kbihjiaEvCWqs4YW5ygrigoHVqOA7aTKQ6/4JOgg1pcnt4pX
YLju7KF9ggKtGUDiYqYtiTJ+Y3Xexhv1tv5Iyvw2dbb3An1T5pidlHghqIIQzR7T
Yh9cYFRf
-----END TSS2 PRIVATE KEY-----
export OPENSSL_CONF=`pwd`/openssl.cnf
export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/
export TPM2OPENSSL_TCTI="device:/dev/tpmrm0"
openssl rsa -provider tpm2 -provider default -in certs/tpmc.key --textcreate server.py
from flask import Flask, request
import ssl
app = Flask(__name__)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('certs/server.crt', 'certs/server.key')
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations('ca/root-ca.crt')
@app.route('/')
def index():
client_cert = request.environ.get('SSL_CLIENT_CERT')
if client_cert:
# Validate the client certificate
# ...
return 'Hello, authenticated client!'
else:
return 'Client certificate not found', 401
if __name__ == '__main__':
app.run(ssl_context=context,host="127.0.0.1", port=8443, debug=True)then,
python3 server.py#!/usr/bin/env python
import requests
response = requests.get('https://localhost:8443/', verify='ca/root-ca.crt', cert=('certs/tpmc.crt', 'certs/tpmc.key'))
print("Status Code: %s" % response.status_code)
print(response.text)First create openssl.cnf and with content:
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
tpm2 = tpm2_sect
[default_sect]
activate = 1
[tpm2_sect]
activate = 1
Then
export OPENSSL_CONF=`pwd`/openssl.cnf
export OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/
export TPM2OPENSSL_TCTI="device:/dev/tpmrm0"
python3 client.py