Index: README.txt |
diff --git a/README.txt b/README.txt |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4441de49e5bfd090ce0d5c88ee42d3455d75d2e3 |
--- /dev/null |
+++ b/README.txt |
@@ -0,0 +1,316 @@ |
+ |
+Testing PKCS11 on a development box |
+=================================== |
+ |
+It's quite useful to be able to unit test and debug actual PKCS11 calls on |
+your dev machine. It saves the time of fumbling with the little netbook and |
+makes iteration much faster. |
+ |
+Our typical z600's don't have a hardware TPM, but that's actually not a problem. |
+It turns out its much easier to unit test with a software TPM, since they |
+never require hard reboots to clear the TPM. |
+ |
+So, if you get to the point where you want to hack on pkcs11 calls on your |
+dev box, this document can help you get a working software TPM. |
+ |
+Install "TPM Emulator" |
+---------------------- |
+ |
+TPM Emulator requires cmake, which wasn't installed on my machine. In addition, |
+the version of it that apt-get wanted to install was too old. I downloaded |
+the latest binary tarball from <http://www.cmake.org/cmake/resources/ |
+software.html> and expanded it on my local disk. I ran cmake using an |
+absolute path to the binary. You might want to properly install it in your |
+path somewhere, but I was in a rush. |
+ |
+TPM Emulator also requires GMP, from <http://gmplib.org/>. This installed (on |
+the host, outside of the chroot) without a hitch. Just remember to build it |
+on the local disk so you can install it when its done*. |
+ |
+Finally, TPM Emulator comes with a kernel module, and needs your kernel |
+headers to compile it. In my case `sudo apt-get install |
+linux-headers-2.6.24-gg804006` did the trick. You are almost definitely |
+running a different version of the kernel. Check it with `uname -a`, find the |
+appropriate headers package, and install it. |
+ |
+Once you've got the requirements installed, download the latest tarball from |
+<http://tpm-emulator.berlios.de/>. Build it on your machine, outside of the |
+chroot. Make sure to build it on the local disk, so you can |
+`sudo make install` when its done*. The TPM Emulator page has build |
+instructions. In my case it went like: |
+ |
+ $ cd ~/local/src/tpm-emulator/ |
+ $ mkdir build |
+ $ cd build |
+ $ ~/local/cmake/bin/cmake ../ |
+ $ make install |
+ |
+Once you've got that build, insert the kernel module. The module doesn't seem |
+to get installed as part of `make install`, so you need to install it from the |
+build directory... |
+ |
+ $ cd ~/local/src/tmp-emulator/ |
+ $ sudo insmod build/tmpd_dev/linux/tmpd_dev.ko |
+ |
+This kernel module appears to be a small redirector that sends requests from |
+/dev/tpm over to the Unix domain socket that the emulator will actually listen |
+to. You can verify that it was properly installed with... |
+ |
+ $ lsmod | grep tpmd_dev |
+ |
+And remove it with... |
+ |
+ $ rmmod tpmd_dev |
+ |
+But you don't want to remove it right now. Instead, continue on by starting |
+up the emulator. First, make a directory for the emulator to stash its |
+working state. The default location for the tpm emulator state clashes with |
+trousers, so you'll want to pick a new location. I used... |
+ |
+ $ mkdir ~/local/var/tpm/ |
+ |
+Then, start up the daemon... |
+ |
+ $ sudo tpmd -f -d -s ~/local/var/tpm/ |
+ |
+The -f argument tells it to run in the foreground, so you can easily stop it |
+with Ctrl-C if you want. The -d argument makes it print extra debugging info. |
+ |
+*Note: On Google workstations, root can't access your NFS home directory. If |
+you're not using a Google workstation, this probably doesn't apply to you. |
+ |
+Setup TrouSerS |
+-------------- |
+ |
+Install TrouSerS if you don't already have it, using... |
+ |
+ $ sudo apt-get install trousers |
+ |
+TrouSerS is an API over raw /dev/tpm access, so that applications can code to a |
+higher level of abstraction. Start it on your host (outside of the chroot) |
+with... |
+ |
+ $ sudo tcsd -f |
+ |
+Now you can try actually poking at your tpm. Trousers comes with a set of |
+tpm utilities in /usr/sbin, though you don't actually need root to run them. |
+Start off with an easy one... |
+ |
+ $ /usr/sbin/tpm_version |
+ TPM Version: 01010000 |
+ Manufacturer Info: 4554485a |
+ |
+Then... |
+ |
+ $ /usr/sbin/tpm_getpubek |
+ Public Endorsement Key: |
+ ... lots of stuff... |
+ |
+If that all works, try taking ownership of the TPM... |
+ |
+ $ /usr/sbin/tpm_takeownership |
+ |
+Enter 111111 (six ones) for both the owner and the Storage Root Key (SRK) |
+passwords. Now clear the SRK password... |
+ |
+ $ /usr/sbin/tmp_changeownerauth -s |
+ Enter owner password: |
+ Enter new SRK password: |
+ Confirm password: |
+ |
+Enter 111111 for the owner password, then leave the SRK password blank (just |
+press ENTER.) After this, check to be sure you actually have ownership, try |
+something like... |
+ |
+ $ /usr/sbin/tpm_setclearable -s |
+ Enter owner password: |
+ Owner Clear Disabled: false |
+ Force Clear Disabled: false |
+ |
+The -s means 'status', which will just print whether or not the TPM can be |
+cleared. If you get "Authentication failed", something is bad and you've got |
+to fix it. |
+ |
+If it works, then it's time to try in the chroot, read on. |
+ |
+The /dev/ tree in chroot is linked to /dev on your host. You should be able |
+to verify that /dev/tpm is the same in both places by running `ls -i /dev/tpm/` |
+in and out of the chroot. It should return the same inode number both times. |
+ |
+Now enter your chroot and try tpm_setclearable again. This time though, |
+you're going to have to run the binary that was built for the target, using |
+something like... |
+ |
+ chroot$ scripts/run_32bit.sh /build/x86-generic/usr/sbin/tpm_setclearable -s |
+ |
+The run_32bit.sh shell script just modifies your library path so that the |
+32 bit libraries come first, so that you can run things that were build for |
+the 32 bit image. |
+ |
+The tpm_setclearable command should work exactly the same as it did outside of |
+the chroot. If so, go get a coffee, a smoke, or go for a run around the block. |
+You're getting close. |
+ |
+PKCS#11, OpenCryptoKi, and You |
+------------------------------ |
+ |
+PKCS#11 defines an API for talking to cryptographic smart cards, or "tokens". |
+These tokens are hardware that can perform cryptographic operations. They are |
+used for things like... |
+ |
+ * Generating a secure keypair on the hardware, without revealing the |
+ private portion of the key. Both the public and private key reside |
+ in some form of NVRAM on the token, but the token may only reveal the |
+ public key. |
+ * Perform on-chip encryption or decryption using the keypair. |
+ * Storing arbitrary application data on-chip in public or password |
+ protected NVRAM. |
+ |
+The API assumes that your machine has one or more slots, which can each |
+contain a token. Not all tokens support all operations, and the API has |
+a way to query the token to find out what it supports. |
+ |
+OpenCryptoKi is an implementation of the PKCS#11 API specification. It can |
+be used to talk to real hardware tokens, but it also comes with a software |
+based token that uses the TPM to encrypt an on-disk database of the token's |
+NVRAM. This software based token is what the Enterprise Daemon uses to |
+store VPN and 802.1x certificates. |
+ |
+Setup OpenCryptoKi |
+------------------ |
+ |
+From here on out, we'll be working in the chroot. We have a particular version |
+of opencryptoki in there, and it's sometimes a finicky piece of software to |
+work with. |
+ |
+Before you get started, make sure you've built a recent tree, and that it works. |
+It's helpful to know that whatever you've got built in the chroot is sane, so |
+go ahead and build an image and boot it on a device. |
+ |
+Then, from inside the chroot, add yourself to the pkcs11 group. Something |
+like... |
+ |
+ chroot$ sudo /usr/sbin/usermod -a -G pkcs11 $USER |
+ |
+( The pkcs11 group should be made as part of the build. If you don't have it ) |
+( try exiting the chroot and re-entering. ) |
+ |
+Then exit the chroot and come back in, to make sure it took affect. Prove it |
+to yourself with something like... |
+ |
+ chroot$ groups | grep pkcs11 |
+ |
+Now you'll need to create the virtual slot with the TPM based virtual token... |
+ |
+ chroot$ cd ~/trunk/src/scripts |
+ chroot$ sudo ./run32_bit.sh /build/x86-generic/usr/sbin/pkcs_slot -- 0 tpm |
+ |
+( A lot of the commands in this part require the run32_bit.sh script. You ) |
+( can save yourself some typing by running `./run32_bit.sh bash`, so that ) |
+( the environment variable changes live for the life of the new bash shell. ) |
+( When you're done, press Ctrl-D to return back to the previous ) |
+( environment. ) |
+ |
+The pkcs_slot script from OpenCryptoKi is written in Bash, you can peek |
+inside if you're curious what it really does. |
+ |
+The pkcsslotd program expects to be run from /usr/sbin, but in the chroot |
+it is built into /build/x86-generic/usr/sbin. A symlink will fix that... |
+ |
+ chroot$ cd /usr/sbin/ |
+ chroot$ sudo ln -s /build/x86-generic/usr/sbin/pkcsslotd . |
+ |
+Now start pkcsslotd with... |
+ |
+ chroot$ cd ~/trunk/src/scripts |
+ chroot$ sudo run_32bit.sh /usr/sbin/pkcsslotd |
+ |
+This should start without issue, and you can move on to some quick tests... |
+ |
+ chroot$ ./run_32bit.sh /build/x86-generic/usr/sbin/pkcsconf -- -i |
+ PKCS#11 Info |
+ ... |
+ |
+ chroot$ ./run_32bit.sh /build/x86-generic/usr/sbin/pkcsconf -- -s |
+ Slot #0 Info |
+ ... |
+ |
+ chroot$ ./run_32bit.sh /build/x86-generic/usr/sbin/pkcsconf -- -t |
+ Token #0 Info: |
+ ... |
+ Flags: 0x880045 (RNG|LOGIN_REQUIRED|CLOCK_ON_TOKEN|USER_PIN_TO_BE_CHANGED| |
+ SO_PIN_TO_BE_CHANGED) |
+ ... |
+ |
+Notice the flags associated with the token. The fact that it is missing |
+TOKEN_INITIALIZED means that the token hasn't yet been set up. Also notice |
+USER_PIN_TO_BE_CHANGED and SO_PIN_TO_BE_CHANGED, which mean that our token |
+these PINs (numeric passwords) to be changed. Tpmtoken_init helps with that... |
+ |
+ chroot$ ./run_32bit.sh /build/x86-generic/usr/bin/tpmtoken_init |
+ A new TPM security officer password is needed. The password must be between |
+ 6 and 127 characters in length. |
+ Enter new password: |
+ |
+Type 111111 (six ones) and press enter. When this completes the tokens |
+flags should be different... |
+ |
+ chroot$ ./run_32bit.sh /build/x86-generic/usr/sbin/pkcsconf -- -t |
+ Token #0 Info: |
+ ... |
+ Flags: 0x44D (RNG|LOGIN_REQUIRED|USER_PIN_INITIALIZED|CLOCK_ON_TOKEN| |
+ TOKEN_INITIALIZED) |
+ ... |
+ |
+Now we have TOKEN_INITIALIZED, and the PINs no longer need to be changed. |
+Now list out all of the object stored on the token... |
+ |
+ $ ./run_32bit.sh /build/x86-generic/usr/bin/tpmtoken_objects |
+ Enter your TPM user password: |
+ No objects found |
+ |
+And there you go! We haven't put anything on the token yet, so there is |
+nothing to list. You're now ready to unit tests that require a functioning |
+PKCS#11 device, without having to copy them to the netbook, or reboot to |
+clear your TPM. |
+ |
+Troubleshooting |
+--------------- |
+ |
+Don't forget to remove the SRK password as described above. If you do forget, |
+you'll get a 0x6 error (CKR_FUNCTION_FAILED) when you try to initialize the |
+token. |
+ |
+If you're getting 0x2 (CKR_HOST_MEMORY) errors, you probably aren't in the |
+pkcs11 group, or pkcsslotd hasn't started. |
+ |
+The openCryptoki website is absolutely awful. It's basically a blank page that |
+looks like it should have some information in it, but doesn't. There is |
+a little documentation in the source though. Start with the FAQ: |
+<http://opencryptoki.git.sourceforge.net/git/gitweb.cgi?p=opencryptoki/ |
+opencryptoki;a=blob_plain;f=FAQ;hb=HEAD>. |
+ |
+For more information on the PKCS#11 API see the RSA website <http://www.rsa.com/ |
+rsalabs/node.asp?id=2133>. Specifically, the PKCS#11 Core Specification, which |
+is not as daunting as it looks at first. |
+ |
+For a little more nitty gritty, open /build/x86-generic/usr/include/ |
+opencryptoki/pkcs11types.h in your editor. This can be a handy way to map |
+hexadecimal error codes to their mnemonics when things go wrong. |
+ |
+If you get sideways and want to start from scratch, here are the things you |
+might want to remove (it's probably a good idea to stop the daemons that might |
+have open file handles before removing this stuff): |
+ |
+ * Outside of the chroot, tpmd is going to store some state wherever you told |
+ it to with the -s option. This document recommended ~/local/var/tpm. |
+ * Also outside of the chroot, the TrouSerS daemon tcsd stores some state in |
+ /var/lib/tpm/. |
+ * Inside the chroot, pkcsslotd stores your token data under |
+ /var/lib/opencryptoki/... |
+ - The pk_config_data file is a manifest of slots, created by pkcs_slot. |
+ - The tpm/ directory contains per-user NVRAM for the TPM backed slot. If |
+ you're going to delete this, make sure the entire user directory goes |
+ away. The pkcs_slot script won't correctly repopulate the directory if |
+ it finds some leftovers from a previous run. |
+ |