Portable Symmetric Key Container (PSKC) Library

For the past weeks I have been working on implementing RFC 6030, also known as Portable Symmetric Key Container (PSKC). So what is PSKC? The Portable Symmetric Key Container (PSKC) format is used to transport and provision symmetric keys to cryptographic devices or software.

My PSKC Library allows you to parse, validate and generate PSKC data. The PSKC Library is written in C, uses LibXML, and is licensed under LGPLv2+. In practice, PSKC is most commonly used to transport secret keys for OATH HOTP/TOTP devices (and other OTP devices) between the personalization machine and the OTP validation server. Yesterday I released version 2.0.0 of OATH Toolkit with the new PSKC Library. See my earlier introduction to OATH Toolkit for background. OATH Toolkit is packaged for Debian/Ubuntu and I hope to refresh the package to include libpskc/pskctool soon.

To get a feeling for the PSKC data format, consider the most minimal valid PSKC data:

<?xml version="1.0"?>
<KeyContainer xmlns="urn:ietf:params:xml:ns:keyprov:pskc" Version="1.0">
  <KeyPackage/>
</KeyContainer>

The library can easily be used to export PSKC data into a comma-separated value (CSV) format, in fact the PSKC library tutorial concludes with that as an example. There is complete API documentation for the library. The command line tool is more useful for end-users and allows you to parse and inspect PSKC data. Below is an illustration of how you would use it to parse some PSKC data, first we show the content of a file “pskc-figure2.xml”:

<?xml version="1.0" encoding="UTF-8"?>
<KeyContainer Version="1.0"
	      Id="exampleID1"
	      xmlns="urn:ietf:params:xml:ns:keyprov:pskc">
  <KeyPackage>
    <Key Id="12345678"
         Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:hotp">
      <Issuer>Issuer-A</Issuer>
      <Data>
        <Secret>
          <PlainValue>MTIzNA==
          </PlainValue>
        </Secret>
      </Data>
    </Key>
  </KeyPackage>
</KeyContainer>

Here is how you would parse and pretty print that PSKC data:

jas@latte:~$ pskctool -c pskc-figure2.xml 
Portable Symmetric Key Container (PSKC):
	Version: 1.0
	Id: exampleID1
	KeyPackage 0:
		DeviceInfo:
		Key:
			Id: 12345678
			Issuer: Issuer-A
			Algorithm: urn:ietf:params:xml:ns:keyprov:pskc:hotp
			Key Secret (base64): MTIzNA==

jas@latte:~$

For more information, see the OATH Toolkit website and the PSKC Library Manual.

Using OATH Toolkit with Dropbox

Today there was an announcement that Dropbox supports two-factor authentication. On their page with detailed instructions there is (at the bottom) a link to the man page of the OATH Toolkit command line utility oathtool. OATH Toolkit is available in Ubuntu 12.04 and Debian Wheezy. (Note that the 1.10.4 version in Ubuntu does not support the base32 features.) There is not a lot of details in the documentation on Dropbox’s site on how to use oathtool, but I have experimented a bit with the setup and I’d like to share my findings. I assume you are somewhat familiar with the OATH Toolkit; if not I suggest reading my earlier introduction to OATH Toolkit.

To use OATH Toolkit’s command line utility to generate OTPs that are accepted by Dropbox, here is how you proceed. When you enable two-factor authentication on Dropbox’s site, you must select “Use a mobile app” and on the next screen with the QR code image, click the “enter your secret key manually” link. You will then be presented with a code that looks like this: gr6d 5br7 25s6 vnck v4vl hlao re

Now this code is actually space-delimitted base32 encoded data, without any padding. Since version 1.12.0, oathtool can read base32 encoded keys. However, parsing the raw string fails, so to make it work, you need to remove the spaces and add padding characters. I have yet to see any documentation on the Dropbox implementation, but I assume they always generate 16 binary octets that are base32 encoded into 26 characters like the codes that I have seen. The code is the cryptographic key used for the HMAC-SHA1 computation described in the RFC 6238 that specify OATH TOTP. If you study the base32 encoding you discover that 26 characters needs six pad characters. So converted into proper base32, the string would be gr6d5br725s6vnckv4vlhlaore======. Now generating OTPs are easy, see below.

jas@latte:~$ oathtool --verbose --totp --base32 "gr6d5br725s6vnckv4vlhlaore======"
Hex secret: 347c3e863fd765eab44aaf2ab3ac0e89
Base32 secret: GR6D5BR725S6VNCKV4VLHLAORE======
Digits: 6
Window size: 0
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: 2012-08-27 21:22:54 UTC (1346102574)
Counter: 0x2ACA9C5 (44870085)

125860
jas@latte:~$

