Bug 1479: GnuPG curl-shim TCP half-close harms HTTP interop

Phil Pennock gnupg-devel at spodhuis.org
Sat Mar 2 08:14:45 CET 2013


On 2013-03-01 at 20:19 -0500, David Shaw wrote:
> While I believe you are seeing this, I'm not, and you're reporting a
> bug (keyserver fetches not working at all) that I daresay would have
> been noticed a long time ago.

No, keyserver fetches appeared to work, but with a spurious complaint
that they don't work.  In fact, it's worse.

Tracked it down: the existing problem with the shutdowns?  It can result
in nginx dropping a connection part-way through, returning truncated
results.  So in the cases where it does error, GnuPG sees no final armor
line, and complains about the _no_ data, then appears to import
successfully anyway, when what it's actually getting is _incomplete_
data, a key with some of its signatures.

So the user sees the import happen anyway and assumes they got a
complete key.

:(

To see this, it needs to be a keyserver with an nginx proxy which has
not yet rebuilt/reconfigured to avoid treating the write shutdown as a
connection abort, you must have curl-shim in use, and you must be just
the right network distance from the keyserver that you _usually_ succeed
in connecting and getting data back, but the abort is processed while
the connection is still returning data.

For me, that's the distance between sks.spodhuis.org and
keys2.kfwebs.net, especially when connecting over IPv6.

It's still the nginx component in play, because this doesn't happen
without the shutdown(sock, SHUT_WR).

Do you think it's worth GnuPG detecting that it got truncated results by
the missing final armor line and handling that with an explicit warning
that it only got part of the keydata and signatures might be missing?


In zsh:

function keycheck {
  local server="$1" key="${2:-310D6001650E06D3}";
  { print -l 'COMMAND GET' "HOST $server" 'PORT 11371' 'SCHEME hkp' '' $key | \
    /usr/local/libexec/gpg2keys_hkp 2>&1 1>&3 | sed 's/^/STDERR: /'
  } 3>&1 1>&2
}

% keycheck keys2.kfwebs.net | wc -l
STDERR: * HTTP host:port post-SRV is "keys2.kfwebs.net:11371"
STDERR: gpgkeys: key 310D6001650E06D3 not found on keyserver
     169
% keycheck 84.215.15.221 | wc -l
STDERR: * HTTP host:port post-SRV is "84.215.15.221:11371"
STDERR: gpgkeys: key 310D6001650E06D3 not found on keyserver
     222
% keycheck '[2001:16d8:ee3d:ee30:215:5dff:fe00:120d]' | wc -l
STDERR: * HTTP host:port post-SRV is "2001:16d8:ee3d:ee30:215:5dff:fe00:120d:11371"
STDERR: gpgkeys: key 310D6001650E06D3 not found on keyserver
     169
% keycheck sks.spodhuis.org | wc -l
STDERR: * HTTP host:port post-SRV is "sks.spodhuis.org:11371"
     228
% keycheck localhost | wc -l
STDERR: * HTTP host:port post-SRV is "localhost:11371"
     228

Loose guess: Kristian has IPv6 via a tunnel, things get slightly slow
while waiting for path MTU discovery to handle fragmentation, and so I
get 169 lines of output, or 222 over IPv4, still truncated.

(Those numbers are fairly repeatable for me, occasional variances.)

Last few lines are:
----------------------------8< cut here >8------------------------------
rmMtbTaeuJu3lp+Or2OIcDGai8oal2GZf0cUjBg8tgXJ2/x1aVKwj8eQTKy3BRwxS9ZG/v2H
kgB57OhUzC8Wne+PsdbPlbHB7Iwdq8e7Rc9BI3QyPcsSSWDM2bsvoe4DFp5XS5z2HP8eEBXp
Znf9TXa+I3+WTK4Au7HTKfYqNXShP5nqlC1n8QacZdunpVbGaJRQV7T3fH9NSdxVGuo/ZWzV
G2ur5R5PU2unozXCd4RyJ2r1OJwPiHFagp+nRXjR+KkhDC4oQLqODuUawHb2p70tMagCdc8e
SI31niWrRDjZqWLQNt31nrHHUZuCE05ObEos12XfRIq97DHx75LvGtmT1uuPnHyJYwfDXhhE
69DI70zvh0fXV1AV2IaH7QZPygZ/Q0KWQTeeoF5o
=E9CG
-----END PGP PUBLIC KEY BLOCK-----
----------------------------8< cut here >8------------------------------

Over IPv4, get as far as:
----------------------------8< cut here >8------------------------------
rmMtbTaeuJu3lp+Or2OIcDGai8oal2GZf0cUjBg8tgXJ2/x1aVKwj8eQTKy3BRwxS9ZG/v2H
STDERR: gpgkeys: key 310D6001650E06D3 not found on keyserver
kgB57OhUzC8Wne+PsdbPlbHB7
KEY 0x310D6001650E06D3 FAILED 6
----------------------------8< cut here >8------------------------------
and that "PlbHB7" is at the end of a packet, per tcpdump.

----------------------------8< cut here >8------------------------------
	0x05c0:  3248 0a6b 6742 3537 4f68 557a 4338 576e  2H.kgB57OhUzC8Wn
	0x05d0:  652b 5073 6462 506c 6248 4237            e+PsdbPlbHB7
02:10:23.566187 IP (tos 0x0, ttl 64, id 47894, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->cc64)!) 94.142.240.6.55095 > 84.215.15.221.11371: ., cksum 0xc322 (correct), 144:144(0) ack 15929 win 8145 <nop,nop,timestamp 1380595860 162964942>
	0x0000:  4500 0034 bb16 4000 4006 0000 5e8e f006  E..4.. at .@...^...
	0x0010:  54d7 0fdd d737 2c6b 8b4b e740 742b bbc2  T....7,k.K. at t+..
	0x0020:  8010 1fd1 c322 0000 0101 080a 524a 3894  ....."......RJ8.
	0x0030:  09b6 a5ce                                ....
02:10:23.566190 IP (tos 0x0, ttl 54, id 55379, offset 0, flags [DF], proto TCP (6), length 52) 84.215.15.221.11371 > 94.142.240.6.55095: F, cksum 0xe2cf (correct), 15929:15929(0) ack 144 win 114 <nop,nop,timestamp 162964945 1380595778>
	0x0000:  4500 0034 d853 4000 3606 b927 54d7 0fdd  E..4.S at .6..'T...
	0x0010:  5e8e f006 2c6b d737 742b bbc2 8b4b e740  ^...,k.7t+...K.@
	0x0020:  8011 0072 e2cf 0000 0101 080a 09b6 a5d1  ...r............
	0x0030:  524a 3842                                RJ8B
02:10:23.566204 IP (tos 0x0, ttl 64, id 47895, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->cc63)!) 94.142.240.6.55095 > 84.215.15.221.11371: ., cksum 0xc31f (correct), 144:144(0) ack 15930 win 8144 <nop,nop,timestamp 1380595860 162964945>
	0x0000:  4500 0034 bb17 4000 4006 0000 5e8e f006  E..4.. at .@...^...
	0x0010:  54d7 0fdd d737 2c6b 8b4b e740 742b bbc3  T....7,k.K. at t+..
	0x0020:  8010 1fd0 c31f 0000 0101 080a 524a 3894  ............RJ8.
	0x0030:  09b6 a5d1                                ....
----------------------------8< cut here >8------------------------------

(Ignore the bad cksum, that applies always to outbound frames, they're
 captured by BPF before the checksum is calculated)

-Phil



More information about the Gnupg-devel mailing list