Disclaimer
Disclaimer: This text is a collection of observations and complaints about the state of PKI in general, PKCS#11 in particular, and about some software products. Let me preface that the provider of the cryptotoken (and software) that this text is based on has three things in their favor: 1. Their products work, 2. Their support is good, 3. Their products work.
It cannot be stressed enough that spending lots of money on crypto hardware is no guarantee whatsoever that what you get works, or works better, or is better supported.
The goal
Save important secrets in a cryptotoken to be safe from theft of file based secrets.
Ideal turn of events
- Acquire cryptotoken at an affordable price (under 20$)
- Generate Keypair(s) on cryptotoken
- Simply point SSH and GPG at cryptotoken instead of file based secrets
- Profit! I will now know that I have lost my secrets when I lose the physical token. But then I know I have to take action and can safely revoke trust in any of the data that was on the token.
Sounds great, right?
Actual turn of events
- Cheap cryptotokens are available, but you might not want to buy the cheapest ones as they're built by people with a reputation of coordinating with Nation State Attackers. Also, they don't work. If you need a working Cryoptotoken, the price is at 25$ plus shipping for a slow one where some features are disabled.
- Generating the keys on the cryptotoken is pretty easy. But only if you forgo the vendor software and dive right back into the world of dynamically loading c libraries into command line tools you might need to build from scratch because the ones that come with your computer are broken or outdated or both. And if your command line tool's test run crashes and burns with a segfault, it's probably not a big deal; you won't know whether it's your command line tool, your token, or the library module interfacing between the two that's messing things up. You probably don't want to use that specific operation anyway.
- HAHAHAHAHAHAHA!
With SSH, this should be relatively straightforward:
eval $(ssh-agent -s)
ssh-add -s /path/to/cryptotoken_pkcs.dylib
ssh-copy-id user@target # to copy over the token backed public key
ssh user@target # to try the new hotness
In reality, if you're on a Mac, trying the
ssh-add
line above triggers a bug ssh-agent will forkbomb you with ssh-pkcs11-helper processes. So if you were a purist before, this is where you go and turn to homebrew for help. Even Yubico mentions this in their official documentation!
OK, you rebuilt all of ssh, modified your environment so that your bespoke ssh client and associated programs run instead of the system provided one. That was almost straightforward.
Do you like to poke your eye out with a rusty nail? Then you will also like the hoops you have to jump through to get GPG to talk to your cryptotoken.
Don't worry that the
gnupg-pkcs11-scd software
is hosted on a site that's turned so toxic in the four years since the last update to the software that any decent ad blocker will warn you not to go there. Don't worry that you have to run openssl with a dynamically loaded pkcs11 engine which you need to configure in arcane ways even for UNIX standards. Don't worry at all that you may need to manually kill the already running gpg-agent so a new one that knows it needs to talk to the smart card daemon which talkes PGPCard in the direction of gnupg and PKCS11 in the direction of your cryptotoken. Don't worry that the man page for said daemon mentions that the protocol the different components use is unprotected plaintext. Just don't worry, and be enlightened why even smart people stick with file based secrets.In the future
Just hope that you have the instructions how to renew the certificate you need to emulate the PGP card when your key eventually expires. Just hope that you will never need to import another pre-existing keypair to save it from prying eyes. Just hope that apparently everyone who decided to give up was right to do so.
Instructions
- Buy cryptotoken at https://www.cryptas.com/cryptoshop.html they're affordable and deliver quickly.
- Download and install their software (but see the Apocrypha below) and reboot.
- I hid step 3 at the end of the previous step.
- Using homebrew, install (at the bare minimum)
homebrew/dupes/openssh
(for non-broken PKCS#11 support)opensc
(for pkcs11-tool)openssl
(because Apple provides a randomly patched OpenSSL 0.9.8 ...)engine_pkcs11
(to sign your cert with the key in the token for PGP)
- Initialize your token and set your PINs. Don't forget that PINs do not need to be numbers, you can actually use proper password like strings. Depending on your token, you may run into strange limitations like maximum length.
- On the token, generate a keypair. Don't forget to set a key label and id. Do not despair if your token has limits on RSA bit size
- With
engine_pkcs11
, coaxopenssl
into signing a Certificate Signing Request with the key material on the token. I followed random, ancient instructions and things worked, but it's quite a brittle procedure. - As it doesn't seem to be possible to save the signed cert into the token directly, import the cert into your token. Don't forget to set a label and id identical to the keys above, or
gnupg_pkcs11_scd
will not work. - Go through the five step procedure to get the hash that
gnupg_pkcs11_scd
needs to fake the PGPCard side of the deal. I followed some other random, ancient instructions, ignoring everything before "Use eToken with GnuPG", since the instructions begin creating the secrets in files and then importing them, kind of defeating the purpose of having keys in a secure token. I still don't fully understand whygpg --card-status
says I can only use my key for auth, but then the website states Don’t worry about the missing encryption key, actually it is same as the auth key. - Create a revocation cert for your on-token GPG key in case you lose the token. You want to be able to tell the world when you stop being identified by it. Or don't, because why should they trust anyone claiming that a key isn't in use anymore if that information is signed by another key with no history.
- Make sure that all the necessary agents and stuff are automatically loaded and correctly configured. This is where I seriously consider self-managing stuff with puppet, and/or storing pertinent information on the crypto token so I am less likely to lose it. I should have backups somewhere anyway ...
Apocrypha
So, step two in the instructions looks quite innocuous, but I am used from previous and current engagements to check out what Mac installers, especially by companies that are not Mac shops, do. Luckily, most of the installer stuff is preserved in /etc/Athena. Let's take a look:
hwagener:~ hwagener$ cd /etc/Athena/
hwagener:Athena hwagener$ ls -la
total 232
drwxr-xr-x 13 root wheel 442 2 Jul 23:38 .
drwxr-xr-x 90 root wheel 3060 3 Jul 00:31 ..
-rwxrwxrwx 1 root wheel 85852 1 Mai 2014 EditPInfoList
-rwxrwxrwx 1 root wheel 2087 14 Mai 2013 IDPClientDB.xml
-rwxrwxrwx 1 root wheel 2411 7 Apr 2013 IDProtectManager.png
-rwxrwxrwx 1 root wheel 1029 14 Feb 2013 IDProtectPINTool.png
-rwxrwxrwx 1 root wheel 160 20 Jun 2013 Manager
-rwxrwxrwx 1 root wheel 2606 19 Jun 2013 Mozilla
-rwxrwxrwx 1 root wheel 159 20 Jun 2013 PinTool
-rwxrwxrwx 1 root wheel 1823 5 Mai 15:01 postflight
drwxrwxrwx 3 root wheel 102 2 Jul 14:36 ppc
-rwxrwxrwx 1 root wheel 3104 20 Jun 2013 uninstall
drwxrwxrwx 3 root wheel 102 2 Jul 14:36 x86
hwagener:Athena hwagener$
Don't worry for now that we have root-owned world writable binaries and other files here. Don't worry that the installer packs it's own
EditPInfoList
even though /usr/libexec/PlistBuddy
and plutil
exist. I'll get back to that in a bit, let's first bask in a little taste of what all this does:hwagener:Athena hwagener$ cat PinTool
for i in $(dscl . list /Users UniqueID | grep -v Old | awk '$2 >= 500') ; do ln -s /Applications/IDProtect_PINTool.app/ /Users/$i/Desktop/PINTool ; done
Yes, that one-liner creates a symlink on the Desktop of all users pointing to the PinTool. +1 Point for using
dscl . list /Users
, -5 points for lamely assuming that all UIDs > 500 are game for this. 'Manager' does the same, only for the card manager. The Mozilla
script does abominable things and still references PPC architecture. What year is it?! Oh, and -100,000,000 points for not allowing you to disable this in the installer in the first place!
OK, these are small little scripts that try to be nice and set up things for users so it works easily when you use Firefox. But the real nuggets are in the postflight script.
- Patching system files that may be clobbered by any upcoming OS updates. Will this even continue working in OS X 10.11?
sudo "/etc/Athena/EditPInfoList" "0x0DC3" "0x1004" "Athena ASEDrive CCID" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x0DC3" "0x1007" "Athena ASEDrive IIIe KB BIO-PIV" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x0DC3" "0x0900" "Athena IDProtect Key" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x0DC3" "0x1102" "Athena ASEDrive IIIe KB" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x0DC3" "0x100F" "Athena ASEKey CCID" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x24DC" "0x0101" "Aladdin RD JaCarta PKI" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist" sudo "/etc/Athena/EditPInfoList" "0x24DC" "0x100F" "Aladdin RD JaCarta PKI Flash" "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist"
- Creating random directories in the home directory of the user that originally started the installer. And then copies random XML files in there:
if [ ! -d $HOME/.ase ] then mkdir -p $HOME/.ase fi ls -l *.xml mv -f /private/tmp/*.xml "$HOME/.ase"
The one file that will end up in $HOME/.ase on a non-hostile system isIDPClientDB.xml
, but it looks eminently different than/etc/Athena/IDPClientDB.xml
- Deleting random directories in the home directory of the user that originally started the installer
if [ -f "$HOME/real_fox" ] then export DB_PATH=`cat "$HOME/temp_path"` if [ -f "$HOME/real_fox" ] then rm "$HOME/real_fox" fi if [ -f "$HOME/temp_path" ] then rm "$HOME/temp_path" fi fi
- Hiding cleanup jobs to remove another application's configuration. This is great for people that need backwards compatibility, I guess?
if [ -f "/Library/Application Support/Athena/SCLauncher" ] then rm "/Library/Application Support/Athena/SCLauncher" fi if [ -f "/Library/LaunchAgents/SCLauncher.plist" ] then rm "/Library/LaunchAgents/SCLauncher.plist" fi
In a nutshell, if you need to deploy this in a managed environment, you want to try to isolate the necessary steps and re-roll the install package so that:
- Only the necessary files are installed (I omitted that the pin tool and manager bring their own QT and plunk that somewhere in
/usr/local
; the only reason to keep them around is that you cannot reset the SO-PIN withpkcs11-tool
— you need the proprietary PinTool for that.). - Changes to system files are self-contained and can be re-done after OS updates without having to effectively re-run a bunch of hostile shell scripts.
- The package can be managed with the likes of munki and that uninstalls are possible.
By the way, the real bad news is that all this is not as bad as I've seen before from other security companies that realized their business model should embrace Apple products.