]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
OpenSSL: Loop over DTLS ciphersuites looking for the one we asked for.
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 9 Jan 2019 12:02:57 +0000 (12:02 +0000)
committerDavid Woodhouse <dwmw2@infradead.org>
Wed, 9 Jan 2019 12:06:30 +0000 (12:06 +0000)
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 <dwmw2@infradead.org>
openssl-dtls.c

index cd2128a42cc132f3bc100c4a43960e6fb5b44229..e8ae5ac3c56834c1fe054f18bc147800d7c01696 100644 (file)
@@ -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);