Dropbox’s implementation is robust in that it requests a valid OTP from me, generated using the secret they just displayed, before proceeding. This verifies that the user was able to import the key correctly, and that the users’ OATH TOTP implementation appears to work. If I type in the OTP generated from oathtool this way, it allowed me to enable two-factor authentication and I agreed. From that point, signing into the Dropbox service will require a OTP. I invoke the tool, using the same arguments as above, and the tool will use the current time to compute a fresh OTP.

Reflecting on how things could work smoother, I suppose oathtool could be more permissive when it performs the base32 decoding so that the user doesn’t have to fix the base32 spacing/padding manually. I’ll consider this for future releases.

Small syslog server

My home network has several devices that do not have large persistent storage to keep log files. For example, my wireless routers based on OpenWRT doesn’t log to the limited local storage it has, and a Flukso energy metering device log power readings to a ramdisk. These devices log a fair amount of information that I ideally would like to keep for later analysis. I have never before seen a need to setup a syslogd server, thinking that storing logs locally and keeping regular backups of the machine is good enough. However, it appears like this situation calls for a syslogd server. I found an old NSLU2 in my drawer and installed Debian Squeeze on it following Martin Michlmayr’s instructions. I’m using a 4GB USB memory stick for storage, which should hold plenty of log data. I keep backups of the machine in case the USB memory stick wears out.

After customizing the installation to my preferences (disable ssh passwords, disable portmap/rpc.statd/exim4, installing etckeeper, emacs23-nox, etc) I am ready to configure Rsyslog. I found what looked like the perfect configuration example, “Storing messages from a remote system into a specific file”, but it requires me to hard code a bit too much information in the configuration file for my taste. Instead, I found the DynFile concept. With a file /etc/rsyslogd.d/logger.conf as below I can point any new device to my log server and it will automatically create a new file for it. And since the dates are embedded into the filename, I get log rotation suitable for rsync-style backups for free.

$ModLoad imudp
$UDPServerRun 514

$ModLoad imtcp
$InputTCPServerRun 514

$template DynFile,”/var/log/network-%HOSTNAME%-%$year%-%$month%-%$day%.log”
:fromhost-ip, !isequal, “127.0.0.1” ?DynFile
:fromhost-ip, !isequal, “127.0.0.1” ~

After this, I get log files written to /var/log/network-IP-YEAR-MONTH-DAY.log. For example:

pepparkaka:~# tail /var/log/network-192.168.1.47-2012-03-20.log 
Mar 20 13:40:21 192.168.1.47 avahi-daemon[1508]: Registering new address record for 192.168.1.47 on br-lan.IPv4.
Mar 20 13:40:21 192.168.1.47 avahi-daemon[1508]: Registering HINFO record with values 'MIPS'/'LINUX'.
Mar 20 13:40:21 192.168.1.47 sysinit: setting up led WAN LED (green)
Mar 20 13:40:21 192.168.1.47 kernel: ar71xx-wdt: enabling watchdog timer

Use uci to configure the OpenWRT boxes to send log messages to this server:

uci set system.@system[0].log_ip=192.168.1.51
uci commit

Update! By default rsylog performs reverse lookups of incoming requests. This easily causes problems in case your DNS server is unreachable. Rsyslogd appears to have a long timeout for DNS queries, so if you expect incoming log messages to end up in the log when they are sent, think again. In my testing, it can take minutes until they end up in the log. For me, reverse DNS lookups does not add anything of value. To disable DNS lookups, make sure rsyslogd is invoked with the ‘-x’ parameter. On Debian, this is done by adding ‘-x’ to /etc/defaults/rsyslog like this:

RSYSLOGD_OPTIONS=”-c4 -x”

Unattended SSH with Smartcard

I have several backup servers that run the excellent rsnapshot software, which uses Secure Shell (SSH) for remote access. The SSH private key of the backup server can be a weak link in the overall security. To see how it can be a problem, consider if someone breaks into your backup server and manages to copy your SSH private key, they will now have the ability to login to all machines that you take backups off (and that should be all of your machines, right?).

The traditional way to mitigate SSH private key theft is by password protecting the private key. This works poorly in an unattended server environment because either the decryption password needs to be stored in disk (where the attacker can read it) or the decrypted private key has to be available in decrypted form in memory (where attacker can read it).

A better way to deal with the problem is to move the SSH private key to a smartcard. The idea is that the private key cannot be copied by an attacker who roots your backup server. (Careful readers may have spotted a flaw here, and I need to explain one weakness with my solution: an attacker will still be able to login to all your systems by going through your backup server, however it will require an open inbound network connection to your backup server and the attacker will never know what your private key is. What this does is to allow you to more easily do damage control by removing the smartcard from the backup server.)

In this writeup, I’ll explain how to accomplish all this on a Debian/Ubuntu-system using a OpenPGP smartcard, a Gemalto USB Shell Token v2 with gpg-agent/scdaemon from GnuPG together with OpenSSH.

Continue reading Unattended SSH with Smartcard