From 0641c2d1f0fd9535ecfadeb2cc333d49683c0504 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 27 Oct 2014 23:21:36 +0100 Subject: [PATCH] Make the cipher strings consistent based on which library is in use Signed-off-by: Nikos Mavrogiannopoulos Signed-off-by: David Woodhouse --- dtls.c | 12 +++++++++--- gnutls.c | 21 +++++++++++++++------ gnutls.h | 2 ++ library.c | 13 +++++++++++++ openconnect-internal.h | 1 + openconnect.h | 3 +-- 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/dtls.c b/dtls.c index 1e704307..b52b93ce 100644 --- a/dtls.c +++ b/dtls.c @@ -316,6 +316,7 @@ void dtls_shutdown(struct openconnect_info *vpninfo) #elif defined(DTLS_GNUTLS) #include +#include "gnutls.h" struct { const char *name; @@ -400,6 +401,7 @@ static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) int dtls_try_handshake(struct openconnect_info *vpninfo) { int err = gnutls_handshake(vpninfo->dtls_ssl); + char *str; if (!err) { #ifdef HAVE_GNUTLS_DTLS_SET_DATA_MTU @@ -426,9 +428,13 @@ int dtls_try_handshake(struct openconnect_info *vpninfo) #endif vpninfo->dtls_state = DTLS_CONNECTED; - vpn_progress(vpninfo, PRG_INFO, - _("Established DTLS connection (using GnuTLS). Ciphersuite %s.\n"), - vpninfo->dtls_cipher); + str = get_gnutls_cipher(vpninfo->dtls_ssl); + if (str) { + vpn_progress(vpninfo, PRG_INFO, + _("Established DTLS connection (using GnuTLS). Ciphersuite %s.\n"), + str); + gnutls_free(str); + } vpninfo->dtls_times.last_rekey = vpninfo->dtls_times.last_rx = vpninfo->dtls_times.last_tx = time(NULL); diff --git a/gnutls.c b/gnutls.c index 5f1c9e5c..4a98590e 100644 --- a/gnutls.c +++ b/gnutls.c @@ -2167,17 +2167,26 @@ void openconnect_init_ssl(void) gnutls_global_init(); } -const char *openconnect_get_cstp_cipher(struct openconnect_info *vpninfo) +char *get_gnutls_cipher(gnutls_session_t session) { - if (vpninfo->cstp_cipher == NULL) { + char *str; #if GNUTLS_VERSION_NUMBER > 0x03010a - vpninfo->cstp_cipher = gnutls_session_get_desc(vpninfo->https_sess); + str = gnutls_session_get_desc(session); #else - vpninfo->cstp_cipher = gnutls_strdup(gnutls_cipher_suite_get_name( - gnutls_kx_get(vpninfo->https_sess), gnutls_cipher_get(vpninfo->https_sess), - gnutls_mac_get(vpninfo->https_sess))); + str = gnutls_strdup(gnutls_cipher_suite_get_name( + gnutls_kx_get(session), gnutls_cipher_get(session), + gnutls_mac_get(session))); #endif + return str; +} + +const char *openconnect_get_cstp_cipher(struct openconnect_info *vpninfo) +{ + if (vpninfo->cstp_cipher != NULL) { + gnutls_free(vpninfo->cstp_cipher); } + + vpninfo->cstp_cipher = get_gnutls_cipher(vpninfo->https_sess); return vpninfo->cstp_cipher; } diff --git a/gnutls.h b/gnutls.h index 3951f9f5..30723c57 100644 --- a/gnutls.h +++ b/gnutls.h @@ -69,4 +69,6 @@ static inline int sign_dummy_data(struct openconnect_info *vpninfo, int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig); +char *get_gnutls_cipher(gnutls_session_t session); + #endif /* __OPENCONNECT_GNUTLS_H__ */ diff --git a/library.c b/library.c index 1de96c49..c69b956f 100644 --- a/library.c +++ b/library.c @@ -38,6 +38,10 @@ #include "openconnect-internal.h" +#if defined(OPENCONNECT_GNUTLS) +#include "gnutls.h" +#endif + struct openconnect_info *openconnect_vpninfo_new(const char *useragent, openconnect_validate_peer_cert_vfn validate_peer_cert, openconnect_write_new_config_vfn write_new_config, @@ -193,6 +197,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo) free(vpninfo->dtls_cipher); #if defined(OPENCONNECT_GNUTLS) gnutls_free(vpninfo->cstp_cipher); + gnutls_free(vpninfo->gnutls_dtls_cipher); #else free(vpninfo->cstp_cipher); #endif @@ -667,5 +672,13 @@ int openconnect_setup_tun_device(struct openconnect_info *vpninfo, const char *openconnect_get_dtls_cipher(struct openconnect_info *vpninfo) { +#if defined(DTLS_GNUTLS) + /* in DTLS rehandshakes don't switch the ciphersuite as only + * one is enabled. */ + if (vpninfo->gnutls_dtls_cipher == NULL) + vpninfo->gnutls_dtls_cipher = get_gnutls_cipher(vpninfo->dtls_ssl); + return vpninfo->gnutls_dtls_cipher; +#else return vpninfo->dtls_cipher; +#endif } diff --git a/openconnect-internal.h b/openconnect-internal.h index 4d792997..ecd0621e 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -342,6 +342,7 @@ struct openconnect_info { NULL or not or pass it to DTLS_SEND/DTLS_RECV. This way we have fewer ifdefs and accessor macros for it. */ gnutls_session_t dtls_ssl; + char *gnutls_dtls_cipher; /* cached for openconnect_get_dtls_cipher() */ #endif int dtls_state; struct keepalive_info dtls_times; diff --git a/openconnect.h b/openconnect.h index 7d660dfa..30e2e92d 100644 --- a/openconnect.h +++ b/openconnect.h @@ -306,8 +306,7 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo); int openconnect_obtain_cookie(struct openconnect_info *vpninfo); void openconnect_init_ssl(void); -/* These are strictly cosmetic. The strings differ for the same cipher - * suite between DTLS and CSTP, and for CSTP they change depending on +/* These are strictly cosmetic. The strings differ depending on * whether OpenSSL or GnuTLS is being used. And even depending on the * version of GnuTLS. Do *not* attempt to do anything meaningful based * on matching these strings; if you want to do something like that then