<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
 <channel>
  <title>Blargh - Thomas Habets blog</title>
  <link>http://blog.habets.pp.se/</link>
  <description>Network, unix, Erlang and other fun projects</description>
  <copyright>Copyright Thomas Habets 2009</copyright>
  <lastBuildDate>Thu, 28 Feb 2013 00:00:00 GMT</lastBuildDate>
  <pubDate>Thu, 28 Feb 2013 00:00:00 GMT</pubDate>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <atom:link href="http://blog.habets.pp.se/rss" rel="self"
             type="application/rss+xml" />
  <language>en-us</language>
  <item>
   <title>GPG and SSH with Yubikey NEO</title>
   <description><![CDATA[<p>
  I'm a big fan of hardware tokens for access. The three basic technologies where
  you have public key crypto are SSH, GPG and SSL. Here I will show how to use
  a Yubikey NEO to protect GPG and SSH keys so that they cannot be stolen or
  copied. (well, they can be physically stolen, of course).
</p>

<p>
  Let's hope pkcs11 support is coming, so that SSH support improves and SSL keys can also be protected.
</p>
<p>
  Parts of this howto are all but copied from <a href="http://www.yubico.com/2012/12/yubikey-neo-openpgp/">YubiKey
  NEO and OpenPGP</a>. I complete it with some details and the SSH parts.
</p>

<h2>GPG</h2>
<p>
  GPG normally keeps your private key encrypted using your password. If your keyring is
  stolen someone can brute force your password and from there decrypt all your files. If someone steals
  your keyring you should revoke the key as soon as possible, but assuming this revokation gets to all
  interested parties this will only protect new messages from being encrypted to this key. Old encrypted
  files could be decrypted by the attacker. Signatures are a bit better off. Sure, you have to re-sign everything
  and redistributed the signatures, but not nearly as bad.
</p>
<ol>
  <li><h3>Install some dependencies</h3>
    <blockquote><pre>sudo aptitude install gnupg gnupg-agent gpgsm</pre></blockquote>
  </li>

  <li><h3>Install Yubikey personalizer</h3>
    Compile and install <a href="http://github.com/Yubico/yubico-c">the Yubico library</a>
    and <a href="http://github.com/Yubico/yubikey-personalization">the Yubikey personalization tool</a>.
  </li>

  <li><h3>Switch Yubikey to HID/CCID (smartcard) mode</h3>
  <blockquote><pre>$ ykpersonalize -m82
Firmware version 3.0.1 Touch level 1536 Unconfigured

The USB mode will be set to: 0x82

Commit? (y/n) [n]: y</pre></blockquote>
</li>

  <li><h3>Set up USB device permissions</h3>
    While the Yubikey in normal keyboard mode will work without thinking about permissions,
    when used as a smartcard your user needs to have read/write access to the device. You have three options.
    <ul>
      <li>Set device owner or permissions manually: <quote>chmod 666 /dev/bus/usb/xxx/yyy</quote></li>
      <li>Set owner or permissions via udev in /etc/udev/rules.d/99-yubikeys.rules:
        <quote>SUBSYSTEMS=="usb", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0111", OWNER="thomas"</quote></li>
      <li>Be in whatever group defaults to owning the device on your system</li>
    </ul>
  </li>

  <li><h3>Create GPG key pair</h3>
  <blockquote><pre>$ gpg --card-edit

Application ID ...: D2760001240102000000000000010000
Version ..........: 2.0
Manufacturer .....: test card
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
Admin commands are allowed

gpg/card> generate

Please note that the factory settings of the PINs are
   PIN = `123456'     Admin PIN = `12345678'
You should change them using the command --change-pin

[enter 12345678 and 123456 when asked for admin PIN and PIN]

[fill in standard GPG key info]
</pre></blockquote>
  GPG using the newly created key should now work. It shouldn't even look special,
  except it will ask you for the PIN when needed, and won't work when the Yubikey NEO
  is not connected.
  </li>
</ol>

<h2>SSH</h2>
<p>
  Turns out gpg-agent can act as an ssh-agent too. The reason for doing this
  is so that you can use your GPG key as an SSH key. It doesn't appear to support SSH
  certificates though, so I'm not ready to use it as my default one.
</p>
<p>
</p>
<ol>
  <li><h2>Get public key in SSH format</h2>
    <blockquote><pre>$ gpg-agent --enable-ssh-support --daemon ssh-add -l
2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx cardno:000000000001 (RSA)
$ gpg-agent --enable-ssh-support --daemon ssh-add -L
ssh-add AAAA[...] cardno:000000000001</pre></blockquote>
    Install this public key in ~/.ssh/authorized_keys of the remote machine.
  </li>

  <li><h2>Create SSH wrapper script for using gpg-agent</h2>
    <blockquote><pre>#!/bin/sh
exec gpg-agent --enable-ssh-support --daemon ssh "$@"</pre></blockquote>
    <p>
      You will be asked for your PIN code. Make sure you have a good PIN code, or
      no PIN code. Having the default of 123456 is intellectually dishonest.
    </p><p>
      Using the key with SSH like this does not require setting up gnupg, or
      a keyring in ~/.gnupg or anything like that. Just install the required
      prerequisites, fix device permissions, and run the wrapper script.
    </p>
  </li>
</ol>


<h2>Links</h2>
<ul>
  <li><a href="http://www.yubico.com/2012/12/yubikey-neo-openpgp/">Yubico blog describing setting up GPG with the NEO</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2013/02/GPG-and-SSH-with-Yubikey-NEO</link>
   <guid>http://blog.habets.pp.se/2013/02/GPG-and-SSH-with-Yubikey-NEO</guid>
   <pubDate>Thu, 28 Feb 2013 00:00:00 GMT</pubDate>
  </item>
  <item>
   <title>Plug computer for always-on VPN</title>
   <description><![CDATA[<p>
  Last time I was at a hacker conference I for obvious reasons didn't want to connect to the local network.
  It's not just a matter of setting up some simple firewall rules, since the people around you are people
  who have and are inventing new and unusual attacks. Examples of this would be rogue IPv6
  RA and NDs, and people who have actually generated their own signed root CAs. There's also the
  risk (or certainty) of having all your unencrypted traffic sniffed and altered.
</p>
<p>
  For next time I've prepared a <a href="http://en.wikipedia.org/wiki/SheevaPlug">SheevaPlug</a>
  computer I had laying around. I updated it to a modern Debian installation, added a USB network card,
  and set it up to provide always-on VPN. This could also be done using a raspberry pi, but I don't
  have one.
</p>

<p>
  Always-on VPN is where you have NO network access unless your VPN is up, and then ALL traffic
  goes through the VPN. By setting up a plug computer as a VPN client you can just plug in
  an unprotected computer to the "inside" and you'll be protected against the attackers on your
  local network.
</p>
<p>
  Here are my notes on setting this up. Some of it may not be useful to other people, but it was
  enough of a hassle looking this up the first time that I want to note it down in case I have
  to do it again.
</p><p>
  <b>WARNING:</b> You may brick your device if you have a different device and/or don't know what
  you're doing.
</p>
<ol>
  <li><h3>Upgrade Uboot</h3>
    Download <a href="http://people.debian.org/~tbm/u-boot/2011.12-3/sheevaplug/u-boot.kwb">u-boot.kwb</a>
    to your tftp server.
<blockquote><pre>
Marvell>> version
U-Boot 1.1.4 (Mar 19 2009 - 16:06:59) Marvell version: 3.4.16
Marvell>> print ethaddr       # Write this down
ethaddr=00:11:22:33:44:55

setenv serverip 192.168.1.10 # IP of your TFTP server
setenv ipaddr 192.168.1.20
tftpboot 0x0800000 u-boot.kwb
nand erase 0x0 0x60000
nand write 0x0800000 0x0 0x60000
reset
setenv ethaddr 00:11:22:33:44:55
saveenv
reset
</pre></blockquote>
  </li>

  <li><h3>Install Debian</h3>
    Download the Debian installer <a href="ftp://ftp.debian.org/debian/dists/stable/main/installer-armel/current/images/kirkwood/netboot/marvell/sheevaplug/uImage">uImage</a>
    and <a href="ftp://ftp.debian.org/debian/dists/stable/main/installer-armel/current/images/kirkwood/netboot/marvell/sheevaplug/uInitrd">uInitrd</a> to the tftp server.
<blockquote><pre>setenv ipaddr 192.168.1.20
setenv serverip 192.168.1.10
tftpboot 0x00800000 uImage
tftpboot 0x01100000 uInitrd
setenv bootargs console=ttyS0,115200n8 base-installer/initramfs-tools/driver-policy=most
bootm 0x00800000 0x01100000
</pre></blockquote>
Then install normally.
  </li>

  <li><h3>Set up boot to load kernel and initrd from SD card</h3>
<blockquote><pre>setenv bootargs_console console=ttyS0,115200
setenv bootcmd_mmc 'mmc init; ext2load mmc 0:1 0x00800000 /uImage; ext2load mmc 0:1 0x01100000 /uInitrd'
setenv bootcmd 'setenv bootargs $(bootargs_console); run bootcmd_mmc; bootm 0x00800000 0x01100000'
saveenv
run bootcmd</pre></blockquote>
  </li>

  <li><h3>Install some stuff</h3>
<blockquote><pre>mv /etc/motd{,.dist}
apt-get install openssh-server screen mg openvpn git python-webpy sudo tcpdump tshark uptimed ntp ntpdate isc-dhcp-server arping pv gcc make kernel-package</pre></blockquote>
  </li>

  <li><h3>Setup useful environment</h3>
<blockquote><pre>alias emacs=mg
alias tl='sudo iptables -n -v --line -L'
alias ls='ls --color'
# set up .screenrc
# visudo: thomas  ALL=NOPASSWD: ALL</pre></blockquote>
  </li>

  <li><h3>Set up network interfaces</h3>
    /etc/network/interfaces
<blockquote><pre>iface eth0 inet static
    address 10.1.2.1
    netmask 255.255.255.0
iface eth1 inet dhcp
    pre-up /.../bin/start
iface eth2 inet dhcp
    pre-up /.../bin/start
iface eth3 inet dhcp
    pre-up /.../bin/start</pre></blockquote>
    (many interfaces since they may be swapped around, and the names are persistent by default)
  </li>

  <li><h3>Install OpenSSH user CA</h3>
/etc/ssh/sshd_config:
<blockquote><pre>TrustedUserCAKeys /etc/ssh/user_ca.pub</pre></blockquote>
<blockquote><pre>cat > /etc/ssh/user_ca.pub</pre></blockquote>
  </li>

  <li><h3>Install dnetc</h3>
Just for fun.
<a href="http://http.distributed.net/pub/dcti/current-client/dnetc-linux-arm-eabi.tar.gz">Download</a>.
  </li>

  <li><h3>Set up remote OpenVPN server</h3>
    Out of scope for this blog post.
  </li>

  <li><h3>Set up DHCP server</h3>
    /etc/dhcp/dhcpd.conf
<blockquote><pre>
ddns-update-style none;
option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;
subnet 10.1.2.0 netmask 255.255.255.0 {
        range 10.1.2.11 10.1.2.250;
        option broadcast-address 10.1.2.255;
        option routers 10.1.2.1;
}
</pre></blockquote>
  </li>

  <li><h3>Install firewalling scripts</h3>
    <blockquote><pre>git clone git://github.com/ThomasHabets/profy.git</pre></blockquote>
  </li>

  <li><h3>Set up OpenVPN</h3>
    Crate ovpn.conf config in cfg/ using ovpn.conf.template as a template.
    Symlink /etc/openvpn/ovpn.conf to that file.
  </li>

  <li><h3>Set noatime on all filesystems in /etc/fstab</h3></li>

  <li><h3>Set up kernel build environment</h3>
    USB network drivers sucked in default kernel. I only got 2Mbps for the ones that even
    had drivers. 65% of CPU was interrupt handling, OpenVPN only about 5%.
<blockquote><pre>cd /usr/bin
for i in ld objdump ar nm strip objcopy size; do
  ln -s {,arm-linux-gnueabi-}$i
done</pre></blockquote>
  </li>

  <li><h3>Build and install new kernel</h3>
<blockquote><pre>cp /boot/config* .config
make menuconfig
time fakeroot make-kpkg kernel_image
dpkg -i ../kernel*.deb
mkinitramfs -o /boot/initrd.img-3.7.6 3.7.6
cd /boot
mkimage -A ARM -O Linux -T Kernel -C none -a 0x00008000 -e 0x00008000 -n 3.7.6 -d vmlinuz-3.7.6  uImage-3.7.6
mkimage -A ARM -O Linux -T RAMDisk -C gzip -a 0x00000000 -e 0x00000000 -n 3.7.6 -d initrd.img-3.7.6  uInitrd-3.7.6</pre></blockquote>
  </li>

  <li><h3>Test the new kernel</h3>
    Copy new kernel to tftp server.
<blockquote><pre>setenv ipaddr 192.168.1.20
setenv serverip 192.168.1.10
tftpboot 0x00800000 uImage-3.7.6
tftpboot 0x01100000 uInitrd-3.7.6
bootm 0x00800000 0x01100000</pre></blockquote>
   </li>

   <li><h3>If working, default to new kernel</h3>
<blockquote><pre>cd /boot
mv uImage{,.dist}
mv uInitrd{,.dist}
ln -s uImage-3.7.6 uImage
ln -s uInitrd-3.7.6 uInitrd</pre></blockquote>
  </li>

  <li><h3>Profit</h3>
     I get about 14Mbps, with &lt;50% CPU assigned to OpenVPN, and the rest curiously "idle".
     Keep in mind that the SheevaPlug is about 4 years old at this point.
  </li>
</ol>
<h2>Photo</h2>
<img style="max-width: 100%" src="/static/2013-02-09_plug_vpn.jpg" />

<h2>Links</h2>
<ul>
  <li><a href="http://www.cyrius.com/debian/kirkwood/sheevaplug/install.html">Install Debian on SheevaPlug</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2013/02/Plug-computer-for-always-on-VPN</link>
   <guid>http://blog.habets.pp.se/2013/02/Plug-computer-for-always-on-VPN</guid>
   <pubDate>Sat, 09 Feb 2013 00:00:00 GMT</pubDate>
  </item>
  <item>
   <title>Compiling C++ statically</title>
   <description><![CDATA[<p>
  To properly compile a static C++ binary on Linux you have to supply
  <quote>-static</quote>,
  <quote>-static-libgcc</quote>
  and <quote>-static-libstdc++</quote> when linking.
</p>



<p>That's fucked up.</p>

<p>Never EVER think that linking (at link time or runtime) is easy or obvious.</p>

<p>
  I link my current pet project with:
  <blockquote><pre>g++ -Wl,-z,now -Wl,-z,relro -pie -static-libstdc++</pre></blockquote>
</p>

<p>
  The binary then seems to work across the systems I currently want to run it on.
  Specifically it makes me able to run the binary compiled on Debian Testing on a
  Debian Stable installation.
</p>

<p>
  Skipping that whole dynamic libraries thing is something Go got right.
</p>

<h2>Update: some clarification on why you'd want to compile statically</h2>
<p>
  Let's start with the reason for wanting to compile static in the first place.
  While shared libraries are better in some aspects, "save RAM" is no longer a good reason
  for always compiling dynamically. There are reasons why you'd want dynamic linking still,
  but that aint it. The savings in RAM for the .text and .rodata sections (and unmodified .data,
  I guess) are negligible when compared to RAM footprint of interesting applications.
  There the interesting data is usually mmap()ed or simply read or generated. Shared libraries
  won't help you with that. KSM (Kernel Samepage Merging) will even help in doing
  reverse copy-on-write to take back even this loss.
</p><p>

  Take /usr/bin/ssh for example.
  <blockquote><pre>$ ldd $(which ssh) | awk '{print $3}' | sed 1d | grep -v ^$ | xargs du -Dhcs | tail -1
4.6M total</pre></blockquote>
  Really? You care about saving me 5MB? Sure, multiply by number of (unique!) running system utilities
  that's one thing, but I'm not taliking about those. I'm talking about, say, your SOA backend application.
  Or Quake 9.
</p><p>
  No, the big benefit of shared libraries is the fact that you only have to upgrade in
  *one* place to have the code upgraded everywhere.
</p><p>

  Where static linking wins is where you have control of "all" aspects of operations.
  That is, if there is a new version of openssl to fix a bug, it's feasible in your environment
  to recompile. You then also have the option to roll back, and roll back openssl to only
  one application in case there is an incompatibility. This won't, of course, help
  with dlopen()ed libraries.
</p><p>
  Now back to what the options mean. "-static" is the option to ostensibly not require
  (assume existence and compatibility of) shared libraries on the target system. Turns out
  it's not that simple. "-static-libstdc++" is often (I dare almost say "usually") needed
  if the libstdc++ versions between build and target systems differ by a few years on Linux.
  Like I said I needed this to compile my C++11 stuff on Debian Testing (frozen to be stable,
  IIRC) and Debian Stable. One binary. Just scp it to the target and run. No dependencies.
</p><p>
  As for libgcc it's mostly for cases where you can't count on access to *any* libraries (such
  as what you mentioned, as OS hacking), but isn't that why you gave "-static" in the first place? :-)
</p><p>
  This post doesn't address other aspects of static linking, such as glibc being static-hostile, a whole topic in itself.
  Compiling static won't make everything "just work" either.
</p>]]></description>
   <link>http://blog.habets.pp.se/2013/01/Compiling-C++-statically</link>
   <guid>http://blog.habets.pp.se/2013/01/Compiling-C++-statically</guid>
   <pubDate>Mon, 14 Jan 2013 00:00:00 GMT</pubDate>
  </item>
  <item>
   <title>Interesting Arping bug report</title>
   <description><![CDATA[<p itemprop="description">
  A few months ago I was strolling in the <a href="http://bugs.debian.org">Debian bug tracking system</a>
  and found <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667808">a curious bug</a> filed
  against <a href="http://www.habets.pp.se/synscan/programs.php?prog=arping">Arping</a>, a program I maintain.
</p>
<p>
  It said that unlike Arping 2.09, in Arping 2.11 the ARP cache was not updated after successful reply.
  I thought that was odd, since there's no code to touch the ARP cache, neither read nor write. Surely
  this behaviour hasn't changed?
</p>


<p>
  I tried to reproduce the behaviour and sure enough, with Arping 2.09 the arp cache is updated,
  while with 2.11 it's not.
  <blockquote><pre>$ arp -na | grep 192.168.0.123
$ # --- First try Arping 2.11 ---
$ sudo ./arping-2.11 -c 1 192.168.0.123
ARPING 192.168.0.123
60 bytes from 00:22:33:44:55:66 (192.168.0.123): index=0 time=1.188 msec

--- 192.168.0.123 statistics ---
1 packets transmitted, 1 packets received,   0% unanswered (0 extra)
$ arp -na | grep 192.168.0.123
$ # --- Ok, that didn't change the ARP cache. Now try 2.09 ---
$ sudo ./arping-2.09 -c 1 192.168.0.123
ARPING 192.168.0.123
60 bytes from 00:22:33:44:55:66 (192.168.0.123): index=0 time=794.888 usec

--- 192.168.0.123 statistics ---
1 packets transmitted, 1 packets received,   0% unanswered (0 extra)
$ arp -na | grep 192.168.0.123
? (192.168.0.123) at 00:22:33:44:55:66 [ether] on wlan0</pre></blockquote>
  How could that be? I suspected that maybe the kernel saw the ARP reply, and snooped it into the
  ARP table. But I quickly confirmed that the packets going over the wire were the same for 2.09 and 2.11
  (as they should be).
</p>
<p>
  So what changed between 2.09 and 2.11?
  <blockquote><pre>$ git log --pretty=oneline arping-2.09..arping-2.11 | wc -l
43</pre></blockquote>
  Ugh. Before doing a <a href="http://git-scm.com/book/en/Git-Tools-Debugging-with-Git">bisection</a>
  I skimmed through the descriptions. Most were
  comments, compile fixes and documentation. The only functionality changes were
  <ul>
    <li>Switching to <code>clock_gettime()</code> (various patches).
      Read <a href="/2010/09/gettimeofday-should-never-be-used-to-measure-time">gettimeofday() should never be used to
      measure time</a> for why.</li>
    <li><a href="https://github.com/ThomasHabets/arping/commit/b0a754550bb873b4fdb7049bfc394d38bfe3c72b">Switching
    to <code>select()</code> from <code>poll()</code></a></li>
    <li><a href="https://github.com/ThomasHabets/arping/commit/a03413aa161cace9733a0a3c3c98420c761484ee">Adding
    support to use <code>getifaddr()</code> to find the correct output interface</a></li>
  </ul>
  Well, the first two don't look suspicious, so either it's the <code>getifaddrs()</code> or some minor change that
  shouldn't have mattered.
</p>
<p>
  Between Arping 2.09 and 2.10 I changed the interface finding code from an ugly hack of running
  <quote>/sbin/ip route get 1.1.1.1</quote>
  to get the outgoing interface from the routing table. Since the output of the various "show me the routing table" commands
  are different in different OSs, I had to implement this subprocess (ugly) and parsing (ugly) several times. The new
  implementation uses <code>getifaddrs()</code> to traverse the interfaces programmatically.
</p>
<p>
  The old code was still there as a fallback. It would never actually get used unless there's a Linux
  system out there that doesn't <em>have</em> <code>getifaddrs()</code>. It seems
  <a href="http://sourceware.org/git/?p=glibc.git;a=commit;h=7f1deee65e0a90d9e6699068b5d63a28d2546e12">it
  was added to glibc 2.3 back in 2002</a>. Anyway it was trivial to temporarily switch interface selection
  back to the old method. I confirmed that this was indeed what caused this change of behaviour.
</p>
<p>
  Surely <quote>ip route get</quote> doesn't send an ARP request and populates the ARP cache when it gets the reply? No.
  So if <quote>ip route get 1.1.1.1</quote> doesn't do it,
  and <quote>arping-2.11 1.1.1.1</quote> doesn't do it,
  then surely <quote>ip route get 1.1.1.1 ; arping-2.11 1.1.1.1</quote> doesn't do it?
</p>
<p>
  Yes, yes it does. It seems <quote>ip route get 1.1.1.1</quote> followed by
  <quote>arping-2.11 1.1.1.1</quote> <b>will</b> cause 1.1.1.1 to show
  up in the ARP cache. And it doesn't matter if <quote>ip route get</quote>
  is run as an ordinary user or as root! (arping of course
  has to run as root or have NET_ADMIN capability).
  Only the exact address given to <quote>ip route get</quote> will be
  "open to be filled" by the second command,
  so it seems to be per address, and that <quote>ip route get</quote> will modify state in the kernel.
</p>
<blockquote><pre>
$ arp -na | grep 192.168.0.123
$ sudo ./arping-2.11 -i wlan0 -q -c 1 192.168.0.123
$ arp -na | grep 192.168.0.123
$ # --- Ok, still no entry in the ARP cache Now try running both commands ---
$ ip route get 192.168.0.123 ; sudo ./arping-2.11 -i wlan0 -q -c 1 192.168.0.123
192.168.0.123 dev wlan0  src 192.168.0.100 
    cache  mtu 1500 advmss 1460 hoplimit 64
$ arp -na | grep 192.168.0.123
? (192.168.0.123) at 00:22:33:44:55:66 [ether] on wlan0</pre></blockquote>
<p>
  I closed the bug since it's working as intended.
</p>
<p>
  I have not dived into the kernel source to find the reason for this, but I may come back and
  update this post if and when I do.
</p>

<h3>Links</h3>
<ul>
  <li><a href="https://github.com/ThomasHabets/arping">Arping on github</a></li>
  <li><a href="http://www.habets.pp.se/synscan/programs.php?prog=arping">Arping home page</a></li>
  <li><a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667808">Debian bug 667808:
    Arping 2.11 not update arp cache entry</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2012/10/Interesting-Arping-bug-report</link>
   <guid>http://blog.habets.pp.se/2012/10/Interesting-Arping-bug-report</guid>
   <pubDate>Fri, 05 Oct 2012 21:26:53 GMT</pubDate>
  </item>
  <item>
   <title>Shared libraries diamond problem</title>
   <description><![CDATA[<p>
  If you split up code into different libraries you can get a diamond dependency problem.
  That is you have two parts of your code that depend on different incompatible versions of the same library.
  <br/>
  <img src="/static/2012-05-19_diamond.png"
       width="260" height="244">
</p>
<p>
  Normally you shouldn't get in this situation. Only someone who hates their users
  makes a non backwards compatible change to a library ABI. You don't hate your users, do you?
</p>

<p>
  (just kidding about hating your users.)
</p>

<h2>Disclaimer</h2>
<p>
  I thought I'd dive into this problem as a weekend project.
  Don't rely on this article as a source of truth, but please correct me
  where I'm wrong. I'm not an expert in creating shared libraries, and it's much harder
  that it would first appear. The existence of <code>libtool</code> proves that.
</p>

<p>
  Example project described can be found <a href="https://github.com/ThomasHabets/diamond_linking_example">here</a>.
</p>

<h2>Multiple versions of the same library</h2>
<p>
  The lovely land of modern Unix will allow you to have multiple versions of the same library
  installed at the same time. That's not the problem. The problem is that when you load the libraries
  all the symbols are resolved inside the same namespace. There can't be two versions in use of the same function
  with the same name, even if they are in different libraries (well, it won't work the way you want it to).
  You can't choose which one to see from different code.
  (see breadth first search description <a href="http://guru.multimedia.cx/ld-so-gnu-linkerloader/">here</a> for details).
</p>

<h2>The scenario</h2>
<p>
  In this scenario there are three separate libraries:
  <ul>
    <li><code>libd1</code> - Calls functions in <code>libd2</code> and <code>libbase</code> version 1.
        File name is simply <code>libd1.so</code>.</li>
    <li><code>libd2</code> - Calls functions in <code>libd1</code> and <code>libbase</code> version 2.
        File name is simply <code>libd2.so</code>.
        (cross dependency between <code>libd1</code> and <code>libd2</code>)</li>
    <li><code>libbase</code> - This is the library that made non backwards compatible changes between version 1 and 2.
        Files are <code>libbase.so.1.0</code> and <code>libbase.so.2.0</code>, with traditional symlinks from
        <code>libbase.so</code>.<i>n</i>. The important bit here is that the two versions are to be considered
        incompatible and must both be usable in the same process at the same time.</li>
  </ul>
  And the executable <code>p</code> which links to <code>libd1</code> and <code>libd2</code>.
</p><p>
  What we want to achieve is to have <code>libd1</code> and <code>libd2</code> be able to call
  functions in <code>libbase</code>, but to have them
  call different versions. Both <code>libbase.so.1</code> and <code>libbase.so.2</code>
  should be loaded and active (have their functions callable).
</p>

<h2>What normally happens</h2>
<p>
  When you link an executable with <code>-lfoo</code> the linker finds
  <code>libfoo.so</code> and verifies that it (along with default libraries)
  contain all the symbols that are currently unresolved. Linking shared objects
  (<a href="http://en.wikipedia.org/wiki/Dynamic_Shared_Object">DSO</a>, <code>.so</code> files) is similar, except
  <a href="http://blog.flameeyes.eu/2008/11/relationship-between-as-needed-and-no-undefined-part-1-what-do-they-do">there's
  no requirement that all symbols are resolved</a>. If an unresolved symbol exists in more than one
  library then only one is actually used.
  You can't therefore link two overlapping
  <a href="http://en.wikipedia.org/wiki/Application_binary_interface">ABI</a>s,
  even indirectly via an intermediate dependency. Well, you can, but
  are you comfortable with one of them being "hidden"? (which one is not important for this article)
</p>
<p>
  Both versions of the library can therefore be loaded, but if they overlap then one will hide the other (in the overlap).
</p>

<h2>How to solve it</h2>
<p>
  The hiding of one of the symbols in a name clash is done by the dynamic linker (<code>ld.so</code>)
  at load time (run time). Since
  symbols are referenced by name the only way to differentiate the two names is to force them to
  have different names.
</p>
<p>
  This can be done in different ways; manually, or automatically.
  Both append some text to every symbol you want to differentiate.
</p>
<h3>Automatic (with <code>--default-symver</code>)</h3>
<p>
  <blockquote><pre>$ gcc -fPIC -Wall -pedantic   -c -o base1.o base1.c
$ gcc -shared \
		-Wl,--default-symver \
		-Wl,-soname,libbase.so.1 \
		-o libbase.so.1.0 base1.o
$ nm libbase.so.1.0
[...] 00000000000006f0 T base_print     <--- same name as without the special args
[...] 0000000000000000 A libbase.so.1   <--- this is new with --default-symver
[...]</pre></blockquote>
  A small change. Certainly doesn't *appear* to refer to a new name. You can also
  inspect with <code>objdump -T</code>, but the magic happens when you link something to it.
</p>
<p>
  Let's compile and link one of the libraries that uses <code>libbase.so</code>:
  <blockquote><pre>$ ldconfig -N -f ld.so.conf
$ ln -fs libbase.so.1 libbase.so  # library to link with
$ gcc -fPIC -Wall -pedantic   -c -o d1.o d1.c
$ gcc -Wl,-rpath=. -L. \
		-Wl,--default-symver \
		-Wl,-soname,libd1.so \
		-shared -o libd1.so d1.o -lbase
$ nm d1.o
[...]            U base_print
[...]            U d2_print
[...]
$ nm libd1.so
[...]            U base_print@@libbase.so.1
[...]            U d2_print
[...]
$ ldd libd1.so
[...]      libbase.so.1 => ./libbase.so.1
[...]</pre></blockquote>
  Interesting. The unresolved symbol <em>base_print</em> was changed in the linking step, but <em>d2_print</em> was not.
  This is because the version info was put into <code>libbase.so</code> (symlinked to
  <code>libbase.so.1.0</code>). <code>libd2.so</code> didn't yet exist,
  so it can't have version info attached. If you want version info for <code>libd1</code> and
  <code>libd2</code> referencing each other then
  you'll first have to create versions of the libraries that don't depend on each other but do have version info.
  It's probably possible to bootstrap this manually, but I haven't looked into it.
</p><p>
  Also note that <code>libd1.so</code> knows that it's depending on <code>libbase.so.1</code> (not
  plain <code>libbase.so</code>). This is
  the name given with the <code>-soname</code> option when linking <code>libbase.so</code>. So there's
  even more magic going on than I led on. And it's a good reason for having that option.
</p>
<p>
  <code>libd2.so</code> is compiled similarly, except against version 2 of <code>libbase.so</code>.
  The program <code>p</code> is then linked to both <code>libd1.so</code> and <code>libd2.so</code>, which in
  turn pulls in both versions of <code>libbase.so</code>:
  <blockquote><pre>$ cc -Wl,-rpath=. -o p p.o -L. -Wl,-rpath=. -ld1 -ld2
$ ldd p
	linux-vdso.so.1 =>  (0x00007ffff41f8000)
	libd1.so => ./libd1.so (0x00007fe08b788000)
	libd2.so => ./libd2.so (0x00007fe08b586000)
	libc.so.6 => /lib/libc.so.6 (0x00007fe08b1e5000)
	libbase.so.1 => ./libbase.so.1 (0x00007fe08afe3000)
	libbase.so.2 => ./libbase.so.2 (0x00007fe08ade1000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fe08b98c000)
$ nm p | grep libd
                 U d1@@libd1.so
                 U d2@@libd2.so
$ ./p
base version 2> init
base version 1> init
d1> init
d2> init
d1()
 d2_print()
  base version 2> d1        <--- libd1 -> libd2 -> libbase version 2
d2()
 d1_print()
  base version 1> d2        <--- libd2 -> libd1 -> libbase version 1
d2> fini
d1> fini
base version 1> fini
base version 2> fini</pre></blockquote>
  Note that both base versions are loaded, and that <code>d1()</code> calls <code>d<b>2</b>_print()</code> and vice versa.
  Diamond problem solved. Yay!
</p>

<h3>Manual with --version-script</h3>
<p>
  Instead of <code>--default-syms</code> one can use <code>--version-script=base1.map</code>
  and create the map file.
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="code"><pre>BASE1 {
      global: base_print;
      local: *;
};
</pre></div>
</td></tr></table>

<h3>Manual from within the code</h3>
  Outside functions, add:
  <blockquote><pre>asm(".symver base_print_foo,base_print@@BASE1");</pre></blockquote>
  to create <code>base_print@@BASE1</code> from <code>base_print_foo</code>. This may still need a map file,
  but it will override it.
</p>

<h2>Notes</h2>
<ul>
  <li>"@@" in a name means "this version and the default". A single "@" means just "this version".</li>
</ul>

<h2>Summary</h2>
<p>
  … yet Unix still has much less DLL hell than Windows.
</p>
<p>
  I aimed to provide an accessible view into shared libraries by solving a specific
  problem. For more in-depth information from people who know more about it than me see
  the links below. I've barely scratched the surface.
</p><p>
  The compile time linker (<code>ld</code>) and the dynamic linker (<code>ld.so</code>) do
  a lot of magic. More than you'd expect if you haven't thought about it before.
</p>

<h2>Links</h2>
<ul>
  <li><a href="https://github.com/ThomasHabets/diamond_linking_example">Example project</a></li>
  <li><a href="http://www.akkadia.org/drepper/dsohowto.pdf">How To Write Shared Libraries</a>, by Ulrich Drepper</li>
  <li><a href="http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html">Program Library HOWTO
      - 3. Shared Libraries</a></li>
  <li><a href="http://guru.multimedia.cx/ld-so-gnu-linkerloader/">ld.so GNU linker/loader</a></li>
  <li><a href="http://blog.flameeyes.eu/2011/06/gold-readiness-obstacle-1-berkeley-db">Gold readiness obstacle #1:
      Berkeley DB</a>. Also see other linker related posts on that blog.</li>
  <li><a href="http://blog.flameeyes.eu/2010/11/it-s-not-all-gold-that-shines-why-underlinking-is-a-bad-thing">It's not
      all gold that shines — Why underlinking is a bad thing</a>. Nice illustrations of the problem.</li>
  <li><a href="http://www.flameeyes.eu/autotools-mythbuster/libtool/index.html">Autotools Mythbuster - Chapter 3. Building All Kinds of Libraries — libtool</a></li>
  <li><a href="http://blog.flameeyes.eu/2009/10/a-shared-library-by-any-other-name">Why there are shared object files and a bunch of symlinks</a></li>
  <li><a href="http://sourceware.org/binutils/docs/ld/VERSION.html">Binutils ld manual - 3.9 VERSION Command</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2012/05/Shared-libraries-diamond-problem</link>
   <guid>http://blog.habets.pp.se/2012/05/Shared-libraries-diamond-problem</guid>
   <pubDate>Sat, 19 May 2012 22:03:59 GMT</pubDate>
  </item>
  <item>
   <title>Be careful with hashmaps</title>
   <description><![CDATA[<p itemprop="description">
  As you remember from long ago hashes are <code>O(1)</code> best case, but can be <code>O(n)</code>
  if you get hash collisions. And if you're adding <code>n</code> new entries
  that means <code>O(n^2)</code>.
</p>
<p>
  I thought I'd take a look at the hash_set/hash_map GNU C++ extension.
</p>


In <code>/usr/include/c++/4.4.3/backward/hash_fun.h</code>:
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="code"><pre>  <span class="kr">inline</span> <span class="kt">size_t</span>
  <span class="nf">__stl_hash_string</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">__s</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">__h</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span> <span class="p">;</span> <span class="o">*</span><span class="n">__s</span><span class="p">;</span> <span class="o">++</span><span class="n">__s</span><span class="p">)</span>
      <span class="n">__h</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="n">__h</span> <span class="o">+</span> <span class="o">*</span><span class="n">__s</span><span class="p">;</span>
    <span class="k">return</span> <span class="kt">size_t</span><span class="p">(</span><span class="n">__h</span><span class="p">);</span>
  <span class="p">}</span>
</pre></div>
</td></tr></table>

Test program that loads some strings:
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33</pre></div></td><td class="code"><div class="code"><pre><span class="cp">#include&lt;time.h&gt;</span>
<span class="cp">#include&lt;iostream&gt;</span>
<span class="cp">#include&lt;hash_set&gt;</span>

<span class="kt">double</span> <span class="nf">getclock</span><span class="p">()</span>
<span class="p">{</span>
  <span class="k">struct</span> <span class="n">timespec</span> <span class="n">ts</span><span class="p">;</span>
  <span class="n">clock_gettime</span><span class="p">(</span><span class="n">CLOCK_MONOTONIC</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">ts</span><span class="p">);</span>
  <span class="k">return</span> <span class="n">ts</span><span class="p">.</span><span class="n">tv_sec</span> <span class="o">+</span> <span class="n">ts</span><span class="p">.</span><span class="n">tv_nsec</span> <span class="o">/</span> <span class="mf">1e9</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">_GLIBCXX_BEGIN_NAMESPACE</span><span class="p">(</span><span class="n">__gnu_cxx</span><span class="p">)</span>
<span class="n">template</span><span class="o">&lt;&gt;</span> <span class="k">struct</span> <span class="n">hash</span><span class="o">&lt;</span> <span class="o">::</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="p">{</span>
  <span class="kt">size_t</span> <span class="n">operator</span><span class="p">()(</span><span class="k">const</span> <span class="o">::</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">x</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">hash</span><span class="o">&lt;</span><span class="k">const</span> <span class="kt">char</span><span class="o">*&gt;</span><span class="p">()(</span><span class="n">x</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
  <span class="p">}</span>
<span class="p">};</span>
<span class="n">_GLIBCXX_END_NAMESPACE</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
  <span class="n">__gnu_cxx</span><span class="o">::</span><span class="n">hash_set</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">the_set</span><span class="p">;</span>
  <span class="kt">double</span> <span class="n">start</span> <span class="o">=</span> <span class="n">getclock</span><span class="p">();</span>

  <span class="k">while</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">.</span><span class="n">good</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
    <span class="n">getline</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">,</span> <span class="n">line</span><span class="p">);</span>

    <span class="n">the_set</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;Size: &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">the_set</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span>
            <span class="o">&lt;&lt;</span> <span class="s">&quot;Time: &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">getclock</span><span class="p">()</span><span class="o">-</span><span class="n">start</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>

Running the loader with different inputs:
<blockquote><pre>
$ ./generateCollisions 5 > coll-5
$ ./generateCollisions 6 > coll-6
$ wc -l coll-5 coll-6
  13826 coll-5
 149696 coll-6
 163522 total
$ seq -f "%06.0f" 13826 > num-5
$ seq -f "%06.0f" 149696 > num-6
$ ./load < num-5
Size: 13827
Time: 0.0148379
$ ./load < num-6
Size: 149697
Time: 0.135555
$ ./load < coll-5
Size: 13827
Time: 1.44663
$ ./load < coll-6
Size: 149697
Time: 212.009</pre></blockquote>
That's going from 0.14 seconds to over 3 and a half minutes.

<h2>Collision generator</h2>
Left as an exercise to the reader. My code is too ugly to release.

<h2>Summary</h2>
Nothing new, just a friendly reminder to treat input data as untrusted. Think of all the places
where you use a hash map. How many of the keys come straight from untrusted sources? (user names,
photo tags, JSON or XML data that at some point is shoved into suitable data structures, etc...)

<h2>Links</h2>
<ul>
<li><a href="http://events.ccc.de/congress/2011/Fahrplan/events/4680.en.html">28C3:
    Effective Denial of Service attacks against web application platforms</a></li>
</ul>
]]></description>
   <link>http://blog.habets.pp.se/2012/02/Be-careful-with-hashmaps</link>
   <guid>http://blog.habets.pp.se/2012/02/Be-careful-with-hashmaps</guid>
   <pubDate>Tue, 07 Feb 2012 22:57:14 GMT</pubDate>
  </item>
  <item>
   <title>Benchmarking TPM-backed SSL</title>
   <description><![CDATA[<p>
  <img src="/static/2012-02-05_TPM_handshake_performance.png"/><br/>
</p>
<p>
  As you can plainly see from this graph, my TPM chip can do
  approximately 1.4 SSL handshakes per second. A handshake takes about 0.7 seconds of TPM time,
  so when two clients are connecting the average connect time is 1.4 seconds.
  This means probably not useful on server side, but should be good for some client side applications.
</p>

<p>
  To replicate the test, start a server:
  <blockquote><pre>openssl s_server -keyform engine -engine tpm -accept 12345 -cert foo.crt -key foo.key -tls1 -CAfile foo.crt -verify 1 -status</pre></blockquote>
  And then connect 100 times:
  <blockquote><pre>for n in $(seq 100); do time openssl s_client -tls1 -connect localhost:12345 < /dev/null >/dev/null 2>/dev/null;done 2> timelog</pre></blockquote>
  Then just look at the "real" time in the timelog. (if in doubt, use bash. zsh gave me some crap in the log) Example GNUPlot:
  <blockquote><pre>plot [1:] [0:2] '2' using (2/$1) w l title '2 clients','1' using (1/$1) w l title '1 client'</pre></blockquote>
</p>]]></description>
   <link>http://blog.habets.pp.se/2012/02/Benchmarking-TPM-backed-SSL</link>
   <guid>http://blog.habets.pp.se/2012/02/Benchmarking-TPM-backed-SSL</guid>
   <pubDate>Sun, 05 Feb 2012 13:02:16 GMT</pubDate>
  </item>
  <item>
   <title>TPM-backed SSL</title>
   <description><![CDATA[<p>
  This is a short howto on setting up TPM-backed SSL. This means that
  the secret key belonging to an SSL cert is protected by the TPM and
  cannot be copied off of the machine or otherwise inspected.
</p>

<p>
  Meaning even if you get hacked the attackers cannot impersonate you,
  if you manage to kick them off or just shut down the server. The
  secret key is safe. It has never been outside the TPM and never will be.
</p>

<p>
  This can be used for both client and server certs.
</p>



<h2>Prerequisites</h2>
<ul>
  <li>A TPM chip. Duh. May need to be turned on in the BIOS. Could be called "security chip" or something.
      If you don't have a TPM chip but still want to follow along (maybe add TPM support to some program)
      then you can install a TPM emulator. See links at the end on how to install a TPM emulator.</li>
  <li>A working CA that will sign your CSR. I will assume you're
      running your own CA, but you can send the CSR to someone else
      to sign if you want cert creating step.</li>
  <li>Installed "stuff": <blockquote><pre>$ aptitude install tpm-tools libengine-tpm-openssl</pre></blockquote></li>
</ul>

<h2>Initialize TPM</h2>
<ul>
  <li>Make sure you can communicate with the TPM chip:
<blockquote><pre>$ tpm_version
  TPM 1.2 Version Info:
  Chip Version:        1.2.4.1
  Spec Level:          2
  Errata Revision:     2
  TPM Vendor ID:       INTC
  Vendor Specific data: 00040001 0003040e
  TPM Version:         01010000
  Manufacturer Info:   494e5443
</pre></blockquote>
  </li>

  <li>Clear the chip:
<blockquote><pre>$ tpm_clear --force
$ tpm_setenable --enable --force
$ tpm_setactive --active</pre></blockquote>
These steps may require reboots. They will probably tell you if that's the case.
  </li>

  <li>Take ownership and create SRK:
  <blockquote><pre>$ tpm_takeownership -u -y
Enter SRK password: <b>&lt;just press enter&gt;</b>
Confirm password: <b>&lt;just press enter&gt;</b></pre></blockquote>
  Yes really, empty password. This password protects TPM operations, so
  worst case is that someone with shell access can put some load on your TPM chip.
  They can't use it to crack keys or anything. This is not a password that protects
  your secrets, they're already secure. You may want to supply an owner password. If so,
  leave out the <code>-y</code> option.
  </li>

</ul>

<h2>Create SSL certificate</h2>
<ul>
  <li>Use script from libengine-tpm-openssl to create key: <code>create_tpm_key foo.key</code></li>
  <li>Create CSR for key: <code>openssl req -keyform engine -engine tpm -key foo.key -new -out foo.csr</code></li>
  <li>Sign the CSR with your CA: <code>openssl x509 -req -days 365 -in foo.csr -CA ca.crt -CAkey ca.key -CAserial serial -out foo.crt</code></li>
</ul>

<h2>Test it</h2>
On the server:<blockquote><pre>$ openssl s_server -accept 12345 -cert /path/to/server.crt -key /path/to/server.key -CAfile CA/ca.crt -Verify 1</pre></blockquote>

On the client
<blockquote><pre>$ openssl s_client -keyform engine -engine tpm -connect server-name-here:12345 -cert foo.crt -key foo.key</pre></blockquote>

<h2>Use in your code</h2>
<p>
  Instead of using <code>SSL_CTX_load_verify_locations()</code>,
  use <code>ENGINE_*()</code> and <code>SSL_CTX_use_PrivateKey()</code>
</p>
<p>
Without TPM:
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="code"><pre><span class="kt">void</span> <span class="nf">loadpriv</span><span class="p">(</span><span class="n">SSL_CTX</span><span class="o">*</span> <span class="n">ctx</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">file</span><span class="p">)</span>
<span class="p">{</span>
  <span class="n">SSL_CTX_use_PrivateKey_file</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">SSL_FILETYPE_PEM</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
</p>
<p>
With TPM:
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10</pre></div></td><td class="code"><div class="code"><pre><span class="kt">void</span> <span class="nf">loadpriv</span><span class="p">(</span><span class="n">SSL_CTX</span><span class="o">*</span> <span class="n">ctx</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">file</span><span class="p">)</span>
<span class="p">{</span>
  <span class="n">ENGINE_load_builtin_engines</span><span class="p">();</span>
  <span class="n">ENGINE</span><span class="o">*</span> <span class="n">engine</span> <span class="o">=</span> <span class="n">ENGINE_by_id</span><span class="p">(</span><span class="s">&quot;tpm&quot;</span><span class="p">);</span>
  <span class="n">ENGINE_init</span><span class="p">(</span><span class="n">engine</span><span class="p">);</span>

  <span class="n">UI_METHOD</span><span class="o">*</span> <span class="n">ui_method</span> <span class="o">=</span> <span class="n">UI_OpenSSL</span><span class="p">();</span>
  <span class="n">EVP_PKEY</span><span class="o">*</span> <span class="n">pkey</span> <span class="o">=</span> <span class="n">ENGINE_load_private_key</span><span class="p">(</span><span class="n">engine</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">ui_method</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
  <span class="n">SSL_CTX_use_PrivateKey</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">pkey</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
Error handling left as an exercise for the reader.
</p>

<h2>Use in the real world</h2>
<p>
  Huh. I haven't actually seen this implemented in any Open Source software (besides the openssl command
  line interface)
  Well, actually curl and stunnel4 <em>appear</em> that they could support it, but
  it's not clear how. <a href="http://comments.gmane.org/gmane.network.stunnel.user/3109">Here</a>
  is someone else wondering how to get stunnel to do it. It's from 2006 with no replies.
</p>
<p>
  The only thing I have that uses the TPM chip is my Chromebook. Client certs there are
  protected by it by default.
</p>
<p>
  Please leave comments if you know of any TPM support in Open Source stuff.
</p>

<h2>tlssh</h2>
I have added support for <a href="http://github.com/ThomasHabets/tlssh">tlssh</a>
to use TPM on both the server and client side. Add "-E tpm" on the
client side, and have something like this on the server side config
(or only on one side. There's no requirement that both sides use TPM):
<table class="codetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="code"><pre>PrivkeyEngine tpm
TpmSrkPassword
PrivkeyPassword secretpasswordhere
</pre></div>
</td></tr></table>
That last line is just needed if the key has a password. The client can be configured
in the same way to not have to ask for the passwords.
</p>
<p>
  If <code>PrivkeyEngine tpm</code> or <code>-E tpm</code> is supplied the secret key
  will be assumed to be TPM protected and should be in the form of a "BEGIN TSS KEY BLOB"
  section instead of a PEM format "BEGIN RSA PRIVATE KEY" section.
</p>

<h2>Performance</h2>
<p>
  Oh, it's slow. Really slow. Luckily it's just used in the handshake.
  I haven't done proper benchmarks, but let's just say you won't be
  using it to power your webmail. I may do some benchmarking in a coming blog post.
</p>
<p>
  <b>Update:</b> It can do about 1.4 connections per second.
  See <a href="/2012/02/Benchmarking-TPM-backed-SSL">Benchmarking TPM backed SSL</a>
  for details.
</p>

<h2>Misc notes</h2>
<ul>
  <li>The .key file for the TPM-backed cert contains the secret key encrypted
      with something that's in the TPM. It's not usable without the exact same TPM chip.</li>
  <li>You can choose to create a key in the normal way and then "convert" it to a TPM-backed key.
      It's not as secure since you can't say the key was never stored outside the TPM chip, but
      use the <code>-w</code> switch to <code>create_tpm_key</code> if you want to do this.</li>
  <li>OpenSSL is probably the most horrible, disgusting, undocumented crap library I've ever seen.
      Some of this can be blamed on SSL, X509 and ASN.1, but far from all.</li>
  <li>Emulated TPM is not completely useless. Since the emulator runs as root and the user
      has no insight into it you can have users be able to use private keys that they
      can't read or copy to other machines. (caveat: I don't know if the emulator is
      actually secure in this mode, but it can be made to be)</li>
  <li>My TPM chip doesn't seem to like importing (<code>create_tpm_key -w foo.key</code>)
      4096 bit keys. 2048 was fine though.</li>
</ul>

<h2>Links</h2>
<ul>
  <li><a href="http://www.infond.fr/2010/03/trusted-platforms-module-tpm-openssl.html">trusted platforms
      module (TPM), openssl and ecryptfs tutorial</a>. Another
      nice use of TPM. Also installation instructions for TPM emulator</li>
  <li><a href="http://www.cs.tau.ac.il/~orkaplan/TPMWorkshop/downloads/">Resources from a TPM workshop</a></li>
  <li><a href="https://sites.google.com/site/ourcomputernotes/security/use-tpm-on-linux">Use TPM on Linux</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2012/02/TPM-backed-SSL</link>
   <guid>http://blog.habets.pp.se/2012/02/TPM-backed-SSL</guid>
   <pubDate>Sat, 04 Feb 2012 15:22:29 GMT</pubDate>
  </item>
  <item>
   <title>Secure browser-to-proxy communication</title>
   <description><![CDATA[<p>
  When connecting to a possibly hostile network I want to tunnel
  all traffic from my browser to some proxy I have set up on the Internet.
</p>

<p>
  The obvious way to do this is with a proxy. The problem with that is
  that the traffic from the browser to the proxy is not encrypted. Even
  when you browse to secure SSL sites some traffic is being sent in the
  clear, such as the host name. That's not so bad, but I want to hide my
  HTTP traffic too.
</p>



<p>
  Turns out that at least
  <a href="http://www.chromium.org/developers/design-documents/secure-web-proxy">Chrome
  <em>does</em> support using SSL between the browser and the proxy</a>,
  but you can't configure it directly. You have to use Proxy Auto Configuration
  to point to an HTTPS host:port.
</p>

<p>
  Running OpenVPN is out in this case since I want it to work with everything, including Android
  and ChromeOS… and Windows (without installing "stuff"). Not that I've tried it with Windows yet,
  but it should work.
</p>

<p>
  For added fun I wanted to authenticate to the proxy using a client
  certificate, so that I don't have to worry about remembering or losing passwords.
</p>

<p>
  Before you set off to do the same thing I should warn you that either I haven't
  done it quite right or there is a bug in Chrome. If the network has a hickup
  so that the proxy or the .pac file is unavailable it will fall back to connecting
  directly. I want it to never fall back. That's kind of the point.
</p>

<p>
  But all is not in vain. I also set up IPSec with these same certificates. There
  will be a follow-up post describing how I set this up to tunnel securely with
  both Chromebook and my phone.
</p>

<p>
  This is what I did (caveat: some of this is from memory.
  If you find any errors please let me know):
<ol>
<li><h3>Copy easyrsa 2.0 from openvpn sources</h3>
  This is a set of scripts to manage a CA. We'll be using
  this directory/set of scripts both to create a server and
  client certificates. But only the client certificates will
  be signed by our own CA.
</li>

<li><h3>Edit <code>vars</code> file</h3>
  I like to change KEY_SIZE to 2048, country and other stuff.
  These will be the defaults when creating certs.
</li>

<li><h3>Init easyrsa</h3>
  <code>./clean-all</code><br/>
  This is a one-time init. Don't run this script again.
</li>

<li><h3>Build the CA for the client certs</h3>
  <code>./build-ca</code>
</li>

<li><h3>Copy CA cert to proxy server</h3>
  <code>scp keys/ca.crt proxy:/etc/proxy-ssl/proxy-ca.crt</code>
</li>

<li><h3>Build server key and signing request</h3>
  <code>./build-req proxy.foo.com</code>
</li>

<li><h3>Get signed server cert</h3>
  Send keys/proxy.foo.com.csr to your real CA (e.g. cacert.org or Verisign).
  You'll get back proxy.foo.com.crt. If you do use cacert.org then make sure that
  your browser trusts <a href="http://www.cacert.org">their root</a> by importing it.
</li>

<li><h3>Put proxy.foo.com cert and key on proxy server</h3>
 <code>scp keys/proxy.foo.com.{crt,key} proxy:/etc/proxy-ssl/</code>
</li>

<li><h3>Install squid proxy and stunnel on proxy server</h3>
  On Debian/Ubuntu: <code>apt-get install squid3 stunnel</code>
</li>

<li><h3>Configure & start stunnel</h3>
  <ol>
    <li>set ENABLE=1 in /etc/defaults/stunnel.conf</li>
    <li>In /etc/stunnel/stunnel.conf
      <code><pre>
      cert=/etc/proxy-ssl/proxy.foo.com.crt
      key=/etc/proxy-ssl/proxy.foo.com.key
      verify=2
      CAfile=/etc/proxy-ssl/proxy-ca.crt
      [proxy]
      accept  = 12346
      connect = 3128</pre></code>
    </li>
    <li>/etc/init.d/stunnel4 start</li>
  </ol>
</li>

<li><h3>Create .pac file somewhere on an https url</h3>
<blockquote><pre>
function FindProxyForURL(url, host)
{
      return "HTTPS proxy.foo.com:12346";
}
</pre></blockquote>
Make sure that the certificate of the https server is one that the browser will accept.

<li><h3>Set proxy autoconf to the url to this .pac file</h3>
  Spanner-&gt;Preferences-&gt;Under the Bonnet-&gt;Change proxy settings-&gt;Automatic Proxy Configuration<br/>
  Set the URL to where the file is, including "https://".
</li>

<li><h3>Try it now. It should fail with SSL errors</h3>
  It should fail because proxy doesn't accept your cert
  (you don't have a cert in the browser yet). Don't continue if you get some other error.
</li>

<li><h3>Create client cert signed by your own CA</h3>
  <code>./build-key my-proxy-key</code><br>
  Don't set a password.
</li>

<li><h3>Convert the client key+cert to .p12, because that's what Android and Chrome wants</h3>
  <code>openssl pkcs12 -export -in keys/my-proxy-key.crt -inkey keys/my-proxy-key.key -out my-proxy-key.p12</code><br/>
  It'll ask for a password that will only be used in the next step. No need to save it for later.
</li>

<li><h3>Import the client certificate into the browser</h3>
  On your Chrome (or chromebook) go Spanner-&gt;Preferences-&gt;Under the Bonnet-&gt;Certificate Manager-&gt;Your Certificates-&gt;Import (or "Import and Bind to Device").
</li>

<li><h3>Try to browse somewhere. Now it should work</h3>
  Make sure you're actually using the proxy. Go to <a href="http://www.whatismyip.com">www.whatismyip.com</a>
  or something and make sure that it sees the IP of the proxy.  
  It'll probably tell you that you're using a proxy. If it doesn't work then good luck. :-)
</li>
</ol>

<h2>Problems</h2>
<p>
  Like I said it seems that it falls back to connecting directly, even though
  the .pac file doesn't have a fallback mechanism configured. Stay tuned for the IPSec version.
</p>]]></description>
   <link>http://blog.habets.pp.se/2011/12/Secure-browser-to-proxy-communication</link>
   <guid>http://blog.habets.pp.se/2011/12/Secure-browser-to-proxy-communication</guid>
   <pubDate>Tue, 27 Dec 2011 01:16:10 GMT</pubDate>
  </item>
  <item>
   <title>Optimizing TCP slow start</title>
   <description><![CDATA[<p>
  The short version of the problem and solution I will describe is that while TCP gets up to speed
  fairly fast, and "fast enough" for many uses, it doesn't accelerate
  fast enough for short-lived connections such as web page requests. If I have 10Mbps connection
  and the server has 10Mbps to spare, why doesn't a 17kB web page transfer at 10Mbps from
  first to last byte? (that is, when excluding TCP handshake, HTTP request and server side
  page rendering)
</p>

<p>
  This is pretty Linux-focused, but I'll add pointers for other OSs if I see them.
</p>


<h2>Short version</h2>
<p>
  This will get a bit basic for some people, so here's the short version. Make sure you measure
  the effect of changing these settings. Don't just increase them and think "more is better".
</p>
On receiver side (requires kernel version 2.6.33 or newer (and a fairly new iproute package. iproute2-ss100519 works). Use your default route instead of "x.x.x.x"):
<blockquote><pre>
ip route change default via x.x.x.x initrwnd 20
</pre></blockquote>

On sender side:
<blockquote><pre>
ip route change default via x.x.x.x initcwnd 20
</pre></blockquote>

To tweak both send and receive:
<blockquote><pre>
ip route change default via x.x.x.x initcwnd 20 initrwnd 20
</pre></blockquote>


<h2>The path to enlightenment</h2>
<p>
  In short, the number of bytes in flight in TCP is the lowest of the senders congestion window (cwnd)
  and the receiver window size. The window size is the receiver announcing how much it's ready
  to receive, and the sender will therefore not send any more than that. The cwnd is the sender
  trying to avoid causing congestion. (since TCP is two-way both sides have both, but think of it as one-way for now)
</p>
<p>
  The window size is announced in every segment (TCP packets are called "segments") and is the receivers
  method of throttling. The cwnd is not sent across the network, but is a local sender-side throttling only.
</p>
<p>
  Both of these default to "a few" multiples of the maximum size segments (MSS).
  The MSS is announced in the SYN and SYN|ACK packets and are adjusted so that a TCP segment
  fits in the path MTU (hopefully). Typical initial window size and cwnd is on the order of 4kB.
  Linux has an initial cwnd of 10*MSS nowadays, but that doesn't help if the receiver window is smaller
  that that.
  Both window size and cwnd will change as the connection progresses. How and why is a huge topic in itself. I'm
  focusing here on a specific problem of initial size and TCP slow start.
</p>
<p>
  The problem I was having was that when I downloaded <a href="http://blog.habets.pp.se">http://blog.habets.pp.se</a>
  over a ~50ms RTT connection these values don't go up fast enough. During the ~300ms transaction (including everything)
  the sender stalls about 4-6 times waiting for the receiver to give the go-ahead. (I only have approximate numbers since
  the RTT between the servers I was testing was a bit unstable. Virtual servers and all that).
  The time between first and last byte was about 170ms. Really? ~50ms RTT and 17kB in 170ms? That's not good.
</p><p>
  Ideally there should be two round trips involved. One where the client has sent SYN and is waiting for SYN|ACK,
  and the other when the client has sent the request and is waiting for the results. If this was a long-running
  connection (with <a href="http://en.wikipedia.org/wiki/HTTP_persistent_connection">HTTP keep-alive</a> for example)
  this wouldn't be a problem, but since I'm looking at the first request in a new TCP connection it is.
</p>
<h3>Increase receiver window size</h3>
<p>
  Since I couldn't find it in <code>sysctl</code> or <code>/sys</code> I looked at the source.
  <code>net/ipv4/tcp_output.c</code> has a function called <code>tcp_select_initial_window()</code>.
  The last parameter is <code>__u32 init_rcv_win</code>. Well, that was easy. Because
  I'm lazy I just compiled the kernel hardcoding it to 10 (it's in multiples of MSS).
  I started a lab virtual machine and sure enough the initial window is now a lot bigger.
  Still not seeing a reduction in round trip waits though, and it's as slow as before.
  At least now it's not the receivers fault. The window has lots of space left but the
  sender is quiet.
</p><p>
  What is this <code>dst_metric(dst, RTAX_INITRWND)</code> that it was before I changed
  it to hardcoded 10 though? <code>include/linux/rtnetlink.h</code> which defines RTAX_INITRWND looks like mostly
  routing related stuff. Aha! Sure enough:
  <blockquote><pre>
user@hostname$ ip route help
[...]
OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]
       [ rtt TIME ] [ rttvar TIME ] [reordering NUMBER ]
       [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]
       [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]
       [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]
[...]  </pre></blockquote>
  Setting these things per route table entry? Yeah that does make sense. I set values as
  seen under "Short version" above and a HTTP request is now just two round trips (three
  if you count closing the connection, but the web page is already downloaded at that point so
  I'm not counting it), and single-digit milliseconds from first to last byte. A 96% reduction
  (26% if you include the connection setup & HTTP request). (very inexact numbers, I just ran
  the test once. It's late. For details on how cwnd affects latency see
<a href="http://code.google.com/speed/articles/tcp_initcwnd_paper.pdf">Googles paper on it</a>.
</p>

<h2>Misc</h2>
<ul>
  <li>As far as I can see window size and cwnd can not be set per-socket by <code>setsockopt()</code> or similar. If they could this would cause people to write evil applications that don't play well with the rest of the Internet.</li>
  <li>Current cwnd, window size and other data can be seen with <code>getsockopt(..., TCP_INFO, ...)</code>.</li>
  <li><a href="http://code.google.com/speed/articles/tcp_initcwnd_paper.pdf">An Argument for Increasing TCP’s Initial Congestion Window</a></li>
  <li><a href="http://blog.benstrong.com/2010/11/google-and-microsoft-cheat-on-slow.html">Google and Microsoft Cheat on Slow-Start. Should You?</a></li>
  <li><a href="http://www.amailbox.org/mailarchive/linux-netdev/2010/5/26/6278007">Linux kernel patch</a> for adding <code>setsockopt()</code> for changing cwnd. Not needed. It was rejected for a reason.</li>
</ul>

<h2>Links</h2>
<ul>
  <li>Draft to <a href="http://tools.ietf.org/html/draft-hkchu-tcpm-initcwnd-01">increase TCP's initial window</a> by default to 10 * MSS. This has been implemented in Linux.</li>
  <li><a href="http://www.andysnotebook.com/2011/11/increasing-the-tcp-initial-congestion-window-on-windows-2008-server-r2.html">Increasing the TCP Initial Congestion Window on Windows 2008 Server R2</a></li>
</ul>]]></description>
   <link>http://blog.habets.pp.se/2011/10/Optimizing-TCP-slow-start</link>
   <guid>http://blog.habets.pp.se/2011/10/Optimizing-TCP-slow-start</guid>
   <pubDate>Sat, 15 Oct 2011 23:21:49 GMT</pubDate>
  </item>
 </channel>
</rss>
