Commit 30f05b19 authored by Matt Caswell's avatar Matt Caswell
Browse files

Create the NewSessionTicket message in TLSv1.3

parent b2f7e8c0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -602,7 +602,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
        break;

    case TLS_ST_OK:
        return tls_finish_handshake(s, wst);
        return tls_finish_handshake(s, wst, 1);
    }

    return WORK_FINISHED_CONTINUE;
+26 −15
Original line number Diff line number Diff line
@@ -821,7 +821,12 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk,
    return 1;
}

WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
/*
 * Tidy up after the end of a handshake. In the case of SCTP this may result
 * in NBIO events. If |clearbufs| is set then init_buf and the wbio buffer is
 * freed up as well.
 */
WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs)
{
    void (*cb) (const SSL *ssl, int type, int val) = NULL;

@@ -834,9 +839,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
    }
#endif

    /* clean a few things up */
    ssl3_cleanup_key_block(s);

    if (clearbufs) {
        if (!SSL_IS_DTLS(s)) {
            /*
             * We don't do this in DTLS because we may still need the init_buf
@@ -845,10 +848,9 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
            BUF_MEM_free(s->init_buf);
            s->init_buf = NULL;
        }

        ssl_free_wbio_buffer(s);

        s->init_num = 0;
    }

    if (s->statem.cleanuphand) {
        /* skipped if we just sent a HelloRequest */
@@ -856,6 +858,8 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
        s->new_session = 0;
        s->statem.cleanuphand = 0;

        ssl3_cleanup_key_block(s);

        if (s->server) {
            ssl_update_cache(s, SSL_SESS_CACHE_SERVER);

@@ -887,6 +891,13 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
        }
    }

    /*
     * If we've not cleared the buffers its because we've got more work to do,
     * so continue.
     */
    if (!clearbufs)
        return WORK_FINISHED_CONTINUE;

    return WORK_FINISHED_STOP;
}

+1 −1
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ __owur int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
__owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);

__owur int tls_construct_finished(SSL *s, WPACKET *pkt);
__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst);
__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs);
__owur WORK_STATE dtls_wait_for_dry(SSL *s);

/* some client-only functions */
+42 −4
Original line number Diff line number Diff line
@@ -439,6 +439,18 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
        return WRITE_TRAN_FINISHED;

    case TLS_ST_SR_FINISHED:
        /*
         * Technically we have finished the handshake at this point, but we're
         * going to remain "in_init" for now and write out the session ticket
         * immediately.
         * TODO(TLS1.3): Perhaps we need to be able to control this behaviour
         * and give the application the opportunity to delay sending the
         * session ticket?
         */
        st->hand_state = TLS_ST_SW_SESSION_TICKET;
        return WRITE_TRAN_CONTINUE;

    case TLS_ST_SW_SESSION_TICKET:
        st->hand_state = TLS_ST_OK;
        ossl_statem_set_in_init(s, 0);
        return WRITE_TRAN_CONTINUE;
@@ -626,7 +638,14 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
        return WORK_FINISHED_CONTINUE;

    case TLS_ST_SW_SESSION_TICKET:
        if (SSL_IS_DTLS(s)) {
        if (SSL_IS_TLS13(s)) {
            /*
             * Actually this is the end of the handshake, but we're going
             * straight into writing the session ticket out. So we finish off
             * the handshake, but keep the various buffers active.
             */
            return tls_finish_handshake(s, wst, 0);
        } if (SSL_IS_DTLS(s)) {
            /*
             * We're into the last flight. We don't retransmit the last flight
             * unless we need to, so we don't use the timer
@@ -653,7 +672,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
        return WORK_FINISHED_CONTINUE;

    case TLS_ST_OK:
        return tls_finish_handshake(s, wst);
        return tls_finish_handshake(s, wst, 1);
    }

    return WORK_FINISHED_CONTINUE;
@@ -788,6 +807,11 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
            return WORK_ERROR;
        }
        break;

    case TLS_ST_SW_SESSION_TICKET:
        if (SSL_IS_TLS13(s) && statem_flush(s) != 1)
            return WORK_MORE_A;
        break;
    }

    return WORK_FINISHED_CONTINUE;
@@ -3219,8 +3243,12 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
    SSL_CTX *tctx = s->initial_ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
    int iv_len;
    int iv_len, al = SSL_AD_INTERNAL_ERROR;
    size_t macoffset, macendoffset;
    union {
        unsigned char age_add_c[sizeof(uint32_t)];
        uint32_t age_add;
    } age_add_u;

    /* get session encoding length */
    slen_full = i2d_SSL_SESSION(s->session, NULL);
@@ -3313,12 +3341,18 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
               sizeof(tctx->ext.tick_key_name));
    }

    if (SSL_IS_TLS13(s) && RAND_bytes(age_add_u.age_add_c,
                                      sizeof(age_add_u)) <= 0)
        goto err;

    /*
     * Ticket lifetime hint (advisory only): We leave this unspecified
     * for resumed session (for simplicity), and guess that tickets for
     * new sessions will live as long as their sessions.
     */
    if (!WPACKET_put_bytes_u32(pkt, s->hit ? 0 : s->session->timeout)
            || (SSL_IS_TLS13(s)
                && !WPACKET_put_bytes_u32(pkt, age_add_u.age_add))
               /* Now the actual ticket data */
            || !WPACKET_start_sub_packet_u16(pkt)
            || !WPACKET_get_total_written(pkt, &macoffset)
@@ -3345,7 +3379,11 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
            || hlen > EVP_MAX_MD_SIZE
            || !WPACKET_allocate_bytes(pkt, hlen, &macdata2)
            || macdata1 != macdata2
            || !WPACKET_close(pkt)) {
            || !WPACKET_close(pkt)
            || (SSL_IS_TLS13(s)
                && !tls_construct_extensions(s, pkt,
                                             EXT_TLS1_3_NEW_SESSION_TICKET,
                                             NULL, 0, &al))) {
        SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
        goto err;
    }