Skip to content

mTLS: server session resumption fails #3780

Open
@qzhuyan

Description

@qzhuyan

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
  • 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;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions