Commit 20c0bce5 authored by Matt Caswell's avatar Matt Caswell
Browse files

Only dump session data after we have received it



s_client was dumping session data at the end of the handshake. In TLSv1.3
we don't have session data until receipt of a NewSessionTicket message
which happens post-handshake. Therefore we delay dumping the session data
until that message has arrived if TLSv1.3 has been negotiated.

Fixes #6482

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6590)
parent 71419442
Loading
Loading
Loading
Loading
+39 −15
Original line number Original line Diff line number Diff line
@@ -844,8 +844,10 @@ static void freeandcopy(char **dest, const char *source)
        *dest = OPENSSL_strdup(source);
        *dest = OPENSSL_strdup(source);
}
}


static int new_session_cb(SSL *S, SSL_SESSION *sess)
static int new_session_cb(SSL *s, SSL_SESSION *sess)
{
{

    if (sess_out != NULL) {
        BIO *stmp = BIO_new_file(sess_out, "w");
        BIO *stmp = BIO_new_file(sess_out, "w");


        if (stmp == NULL) {
        if (stmp == NULL) {
@@ -854,6 +856,18 @@ static int new_session_cb(SSL *S, SSL_SESSION *sess)
            PEM_write_bio_SSL_SESSION(stmp, sess);
            PEM_write_bio_SSL_SESSION(stmp, sess);
            BIO_free(stmp);
            BIO_free(stmp);
        }
        }
    }

    /*
     * Session data gets dumped on connection for TLSv1.2 and below, and on
     * arrival of the NewSessionTicket for TLSv1.3.
     */
    if (SSL_version(s) == TLS1_3_VERSION) {
        BIO_printf(bio_c_out,
                   "---\nPost-Handshake New Session Ticket arrived:\n");
        SSL_SESSION_print(bio_c_out, sess);
        BIO_printf(bio_c_out, "---\n");
    }


    /*
    /*
     * We always return a "fail" response so that the session gets freed again
     * We always return a "fail" response so that the session gets freed again
@@ -1919,11 +1933,9 @@ int s_client_main(int argc, char **argv)
     * come at any time. Therefore we use a callback to write out the session
     * come at any time. Therefore we use a callback to write out the session
     * when we know about it. This approach works for < TLSv1.3 as well.
     * when we know about it. This approach works for < TLSv1.3 as well.
     */
     */
    if (sess_out != NULL) {
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT
                                        | SSL_SESS_CACHE_NO_INTERNAL_STORE);
                                        | SSL_SESS_CACHE_NO_INTERNAL_STORE);
    SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
    SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
    }


    if (set_keylog_file(ctx, keylog_file))
    if (set_keylog_file(ctx, keylog_file))
        goto end;
        goto end;
@@ -3125,7 +3137,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
    X509 *peer = NULL;
    X509 *peer = NULL;
    STACK_OF(X509) *sk;
    STACK_OF(X509) *sk;
    const SSL_CIPHER *c;
    const SSL_CIPHER *c;
    int i;
    int i, istls13 = (SSL_version(s) == TLS1_3_VERSION);
    long verify_result;
#ifndef OPENSSL_NO_COMP
#ifndef OPENSSL_NO_COMP
    const COMP_METHOD *comp, *expansion;
    const COMP_METHOD *comp, *expansion;
#endif
#endif
@@ -3282,7 +3295,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
    }
    }
#endif
#endif


    if (SSL_version(s) == TLS1_3_VERSION) {
    if (istls13) {
        switch (SSL_get_early_data_status(s)) {
        switch (SSL_get_early_data_status(s)) {
        case SSL_EARLY_DATA_NOT_SENT:
        case SSL_EARLY_DATA_NOT_SENT:
            BIO_printf(bio, "Early data was not sent\n");
            BIO_printf(bio, "Early data was not sent\n");
@@ -3297,9 +3310,20 @@ static void print_stuff(BIO *bio, SSL *s, int full)
            break;
            break;


        }
        }
    }


        /*
         * We also print the verify results when we dump session information,
         * but in TLSv1.3 we may not get that right away (or at all) depending
         * on when we get a NewSessionTicket. Therefore we print it now as well.
         */
        verify_result = SSL_get_verify_result(s);
        BIO_printf(bio, "Verify return code: %ld (%s)\n", verify_result,
                   X509_verify_cert_error_string(verify_result));
    } else {
        /* In TLSv1.3 we do this on arrival of a NewSessionTicket */
        SSL_SESSION_print(bio, SSL_get_session(s));
        SSL_SESSION_print(bio, SSL_get_session(s));
    }

    if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) {
    if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) {
        BIO_printf(bio, "Keying material exporter:\n");
        BIO_printf(bio, "Keying material exporter:\n");
        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);