Server certificate hash checking

Woodhouse, David david.woodhouse at intel.com
Mon Nov 3 09:50:09 PST 2014


I've just pushed out some changes to the way we handle server
certificates.

Firstly, the OPENCONNECT_X509 opaque type is dead, along with the
openconnect_get_peer_cert() function.

The openconnect_get_cert_DER() and openconnect_get_cert_details()
functions were *only* ever called on the peer cert (there was no way of
getting any *other* object of the OPENCONNECT_X509 type), and they have
been changes to openconnect_get_peer_cert_DER() and
openconnect_get_peer_cert_details() respectively.

The openconnect_get_cert_sha1() function has been changed to
openconnect_get_peer_cert_hash() and it no longer returns a SHA1 of the
whole certificate DER. Instead, it returns a hash (*currently* SHA1) of
the server's public key. the horrid "pass me a pointer to a 41-character
buffer" part of the libopenconnect API is also now gone, as this new
function returns a const char *.

Hashing just the public key means that the certificate can be reissued
and as long as the key remains the same, the user doesn't have to
manually accept the key again. It also defends against social
engineering attacks where a MITM repeatedly tampers with non-critical
parts of the certificate, effectively training the user to just click
'accept' each time... until one time, the attacker *has* hijacked the
connection.

There is a new openconnect_check_peer_cert_hash() function which, given
a hash, will check it against the server's certificate. It will accept
either the old-style 40-digit SHA1 of the whole cert, *or* the new-style
SHA1 of the pubkey, which is prefixed by 'sha1:'.

In future, the new style may use something better than SHA1 and the
openconnect_check_peer_cert_hash() function will obviously be adjusted
to cope.

A client is expected to use openconnect_check_peer_cert_hash() to check
if a 'remembered' certificate is indeed a match for the one currently
offered by the server — don't use strcmp() against the new hash because
you'll get false negatives. Even on a match, the client is expected to
update its storage to contain *new* hash returned by
openconnect_get_peer_cert_hash().

The --servercert and --authenticate command line options now behave this
way too. The former will accept either type of hash, and the latter
generates the new style only for its FINGERPRINT= output.


-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse at intel.com                              Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3437 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20141103/fb9cc3ab/attachment.bin>


More information about the openconnect-devel mailing list