Commit 8723588e authored by Matt Caswell's avatar Matt Caswell
Browse files

Implement Client TLS state machine



This swaps the implementation of the client TLS state machine to use the
new state machine code instead.

Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
parent b9908bf9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -127,8 +127,7 @@ int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
     */
    if ((SSL_in_init(s) && !s->in_handshake) ||
        (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
         (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
          || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)))
         statem_in_sctp_read_sock(s)))
#else
    if (SSL_in_init(s) && !s->in_handshake)
#endif
+3 −5
Original line number Diff line number Diff line
@@ -440,9 +440,8 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
     * SCTP.
     */
    if ((!s->in_handshake && SSL_in_init(s)) ||
        (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
         (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
          || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)
        (BIO_dgram_is_sctp(SSL_get_rbio(s))
         && statem_in_sctp_read_sock(s)
         && s->s3->in_read_app_data != 2))
#else
    if (!s->in_handshake && SSL_in_init(s))
@@ -586,8 +585,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
         */
        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
            SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA &&
            (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
             || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) {
            statem_in_sctp_read_sock(s)) {
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
+1 −10
Original line number Diff line number Diff line
@@ -1450,16 +1450,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
         * application data at this point (session renegotiation not yet
         * started), we will indulge it.
         */
        if (s->s3->in_read_app_data &&
            (s->s3->total_renegotiations != 0) &&
            (((s->state & SSL_ST_CONNECT) &&
              (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
              (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
             ) || ((s->state & SSL_ST_ACCEPT) &&
                   (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
                   (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
             )
            )) {
        if (statem_app_data_allowed(s)) {
            s->s3->in_read_app_data = 2;
            return (-1);
        } else {
+64 −0
Original line number Diff line number Diff line
@@ -446,6 +446,70 @@ unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
    return l + SSL_HM_HEADER_LENGTH(s);
}

enum WORK_STATE tls_finish_handshake(SSL *s, enum WORK_STATE wst)
{
    void (*cb) (const SSL *ssl, int type, int val) = NULL;

#ifndef OPENSSL_NO_SCTP
    if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) {
        enum WORK_STATE ret;
        ret = dtls_wait_for_dry(s);
        if (ret != WORK_FINISHED_CONTINUE)
            return ret;
    }
#endif

    /* clean a few things up */
    ssl3_cleanup_key_block(s);
    BUF_MEM_free(s->init_buf);
    s->init_buf = NULL;

    ssl_free_wbio_buffer(s);

    s->init_num = 0;

    if (!s->server || s->renegotiate == 2) {
        /* skipped if we just sent a HelloRequest */
        s->renegotiate = 0;
        s->new_session = 0;

        if (s->server) {
            s->renegotiate = 0;
            s->new_session = 0;

            ssl_update_cache(s, SSL_SESS_CACHE_SERVER);

            s->ctx->stats.sess_accept_good++;
            s->handshake_func = ssl3_accept;
        } else {
            ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
            if (s->hit)
                s->ctx->stats.sess_hit++;

            s->handshake_func = ssl3_connect;
            s->ctx->stats.sess_connect_good++;
        }

        if (s->info_callback != NULL)
            cb = s->info_callback;
        else if (s->ctx->info_callback != NULL)
            cb = s->ctx->info_callback;

        if (cb != NULL)
            cb(s, SSL_CB_HANDSHAKE_DONE, 1);

        if (SSL_IS_DTLS(s)) {
            /* done with handshaking */
            s->d1->handshake_read_seq = 0;
            s->d1->handshake_write_seq = 0;
            s->d1->next_handshake_write_seq = 0;
        }
    }

    return WORK_FINISHED_STOP;
}


/*
 * Obtain handshake message of message type 'mt' (any if mt == -1), maximum
 * acceptable body length 'max'. The first four bytes (msg_type and length)
+44 −0
Original line number Diff line number Diff line
@@ -165,11 +165,22 @@

static int ssl_set_version(SSL *s);
static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
#if 0
/*
 * Temporarily disabled during development of new state machine code.
 * TODO: Clean me up
 */
static int ssl3_check_change(SSL *s);
#endif
static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
                                    unsigned char *p);


#if 0
/*
 * Temporarily disabled during development of new state machine code.
 * TODO: Clean me up
 */
int ssl3_connect(SSL *s)
{
    BUF_MEM *buf = NULL;
@@ -631,6 +642,7 @@ int ssl3_connect(SSL *s)
    return (ret);
}

#endif /* End temp disabled ssl3_connect */
/*
 * Work out what version we should be using for the initial ClientHello if
 * the version is currently set to (D)TLS_ANY_VERSION.
@@ -1285,6 +1297,32 @@ enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
        goto f_err;
    }

#ifndef OPENSSL_NO_SCTP
    if (SSL_IS_DTLS(s) && s->hit) {
        unsigned char sctpauthkey[64];
        char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];

        /*
         * Add new shared key for SCTP-Auth, will be ignored if
         * no SCTP used.
         */
        snprintf((char *)labelbuffer,
                 sizeof(DTLS1_SCTP_AUTH_LABEL),
                 DTLS1_SCTP_AUTH_LABEL);

        if (SSL_export_keying_material(s, sctpauthkey,
                                   sizeof(sctpauthkey),
                                   labelbuffer,
                                   sizeof(labelbuffer), NULL, 0,
                                   0) <= 0)
            goto err;

        BIO_ctrl(SSL_get_wbio(s),
                 BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
                 sizeof(sctpauthkey), sctpauthkey);
    }
#endif

    return MSG_PROCESS_CONTINUE_READING;
 f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -3489,6 +3527,11 @@ int ssl3_check_cert_and_algorithm(SSL *s)
 * pre-shared secret, we have a "ticket" and the next server message
 * is CCS; and 0 otherwise. It returns -1 upon an error.
 */
 #if 0
 /*
  * TODO: No longer required. Temporarily kept during state machine development
  * To be deleted by later commits
  */
static int ssl3_check_change(SSL *s)
{
    int ok = 0;
@@ -3518,6 +3561,7 @@ static int ssl3_check_change(SSL *s)

    return 0;
}
#endif

#ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_send_next_proto(SSL *s)
Loading