From 6526aa640a7d6897778cd4ea68d5a61524ebeae0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 9 Jan 2019 12:02:57 +0000 Subject: [PATCH] OpenSSL: Loop over DTLS ciphersuites looking for the one we asked for. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit As of OpenSSL 1.1.1, the trick of using SSL_CTX_set_cipher_list() and then expecting only the one ciphersuite to be present in what we get back from SSL_get_ciphers(), is no longer working. It now always returns the TLSv1.3 ciphers, even though we don't have DTLSv1.3 yet. Reported as https://github.com/openssl/openssl/issues/8004 but probably not going to change; the most likely outcome there is that I'm told that I'm Doing It Wrong™ and a different approach is suggested. In the meantime, just loop over the results and pick the one that we actually asked for. Signed-off-by: David Woodhouse --- openssl-dtls.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/openssl-dtls.c b/openssl-dtls.c index cd2128a4..e8ae5ac3 100644 --- a/openssl-dtls.c +++ b/openssl-dtls.c @@ -324,7 +324,6 @@ static const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) { - STACK_OF(SSL_CIPHER) *ciphers; method_const SSL_METHOD *dtls_method; SSL_SESSION *dtls_session; SSL *dtls_ssl; @@ -423,9 +422,20 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) if (dtlsver) { - ciphers = SSL_get_ciphers(dtls_ssl); - if (dtlsver != 0 && sk_SSL_CIPHER_num(ciphers) != 1) { - vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n")); + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(dtls_ssl); + const SSL_CIPHER *ssl_ciph = NULL; + int i; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + ssl_ciph = sk_SSL_CIPHER_value(ciphers, i); + /* For PSK-NEGOTIATE just use the first one we find */ + if (!dtlsver || !strcmp(SSL_CIPHER_get_name(ssl_ciph), cipher)) + break; + } + + if (i == sk_SSL_CIPHER_num(ciphers)) { + vpn_progress(vpninfo, PRG_ERR, _("DTLS cipher '%s' not found\n"), + cipher); SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); vpninfo->dtls_ctx = NULL; @@ -434,8 +444,7 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd) } /* We're going to "resume" a session which never existed. Fake it... */ - dtls_session = generate_dtls_session(vpninfo, dtlsver, - sk_SSL_CIPHER_value(ciphers, 0), 0); + dtls_session = generate_dtls_session(vpninfo, dtlsver, ssl_ciph, 0); if (!dtls_session) { SSL_CTX_free(vpninfo->dtls_ctx); SSL_free(dtls_ssl); -- 2.50.1