msquic icon indicating copy to clipboard operation
msquic copied to clipboard

mTLS: server session resumption fails

Open qzhuyan opened this issue 2 years ago • 2 comments

Describe the bug

TLS session resumption fails if we enable server-side peer certificate validation (QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED is set.)

unset QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED and set QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION;at server side solves the problem.

client-side get connection shutdown error code: 0xbebc350. server-side reports:

[2][15f29d.15f3c9][05:30:48.537535][conn][0xfffec8000b60] TLS handshake error: error:140D9115:SSL routines:ssl_get_prev_session:session id context uninitialized, file:les/openssl/ssl/ssl_sess.c:577

client: msquic 2.2.2 server: msquic 2.1.8

Affected OS

  • [ ] Windows
  • [X] Linux
  • [ ] macOS
  • [ ] Other (specify below)

Additional OS information

ubuntu20.04 arm

MsQuic version

v2.1

Steps taken to reproduce bug

  1. Server starts the listener with QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED set, QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION unset.
  2. Client init connection with mTLS. 1RTT handshake works
  3. Server sends a resumption ticket
MsQuic->ConnectionSendResumptionTicket(
      c_ctx->Connection, QUIC_SEND_RESUMPTION_FLAG_NONE, 0, NULL);
// also tried flag: QUIC_SEND_RESUMPTION_FLAG_FINAL
  1. Client receives the new session ticket
  2. A few rounds of application data exchanges.
  3. Client/Server disconnects the connection
  4. Client starts new connection with the session ticket received above (tried both with/without 0-RTT early data)
  5. Server sends CONNECTION_CLOSE frame with ERROR 336, TLS Alert Internal Error (80)

Expected behavior

in 8) Server should accept the connection

Actual outcome

Connection close with ERROR 336, TLS Alert Internal Error (80).

Additional details

Note 1

In step 1), AT SERVER SIDE, if we unset QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED AND set QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION

also tried following, resumption failed too

set QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED AND set QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION

Session resume will success and all data exchange could work.

Note 2

We used self-signed certs that one rootCA signs both server and client certs. The application validates the peer cert after we get the cert from QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED event.

Note 3

set QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED is a precondition to trigger QUIC_CONNECTION_EVENT_PEER_CERTIFICATE_RECEIVED

Note 4

from: openssl/ssl/ssl_sess.c:577, where triggers the TLS alert I believe.

    if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
        /*
         * We can't be sure if this session is being used out of context,
         * which is especially important for SSL_VERIFY_PEER. The application
         * should have used SSL[_CTX]_set_session_id_context. For this error
         * case, we generate an error instead of treating the event like a
         * cache miss (otherwise it would be easy for applications to
         * effectively disable the session cache by accident without anyone
         * noticing).
         */

        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_PREV_SESSION,
                 SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
        fatal = 1;
        goto err;
    }

qzhuyan avatar Jul 28 '23 18:07 qzhuyan

CLOG file:

2.log look for

[2][15f29d.15f3c9][05:30:48.537535][conn][0xfffec8000b60] TLS handshake error: error:140D9115:SSL routines:ssl_get_prev_session:session id context uninitialized, file:les/openssl/ssl/ssl_sess.c:577

qzhuyan avatar Jul 28 '23 18:07 qzhuyan

Thanks for all the details. We'll take a look!

nibanks avatar Jul 29 '23 15:07 nibanks