Commit 473483d4 authored by Matt Caswell's avatar Matt Caswell
Browse files

Implement DTLS client move to new state machine



Move all DTLS client side processing into the new state machine code. A
subsequent commit will clean up the old dead code.

Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
parent 76af3037
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1928,6 +1928,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_DTLS1_SEND_SERVER_HELLO                    266
# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE             267
# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES                 268
# define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC          371
# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE               370
# define SSL_F_READ_STATE_MACHINE                         352
# define SSL_F_SSL3_ACCEPT                                128
+53 −23
Original line number Diff line number Diff line
@@ -582,6 +582,7 @@ int dtls_get_message(SSL *s, int *mt, unsigned long *len)
        /*
         * This isn't a real handshake message so skip the processing below.
         */
        *len = (unsigned long)tmplen;
        return 1;
    }

@@ -1102,6 +1103,19 @@ static int dtls_get_reassembled_message(SSL *s, long *len)
    return 0;
}


int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
{
    if (s->state == a) {
        if (dtls_construct_change_cipher_spec(s) == 0)
            return -1;
    }

    /* SSL3_ST_CW_CHANGE_B */
    return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
}


/*-
 * for these 2 messages, we need to
 * ssl->enc_read_ctx                    re-init
@@ -1111,11 +1125,10 @@ static int dtls_get_reassembled_message(SSL *s, long *len)
 * ssl->session->read_compression       assign
 * ssl->session->read_hash              assign
 */
int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
int dtls_construct_change_cipher_spec(SSL *s)
{
    unsigned char *p;

    if (s->state == a) {
    p = (unsigned char *)s->init_buf->data;
    *p++ = SSL3_MT_CCS;
    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
@@ -1134,16 +1147,33 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)

    /* buffer the message to handle re-xmits */
    if (!dtls1_buffer_message(s, 1)) {
            SSLerr(SSL_F_DTLS1_SEND_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
            return -1;
        SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
        return 0;
    }

        s->state = b;
    return 1;
}

    /* SSL3_ST_CW_CHANGE_B */
    return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
#ifndef OPENSSL_NO_SCTP
enum WORK_STATE dtls_wait_for_dry(SSL *s)
{
    int ret;

    /* read app data until dry event */
    ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
    if (ret < 0)
        return WORK_ERROR;

    if (ret == 0) {
        s->s3->in_read_app_data = 2;
        s->rwstate = SSL_READING;
        BIO_clear_retry_flags(SSL_get_rbio(s));
        BIO_set_retry_read(SSL_get_rbio(s));
        return WORK_MORE_A;
    }
    return WORK_FINISHED_CONTINUE;
}
#endif

int dtls1_read_failed(SSL *s, int code)
{
+16 −10
Original line number Diff line number Diff line
@@ -126,7 +126,9 @@
#endif

static const SSL_METHOD *dtls1_get_client_method(int ver);
#if 0
static int dtls1_get_hello_verify(SSL *s);
#endif

static const SSL_METHOD *dtls1_get_client_method(int ver)
{
@@ -156,6 +158,7 @@ IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
                          dtls1_connect,
                          dtls1_get_client_method, DTLSv1_2_enc_data)

#if 0
int dtls1_connect(SSL *s)
{
    BUF_MEM *buf = NULL;
@@ -785,13 +788,16 @@ int dtls1_connect(SSL *s)
        cb(s, SSL_CB_CONNECT_EXIT, ret);
    return (ret);
}
#endif

#if 0
static int dtls1_get_hello_verify(SSL *s)
{
    int n, al, ok = 0;
    unsigned char *data;
    unsigned int cookie_len;

    /* TODO: CHECK first_packet handling!!! */
    s->first_packet = 1;
    n = s->method->ssl_get_message(s,
                                   DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
@@ -801,12 +807,14 @@ static int dtls1_get_hello_verify(SSL *s)

    if (!ok)
        return ((int)n);

    if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
        s->d1->send_cookie = 0;
        s->s3->tmp.reuse_message = 1;
        return (1);
}
#endif

enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, unsigned long n)
{
    int al;
    unsigned char *data;
    unsigned int cookie_len;

    data = (unsigned char *)s->init_msg;
    data += 2;
@@ -820,11 +828,9 @@ static int dtls1_get_hello_verify(SSL *s)
    memcpy(s->d1->cookie, data, cookie_len);
    s->d1->cookie_len = cookie_len;

    s->d1->send_cookie = 1;
    return 1;

    return MSG_PROCESS_FINISHED_READING;
 f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
    s->state = SSL_ST_ERR;
    return -1;
    statem_set_error(s);
    return MSG_PROCESS_ERROR;
}
+9 −2
Original line number Diff line number Diff line
@@ -461,8 +461,15 @@ enum WORK_STATE tls_finish_handshake(SSL *s, enum WORK_STATE wst)

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

    if (!SSL_IS_DTLS(s)) {
        /*
         * We don't do this in DTLS because we may still need the init_buf
         * in case there are any unexpected retransmits
         */
        BUF_MEM_free(s->init_buf);
        s->init_buf = NULL;
    }

    ssl_free_wbio_buffer(s);

+33 −1
Original line number Diff line number Diff line
@@ -465,6 +465,7 @@ int tls_construct_client_hello(SSL *s)
    return 0;
}

#if 0
int ssl3_get_server_hello(SSL *s)
{
    int ok, al;
@@ -509,6 +510,7 @@ int ssl3_get_server_hello(SSL *s)
    s->state = SSL_ST_ERR;
    return (-1);
}
#endif

enum MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, unsigned long n)
{
@@ -1921,6 +1923,13 @@ enum MSG_PROCESS_RETURN tls_process_server_done(SSL *s, unsigned long n)
    }
#endif

#ifndef OPENSSL_NO_SCTP
    /* Only applies to renegotiation */
    if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))
            && s->renegotiate != 0)
        return MSG_PROCESS_CONTINUE_PROCESSING;
    else
#endif
        return MSG_PROCESS_FINISHED_READING;
}

@@ -2554,6 +2563,29 @@ int tls_client_key_exchange_post_work(SSL *s)
        SSLerr(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, ERR_R_INTERNAL_ERROR);
        goto err;
    }

#ifndef OPENSSL_NO_SCTP
    if (SSL_IS_DTLS(s)) {
        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 1;
 err:
    OPENSSL_clear_free(pms, pmslen);
Loading