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