[External]Re: openconnect+OpenSSL failing DTLS handshake with ocserv+GnuTLS

Daniel Lenski dlenski at gmail.com
Mon Jul 19 10:53:54 PDT 2021


On Mon, Jul 19, 2021 at 8:48 AM Vuille, Martin (Martin)
<vmartin at avaya.com> wrote:
>
> I single-stepped through start_dtls_handshake() and I can see that
> we end up at line 520 in openssl-dtls.c, where generate_dtls_session()
> is called with DTLS1_VERSION for the dtlsver argument.

Makes sense. The generate_dtls_session functions comes in two
variants: one for OpenSSL <1.1.0, and for newer versions.

> So that explains why the ClientHello has version 1.0 record/1.0 handshake.
> I don't understand why ocserv has an issue with that, but that's not really
> relevant to what I'm trying to do.

I'm just speculating, but it may be because you're trying to use a
DTLSv1.2 cipher with DTLSv1.0 record layer?

> I replaced DTLS1_VERSION with DTLS1_2_VERSION and the handshake
> succeeds. The ClientHello has version 1.2 record/1.2 handshake though,
> which is not the same as with GnuTLS.

Good to know. I don't think we would want to use this as a "permanent"
solution, however, since the intent of PSK-NEGOTIATE is that it will,
well, "negotiate" the desired version of DTLS.

    if (!cipher) {
        dtlsver = 0;
#ifdef HAVE_DTLS12
        /* The F5 BIG-IP server before v16, will crap itself if we
         * even *try* to do DTLSv1.2 */
        if (!vpninfo->dtls12)
            dtlsver = DTLS1_VERSION;
    /* These things should never happen unless they're supported */
    } else if (vpninfo->dtls12) {
        dtlsver = DTLS1_2_VERSION;
    } else if (!strcmp(cipher, "OC-DTLS1_2-AES128-GCM")) {
        dtlsver = DTLS1_2_VERSION;
        cipher = "AES128-GCM-SHA256";
    } else if (!strcmp(cipher, "OC-DTLS1_2-AES256-GCM")) {
        dtlsver = DTLS1_2_VERSION;
        cipher = "AES256-GCM-SHA384";
#ifndef OPENSSL_NO_PSK
    } else if (!strcmp(cipher, "PSK-NEGOTIATE")) {
        dtlsver = 0; /* Let it negotiate */
#endif
#endif
    }

> Then I replaced DTLS1_VERSION with DTLS_ANY_VERSION and that does
> not work. The ClientHello has version 1.0 record/1.2 handshake, same as
> GnuTLS, but is missing the session ID, has truncated cipher list, etc.

That's confusing! generate_dtls_session should definitely be setting
the session_id in this case.

It *seems* like the right fix should be to use DTLS_ANY_VERSION.
You're saying that the following *does not work*?

diff --git a/openssl-dtls.c b/openssl-dtls.c
index 76bcd2f1..6501d8d8 100644
--- a/openssl-dtls.c
+++ b/openssl-dtls.c
@@ -560,7 +560,8 @@ int start_dtls_handshake(struct openconnect_info
*vpninfo, int dtls_fd)
                 * and isn't actually going to be resumed at all.
                 */
                const uint8_t cs[2] = {0x00, 0x2F}; /* RSA-AES-128 */work
-               dtls_session = generate_dtls_session(vpninfo, DTLS1_VERSION,
+               dtls_session = generate_dtls_session(vpninfo, DTLS_ANY_VERSION,

SSL_CIPHER_find(dtls_ssl, cs),
                                                     1);
                if (!dtls_session) {

> Is the hard-coding of DTLS1_VERSION expected?

I don't think so.

Dan



More information about the openconnect-devel mailing list