[Sks-devel] SRV records and HKPS requests

Phil Pennock sks-devel-phil at spodhuis.org
Sun Oct 7 04:20:39 CEST 2012

GnuPG folks (since this is cross-posted, if my mail makes it through):

 there is a bug in GnuPG's SRV handling, I've identified where I think
 it is, it's in the second block of text from me; the first part of this
 mail relates to SKS and some policy issues around the new keyserver
 pool Kristian has added.

On 2012-10-06 at 17:48 +0200, Kristian Fiskerstrand wrote:
> Some background information on this particular pool: My crawler is now
> trying to detect HKPS enabled servers by looking for this SRV record,
> and if no such SRV record is found, attempting to connect and locate a
> SKS stats page on port 443. Servers available on 443 are then included
> as A, AAAA and SRV records, while other SSL-enabled servers are only
> represented as SRV records, as shown in #Snippet 3#

Ah, interesting; in checking, I just discovered that my SRV record for
_pgpkey-https had not been updated since I added nginx proxying, so was
still giving the "0 0 0 ." (explicitly no service here) response, but
what's happening is that you're looking for records on the _server_, I
think, not the "discoverability" records on the _domain_.

Normally, I think the answer is "whatever is given to GnuPG as the
host/domain label in the --keyserver URL".  This is a little different.

Not knowing if you're using the hostname from peering records, or the
hostname reported from the lookup?op=stats pages, I've added records for
both.  That should cover it, right?  Your snippet 3 suggests the
op=stats hostname, but seems safest to just cover both.

(And if I got really unlucky with timing, I'm out of the pool for the
next two hours because of a bogus entry created by forgetting to
re-anchor the RR data after repeating the block in different $ORIGIN
bases.  Duh.)

> kristianf at kristianf-precision-m4600:~$ dig +short srv
> _pgpkey-https._tcp.keys.kfwebs.net any
> 10 10 11375 keys.kfwebs.net.

> kristianf at kristianf-precision-m4600:~$ gpg2 --keyserver-options
> no-check-cert,debug,verbose --keyserver hkps://keys.kfwebs.net
> --recv-key 0x0B7F8B60E3EDFAE3
> gpg: requesting key 0B7F8B60E3EDFAE3 from hkps server keys.kfwebs.net
> gpgkeys: curl version = libcurl/7.22.0 GnuTLS/2.12.14 zlib/
> libidn/1.23 librtmp/2.3
> * About to connect() to keys.kfwebs.net port 443 (#0)
> *   Trying 2001:16d8:ee30::4... * connected

Looking at gnupg's keyserver/gpgkeys_hkp.c as of git commit
76055d49d1c8b8e4f6245e6729cae81b1eaecbf6 it looks like you might be
using an older binary than me?  If I try that command, I get "Host:",
"Port:", ... lines before the "* About to connect()" line from curl.

Still, doesn't appear to be fixed.

I see the bug: if the scheme is hkps: then they set:

695   if(ascii_strcasecmp(opt->scheme,"hkps")==0)
696     {
697       proto="https";
698       port="443";
699     }

then we hit:
729   if(opt->port)
730     port=opt->port;
731   else if(try_srv)
732     {
733       char *srvtag;
735       if(ks_strcasecmp(opt->scheme,"hkp")==0)
736         srvtag="pgpkey-http";
737       else if(ks_strcasecmp(opt->scheme,"hkps")==0)
738         srvtag="pgpkey-https";
739       else
740         srvtag=NULL;
742 #ifdef HAVE_LIBCURL
743       /* We're using libcurl, so fake SRV support via our wrapper.
744          This isn't as good as true SRV support, as we do not try all
745          possible targets at one particular level and work our way
746          down the list, but it's better than nothing. */······
747       srv_replace(srvtag);

Now srv_replace will set opt->port:
531       if(newname && newport)
532         {
533           free(opt->host);
534           free(opt->port);
535           opt->host=newname;
536           snprintf(newport,MAX_PORT,"%u",srvlist->port);
537           opt->port=newport;
538         }

but then in get_key():
266   strcpy(request,proto);
267   strcat(request,"://");
268   strcat(request,opt->host);
269   strcat(request,":");
270   strcat(request,port);
271   strcat(request,opt->path);
294   curl_easy_setopt(curl,CURLOPT_URL,request);

So, there's a `port` and an `opt->port`; the SRV lookups set `opt->port`
but not `port`, while the URL given to curl uses `port`.

It seems like changing 537 to:
  port = opt->port = newport

should fix it as a stop-gap.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
URL: </pipermail/attachments/20121006/e89cad68/attachment.pgp>

More information about the Gnupg-users mailing list