From f2eb598e8e3cd96d41852b669e509ea7cc30c442 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Sun, 5 Mar 2017 11:43:15 +0100 Subject: [PATCH] Added support for RFC7469 key PIN That allows the hash provided to the client to be the RFC7469 key PIN. That is, a base64 encoding of the public key sha256 hash instead of the hex equivalent. That reduces the number of characters that need to be typed. Signed-off-by: Nikos Mavrogiannopoulos Signed-off-by: David Woodhouse --- dtls.c | 19 +++++++++++++++++++ library.c | 3 +++ openconnect-internal.h | 1 + openconnect.8.in | 12 ++++++++---- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/dtls.c b/dtls.c index a10d4ed3..c97d14d1 100644 --- a/dtls.c +++ b/dtls.c @@ -85,6 +85,25 @@ char *openconnect_bin2hex(const char *prefix, const uint8_t *data, unsigned len) return p; } +char *openconnect_bin2base64(const char *prefix, const uint8_t *data, unsigned len) +{ + struct oc_text_buf *buf; + char *p = NULL; + + buf = buf_alloc(); + if (prefix) + buf_append(buf, "%s", prefix); + buf_append_base64(buf, data, len); + + if (!buf_error(buf)) { + p = buf->data; + buf->data = NULL; + } + buf_free(buf); + + return p; +} + static int connect_dtls_socket(struct openconnect_info *vpninfo) { int dtls_fd, ret; diff --git a/library.c b/library.c index 3ca1e7a5..12d48fcd 100644 --- a/library.c +++ b/library.c @@ -978,6 +978,9 @@ int openconnect_check_peer_cert_hash(struct openconnect_info *vpninfo, } else if (strncmp(old_hash, "sha256:", 7) == 0) { fingerprint = openconnect_bin2hex("sha256:", vpninfo->peer_cert_sha256_raw, sizeof(vpninfo->peer_cert_sha256_raw)); min_match_len = real_min_match_len + sizeof("sha256:")-1; + } else if (strncmp(old_hash, "pin-sha256:", 11) == 0) { + fingerprint = openconnect_bin2base64("pin-sha256:", vpninfo->peer_cert_sha256_raw, sizeof(vpninfo->peer_cert_sha256_raw)); + min_match_len = real_min_match_len + sizeof("pin-sha256:")-1; } else { vpn_progress(vpninfo, PRG_ERR, _("Unknown certificate hash: %s.\n"), old_hash); return -EIO; diff --git a/openconnect-internal.h b/openconnect-internal.h index 291eb4b7..4aac2ce6 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -828,6 +828,7 @@ void dtls_detect_mtu(struct openconnect_info *vpninfo); int openconnect_dtls_read(struct openconnect_info *vpninfo, void *buf, size_t len, unsigned ms); int openconnect_dtls_write(struct openconnect_info *vpninfo, void *buf, size_t len); char *openconnect_bin2hex(const char *prefix, const uint8_t *data, unsigned len); +char *openconnect_bin2base64(const char *prefix, const uint8_t *data, unsigned len); /* cstp.c */ void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *buf); diff --git a/openconnect.8.in b/openconnect.8.in index b7e2bfc0..c97dec2b 100644 --- a/openconnect.8.in +++ b/openconnect.8.in @@ -479,11 +479,15 @@ instead of using the normal resolver to look it up. Accept server's SSL certificate only if the provided fingerprint matches. The allowed fingerprint types are .IR SHA1 , +.IR SHA256 , and -.IR SHA256 . -They are distinguished by the 'sha1:' or 'sha256:' prefixes to the hex encoded -hash. To ease certain testing use-cases, a partial match of the hash will also -be accepted, if it is at least 4 characters. +.IR PIN-SHA256 . +They are distinguished by the 'sha1:', 'sha256:' and 'pin-sha256:' prefixes to the +encoded hash. The first two are custom identifiers providing hex +encoding of the peer's public key, while 'pin-sha256:' is the RFC7469 key +PIN, which utilizes base64 encoding. To ease certain +testing use-cases, a partial match of the hash will also +be accepted, if it is at least 4 characters past the prefix. .TP .B \-\-useragent=STRING Use -- 2.49.0