-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Application integration with TPM2 PKCS#11 #605
Comments
|
Thanks Bill, I changed a little bit the CSR generation, to just use CKA_ID=$(tpm2_ptool listobjects --label tls | grep CKA_ID | uniq | awk '{ gsub("\047","", $2); print $2}' | sed 's/.\{2\}/%&/g')
openssl req -new -engine pkcs11 -keyform engine \
-key "pkcs11:id=${CKA_ID};type=private;pin-value=userpin" \
-config client.cnf -out client.csr One weird thing about this:
I was able to provide the PIN to the NodeJS application using the So running the sample NodeJS application like this automatically stablish the connection with sudo OPENSSL_CONF=./ossl.cnf node tls.js pkcs11 38366236363162643431353537643837 ./tls-client/ca.crt ./tls-client/client.crt` I tried removing the PIN requirement by providing an empty PIN, but openssl refused to create the CSR with that key. It request a pin, and the length cannot be empty (minimum 4 characters). I will keep investigating this, let me know if you have any hints. Additionally, the intention of this sample was to be executed from a container. So I created a simple container using Fedora as the base image and installing the pkcs11 dependencies inside (https://gist.github.com/dnoliver/388303c94639b763e9f120e2cbcccf8f#file-dockerfile). Then, running the container like this get the TLS connection done: docker run \
--rm \
--name test \
-ti \
--device /dev/tpm0 \
--device /dev/tpmrm0 \
--volume /etc/tpm2_pkcs11/:/etc/tpm2_pkcs11 \
--volume "$PWD":/root/test \
--net host \
test \
bash -c "OPENSSL_CONF=./ossl.cnf node tls.js pkcs11 38366236363162643431353537643837 ./tls-client/ca.crt ./tls-client/client.crt"
The main idea here is that the system administrator will create private keys in the TPM and get certificates for service using mutual TLS, and then the containers will use those private keys and certs through the PKCS11 interface. The database could be one per host and shared with the containers with a volume mount, or the container itself could generate the db internally. But I think there should be a better way of allowing a container to interact with the TPM other than mounting it as a device. Will keep looking at options here as well. |
@dnoliver I am confused at what I am supposed to do with this? I see you mentioned, "But it is yet not clear how any application could use this engine to retrieve private keys (or certs like in the case of OpenVPN)". Could you help clarify what you'd like? |
Hi Bill, sorry for the delay, I just wanted some review from you on the approach, and you already did that. If the language uses OpenSSL to do the crypto operations, then support should be there, but how to use it depends on language implementation and documentation: you cannot change your cert path with a PKCS11 URI and expect it to work unfortunately. For the PIN: you can create an object without the PIN, but some tools will require it anyways, so you may need to add a PIN. And passing the PIN to the custom application also depends on the language implementation. And finally, if your software runs in a container, the easy way of making it interact with the host TPM is to bind mount Closing this, thank @williamcroberts! |
Yep, and to clarify, PKCS11 URI's are handled at a higher level, usually through something like p11-kit libraries. They are not understood by PKCS11 compliant libraries directly.
You can also fire up qemu with a virtual TPM. See:
|
So, we made the testing and bug fixing work to get tpm2-pkcs11 working for WIFI Authentication and OpenVPN connections.
But it is yet not clear how any application could use this engine to retrieve private keys (or certs like in the case of OpenVPN).
So, I took a shot at trying to use the tpm2-pkcs11 engine from a custom application. And it worked!
Sharing with you how I made it work.
There is a gist as well available here https://gist.github.com/dnoliver/388303c94639b763e9f120e2cbcccf8f
All the test was done with
openssl s_server
,openssl s_client
, EasyRSA and a NodeJS applicationIt is very similar to the https://github.com/tpm2-software/tpm2-pkcs11/blob/master/test/integration/tls-tests.sh.
I will skip the explanation on how to setup the CA, and create the server and client certs. That can be seen in the gist.
Once you have everything create and setup (and after a successful connection with
openssl s_client
), we are ready to create the custom application:Some notes about this very short script:
key
and hope for that to work, but thetls.connect
call complained that the key is not a PEM. My understanding was that private key paths, strings, and pkcs11 uri should be magically interchangeable, but that is not the case for NodeJS at leastprivateKeyIdentifier
, but got weird error messages. The reason why I want to use the uri is because I can set the pin in the URI and not get a prompt. But after setting the Private Key ID, it all worked fineSo, here is the NodeJS version of it:
And the output (server output shown after the
tls.js
script is executed):Based on the output, I assume that the connection was done correctly :)
Some questions (@williamcroberts):
The text was updated successfully, but these errors were encountered: