Using a TPM =========== 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. NOTES ----- 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](http://blog.habets.pp.se/2013/11/TPM-chip-protecting-SSH-keys---properly) * 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. General principals ------------------ 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. Setting up the TPM ------------------ trousers is the tpm management daemon. You'll need that. * Install "trousers" * Make sure tscd is running. * Keep an eye out, it will open a tcp port, make sure it's bound to localhost! * Install "tpm-tools" * Run `sudo tpm_version` and `sudo tpm_selftest` and make sure everything looks healthy. * If not, go back and try and figure out what's wrong. * The most common reason is that you don't actually have a tpm, or it's disabled in the bios. * run `sudo tpm_takeownership` to initialise the tpm. * Hit "enter" when asked for passwords. tpmtoken\_init doesn't understand passwords. (sigh) * If you get the error message "TPM is deactivated" then you need to enable it in your BIOS. This is done because clearing the tpm is a security risk, so it's enforced to have local access by forcing you to use the BIOS. * If you've already taken ownership, you may need to power off the machine completely (incl. taking out the battery and unplugging power) before the "clear tpm" option appears in the BIOS if it's not there. * If you get a "No EK" error anywhere along the lines, try `sudo tpm_createek` * 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) * Run `pkcs_startup` * Restart the pkcsslotd daemon: `sudo service opencryptoki restart` Setting up your user. --------------------- * Run `tpmtoken_init` to create your user key. * Under [debian](https://bugs.launchpad.net/ubuntu/+source/opencryptoki/+bug/926305) this was failing for me, I had to add /usr/lib/opencryptoki/stdll/ to the library search path. * Verify this with: `p11tool --provider /usr/lib/pkcs11/libopencryptoki.so --list-tokens` * If this fails with a set pin failure, you need to go back and take ownership again with an empty password. * The default "security officer" password is "87654321". * Use `/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` * You may get a warning about ALWAYS\_AUTHENTICATE, which means that your tpm doesn't support that feature, don't worry about it. * Most tools will use all keys (or the first key) in the PKCS11 token, so you might as well just create one key and use it for everything (ie: both ssh and client certs) * If you don't set an ID, ssh will claim "no keys". * List the keys: `pkcs11-tool --module=/usr/lib/opencryptoki/libopencryptoki.so.0 --list-objects --login` Setting up p11-kit ------------------ 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 `~/data/.pkcs11/modules/opencryptoki.module` By default, I believe gnutls will use pkcs11 modules that are registered with p11-kit. Setting up Gnome Keyring ------------------------ 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. Setting up SSH -------------- 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` * Can't find private key might mean you have two public keys and it's trying to use the wrong one. * "no keys" might mean you don't have an identifier (-d) on your key. * Be careful that you're not logging in with an existing ssh key. * 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: `ssh-add -l` * 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). Setting up Chrome ----------------- 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). * Install `nss-tools` * 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 `sql:$HOME/.pki/nssdb/` with `~/.mozilla/firefox/*.default/` Setting up dnssec-signzone -------------------------- 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. * Install `bind9` (duh) * Generate a bind key from the key in the TPM. `dnssec-keyfromlabel -l "$(whoami)@$(hostname --fqdn) key" -f KSK example.net` Setting up OpenVPN ------------------ 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](http://openvpn.net/index.php/open-source/documentation/howto.html#pkcs11_pkcs11_token_config) * `openvpn --show-pkcs11-ids /usr/lib/pkcs11/` should list key ids. Pick one with a * adding: `pcks11-providers /usr/lib/pkcs11/` `pkcs11-id 'aaaa/bbb/41545F5349474E415455524581D2A1A1B23C4AA4CB17FAF7A4600'`