This is a security-impacting bug relating to verification of keyserver TLS
certificates.
When chasing SRV records, in *insecure* DNS, GnuPG takes the hostname from the SRV
lookup and uses that, for libcurl, as the hostname to:
(1) pass in ServerNameIndication
(2) use for certificate verification
For testing purposes, "sks.spodhuis.org" is up and running with two different TLS
certificates available. One is from my own CA (cert
https://www.security.spodhuis.org/CA/globnixCA3.crt and trust-details on
https://www.security.spodhuis.org/). That is used for a hostname of
"sks.spodhuis.org" and _most_ hostnames.
The second cert is configured to be used for "pool.sks-keyservers.net *.pool.sks-
keyservers.net" (and the cert itself is for CN=sks.spodhuis.org with subjectAltName
"DNS:hkps.pool.sks-keyservers.net, DNS:sks.spodhuis.org").
Using gnupg with "keyserver-options verbose,debug,ca-cert-file=..." and keyserver
pointing to various hostnames, I can see:
(1) using --keyserver=https://...anything... the path is dropped from the HTTP
request :(
(2) using --keyserver=hkps://sks.spodhuis.org and ca-cert-file pointing to a file
containing globnixCA3.crt, things work
(3) using --keyserver=hkps://hkps.pool.sks-keyservers.net the DNS SRV records are
used; with resolver manipulation (unbound-control in my case):
% unbound-control local_data _pgpkey-https._tcp.hkps.pool.sks-keyservers.net SRV 10
10 443 sks.spodhuis.org
ok
% unbound-control local_data hkps.pool.sks-keyservers.net A 94.142.241.93
ok
we have SRV being used (good!) but then passing sks.spodhuis.org as the hostname in
the handshake, which (1) selects the wrong cert and (2) will be verifying the TLS
cert against untrusted data, instead of the known-good hostname.
TLS certificate verification should not use untrusted data; a corollary is that the
ServerNameIndication, used by the server to select a cert, should specify the same
hostname than the client will be using for verification.