[gnutls-help] HPKH style (pin-sha256) peer verification in gnutls_certificate_verify_function callback
Ondřej Surý
ondrej at sury.org
Mon Jul 18 23:20:34 CEST 2016
Nikos,
thanks for the tips, I ended up using gnutls_certificate_get_peers and
iterating the list with gnutls_x509_crt_import.
JFTR the full implementation starts here:
https://gitlab.labs.nic.cz/labs/knot/blob/dns-over-tls/src/utils/common/netio.c#L262
and looks like this:
if (gnutls_certificate_type_get(session)
!= GNUTLS_CRT_X509) { \
ERR("Invalid certificate
type\n");
return
GNUTLS_E_CERTIFICATE_ERROR;
}
raw_certificate_list =
gnutls_certificate_get_peers(session,
&raw_certificate_list_size);
if (raw_certificate_list == NULL ||
raw_certificate_list_size == 0) {
ERR("Certificate list is
empty\n");
return
GNUTLS_E_NO_CERTIFICATE_FOUND;
}
uint8_t sha256[64] = { 0 };
size_t sha256_len;
for (int i = 0; i <
raw_certificate_list_size; i++) {
ret =
gnutls_x509_crt_init(&certificate);
if (ret < 0) {
return ret;
}
ret =
gnutls_x509_crt_import(certificate,
&raw_certificate_list[i],
GNUTLS_X509_FMT_DER);
if (ret < 0) {
gnutls_x509_crt_deinit(certificate);
return ret;
}
sha256_len = sizeof(sha256);
ret =
gnutls_x509_crt_get_key_id(certificate,
GNUTLS_KEYID_USE_SHA256, sha256,
&sha256_len);
if (ret < 0) {
gnutls_x509_crt_deinit(certificate);
return ret;
}
if (memcmp(sha256, pin,
sha256_len) == 0) {
pin_seen = 1;
INFO("Matched
certificate using
pin-sha256=\"%s\"\n",
value);
}
gnutls_x509_crt_deinit(certificate);
}
And this is inside the verify_certificate callback function.
The TOFU is not really usable here, but the next thing I might look into
is DANE authentication
(https://datatracker.ietf.org/doc/draft-ietf-dprive-dtls-and-tls-profiles/?include_text=1
Section 9.2)
As a side note, I am really impress with the ease I was able to start
implementing things in gnutls, especially the clarity of the API and the
documentation. Really great job!
Cheers,
--
Ondřej Surý <ondrej at sury.org>
Knot DNS (https://www.knot-dns.cz/) – a high-performance DNS server
Knot Resolver (https://www.knot-resolver.cz/) – secure, privacy-aware,
fast DNS(SEC) resolver
Vše pro chleba (https://vseprochleba.cz) – Potřeby pro pečení chleba
všeho druhu
On Mon, Jul 18, 2016, at 21:26, Nikos Mavrogiannopoulos wrote:
> On Sun, 2016-07-17 at 22:49 +0200, Ondřej Surý wrote:
> > Hey,
> >
> > during the IETF hackathon I implemented DNS over TLS (RFC 7858) for
> > kdig
> > utility in Knot DNS[1] and now I am implementing the different TLS
> > Privacy Profiles (Section 4).
> >
> > Using the excellent examples and documentation[*] I was able to
> > implement:
> >
> > - Opportunistic Privacy Profile (just return 0)
> > - hostname verification with system ca-file
> > - custom ca-file
> >
> > and now I would like to implement verification of pin-sha256
> > user-provided values. Could you please guide me to a place where I
> > should start looking? Is there already some other program that
> > implemented HSTS/HPKP using GnuTLS?
> > And if not than a pointer to
> > documentation for SPKI retrieval would be nice (not quite sure
> > https://www.gnutls.org/manual/html_node/X509-certificate-API.html is
> > the
> > right place and what function am I looking for).
>
> If what you want to is to obtain the DER SPKI format you can import the
> certificate to gnutls_pubkey_t structure and export that one to get
> the DER SPKI. The gnutls_pubkey_import_x509_raw() is the function you
> most likely neeed.
>
> Not sure if it is related to your use case, but there is the trust on
> first use API which can be used to pin certificates and keys
> (i.e., gnutls_store_pubkey and gnutls_verify_stored_pubkey).
>
> regards,
> Nikos
>
More information about the Gnutls-help
mailing list