There is now a working integration test available that demonstrates how the TLS attestation part of uniquonym will work.
Check out the code at: https://github.com/uniquonym/tls-attestproxy/blob/b7ac76e85680349029705a5533eafdb4cd0a1cc3/crates/tls-attestproxy/tests/integration_test.rs#L209.
To step through the test:
In the test, a local virtual TPM is started up. In the real world, it will be a cloud provider’s vTPM that is spun up with the instance (and outside user control). The test generates an attestation key, and returns the public key - in production, the attestation key will be in the vTPM, and the public key will be signed by the cloud provider.
The creation of a signing key attested by the attestation key proceeds as it will in production.
The TPM context is then passed into a running webserver (on a random port), ready to serve up the certify endpoint of tls-attestproxy.
Then the client is called to create a session. It provides details of what TLS server to connect to (and what server name to send with Server Name Indication).
When creating a session, the ProxyInfo provides the details of the proxy - the randomly picked port and local address, and the attestation key. It also provides the allowed proxy policy configuration registers (PCRs). The attestation key and allowed PCRs are needed because the client verifies the proxy is attested as running the correct code. The proxy gets access to plaintext content of the TLS session, and so this protects against a malicious proxy deployment stealing information.
Note that despite the name, the proxy doesn’t actually connect to the TLS server. That happens from the client - the client sends plaintext to the proxy, and the proxy sends TLS ciphertext to the client, which sends them to the TLS server. Then when the server replies in ciphertext, it is sent to the proxy, and the proxy sends the plaintext back to the client. When the connection is done (e.g. because the server sends an encrypted alert it is closing the connection), the proxy sends an attestation, with a signed hash of the plaintext transcript (plus some other events, e.g. validated certificate). The client also records the entire transcript.
The client puts the attestation from the proxy together with its own record of the transcript, and the attestation of the proxy’s identity, to create a SignedTranscript. This SignedTranscript can be serialised into a binary representation, and later reloaded back to a SignedTranscript.
It is then possible to verify a SignedTranscript using the proxy PCRs and attestation public key. That attestation checks that the transcript hashes to the signed transcript hash, that the signed transcript hash is in fact signed by the signing key, and that the signing key is correctly attested chaining back to the attestation public key, and that the policy hash (typically for a policy checking the PCRs) matches an allowed set (i.e. in production this would represent a known reproducible build of a trusted version of tls-attestproxy). After that verification, in production the verifier would typically also check that the transcript itself is acceptable (e.g. proves what it is supposed to, relates to the correct hostname etc…).