From eb95f3a9f4a953ec58819b63f19da802caebac24 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 17 Nov 2014 16:52:47 +0000 Subject: [PATCH] Fix GnuTLS 2.12 build Signed-off-by: David Woodhouse --- configure.ac | 2 ++ gnutls.c | 26 +++++++++++++++++++++++--- library.c | 4 +++- openconnect-internal.h | 2 +- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index b8670751..b1d661ef 100644 --- a/configure.ac +++ b/configure.ac @@ -357,6 +357,8 @@ if test "$with_gnutls" = "yes"; then [AC_DEFINE(HAVE_GNUTLS_CERTIFICATE_SET_KEY, 1, [stupid])], []) AC_CHECK_FUNC(gnutls_pk_to_sign, [AC_DEFINE(HAVE_GNUTLS_PK_TO_SIGN, 1, [autoheader])], []) + AC_CHECK_FUNC(gnutls_pubkey_export2, + [AC_DEFINE(HAVE_GNUTLS_PUBKEY_EXPORT2, 1, [autoheader sucks donkey balls])], []) if test "$with_openssl" = "" || test "$with_openssl" = "no"; then AC_CHECK_FUNC(gnutls_session_set_premaster, [have_gnutls_dtls=yes], [have_gnutls_dtls=no]) diff --git a/gnutls.c b/gnutls.c index b68a5a0d..4a42dafa 100644 --- a/gnutls.c +++ b/gnutls.c @@ -1657,7 +1657,7 @@ int get_cert_md5_fingerprint(struct openconnect_info *vpninfo, static int set_peer_cert_hash(struct openconnect_info *vpninfo) { unsigned char sha1[SHA1_SIZE]; - size_t shalen = SHA1_SIZE; + size_t shalen; gnutls_pubkey_t pkey; gnutls_datum_t d; int i, err; @@ -1671,14 +1671,34 @@ static int set_peer_cert_hash(struct openconnect_info *vpninfo) gnutls_pubkey_deinit(pkey); return err; } - +#ifdef HAVE_GNUTLS_PUBKEY_EXPORT2 err = gnutls_pubkey_export2(pkey, GNUTLS_X509_FMT_DER, &d); if (err) { gnutls_pubkey_deinit(pkey); return err; } - +#else + shalen = 0; + err = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_DER, NULL, &shalen); + if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) { + gnutls_pubkey_deinit(pkey); + return err; + } + d.size = shalen; + d.data = gnutls_malloc(d.size); + if (!d.data) { + gnutls_pubkey_deinit(pkey); + return -ENOMEM; + } + err = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_DER, d.data, &shalen); + if (err) { + gnutls_free(d.data); + gnutls_pubkey_deinit(pkey); + return err; + } +#endif gnutls_pubkey_deinit(pkey); + shalen = SHA1_SIZE; err = gnutls_fingerprint(GNUTLS_DIG_SHA1, &d, sha1, &shalen); if (err) { diff --git a/library.c b/library.c index 4c3e3ee3..c19970c1 100644 --- a/library.c +++ b/library.c @@ -198,8 +198,10 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo) free(vpninfo->servercert); free(vpninfo->ifname); free(vpninfo->dtls_cipher); -#if defined(OPENCONNECT_GNUTLS) +#ifdef OPENCONNECT_GNUTLS gnutls_free(vpninfo->cstp_cipher); /* In OpenSSL this is const */ +#endif +#ifdef DTLS_GNUTLS gnutls_free(vpninfo->gnutls_dtls_cipher); #endif free(vpninfo->dtls_addr); diff --git a/openconnect-internal.h b/openconnect-internal.h index 3027b50d..bc377091 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -317,6 +317,7 @@ struct openconnect_info { #elif defined(OPENCONNECT_GNUTLS) gnutls_session_t https_sess; gnutls_certificate_credentials_t https_cred; + char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */ struct pin_cache *pin_cache; #ifdef HAVE_TROUSERS TSS_HCONTEXT tpm_context; @@ -364,7 +365,6 @@ struct openconnect_info { have fewer ifdefs and accessor macros for it. */ gnutls_session_t dtls_ssl; char *gnutls_dtls_cipher; /* cached for openconnect_get_dtls_cipher() */ - char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */ #endif char *cstp_cipher;