sslopenssltls1.0tls1.3

Does only TLS_AES_128_GCM_SHA256 cipher work for psk connections for TLS 1.3?


I have a server running on Ubuntu 1804 with OpenSSL 1.1.1 11 Sep 2018. Clients talk to the server using PSK authentication with PSK-AES256-CBC-SHA as the cipher.

When I use a client built on Windows with openssl-1.1.1c (built using Microsoft Visual Studio 2019) I am unable to make it work.

On the server side, I get the following:

139845863200512:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1528:SSL alert number 40

And on the client side,

11720:error:141970DF:SSL routines:tls_construct_cke_psk_preamble:psk identity not found:ssl\statem\statem_clnt.c:2917

I saw the following in openssl-1.1.1c\ssl\statem\extensions_clnt.c.

            /*
             * We found a PSK using an old style callback. We don't know
             * the digest so we default to SHA256 as per the TLSv1.3 spec
             */
            cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);

So does this mean that only TLS_AES_128_GCM_SHA256 works with TLS1.3? Any pointers to what I might be missing? Any tutorial on how to use client PSK authentication from Windows platform would be helpful.

I am able to connect to the server from a linux box using the same PSK id and key. But unable to connect from a windows box.


Solution

  • TLSv1.3 uses completely different ciphersuites to TLSv1.2 and below. Ciphersuites for TLSv1.3 don't work for protocol versions before that and vice versa.

    So does this mean that only TLS_AES_128_GCM_SHA256 works with TLS1.3?

    No. A TLSv1.3 PSK can be used with any TLSv1.3 compatible ciphersuite. However, OpenSSL provides 2 sets of callbacks for setting up PSKs. The "old style" callbacks were designed before TLSv1.3 came along, and the "new style" callbacks that were designed with TLSv1.3 in mind. If you application uses the "old style" callbacks (which is likely if it was written to work for OpenSSL 1.1.0 or earlier), then in TLSv1.3 the PSK will only work with TLSv1.3 ciphersuites based on SHA256. Which includes all TLSv1.3 ciphersuites supported by OpenSSL except TLS_AES_256_GCM_SHA384. Don't be confused by the use of TLS_AES_128_GCM_SHA256 specifically in the code. Its only the SHA256 bit which is important in this context.

    However all of the above is irrelevant for your particular problem:

    11720:error:141970DF:SSL routines:tls_construct_cke_psk_preamble:psk identity not found:ssl\statem\statem_clnt.c:2917
    

    From the error I can see that the client is trying to construct the CKE message (ClientKeyExchange). This message is not sent in TLSv1.3, so we can be confident that the server selected TLSv1.2 (or below). The error is actually generated by this bit of code in OpenSSL:

    psklen = s->psk_client_callback(s, s->session->psk_identity_hint,
                                    identity, sizeof(identity) - 1,
                                    psk, sizeof(psk));
    
    if (psklen > PSK_MAX_PSK_LEN) {
        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
                 SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
        goto err;
    } else if (psklen == 0) {
        SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
                 SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE,
                 SSL_R_PSK_IDENTITY_NOT_FOUND);
        goto err;
    }
    

    You can see from the above, that the error is generated by OpenSSL if it calls your application callback and gets a psklen of 0 returned back. The question is - why is your code returning a psklen of 0 on Windows?