| 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. | 
| + | 
|  |