A TPM is designed to hold private keys and do operations on them. This means that you can avoid the private key ever being unencrypted in memory on your machine which makes stealing the private key, even with access to the machine hopefully impossible. Hopefully, even with physical access to the machine the worst the attacker can do is destroy the key material, unless they go to rather extreme lengths.
The downside of this is that it's complicated (hence the long list of things to do below), and the TPM is also quite slow.
Before we begin:
opencryptoki creates exportable keys (ie, with the password you can get the key out of the TPM), this is not really expected. You can perhaps experiment with Thomas Habet's implementation of pkcs11 for trousers
opensc appears to be much nicer than opencryptoki, but doesn't currently appear to support the TSS API exported by Trousers.
If things go wrong, unplug the power, unplug the battery (if any), and then when you reassemble everything on the first boot (only!) go to the BIOS and make sure the TPM is enabled, and clear it. The option in the BIOS often won't show unless it's been fully powered down since the last boot. This is to protect against remote attacks.
The general principal here is to use trousers as an API to the TPM. Then use opencryptoki's support for trousters to make that available as a pkcs11 module. Once we have a pkcs11 module, we can configure the machine to use it (using p11-kit) and/or individually configure programs to use pkcs11 directly. In theory a TPM is just another kind of Hardware Security Module (HSM), like a smart card. So we just use the same APIs.
trousers is the tpm management daemon. You'll need that.
sudo tpm_selftestand make sure everything looks healthy.
sudo tpm_takeownership to initialise the tpm.
If you get a "No EK" error anywhere along the lines, try
Add your user to the "tss" and "pkcs11" group using
sudo vigr, make sure
you've picked up this new group information (probably by logging out and
logging in again)
Restart the pkcsslotd daemon:
sudo service opencryptoki restart
tpmtoken_init to create your user key.
p11tool --provider /usr/lib/pkcs11/libopencryptoki.so --list-tokens
/usr/sbin/pkcsconf -t to list the tokens.
Create an RSA key:
pkcs11-tool --module=/usr/lib/opencryptoki/libopencryptoki.so.0 --login --keypairgen -d 01 -a "$(whoami)@$(hostname --fqdn) key" --key-type rsa:2048
List the keys:
pkcs11-tool --module=/usr/lib/opencryptoki/libopencryptoki.so.0 --list-objects --login
Freedesktop have a reasonably sensible api for registering pkcs11 modules called
p11-kit. Create a file in
/etc/pkcs11/modules/opencryptoki.module with the
contents (if it doesn't already exist):
module: /usr/lib/opencryptoki/libopencryptoki.so.0 critical: no
There are other things you might want to specify in this file, see
http://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html. If you don't
have root, you can instead use the filename
By default, I believe gnutls will use pkcs11 modules that are registered with p11-kit.
From what I've seen Gnome Keyring doesn't yet (2013) support using an external pkcs11 implementation to seal it's key database. It will however export it's database via pkcs11 for other applications to use.
By telling ssh-agent how to use the TPM, when you want to authenticate to other machines, ssh-agent will get the TPM to do the crypto operations on it's behalf. Thus the even the ssh-agent doesn't have direct access to the secret material of your private key.
Unfortunately the TPM is very slow, so doing this may add a second or two to your login process.
Optionally, get the public key as a ssh public key:
ssh-keygen -D /usr/lib/opencryptoki/libopencryptoki.so.0 >~/.ssh/id_rsa.pub
Test this with:
ssh -v -I/usr/lib/opencryptoki/libopencryptoki.so.0 $remotehost
Add the private key to your agent:
ssh-add -s /usr/lib/opencryptoki/libopencryptoki.so.0
Alternatively, use p11-kit's proxy (which will use libopencryptoki since you
added it previously):
ssh-add -s /usr/lib/p11-kit-proxy.so
Verify it's there:
Alternatively, instead of using ssh-agent, you can add:
PKCS11Provider /usr/lib/opencryptoki/libopencryptoki.so.0 to ~/.ssh/config
If you have problems with gnome-keyring not supporting a feature (eg ssh certificates), you can use ssh-agent with p11-kit-proxy to get at keys in gnome-keyring (untested).
Chrome doesn't have any UI that lets you configure PCKS11, but does support it. New versions of chrome may use p11-kit automatically (untested).
Add the TPM PKCS11 module to the chrome db (make sure you've quit chrome first) modutil -dbdir sql:$HOME/.pki/nssdb/ -add "TPM" -libfile /usr/lib/opencryptoki/libopencryptoki.so.0
Alternatively, if you're using p11-kit, you can run the command: modutil --dbdir sql:$HOME/.pki/nssdb/ -add p11-kit -libfile /usr/lib/p11-kit-proxy.so -mechanisms RSA:DSA
Verify with: modutil -dbdir sql:$HOME/.pki/nssdb/ -list
Firefox is similar, just substitue
TODO: Try and figure out how on earth dnssec-signzone works. dnssec-signzone appears to take a -E argument that can probably deal with this. These notes are not yet complete.
Generate a bind key from the key in the TPM.
dnssec-keyfromlabel -l "$(whoami)@$(hostname --fqdn) key" -f KSK example.net
TODO: OpenVPN appears to support PKCS11 so this should work fine, but I've not experimented yet. Cribbed from Open's PCKS#11 Token Config Docs
openvpn --show-pkcs11-ids /usr/lib/pkcs11/ should list key ids. Pick one