Remove redundant code
authorMatt Caswell <matt@openssl.org>
Tue, 8 Sep 2015 08:13:50 +0000 (09:13 +0100)
committerMatt Caswell <matt@openssl.org>
Fri, 30 Oct 2015 08:38:18 +0000 (08:38 +0000)
Clean up and remove lots of code that is now no longer needed due to the
move to the new state machine.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
14 files changed:
apps/s_server.c
include/openssl/ssl.h
ssl/d1_both.c
ssl/d1_srvr.c
ssl/record/rec_layer_d1.c
ssl/record/rec_layer_s3.c
ssl/s3_both.c
ssl/s3_lib.c
ssl/s3_msg.c
ssl/s3_srvr.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/ssl_stat.c
ssl/statem.c

index bfc8b1f..6d68fc1 100644 (file)
@@ -2428,7 +2428,7 @@ static int init_ssl_connection(SSL *con)
 #ifdef CERT_CB_TEST_RETRY
     {
         while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
-               && SSL_state(con) == SSL3_ST_SR_CLNT_HELLO_C) {
+               && SSL_state(con) == TLS_ST_SR_CLNT_HELLO) {
             BIO_printf(bio_err,
                        "LOOKUP from certificate callback during accept\n");
             i = SSL_accept(con);
index de3c3be..99f0de6 100644 (file)
@@ -920,6 +920,59 @@ extern "C" {
 # define SSL_CTX_get_app_data(ctx)       (SSL_CTX_get_ex_data(ctx,0))
 # define SSL_CTX_set_app_data(ctx,arg)   (SSL_CTX_set_ex_data(ctx,0,(char *)arg))
 
+
+/*
+ * The valid handshake states (one for each type message sent and one for each
+ * type of message received). There are also two "special" states:
+ * TLS = TLS or DTLS state
+ * DTLS = DTLS specific state
+ * CR/SR = Client Read/Server Read
+ * CW/SW = Client Write/Server Write
+ *
+ * The "special" states are:
+ * TLS_ST_BEFORE = No handshake has been initiated yet
+ * TLS_ST_OK = A handshake has been successfully completed
+ */
+enum HANDSHAKE_STATE {
+    TLS_ST_BEFORE,
+    TLS_ST_OK,
+    DTLS_ST_CR_HELLO_VERIFY_REQUEST,
+    TLS_ST_CR_SRVR_HELLO,
+    TLS_ST_CR_CERT,
+    TLS_ST_CR_CERT_STATUS,
+    TLS_ST_CR_KEY_EXCH,
+    TLS_ST_CR_CERT_REQ,
+    TLS_ST_CR_SRVR_DONE,
+    TLS_ST_CR_SESSION_TICKET,
+    TLS_ST_CR_CHANGE,
+    TLS_ST_CR_FINISHED,
+    TLS_ST_CW_CLNT_HELLO,
+    TLS_ST_CW_CERT,
+    TLS_ST_CW_KEY_EXCH,
+    TLS_ST_CW_CERT_VRFY,
+    TLS_ST_CW_CHANGE,
+    TLS_ST_CW_NEXT_PROTO,
+    TLS_ST_CW_FINISHED,
+    TLS_ST_SW_HELLO_REQ,
+    TLS_ST_SR_CLNT_HELLO,
+    DTLS_ST_SW_HELLO_VERIFY_REQUEST,
+    TLS_ST_SW_SRVR_HELLO,
+    TLS_ST_SW_CERT,
+    TLS_ST_SW_KEY_EXCH,
+    TLS_ST_SW_CERT_REQ,
+    TLS_ST_SW_SRVR_DONE,
+    TLS_ST_SR_CERT,
+    TLS_ST_SR_KEY_EXCH,
+    TLS_ST_SR_CERT_VRFY,
+    TLS_ST_SR_NEXT_PROTO,
+    TLS_ST_SR_CHANGE,
+    TLS_ST_SR_FINISHED,
+    TLS_ST_SW_SESSION_TICKET,
+    TLS_ST_SW_CERT_STATUS,
+    TLS_ST_SW_CHANGE,
+    TLS_ST_SW_FINISHED
+};
+
 /*
  * The following are the possible values for ssl->state are are used to
  * indicate where we are up to in the SSL connection establishment. The
@@ -953,11 +1006,11 @@ extern "C" {
 
 /* Is the SSL_connection established? */
 # define SSL_get_state(a)                SSL_state(a)
-# define SSL_is_init_finished(a)         (SSL_state(a) == SSL_ST_OK)
-# define SSL_in_init(a)                  (SSL_state(a)&SSL_ST_INIT)
-# define SSL_in_before(a)                (SSL_state(a)&SSL_ST_BEFORE)
-# define SSL_in_connect_init(a)          (SSL_state(a)&SSL_ST_CONNECT)
-# define SSL_in_accept_init(a)           (SSL_state(a)&SSL_ST_ACCEPT)
+# define SSL_in_connect_init(a)          (SSL_in_init(a) && !a->server)
+# define SSL_in_accept_init(a)           (SSL_in_init(a) && a->server)
+int SSL_in_init(SSL *s);
+int SSL_in_before(SSL *s);
+int SSL_is_init_finished(SSL *s);
 
 /*
  * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you
@@ -1646,8 +1699,8 @@ void SSL_set_info_callback(SSL *ssl,
                            void (*cb) (const SSL *ssl, int type, int val));
 void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type,
                                                int val);
-__owur int SSL_state(const SSL *ssl);
-void SSL_set_state(SSL *ssl, int state);
+__owur enum HANDSHAKE_STATE SSL_state(const SSL *ssl);
+void SSL_set_state(SSL *ssl, enum HANDSHAKE_STATE state);
 
 void SSL_set_verify_result(SSL *ssl, long v);
 __owur long SSL_get_verify_result(const SSL *ssl);
index a969038..e20278b 100644 (file)
@@ -160,8 +160,6 @@ static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
                                          unsigned short seq_num,
                                          unsigned long frag_off,
                                          unsigned long frag_len);
-static long dtls1_get_message_fragment(SSL *s, int st1, int stn, int mt,
-                                       int *ok);
 static int dtls_get_reassembled_message(SSL *s, long *len);
 
 static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
@@ -438,117 +436,6 @@ int dtls1_do_write(SSL *s, int type)
     return (0);
 }
 
-/*
- * Obtain handshake message of message type 'mt' (any if mt == -1), maximum
- * acceptable body length 'max'. Read an entire handshake message.  Handshake
- * messages arrive in fragments.
- */
-long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
-{
-    int i, al;
-    struct hm_header_st *msg_hdr;
-    unsigned char *p;
-    unsigned long msg_len;
-
-    /*
-     * s3->tmp is used to store messages that are unexpected, caused by the
-     * absence of an optional handshake message
-     */
-    if (s->s3->tmp.reuse_message) {
-        if ((mt >= 0) && (s->s3->tmp.message_type != mt)) {
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
-            goto f_err;
-        }
-        *ok = 1;
-
-
-        /*
-         * Messages reused from dtls1_listen also have the record header in
-         * the buffer which we need to skip over.
-         */
-        if (s->s3->tmp.reuse_message == DTLS1_SKIP_RECORD_HEADER) {
-            s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH
-                          + DTLS1_RT_HEADER_LENGTH;
-        } else {
-            s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
-        }
-        s->init_num = (int)s->s3->tmp.message_size;
-        s->s3->tmp.reuse_message = 0;
-        return s->init_num;
-    }
-
-    msg_hdr = &s->d1->r_msg_hdr;
-    memset(msg_hdr, 0, sizeof(*msg_hdr));
-
- again:
-    i = dtls1_get_message_fragment(s, st1, stn, mt, ok);
-    if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) {
-        /* bad fragment received */
-        goto again;
-    } else if (i <= 0 && !*ok) {
-        return i;
-    }
-
-    if (mt >= 0 && s->s3->tmp.message_type != mt) {
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
-        goto f_err;
-    }
-
-    p = (unsigned char *)s->init_buf->data;
-
-    if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
-        if (s->msg_callback) {
-            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
-                            p, 1, s, s->msg_callback_arg);
-        }
-        /*
-         * This isn't a real handshake message so skip the processing below.
-         * dtls1_get_message_fragment() will never return a CCS if mt == -1,
-         * so we are ok to continue in that case.
-         */
-        return i;
-    }
-
-    msg_len = msg_hdr->msg_len;
-
-    /* reconstruct message header */
-    *(p++) = msg_hdr->type;
-    l2n3(msg_len, p);
-    s2n(msg_hdr->seq, p);
-    l2n3(0, p);
-    l2n3(msg_len, p);
-    if (s->version != DTLS1_BAD_VER) {
-        p -= DTLS1_HM_HEADER_LENGTH;
-        msg_len += DTLS1_HM_HEADER_LENGTH;
-    }
-
-    if (msg_len > (unsigned long)max) {
-        al = SSL_AD_ILLEGAL_PARAMETER;
-        SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-        goto f_err;
-    }
-
-    ssl3_finish_mac(s, p, msg_len);
-    if (s->msg_callback)
-        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
-                        p, msg_len, s, s->msg_callback_arg);
-
-    memset(msg_hdr, 0, sizeof(*msg_hdr));
-
-    s->d1->handshake_read_seq++;
-
-
-    s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
-    return s->init_num;
-
- f_err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    *ok = 0;
-    return -1;
-}
-
 int dtls_get_message(SSL *s, int *mt, unsigned long *len)
 {
     struct hm_header_st *msg_hdr;
@@ -925,30 +812,6 @@ dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr,
     return i;
 }
 
-static long
-dtls1_get_message_fragment(SSL *s, int st1, int stn, int mt, int *ok)
-{
-    long len;
-
-    do {
-        *ok = dtls_get_reassembled_message(s, &len);
-        /* A CCS isn't a real handshake message, so if we get one there is no
-         * message sequence number to give us confidence that this was really
-         * intended to be at this point in the handshake sequence. Therefore we
-         * only allow this if we were explicitly looking for it (i.e. if |mt|
-         * is -1 we still don't allow it). If we get one when we're not
-         * expecting it then probably something got re-ordered or this is a
-         * retransmit. We should drop this and try again.
-         */
-    } while (*ok && mt != SSL3_MT_CHANGE_CIPHER_SPEC
-             && s->s3->tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC);
-
-    if (*ok)
-        s->state = stn;
-
-    return len;
-}
-
 static int dtls_get_reassembled_message(SSL *s, long *len)
 {
     unsigned char wire[DTLS1_HM_HEADER_LENGTH];
@@ -1103,19 +966,6 @@ 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
index 02a944d..47c6203 100644 (file)
@@ -144,720 +144,18 @@ IMPLEMENT_dtls1_meth_func(DTLS1_VERSION,
                           ssl_undefined_function,
                           dtls1_get_server_method, DTLSv1_enc_data)
 
-    IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION,
                           DTLSv1_2_server_method,
                           dtls1_accept,
                           ssl_undefined_function,
                           dtls1_get_server_method, DTLSv1_2_enc_data)
 
-    IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION,
                           DTLS_server_method,
                           dtls1_accept,
                           ssl_undefined_function,
                           dtls1_get_server_method, DTLSv1_2_enc_data)
 
-#if 0
-int dtls1_accept(SSL *s)
-{
-    BUF_MEM *buf;
-    unsigned long Time = (unsigned long)time(NULL);
-    void (*cb) (const SSL *ssl, int type, int val) = NULL;
-    unsigned long alg_k;
-    int ret = -1;
-    int new_state, state, skip = 0;
-#ifndef OPENSSL_NO_SCTP
-    unsigned char sctpauthkey[64];
-    char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
-#endif
-
-    RAND_add(&Time, sizeof(Time), 0);
-    ERR_clear_error();
-    clear_sys_error();
-
-    if (s->info_callback != NULL)
-        cb = s->info_callback;
-    else if (s->ctx->info_callback != NULL)
-        cb = s->ctx->info_callback;
-
-    /* init things to blank */
-    s->in_handshake++;
-    if (!SSL_in_init(s) || SSL_in_before(s)) {
-        if (!SSL_clear(s))
-            return -1;
-    }
-
-#ifndef OPENSSL_NO_SCTP
-    /*
-     * Notify SCTP BIO socket to enter handshake mode and prevent stream
-     * identifier other than 0. Will be ignored if no SCTP is used.
-     */
-    BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
-             s->in_handshake, NULL);
-#endif
-
-#ifndef OPENSSL_NO_HEARTBEATS
-    /*
-     * If we're awaiting a HeartbeatResponse, pretend we already got and
-     * don't await it anymore, because Heartbeats don't make sense during
-     * handshakes anyway.
-     */
-    if (s->tlsext_hb_pending) {
-        dtls1_stop_timer(s);
-        s->tlsext_hb_pending = 0;
-        s->tlsext_hb_seq++;
-    }
-#endif
-
-    for (;;) {
-        state = s->state;
-
-        switch (s->state) {
-        case SSL_ST_RENEGOTIATE:
-            s->renegotiate = 1;
-            /* s->state=SSL_ST_ACCEPT; */
-
-        case SSL_ST_BEFORE:
-        case SSL_ST_ACCEPT:
-        case SSL_ST_BEFORE | SSL_ST_ACCEPT:
-        case SSL_ST_OK | SSL_ST_ACCEPT:
-
-            s->server = 1;
-            if (cb != NULL)
-                cb(s, SSL_CB_HANDSHAKE_START, 1);
-
-            if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) {
-                SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
-                return -1;
-            }
-            s->type = SSL_ST_ACCEPT;
-
-            if (s->init_buf == NULL) {
-                if ((buf = BUF_MEM_new()) == NULL) {
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-                if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
-                    BUF_MEM_free(buf);
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-                s->init_buf = buf;
-            }
-
-            if (!ssl3_setup_buffers(s)) {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            s->init_num = 0;
-            /*
-             * Should have been reset by ssl3_get_finished, too.
-             */
-            s->s3->change_cipher_spec = 0;
-
-            if (s->state != SSL_ST_RENEGOTIATE) {
-                /*
-                 * Ok, we now need to push on a buffering BIO so that the
-                 * output is sent in a way that TCP likes :-) ...but not with
-                 * SCTP :-)
-                 */
-#ifndef OPENSSL_NO_SCTP
-                if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
-#endif
-                    if (!ssl_init_wbio_buffer(s, 1)) {
-                        ret = -1;
-                        s->state = SSL_ST_ERR;
-                        goto end;
-                    }
-
-                ssl3_init_finished_mac(s);
-                s->state = SSL3_ST_SR_CLNT_HELLO_A;
-                s->ctx->stats.sess_accept++;
-            } else {
-                /*
-                 * s->state == SSL_ST_RENEGOTIATE, we will just send a
-                 * HelloRequest
-                 */
-                s->ctx->stats.sess_accept_renegotiate++;
-                s->state = SSL3_ST_SW_HELLO_REQ_A;
-            }
-
-            break;
-
-        case SSL3_ST_SW_HELLO_REQ_A:
-        case SSL3_ST_SW_HELLO_REQ_B:
-
-            s->shutdown = 0;
-            dtls1_clear_record_buffer(s);
-            dtls1_start_timer(s);
-            ret = ssl3_send_hello_request(s);
-            if (ret <= 0)
-                goto end;
-            s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
-            s->state = SSL3_ST_SW_FLUSH;
-            s->init_num = 0;
-
-            ssl3_init_finished_mac(s);
-            break;
-
-        case SSL3_ST_SW_HELLO_REQ_C:
-            s->state = SSL_ST_OK;
-            break;
-
-        case SSL3_ST_SR_CLNT_HELLO_A:
-        case SSL3_ST_SR_CLNT_HELLO_B:
-        case SSL3_ST_SR_CLNT_HELLO_C:
-
-            s->shutdown = 0;
-            ret = ssl3_get_client_hello(s);
-            if (ret <= 0)
-                goto end;
-            dtls1_stop_timer(s);
-
-            if (!s->d1->cookie_verified
-                    && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
-                s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
-            else
-                s->state = SSL3_ST_SW_SRVR_HELLO_A;
-
-            s->init_num = 0;
-            break;
-
-        case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
-        case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
-
-            ret = dtls1_send_hello_verify_request(s);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_FLUSH;
-            s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
-
-            /* HelloVerifyRequest resets Finished MAC */
-            if (s->version != DTLS1_BAD_VER)
-                ssl3_init_finished_mac(s);
-            break;
-
-#ifndef OPENSSL_NO_SCTP
-        case DTLS1_SCTP_ST_SR_READ_SOCK:
-
-            if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
-                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));
-                ret = -1;
-                goto end;
-            }
-
-            s->state = SSL3_ST_SR_CHANGE_A;
-            break;
-
-        case DTLS1_SCTP_ST_SW_WRITE_SOCK:
-            ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
-            if (ret < 0)
-                goto end;
-
-            if (ret == 0) {
-                if (s->d1->next_state != SSL_ST_OK) {
-                    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));
-                    ret = -1;
-                    goto end;
-                }
-            }
-
-            s->state = s->d1->next_state;
-            break;
-#endif
-
-        case SSL3_ST_SW_SRVR_HELLO_A:
-        case SSL3_ST_SW_SRVR_HELLO_B:
-            s->renegotiate = 2;
-            dtls1_start_timer(s);
-            ret = ssl3_send_server_hello(s);
-            if (ret <= 0)
-                goto end;
-
-            if (s->hit) {
-#ifndef OPENSSL_NO_SCTP
-                /*
-                 * 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) {
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-
-                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
-                         sizeof(sctpauthkey), sctpauthkey);
-#endif
-                if (s->tlsext_ticket_expected)
-                    s->state = SSL3_ST_SW_SESSION_TICKET_A;
-                else
-                    s->state = SSL3_ST_SW_CHANGE_A;
-            } else
-                s->state = SSL3_ST_SW_CERT_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_A:
-        case SSL3_ST_SW_CERT_B:
-            /* Check if it is anon DH or normal PSK */
-            if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
-                && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
-                dtls1_start_timer(s);
-                ret = ssl3_send_server_certificate(s);
-                if (ret <= 0)
-                    goto end;
-
-                if (s->tlsext_status_expected)
-                    s->state = SSL3_ST_SW_CERT_STATUS_A;
-                else
-                    s->state = SSL3_ST_SW_KEY_EXCH_A;
-            } else {
-                skip = 1;
-                s->state = SSL3_ST_SW_KEY_EXCH_A;
-            }
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_KEY_EXCH_A:
-        case SSL3_ST_SW_KEY_EXCH_B:
-            alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-
-            /*
-             * clear this, it may get reset by
-             * send_server_key_exchange
-             */
-            s->s3->tmp.use_rsa_tmp = 0;
-
-            /*
-             * only send if a DH key exchange or RSA but we have a sign only
-             * certificate
-             */
-            if (0
-                /*
-                 * PSK: send ServerKeyExchange if PSK identity hint if
-                 * provided
-                 */
-#ifndef OPENSSL_NO_PSK
-                || ((alg_k & SSL_kPSK) && s->cert->psk_identity_hint)
-#endif
-                || (alg_k & SSL_kDHE)
-                || (alg_k & SSL_kECDHE)
-                || ((alg_k & SSL_kRSA)
-                    && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
-                        || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
-                            && EVP_PKEY_size(s->cert->pkeys
-                                             [SSL_PKEY_RSA_ENC].privatekey) *
-                            8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
-                        )
-                    )
-                )
-                ) {
-                dtls1_start_timer(s);
-                ret = ssl3_send_server_key_exchange(s);
-                if (ret <= 0)
-                    goto end;
-            } else
-                skip = 1;
-
-            s->state = SSL3_ST_SW_CERT_REQ_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_REQ_A:
-        case SSL3_ST_SW_CERT_REQ_B:
-            if (                /* don't request cert unless asked for it: */
-                   !(s->verify_mode & SSL_VERIFY_PEER) ||
-                   /*
-                    * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
-                    * during re-negotiation:
-                    */
-                   ((s->session->peer != NULL) &&
-                    (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-                   /*
-                    * never request cert in anonymous ciphersuites (see
-                    * section "Certificate request" in SSL 3 drafts and in
-                    * RFC 2246):
-                    */
-                   ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
-                   /*
-                    * ... except when the application insists on
-                    * verification (against the specs, but s3_clnt.c accepts
-                    * this for SSL 3)
-                    */
-                   !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
-                   /*
-                    * With normal PSK Certificates and Certificate Requests
-                    * are omitted
-                    */
-                   || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
-                /* no cert request */
-                skip = 1;
-                s->s3->tmp.cert_request = 0;
-                s->state = SSL3_ST_SW_SRVR_DONE_A;
-#ifndef OPENSSL_NO_SCTP
-                if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
-                    s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
-                    s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
-                }
-#endif
-            } else {
-                s->s3->tmp.cert_request = 1;
-                dtls1_start_timer(s);
-                ret = ssl3_send_certificate_request(s);
-                if (ret <= 0)
-                    goto end;
-                s->state = SSL3_ST_SW_SRVR_DONE_A;
-# ifndef OPENSSL_NO_SCTP
-                if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
-                    s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
-                    s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
-                }
-# endif
-                s->init_num = 0;
-            }
-            break;
-
-        case SSL3_ST_SW_SRVR_DONE_A:
-        case SSL3_ST_SW_SRVR_DONE_B:
-            dtls1_start_timer(s);
-            ret = ssl3_send_server_done(s);
-            if (ret <= 0)
-                goto end;
-            s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
-            s->state = SSL3_ST_SW_FLUSH;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_FLUSH:
-            s->rwstate = SSL_WRITING;
-            if (BIO_flush(s->wbio) <= 0) {
-                /*
-                 * If the write error was fatal, stop trying
-                 */
-                if (!BIO_should_retry(s->wbio)) {
-                    s->rwstate = SSL_NOTHING;
-                    s->state = s->s3->tmp.next_state;
-                }
-
-                ret = -1;
-                goto end;
-            }
-            s->rwstate = SSL_NOTHING;
-            s->state = s->s3->tmp.next_state;
-            break;
-
-        case SSL3_ST_SR_CERT_A:
-        case SSL3_ST_SR_CERT_B:
-            if (s->s3->tmp.cert_request) {
-                ret = ssl3_get_client_certificate(s);
-                if (ret <= 0)
-                    goto end;
-            }
-            s->init_num = 0;
-            s->state = SSL3_ST_SR_KEY_EXCH_A;
-            break;
-
-        case SSL3_ST_SR_KEY_EXCH_A:
-        case SSL3_ST_SR_KEY_EXCH_B:
-            ret = ssl3_get_client_key_exchange(s);
-            if (ret <= 0)
-                goto end;
-#ifndef OPENSSL_NO_SCTP
-            /*
-             * 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) {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
-                     sizeof(sctpauthkey), sctpauthkey);
-#endif
-
-            s->state = SSL3_ST_SR_CERT_VRFY_A;
-            s->init_num = 0;
-
-            if (s->no_cert_verify) {
-                /*
-                 * For the ECDH ciphersuites when the client sends its ECDH
-                 * pub key in a certificate, the CertificateVerify message is
-                 * not sent.
-                 */
-                s->state = SSL3_ST_SR_CHANGE_A;
-                s->init_num = 0;
-            } else if (SSL_USE_SIGALGS(s)) {
-                s->state = SSL3_ST_SR_CERT_VRFY_A;
-                s->init_num = 0;
-                if (!s->session->peer)
-                    break;
-                if (!s->s3->handshake_buffer) {
-                    SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-                /*
-                 * For sigalgs freeze the handshake buffer. If we support
-                 * extms we've done this already.
-                 */
-                if (!ssl3_digest_cached_records(s, 1)) {
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-            } else {
-                s->state = SSL3_ST_SR_CERT_VRFY_A;
-                s->init_num = 0;
-
-                /*
-                 * We need to get hashes here so if there is a client cert,
-                 * it can be verified
-                 */
-                s->method->ssl3_enc->cert_verify_mac(s,
-                                                     NID_md5,
-                                                     &(s->s3->
-                                                       tmp.cert_verify_md
-                                                       [0]));
-                s->method->ssl3_enc->cert_verify_mac(s, NID_sha1,
-                                                     &(s->s3->
-                                                       tmp.cert_verify_md
-                                                       [MD5_DIGEST_LENGTH]));
-            }
-            break;
-
-        case SSL3_ST_SR_CERT_VRFY_A:
-        case SSL3_ST_SR_CERT_VRFY_B:
-            ret = ssl3_get_cert_verify(s);
-            if (ret <= 0)
-                goto end;
-#ifndef OPENSSL_NO_SCTP
-            if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
-                state == SSL_ST_RENEGOTIATE)
-                s->state = DTLS1_SCTP_ST_SR_READ_SOCK;
-            else
-#endif
-                s->state = SSL3_ST_SR_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SR_CHANGE_A:
-        case SSL3_ST_SR_CHANGE_B:
-            ret = ssl3_get_change_cipher_spec(s, SSL3_ST_SR_CHANGE_A,
-                                              SSL3_ST_SR_CHANGE_B);
-            if (ret <= 0)
-                goto end;
-
-            s->state = SSL3_ST_SR_FINISHED_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SR_FINISHED_A:
-        case SSL3_ST_SR_FINISHED_B:
-            ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
-                                    SSL3_ST_SR_FINISHED_B);
-            if (ret <= 0)
-                goto end;
-            dtls1_stop_timer(s);
-            if (s->hit)
-                s->state = SSL_ST_OK;
-            else if (s->tlsext_ticket_expected)
-                s->state = SSL3_ST_SW_SESSION_TICKET_A;
-            else
-                s->state = SSL3_ST_SW_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_SESSION_TICKET_A:
-        case SSL3_ST_SW_SESSION_TICKET_B:
-            ret = ssl3_send_newsession_ticket(s);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_STATUS_A:
-        case SSL3_ST_SW_CERT_STATUS_B:
-            ret = ssl3_send_cert_status(s);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_KEY_EXCH_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CHANGE_A:
-        case SSL3_ST_SW_CHANGE_B:
-
-            s->session->cipher = s->s3->tmp.new_cipher;
-            if (!s->method->ssl3_enc->setup_key_block(s)) {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            ret = dtls1_send_change_cipher_spec(s,
-                                                SSL3_ST_SW_CHANGE_A,
-                                                SSL3_ST_SW_CHANGE_B);
-
-            if (ret <= 0)
-                goto end;
-
-#ifndef OPENSSL_NO_SCTP
-            if (!s->hit) {
-                /*
-                 * Change to new shared key of SCTP-Auth, will be ignored if
-                 * no SCTP used.
-                 */
-                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
-                         0, NULL);
-            }
-#endif
-
-            s->state = SSL3_ST_SW_FINISHED_A;
-            s->init_num = 0;
-
-            if (!s->method->ssl3_enc->change_cipher_state(s,
-                                                          SSL3_CHANGE_CIPHER_SERVER_WRITE))
-            {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
-            break;
-
-        case SSL3_ST_SW_FINISHED_A:
-        case SSL3_ST_SW_FINISHED_B:
-            ret = ssl3_send_finished(s,
-                                     SSL3_ST_SW_FINISHED_A,
-                                     SSL3_ST_SW_FINISHED_B,
-                                     s->method->
-                                     ssl3_enc->server_finished_label,
-                                     s->method->
-                                     ssl3_enc->server_finished_label_len);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_FLUSH;
-            if (s->hit) {
-                s->s3->tmp.next_state = SSL3_ST_SR_CHANGE_A;
-
-#ifndef OPENSSL_NO_SCTP
-                /*
-                 * Change to new shared key of SCTP-Auth, will be ignored if
-                 * no SCTP used.
-                 */
-                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
-                         0, NULL);
-#endif
-            } else {
-                s->s3->tmp.next_state = SSL_ST_OK;
-#ifndef OPENSSL_NO_SCTP
-                if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
-                    s->d1->next_state = s->s3->tmp.next_state;
-                    s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
-                }
-#endif
-            }
-            s->init_num = 0;
-            break;
-
-        case SSL_ST_OK:
-            /* clean a few things up */
-            ssl3_cleanup_key_block(s);
-
-            /* remove buffering on output */
-            ssl_free_wbio_buffer(s);
-
-            s->init_num = 0;
-
-            if (s->renegotiate == 2) { /* skipped if we just sent a
-                                        * HelloRequest */
-                s->renegotiate = 0;
-                s->new_session = 0;
-
-                ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
-
-                s->ctx->stats.sess_accept_good++;
-                /* s->server=1; */
-                s->handshake_func = dtls1_accept;
-
-                if (cb != NULL)
-                    cb(s, SSL_CB_HANDSHAKE_DONE, 1);
-            }
-
-            ret = 1;
-
-            /* done handshaking, next message is client hello */
-            s->d1->handshake_read_seq = 0;
-            /* next message is server hello */
-            s->d1->handshake_write_seq = 0;
-            s->d1->next_handshake_write_seq = 0;
-            goto end;
-            /* break; */
-
-        case SSL_ST_ERR:
-        default:
-            SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE);
-            ret = -1;
-            goto end;
-            /* break; */
-        }
-
-        if (!s->s3->tmp.reuse_message && !skip) {
-            if (s->debug) {
-                if ((ret = BIO_flush(s->wbio)) <= 0)
-                    goto end;
-            }
-
-            if ((cb != NULL) && (s->state != state)) {
-                new_state = s->state;
-                s->state = state;
-                cb(s, SSL_CB_ACCEPT_LOOP, 1);
-                s->state = new_state;
-            }
-        }
-        skip = 0;
-    }
- end:
-    /* BIO_flush(s->wbio); */
-
-    s->in_handshake--;
-#ifndef OPENSSL_NO_SCTP
-    /*
-     * Notify SCTP BIO socket to leave handshake mode and prevent stream
-     * identifier other than 0. Will be ignored if no SCTP is used.
-     */
-    BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
-             s->in_handshake, NULL);
-#endif
-
-    if (cb != NULL)
-        cb(s, SSL_CB_ACCEPT_EXIT, ret);
-    return (ret);
-}
-#endif
 
 unsigned int dtls1_raw_hello_verify_request(unsigned char *buf,
                                             unsigned char *cookie,
index d91de4d..64e1f74 100644 (file)
@@ -283,8 +283,8 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 #ifndef OPENSSL_NO_SCTP
     /* Store bio_dgram_sctp_rcvinfo struct */
     if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
-        (s->state == SSL3_ST_SR_FINISHED_A
-         || s->state == SSL3_ST_CR_FINISHED_A)) {
+        (SSL_state(s) == TLS_ST_SR_FINISHED
+         || SSL_state(s) == TLS_ST_CR_FINISHED)) {
         BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
                  sizeof(rdata->recordinfo), &rdata->recordinfo);
     }
@@ -472,7 +472,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
      * We are not handshaking and have no data yet, so process data buffered
      * during the last handshake in advance, if any.
      */
-    if (s->state == SSL_ST_OK && SSL3_RECORD_get_length(rr) == 0) {
+    if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
         pitem *item;
         item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
         if (item) {
@@ -901,9 +901,9 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
             goto start;
         }
 
-        if (((s->state & SSL_ST_MASK) == SSL_ST_OK) &&
+        if (SSL_is_init_finished(s) &&
             !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
-            s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
+            statem_set_in_init(s, 1);
             s->renegotiate = 1;
             s->new_session = 1;
         }
@@ -966,14 +966,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
          */
         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)
-             )
-            )) {
+            statem_app_data_allowed(s)) {
             s->s3->in_read_app_data = 2;
             return (-1);
         } else {
index 78e355a..c224fe5 100644 (file)
@@ -779,7 +779,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
      * Some servers hang if iniatial client hello is larger than 256 bytes
      * and record version number > TLS 1.0
      */
-    if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+    if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO
         && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION)
         *(p++) = 0x1;
     else
@@ -1384,9 +1384,9 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
      * Unexpected handshake message (Client Hello, or protocol violation)
      */
     if ((s->rlayer.handshake_fragment_len >= 4) && !s->in_handshake) {
-        if (((s->state & SSL_ST_MASK) == SSL_ST_OK) &&
+        if (SSL_is_init_finished(s) &&
             !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
-            s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
+            statem_set_in_init(s, 1);
             s->renegotiate = 1;
             s->new_session = 1;
         }
index 2afde72..db0197d 100644 (file)
@@ -156,20 +156,6 @@ int ssl3_do_write(SSL *s, int type)
     return (0);
 }
 
-int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
-{
-    if (s->state == a) {
-        if (tls_construct_finished(s, sender, slen) == 0) {
-            statem_set_error(s);
-            return -1;
-        }
-        s->state = b;
-    }
-
-    /* SSL3_ST_SEND_xxxxxx_HELLO_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_finished(SSL *s, const char *sender, int slen)
 {
     unsigned char *p;
@@ -223,7 +209,7 @@ static void ssl3_take_mac(SSL *s)
      */
     if (s->s3->tmp.new_cipher == NULL)
         return;
-    if (s->state & SSL_ST_CONNECT) {
+    if (!s->server) {
         sender = s->method->ssl3_enc->server_finished_label;
         slen = s->method->ssl3_enc->server_finished_label_len;
     } else {
@@ -238,24 +224,6 @@ static void ssl3_take_mac(SSL *s)
 }
 #endif
 
-int ssl3_get_change_cipher_spec(SSL *s, int a, int b)
-{
-    int ok;
-    long n;
-
-    n = s->method->ssl_get_message(s, a, b, SSL3_MT_CHANGE_CIPHER_SPEC, 1, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    if (tls_process_change_cipher_spec(s, n) == 0) {
-        statem_set_error(s);
-        return -1;
-    }
-
-    return 1;
-}
-
 enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n)
 {
     int al;
@@ -320,28 +288,6 @@ enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n)
     return MSG_PROCESS_ERROR;
 }
 
-
-int ssl3_get_finished(SSL *s, int a, int b)
-{
-    int ok;
-    long n;
-
-#ifdef OPENSSL_NO_NEXTPROTONEG
-    /*
-     * the mac has already been generated when we received the change cipher
-     * spec message and is in s->s3->tmp.peer_finish_md
-     */
-#endif
-
-    /* 64 argument should actually be 36+4 :-) */
-    n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    return tls_process_finished(s, (unsigned long)n);
-}
-
 enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n)
 {
     int al, i;
@@ -390,30 +336,6 @@ enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n)
     return MSG_PROCESS_ERROR;
 }
 
-/*-
- * for these 2 messages, we need to
- * ssl->enc_read_ctx                    re-init
- * ssl->rlayer.read_sequence            zero
- * ssl->s3->read_mac_secret             re-init
- * ssl->session->read_sym_enc           assign
- * ssl->session->read_compression       assign
- * ssl->session->read_hash              assign
- */
-int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
-{
-    if (s->state == a) {
-        if(tls_construct_change_cipher_spec(s) == 0) {
-            statem_set_error(s);
-            return 0;
-        }
-
-        s->state = b;
-    }
-
-    /* SSL3_ST_CW_CHANGE_B */
-    return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
-}
-
 int tls_construct_change_cipher_spec(SSL *s)
 {
     unsigned char *p;
@@ -516,87 +438,6 @@ enum WORK_STATE tls_finish_handshake(SSL *s, enum WORK_STATE wst)
     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)
- * are read in state 'st1', the body is read in state 'stn'.
- */
-long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
-{
-    unsigned char *p;
-    long n;
-    int al, mtin;
-
-    if (s->s3->tmp.reuse_message) {
-        s->s3->tmp.reuse_message = 0;
-        if ((mt >= 0) && (s->s3->tmp.message_type != mt)) {
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
-            goto f_err;
-        }
-        *ok = 1;
-        s->state = stn;
-        s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
-        s->init_num = (int)s->s3->tmp.message_size;
-        return s->init_num;
-    }
-
-    p = (unsigned char *)s->init_buf->data;
-
-    if (s->state == st1) {
-        if (tls_get_message_header(s, &mtin) == 0) {
-            /* Could be NBIO */
-            *ok = 0;
-            return -1;
-        }
-        s->state = stn;
-        if (s->init_num == 0
-                && mtin == SSL3_MT_CHANGE_CIPHER_SPEC
-                && (mt < 0 || mt == SSL3_MT_CHANGE_CIPHER_SPEC)) {
-            if (*p != SSL3_MT_CCS) {
-                al = SSL_AD_UNEXPECTED_MESSAGE;
-                SSLerr(SSL_F_SSL3_GET_MESSAGE,
-                       SSL_R_UNEXPECTED_MESSAGE);
-                goto f_err;
-            }
-            s->init_msg = p + 1;
-            s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
-            s->s3->tmp.message_size = s->init_num;
-            *ok = 1;
-            if (s->msg_callback)
-                s->msg_callback(0, s->version,
-                                SSL3_RT_CHANGE_CIPHER_SPEC, p, 1, s,
-                                s->msg_callback_arg);
-            return s->init_num;
-        }
-        if (s->s3->tmp.message_size > (unsigned long)max) {
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-            goto f_err;
-        }
-        if ((mt >= 0) && (mtin != mt)) {
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
-            goto f_err;
-        }
-    }
-
-    /* next state (stn) */
-    if (tls_get_message_body(s, (unsigned long *)&n) == 0) {
-        *ok = 0;
-        return n;
-    }
-
-    *ok = 1;
-    return n;
- f_err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    statem_set_error(s);
-    *ok = 0;
-    return 0;
-}
-
 int tls_get_message_header(SSL *s, int *mt)
 {
     /* s->init_num < SSL3_HM_HEADER_LENGTH */
index 292fb1b..2111d18 100644 (file)
@@ -5014,7 +5014,7 @@ int ssl3_shutdown(SSL *s)
      * Don't do anything much if we have not done the handshake or we don't
      * want to send messages :-)
      */
-    if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) {
+    if ((s->quiet_shutdown) || (SSL_in_before(s))) {
         s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
         return (1);
     }
@@ -5128,10 +5128,9 @@ int ssl3_renegotiate_check(SSL *s)
             && !SSL_in_init(s)) {
             /*
              * if we are the server, and we have sent a 'RENEGOTIATE'
-             * message, we need to go to SSL_ST_ACCEPT.
+             * message, we need to set the state machine into the renegotiate
+             * state.
              */
-            /* SSL_ST_ACCEPT */
-            s->state = SSL_ST_RENEGOTIATE;
             statem_set_renegotiate(s);
             s->s3->renegotiate = 0;
             s->s3->num_renegotiations++;
index fcf4744..8d7f042 100644 (file)
@@ -118,7 +118,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
     const char *sender;
     int slen;
 
-    if (s->state & SSL_ST_ACCEPT)
+    if (s->server)
         i = SSL3_CHANGE_CIPHER_SERVER_READ;
     else
         i = SSL3_CHANGE_CIPHER_CLIENT_READ;
@@ -143,7 +143,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
      * we have to record the message digest at this point so we can get it
      * before we read the finished message
      */
-    if (s->state & SSL_ST_CONNECT) {
+    if (!s->server) {
         sender = s->method->ssl3_enc->server_finished_label;
         slen = s->method->ssl3_enc->server_finished_label_len;
     } else {
index d390f14..85601b0 100644 (file)
@@ -193,641 +193,6 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
 }
 #endif
 
-#if 0
-int ssl3_accept(SSL *s)
-{
-    BUF_MEM *buf;
-    unsigned long alg_k, Time = (unsigned long)time(NULL);
-    void (*cb) (const SSL *ssl, int type, int val) = NULL;
-    int ret = -1;
-    int new_state, state, skip = 0;
-
-    RAND_add(&Time, sizeof(Time), 0);
-    ERR_clear_error();
-    clear_sys_error();
-
-    if (s->info_callback != NULL)
-        cb = s->info_callback;
-    else if (s->ctx->info_callback != NULL)
-        cb = s->ctx->info_callback;
-
-    /* init things to blank */
-    s->in_handshake++;
-    if (!SSL_in_init(s) || SSL_in_before(s)) {
-        if (!SSL_clear(s))
-            return -1;
-    }
-
-#ifndef OPENSSL_NO_HEARTBEATS
-    /*
-     * If we're awaiting a HeartbeatResponse, pretend we already got and
-     * don't await it anymore, because Heartbeats don't make sense during
-     * handshakes anyway.
-     */
-    if (s->tlsext_hb_pending) {
-        s->tlsext_hb_pending = 0;
-        s->tlsext_hb_seq++;
-    }
-#endif
-
-    for (;;) {
-        state = s->state;
-
-        switch (s->state) {
-        case SSL_ST_RENEGOTIATE:
-            s->renegotiate = 1;
-            /* s->state=SSL_ST_ACCEPT; */
-
-        case SSL_ST_BEFORE:
-        case SSL_ST_ACCEPT:
-        case SSL_ST_BEFORE | SSL_ST_ACCEPT:
-        case SSL_ST_OK | SSL_ST_ACCEPT:
-
-            s->server = 1;
-            if (cb != NULL)
-                cb(s, SSL_CB_HANDSHAKE_START, 1);
-
-            if ((s->version >> 8 != 3) && s->version != TLS_ANY_VERSION) {
-                SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
-                s->state = SSL_ST_ERR;
-                return -1;
-            }
-
-            if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) {
-                SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_VERSION_TOO_LOW);
-                return -1;
-            }
-
-            s->type = SSL_ST_ACCEPT;
-
-            if (s->init_buf == NULL) {
-                if ((buf = BUF_MEM_new()) == NULL) {
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-                if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
-                    BUF_MEM_free(buf);
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-                s->init_buf = buf;
-            }
-
-            if (!ssl3_setup_buffers(s)) {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            s->init_num = 0;
-            s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
-            /*
-             * Should have been reset by ssl3_get_finished, too.
-             */
-            s->s3->change_cipher_spec = 0;
-
-            if (s->state != SSL_ST_RENEGOTIATE) {
-                /*
-                 * Ok, we now need to push on a buffering BIO so that the
-                 * output is sent in a way that TCP likes :-)
-                 */
-                if (!ssl_init_wbio_buffer(s, 1)) {
-                    ret = -1;
-                    s->state = SSL_ST_ERR;
-                    goto end;
-                }
-
-                ssl3_init_finished_mac(s);
-                s->state = SSL3_ST_SR_CLNT_HELLO_A;
-                s->ctx->stats.sess_accept++;
-            } else if (!s->s3->send_connection_binding &&
-                       !(s->options &
-                         SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-                /*
-                 * Server attempting to renegotiate with client that doesn't
-                 * support secure renegotiation.
-                 */
-                SSLerr(SSL_F_SSL3_ACCEPT,
-                       SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            } else {
-                /*
-                 * s->state == SSL_ST_RENEGOTIATE, we will just send a
-                 * HelloRequest
-                 */
-                s->ctx->stats.sess_accept_renegotiate++;
-                s->state = SSL3_ST_SW_HELLO_REQ_A;
-            }
-            break;
-
-        case SSL3_ST_SW_HELLO_REQ_A:
-        case SSL3_ST_SW_HELLO_REQ_B:
-
-            s->shutdown = 0;
-            ret = ssl3_send_hello_request(s);
-            if (ret <= 0)
-                goto end;
-            s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C;
-            s->state = SSL3_ST_SW_FLUSH;
-            s->init_num = 0;
-
-            ssl3_init_finished_mac(s);
-            break;
-
-        case SSL3_ST_SW_HELLO_REQ_C:
-            s->state = SSL_ST_OK;
-            break;
-
-        case SSL3_ST_SR_CLNT_HELLO_A:
-        case SSL3_ST_SR_CLNT_HELLO_B:
-        case SSL3_ST_SR_CLNT_HELLO_C:
-
-            ret = ssl3_get_client_hello(s);
-            if (ret <= 0)
-                goto end;
-
-            s->state = SSL3_ST_SW_SRVR_HELLO_A;
-            s->init_num = 0;
-            break;
-
-#ifndef OPENSSL_NO_SRP
-        case SSL3_ST_SR_CLNT_HELLO_D:
-            {
-                enum WORK_STATE wst_ret;
-
-                wst_ret = tls_post_process_client_hello(s, WORK_MORE_B);
-                if (wst_ret == WORK_MORE_B)
-                    goto end;
-                if (wst_ret == WORK_ERROR) {
-                    ret = -1;
-                    goto end;
-                }
-            }
-
-            s->state = SSL3_ST_SW_SRVR_HELLO_A;
-            s->init_num = 0;
-            break;
-#endif
-
-        case SSL3_ST_SW_SRVR_HELLO_A:
-        case SSL3_ST_SW_SRVR_HELLO_B:
-            ret = ssl3_send_server_hello(s);
-            if (ret <= 0)
-                goto end;
-
-            if (s->hit) {
-                if (s->tlsext_ticket_expected)
-                    s->state = SSL3_ST_SW_SESSION_TICKET_A;
-                else
-                    s->state = SSL3_ST_SW_CHANGE_A;
-            } else {
-                s->state = SSL3_ST_SW_CERT_A;
-            }
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_A:
-        case SSL3_ST_SW_CERT_B:
-            /* Check if it is anon DH or anon ECDH, */
-            /* normal PSK or SRP */
-            if (!(s->s3->tmp.new_cipher->algorithm_auth &
-                 (SSL_aNULL | SSL_aSRP | SSL_aPSK))) {
-                ret = ssl3_send_server_certificate(s);
-                if (ret <= 0)
-                    goto end;
-
-                if (s->tlsext_status_expected)
-                    s->state = SSL3_ST_SW_CERT_STATUS_A;
-                else
-                    s->state = SSL3_ST_SW_KEY_EXCH_A;
-            } else {
-                skip = 1;
-                s->state = SSL3_ST_SW_KEY_EXCH_A;
-            }
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_KEY_EXCH_A:
-        case SSL3_ST_SW_KEY_EXCH_B:
-            alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-
-            /*
-             * clear this, it may get reset by
-             * send_server_key_exchange
-             */
-            s->s3->tmp.use_rsa_tmp = 0;
-
-            /*
-             * only send if a DH key exchange, fortezza or RSA but we have a
-             * sign only certificate PSK: may send PSK identity hints For
-             * ECC ciphersuites, we send a serverKeyExchange message only if
-             * the cipher suite is either ECDH-anon or ECDHE. In other cases,
-             * the server certificate contains the server's public key for
-             * key exchange.
-             */
-            if (0
-                /*
-                 * PSK: send ServerKeyExchange if PSK identity hint if
-                 * provided
-                 */
-#ifndef OPENSSL_NO_PSK
-                /* Only send SKE if we have identity hint for plain PSK */
-                || ((alg_k & (SSL_kPSK | SSL_kRSAPSK)) && s->cert->psk_identity_hint)
-                /* For other PSK always send SKE */
-                || (alg_k & (SSL_PSK & (SSL_kDHEPSK | SSL_kECDHEPSK)))
-#endif
-#ifndef OPENSSL_NO_SRP
-                /* SRP: send ServerKeyExchange */
-                || (alg_k & SSL_kSRP)
-#endif
-                || (alg_k & SSL_kDHE)
-                || (alg_k & SSL_kECDHE)
-                || ((alg_k & SSL_kRSA)
-                    && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
-                        || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
-                            && EVP_PKEY_size(s->cert->pkeys
-                                             [SSL_PKEY_RSA_ENC].privatekey) *
-                            8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
-                        )
-                    )
-                )
-                ) {
-                ret = ssl3_send_server_key_exchange(s);
-                if (ret <= 0)
-                    goto end;
-            } else
-                skip = 1;
-
-            s->state = SSL3_ST_SW_CERT_REQ_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_REQ_A:
-        case SSL3_ST_SW_CERT_REQ_B:
-            if (                /* don't request cert unless asked for it: */
-                   !(s->verify_mode & SSL_VERIFY_PEER) ||
-                   /*
-                    * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
-                    * during re-negotiation:
-                    */
-                   ((s->session->peer != NULL) &&
-                    (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-                   /*
-                    * never request cert in anonymous ciphersuites (see
-                    * section "Certificate request" in SSL 3 drafts and in
-                    * RFC 2246):
-                    */
-                   ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
-                   /*
-                    * ... except when the application insists on
-                    * verification (against the specs, but s3_clnt.c accepts
-                    * this for SSL 3)
-                    */
-                   !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
-                   /* don't request certificate for SRP auth */
-                   (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
-                   /*
-                    * With normal PSK Certificates and Certificate Requests
-                    * are omitted
-                    */
-                   || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) {
-                /* no cert request */
-                skip = 1;
-                s->s3->tmp.cert_request = 0;
-                s->state = SSL3_ST_SW_SRVR_DONE_A;
-                if (!ssl3_digest_cached_records(s, 0)) {
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-            } else {
-                s->s3->tmp.cert_request = 1;
-                ret = ssl3_send_certificate_request(s);
-                if (ret <= 0)
-                    goto end;
-                s->state = SSL3_ST_SW_SRVR_DONE_A;
-                s->init_num = 0;
-            }
-            break;
-
-        case SSL3_ST_SW_SRVR_DONE_A:
-        case SSL3_ST_SW_SRVR_DONE_B:
-            ret = ssl3_send_server_done(s);
-            if (ret <= 0)
-                goto end;
-            s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
-            s->state = SSL3_ST_SW_FLUSH;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_FLUSH:
-
-            /*
-             * This code originally checked to see if any data was pending
-             * using BIO_CTRL_INFO and then flushed. This caused problems as
-             * documented in PR#1939. The proposed fix doesn't completely
-             * resolve this issue as buggy implementations of
-             * BIO_CTRL_PENDING still exist. So instead we just flush
-             * unconditionally.
-             */
-
-            s->rwstate = SSL_WRITING;
-            if (BIO_flush(s->wbio) <= 0) {
-                ret = -1;
-                goto end;
-            }
-            s->rwstate = SSL_NOTHING;
-
-            s->state = s->s3->tmp.next_state;
-            break;
-
-        case SSL3_ST_SR_CERT_A:
-        case SSL3_ST_SR_CERT_B:
-            if (s->s3->tmp.cert_request) {
-                ret = ssl3_get_client_certificate(s);
-                if (ret <= 0)
-                    goto end;
-            }
-            s->init_num = 0;
-            s->state = SSL3_ST_SR_KEY_EXCH_A;
-            break;
-
-        case SSL3_ST_SR_KEY_EXCH_A:
-        case SSL3_ST_SR_KEY_EXCH_B:
-            ret = ssl3_get_client_key_exchange(s);
-            if (ret <= 0)
-                goto end;
-            if (s->no_cert_verify) {
-                /*
-                 * For the ECDH ciphersuites when the client sends its ECDH
-                 * pub key in a certificate, the CertificateVerify message is
-                 * not sent. Also for GOST ciphersuites when the client uses
-                 * its key from the certificate for key exchange.
-                 */
-                s->state = SSL3_ST_SR_CHANGE_A;
-                s->init_num = 0;
-            } else if (SSL_USE_SIGALGS(s)) {
-                s->state = SSL3_ST_SR_CERT_VRFY_A;
-                s->init_num = 0;
-                if (!s->session->peer)
-                    break;
-                if (!s->s3->handshake_buffer) {
-                    SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-                /*
-                 * For sigalgs freeze the handshake buffer. If we support
-                 * extms we've done this already so this is a no-op
-                 */
-                if (!ssl3_digest_cached_records(s, 1)) {
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-            } else {
-                int offset = 0;
-                int dgst_num;
-
-                s->state = SSL3_ST_SR_CERT_VRFY_A;
-                s->init_num = 0;
-
-                /*
-                 * We need to get hashes here so if there is a client cert,
-                 * it can be verified FIXME - digest processing for
-                 * CertificateVerify should be generalized. But it is next
-                 * step
-                 */
-                if (!ssl3_digest_cached_records(s, 0)) {
-                    s->state = SSL_ST_ERR;
-                    return -1;
-                }
-                for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
-                    if (s->s3->handshake_dgst[dgst_num]) {
-                        int dgst_size;
-
-                        s->method->ssl3_enc->cert_verify_mac(s,
-                                                             EVP_MD_CTX_type
-                                                             (s->
-                                                              s3->handshake_dgst
-                                                              [dgst_num]),
-                                                             &(s->s3->
-                                                               tmp.cert_verify_md
-                                                               [offset]));
-                        dgst_size =
-                            EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
-                        if (dgst_size < 0) {
-                            s->state = SSL_ST_ERR;
-                            ret = -1;
-                            goto end;
-                        }
-                        offset += dgst_size;
-                    }
-            }
-            break;
-
-        case SSL3_ST_SR_CERT_VRFY_A:
-        case SSL3_ST_SR_CERT_VRFY_B:
-            ret = ssl3_get_cert_verify(s);
-            if (ret <= 0)
-                goto end;
-
-            s->state = SSL3_ST_SR_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-#if !defined(OPENSSL_NO_NEXTPROTONEG)
-        case SSL3_ST_SR_NEXT_PROTO_A:
-        case SSL3_ST_SR_NEXT_PROTO_B:
-            ret = ssl3_get_next_proto(s);
-            if (ret <= 0)
-                goto end;
-            s->init_num = 0;
-            s->state = SSL3_ST_SR_FINISHED_A;
-            break;
-#endif
-
-
-        case SSL3_ST_SR_CHANGE_A:
-        case SSL3_ST_SR_CHANGE_B:
-            ret = ssl3_get_change_cipher_spec(s, SSL3_ST_SR_CHANGE_A,
-                                              SSL3_ST_SR_CHANGE_B);
-            if (ret <= 0)
-                goto end;
-
-#if defined(OPENSSL_NO_NEXTPROTONEG)
-            s->state = SSL3_ST_SR_FINISHED_A;
-#else
-            if (s->s3->next_proto_neg_seen)
-                s->state = SSL3_ST_SR_NEXT_PROTO_A;
-            else
-                s->state = SSL3_ST_SR_FINISHED_A;
-#endif
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SR_FINISHED_A:
-        case SSL3_ST_SR_FINISHED_B:
-            ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
-                                    SSL3_ST_SR_FINISHED_B);
-            if (ret <= 0)
-                goto end;
-            if (s->hit)
-                s->state = SSL_ST_OK;
-            else if (s->tlsext_ticket_expected)
-                s->state = SSL3_ST_SW_SESSION_TICKET_A;
-            else
-                s->state = SSL3_ST_SW_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_SESSION_TICKET_A:
-        case SSL3_ST_SW_SESSION_TICKET_B:
-            ret = ssl3_send_newsession_ticket(s);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_CHANGE_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CERT_STATUS_A:
-        case SSL3_ST_SW_CERT_STATUS_B:
-            ret = ssl3_send_cert_status(s);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_KEY_EXCH_A;
-            s->init_num = 0;
-            break;
-
-        case SSL3_ST_SW_CHANGE_A:
-        case SSL3_ST_SW_CHANGE_B:
-
-            s->session->cipher = s->s3->tmp.new_cipher;
-            if (!s->method->ssl3_enc->setup_key_block(s)) {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            ret = ssl3_send_change_cipher_spec(s,
-                                               SSL3_ST_SW_CHANGE_A,
-                                               SSL3_ST_SW_CHANGE_B);
-
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_FINISHED_A;
-            s->init_num = 0;
-
-            if (!s->method->ssl3_enc->change_cipher_state(s,
-                                                          SSL3_CHANGE_CIPHER_SERVER_WRITE))
-            {
-                ret = -1;
-                s->state = SSL_ST_ERR;
-                goto end;
-            }
-
-            break;
-
-        case SSL3_ST_SW_FINISHED_A:
-        case SSL3_ST_SW_FINISHED_B:
-            ret = ssl3_send_finished(s,
-                                     SSL3_ST_SW_FINISHED_A,
-                                     SSL3_ST_SW_FINISHED_B,
-                                     s->method->
-                                     ssl3_enc->server_finished_label,
-                                     s->method->
-                                     ssl3_enc->server_finished_label_len);
-            if (ret <= 0)
-                goto end;
-            s->state = SSL3_ST_SW_FLUSH;
-            if (s->hit) {
-                s->s3->tmp.next_state = SSL3_ST_SR_CHANGE_A;
-            } else
-                s->s3->tmp.next_state = SSL_ST_OK;
-            s->init_num = 0;
-            break;
-
-        case SSL_ST_OK:
-            /* clean a few things up */
-            ssl3_cleanup_key_block(s);
-
-            BUF_MEM_free(s->init_buf);
-            s->init_buf = NULL;
-
-            /* remove buffering on output */
-            ssl_free_wbio_buffer(s);
-
-            s->init_num = 0;
-
-            if (s->renegotiate == 2) { /* skipped if we just sent a
-                                        * HelloRequest */
-                s->renegotiate = 0;
-                s->new_session = 0;
-
-                ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
-
-                s->ctx->stats.sess_accept_good++;
-                /* s->server=1; */
-                s->handshake_func = ssl3_accept;
-
-                if (cb != NULL)
-                    cb(s, SSL_CB_HANDSHAKE_DONE, 1);
-            }
-
-            ret = 1;
-            goto end;
-            /* break; */
-
-        case SSL_ST_ERR:
-        default:
-            SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
-            ret = -1;
-            goto end;
-            /* break; */
-        }
-
-        if (!s->s3->tmp.reuse_message && !skip) {
-            if (s->debug) {
-                if ((ret = BIO_flush(s->wbio)) <= 0)
-                    goto end;
-            }
-
-            if ((cb != NULL) && (s->state != state)) {
-                new_state = s->state;
-                s->state = state;
-                cb(s, SSL_CB_ACCEPT_LOOP, 1);
-                s->state = new_state;
-            }
-        }
-        skip = 0;
-    }
- end:
-    /* BIO_flush(s->wbio); */
-
-    s->in_handshake--;
-    if (cb != NULL)
-        cb(s, SSL_CB_ACCEPT_EXIT, ret);
-    return (ret);
-}
-#endif
-
-int ssl3_send_hello_request(SSL *s)
-{
-
-    if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
-        if (tls_construct_hello_request(s) == 0) {
-            return -1;
-        }
-        s->state = SSL3_ST_SW_HELLO_REQ_B;
-    }
-
-    /* SSL3_ST_SW_HELLO_REQ_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_hello_request(SSL *s)
 {
     if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) {
@@ -839,49 +204,6 @@ int tls_construct_hello_request(SSL *s)
     return 1;
 }
 
-int ssl3_get_client_hello(SSL *s)
-{
-    int ok;
-    long n;
-    enum WORK_STATE wst_ret;
-
-    if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
-        goto retry_cert;
-
-    /*
-     * We do this so that we will respond with our native type. If we are
-     * TLSv1 and we get SSLv3, we will respond with TLSv1, This down
-     * switching should be handled by a different method. If we are SSLv3, we
-     * will respond with SSLv3, even if prompted with TLSv1.
-     */
-    if (s->state == SSL3_ST_SR_CLNT_HELLO_A) {
-        s->state = SSL3_ST_SR_CLNT_HELLO_B;
-    }
-    s->first_packet = 1;
-    n = s->method->ssl_get_message(s,
-                                   SSL3_ST_SR_CLNT_HELLO_B,
-                                   SSL3_ST_SR_CLNT_HELLO_C,
-                                   SSL3_MT_CLIENT_HELLO,
-                                   SSL3_RT_MAX_PLAIN_LENGTH, &ok);
-
-    if (!ok)
-        return ((int)n);
-    s->first_packet = 0;
-
-    if (tls_process_client_hello(s, n) == 0)
-        return -1;
-
- retry_cert:
-    wst_ret = tls_post_process_client_hello(s, WORK_MORE_A);
-    if (wst_ret == WORK_MORE_A || wst_ret == WORK_ERROR)
-        return -1;
-    if (wst_ret == WORK_MORE_B) {
-        s->state = SSL3_ST_SR_CLNT_HELLO_D;
-        return -1;
-    }
-    return n;
-}
-
 enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n)
 {
     int i, al = SSL_AD_INTERNAL_ERROR;
@@ -1526,18 +848,6 @@ enum WORK_STATE tls_post_process_client_hello(SSL *s, enum WORK_STATE wst)
     return WORK_ERROR;
 }
 
-int ssl3_send_server_hello(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_SRVR_HELLO_A) {
-        if (tls_construct_server_hello(s) != 1)
-            return -1;
-        s->state = SSL3_ST_SW_SRVR_HELLO_B;
-    }
-
-    /* SSL3_ST_SW_SRVR_HELLO_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_server_hello(SSL *s)
 {
     unsigned char *buf;
@@ -1631,19 +941,6 @@ int tls_construct_server_hello(SSL *s)
     return 1;
 }
 
-int ssl3_send_server_done(SSL *s)
-{
-
-    if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
-        if (tls_construct_server_done(s) == 0)
-            return -1;
-        s->state = SSL3_ST_SW_SRVR_DONE_B;
-    }
-
-    /* SSL3_ST_SW_SRVR_DONE_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_server_done(SSL *s)
 {
     if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
@@ -1661,17 +958,6 @@ int tls_construct_server_done(SSL *s)
     return 1;
 }
 
-int ssl3_send_server_key_exchange(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
-        if (tls_construct_server_key_exchange(s) == 0)
-            return -1;
-    }
-
-    s->state = SSL3_ST_SW_KEY_EXCH_B;
-    return ssl_do_write(s);
-}
-
 int tls_construct_server_key_exchange(SSL *s)
 {
 #ifndef OPENSSL_NO_RSA
@@ -2139,18 +1425,6 @@ int tls_construct_server_key_exchange(SSL *s)
     return 0;
 }
 
-int ssl3_send_certificate_request(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_CERT_REQ_A) {
-        if (tls_construct_certificate_request(s) == 0)
-            return -1;
-        s->state = SSL3_ST_SW_CERT_REQ_B;
-    }
-
-    /* SSL3_ST_SW_CERT_REQ_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_certificate_request(SSL *s)
 {
     unsigned char *p, *d;
@@ -2223,25 +1497,6 @@ int tls_construct_certificate_request(SSL *s)
     return 0;
 }
 
-int ssl3_get_client_key_exchange(SSL *s)
-{
-    int ok;
-    long n;
-
-    n = s->method->ssl_get_message(s,
-                                   SSL3_ST_SR_KEY_EXCH_A,
-                                   SSL3_ST_SR_KEY_EXCH_B,
-                                   SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    if (tls_process_client_key_exchange(s, n) == 0)
-        return -1;
-
-    return n;
-}
-
 enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n)
 {
     int al;
@@ -2984,42 +2239,6 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s,
     return WORK_FINISHED_CONTINUE;
 }
 
-int ssl3_get_cert_verify(SSL *s)
-{
-    int ok, ret = 1;
-    long n;
-
-    /*
-     * We should only process a CertificateVerify message if we have received
-     * a Certificate from the client. If so then |s->session->peer| will be non
-     * NULL. In some instances a CertificateVerify message is not required even
-     * if the peer has sent a Certificate (e.g. such as in the case of static
-     * DH). In that case the ClientKeyExchange processing will skip the
-     * CertificateVerify state so we should not arrive here.
-     */
-    if (s->session->peer == NULL) {
-        goto end;
-    }
-
-    n = s->method->ssl_get_message(s,
-                                   SSL3_ST_SR_CERT_VRFY_A,
-                                   SSL3_ST_SR_CERT_VRFY_B,
-                                   SSL3_MT_CERTIFICATE_VERIFY,
-                                   SSL3_RT_MAX_PLAIN_LENGTH, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    if (tls_process_cert_verify(s, n) == 0)
-        ret = -1;
-
- end:
-    BIO_free(s->s3->handshake_buffer);
-    s->s3->handshake_buffer = NULL;
-    return ret;
-}
-
-
 enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
 {
     EVP_PKEY *pkey = NULL;
@@ -3202,56 +2421,6 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n)
     return ret;
 }
 
-int ssl3_get_client_certificate(SSL *s)
-{
-    int ok, al;
-    long n;
-
-    n = s->method->ssl_get_message(s,
-                                   SSL3_ST_SR_CERT_A,
-                                   SSL3_ST_SR_CERT_B,
-                                   -1, s->max_cert_list, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
-        if ((s->verify_mode & SSL_VERIFY_PEER) &&
-            (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
-                   SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
-            al = SSL_AD_HANDSHAKE_FAILURE;
-            goto f_err;
-        }
-        /*
-         * If tls asked for a client cert, the client must return a 0 list
-         */
-        if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
-                   SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            goto f_err;
-        }
-        s->s3->tmp.reuse_message = 1;
-        return 1;
-    }
-
-    if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE);
-        goto f_err;
-    }
-
-    if (tls_process_client_certificate(s, n) == 0)
-        goto f_err;
-
-    return 1;
- f_err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    s->state = SSL_ST_ERR;
-    return -1;
-}
-
 enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n)
 {
     int i, al, ret = MSG_PROCESS_ERROR;
@@ -3377,18 +2546,6 @@ enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n)
     return ret;
 }
 
-int ssl3_send_server_certificate(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_CERT_A) {
-        if (tls_construct_server_certificate(s) == 0)
-            return 0;
-        s->state = SSL3_ST_SW_CERT_B;
-    }
-
-    /* SSL3_ST_SW_CERT_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_server_certificate(SSL *s)
 {
     CERT_PKEY *cpk;
@@ -3409,20 +2566,6 @@ int tls_construct_server_certificate(SSL *s)
     return 1;
 }
 
-/* send a new session ticket (not necessarily for a new session) */
-int ssl3_send_newsession_ticket(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
-        if (tls_construct_new_session_ticket(s) == 0)
-            return -1;
-
-        s->state = SSL3_ST_SW_SESSION_TICKET_B;
-    }
-
-    /* SSL3_ST_SW_SESSION_TICKET_B */
-    return ssl_do_write(s);
-}
-
 int tls_construct_new_session_ticket(SSL *s)
 {
     unsigned char *senc = NULL;
@@ -3567,19 +2710,6 @@ int tls_construct_new_session_ticket(SSL *s)
     return 0;
 }
 
-int ssl3_send_cert_status(SSL *s)
-{
-    if (s->state == SSL3_ST_SW_CERT_STATUS_A) {
-        if (tls_construct_cert_status(s) == 0)
-            return -1;
-
-        s->state = SSL3_ST_SW_CERT_STATUS_B;
-    }
-
-    /* SSL3_ST_SW_CERT_STATUS_B */
-    return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
-}
-
 int tls_construct_cert_status(SSL *s)
 {
     unsigned char *p;
@@ -3615,52 +2745,6 @@ int tls_construct_cert_status(SSL *s)
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /*
- * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message.
- * It sets the next_proto member in s if found
- */
-int ssl3_get_next_proto(SSL *s)
-{
-    int ok;
-    long n;
-
-    /*
-     * Clients cannot send a NextProtocol message if we didn't see the
-     * extension in their ClientHello
-     */
-    if (!s->s3->next_proto_neg_seen) {
-        SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
-               SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
-        s->state = SSL_ST_ERR;
-        return -1;
-    }
-
-    /* See the payload format below */
-    n = s->method->ssl_get_message(s,
-                                   SSL3_ST_SR_NEXT_PROTO_A,
-                                   SSL3_ST_SR_NEXT_PROTO_B,
-                                   SSL3_MT_NEXT_PROTO, 514, &ok);
-
-    if (!ok)
-        return ((int)n);
-
-    /*
-     * s->state doesn't reflect whether ChangeCipherSpec has been received in
-     * this handshake, but s->s3->change_cipher_spec does (will be reset by
-     * ssl3_get_finished).
-     */
-    if (!s->s3->change_cipher_spec) {
-        SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
-        statem_set_error(s);
-        return -1;
-    }
-
-    if (tls_process_next_proto(s, n) == 0)
-        return -1;
-
-    return n;
-}
-
-/*
  * tls_process_next_proto reads a Next Protocol Negotiation handshake message.
  * It sets the next_proto member in s if found
  */
index 9ef3bf7..0aef51f 100644 (file)
@@ -217,7 +217,6 @@ int SSL_clear(SSL *s)
 
     s->type = 0;
 
-    s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT);
     statem_clear(s);
 
     s->version = s->method->version;
@@ -2399,7 +2398,7 @@ void SSL_set_accept_state(SSL *s)
 {
     s->server = 1;
     s->shutdown = 0;
-    s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
+    statem_clear(s);
     s->handshake_func = s->method->ssl_accept;
     clear_ciphers(s);
 }
@@ -2408,7 +2407,7 @@ void SSL_set_connect_state(SSL *s)
 {
     s->server = 0;
     s->shutdown = 0;
-    s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
+    statem_clear(s);
     s->handshake_func = s->method->ssl_connect;
     clear_ciphers(s);
 }
@@ -2538,8 +2537,8 @@ SSL *SSL_dup(SSL *s)
     ret->new_session = s->new_session;
     ret->quiet_shutdown = s->quiet_shutdown;
     ret->shutdown = s->shutdown;
-    ret->state = s->state;      /* SSL_dup does not really work at any state,
-                                 * though */
+    ret->statem = s->statem;      /* SSL_dup does not really work at any state,
+                                   * though */
     RECORD_LAYER_dup(&ret->rlayer, &s->rlayer);
     ret->init_num = 0;          /* would have to copy ret->init_buf,
                                  * ret->init_msg, ret->init_num,
@@ -2841,16 +2840,6 @@ void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ ,
     return ssl->info_callback;
 }
 
-int SSL_state(const SSL *ssl)
-{
-    return (ssl->state);
-}
-
-void SSL_set_state(SSL *ssl, int state)
-{
-    ssl->state = state;
-}
-
 void SSL_set_verify_result(SSL *ssl, long arg)
 {
     ssl->verify_result = arg;
index 891030c..aebd3af 100644 (file)
@@ -718,58 +718,6 @@ DECLARE_STACK_OF(SSL_COMP)
 DECLARE_LHASH_OF(SSL_SESSION);
 
 /*
- * The valid handshake states (one for each type message sent and one for each
- * type of message received). There are also two "special" states:
- * TLS = TLS or DTLS state
- * DTLS = DTLS specific state
- * CR/SR = Client Read/Server Read
- * CW/SW = Client Write/Server Write
- *
- * The "special" states are:
- * TLS_ST_BEFORE = No handshake has been initiated yet
- * TLS_ST_OK = A handshake has been successfully completed
- */
-enum HANDSHAKE_STATE {
-    TLS_ST_BEFORE,
-    TLS_ST_OK,
-    DTLS_ST_CR_HELLO_VERIFY_REQUEST,
-    TLS_ST_CR_SRVR_HELLO,
-    TLS_ST_CR_CERT,
-    TLS_ST_CR_CERT_STATUS,
-    TLS_ST_CR_KEY_EXCH,
-    TLS_ST_CR_CERT_REQ,
-    TLS_ST_CR_SRVR_DONE,
-    TLS_ST_CR_SESSION_TICKET,
-    TLS_ST_CR_CHANGE,
-    TLS_ST_CR_FINISHED,
-    TLS_ST_CW_CLNT_HELLO,
-    TLS_ST_CW_CERT,
-    TLS_ST_CW_KEY_EXCH,
-    TLS_ST_CW_CERT_VRFY,
-    TLS_ST_CW_CHANGE,
-    TLS_ST_CW_NEXT_PROTO,
-    TLS_ST_CW_FINISHED,
-    TLS_ST_SW_HELLO_REQ,
-    TLS_ST_SR_CLNT_HELLO,
-    DTLS_ST_SW_HELLO_VERIFY_REQUEST,
-    TLS_ST_SW_SRVR_HELLO,
-    TLS_ST_SW_CERT,
-    TLS_ST_SW_KEY_EXCH,
-    TLS_ST_SW_CERT_REQ,
-    TLS_ST_SW_SRVR_DONE,
-    TLS_ST_SR_CERT,
-    TLS_ST_SR_KEY_EXCH,
-    TLS_ST_SR_CERT_VRFY,
-    TLS_ST_SR_NEXT_PROTO,
-    TLS_ST_SR_CHANGE,
-    TLS_ST_SR_FINISHED,
-    TLS_ST_SW_SESSION_TICKET,
-    TLS_ST_SW_CERT_STATUS,
-    TLS_ST_SW_CHANGE,
-    TLS_ST_SW_FINISHED
-};
-
-/*
  * Valid return codes used for functions performing work prior to or after
  * sending or receiving a message
  */
@@ -842,6 +790,7 @@ struct statem_st {
     enum READ_STATE read_state;
     enum WORK_STATE read_state_work;
     enum HANDSHAKE_STATE hand_state;
+    int in_init;
     int read_state_first_init;
     int use_timer;
 #ifndef OPENSSL_NO_SCTP
@@ -1398,7 +1347,6 @@ typedef struct ssl3_state_st {
 #  endif
         /* used when SSL_ST_FLUSH_DATA is entered */
         int next_state;
-        int reuse_message;
         /* used for certificate requests */
         int cert_req;
         int ctype_num;
@@ -1885,7 +1833,7 @@ const SSL_METHOD *func_name(void)  \
                 ssl3_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
-                ssl3_get_message, \
+                NULL /*TODO: Fix this */, \
                 ssl3_read_bytes, \
                 ssl3_write_bytes, \
                 ssl3_dispatch_alert, \
@@ -1922,7 +1870,7 @@ const SSL_METHOD *func_name(void)  \
                 ssl3_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
-                ssl3_get_message, \
+                NULL /*TODO: Fix this */, \
                 ssl3_read_bytes, \
                 ssl3_write_bytes, \
                 ssl3_dispatch_alert, \
@@ -1960,7 +1908,7 @@ const SSL_METHOD *func_name(void)  \
                 dtls1_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
-                dtls1_get_message, \
+                NULL /*TODO: fix this */, \
                 dtls1_read_bytes, \
                 dtls1_write_app_data_bytes, \
                 dtls1_dispatch_alert, \
@@ -2054,18 +2002,12 @@ __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
 __owur const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
 __owur int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
 void ssl3_init_finished_mac(SSL *s);
-__owur int ssl3_send_server_certificate(SSL *s);
 __owur int tls_construct_server_certificate(SSL *s);
-__owur int ssl3_send_newsession_ticket(SSL *s);
 __owur int tls_construct_new_session_ticket(SSL *s);
-__owur int ssl3_send_cert_status(SSL *s);
-__owur int ssl3_get_change_cipher_spec(SSL *s, int a, int b);
-__owur int ssl3_get_finished(SSL *s, int state_a, int state_b);
 __owur int tls_construct_cert_status(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, long n);
 __owur enum MSG_PROCESS_RETURN tls_process_finished(SSL *s, unsigned long n);
 __owur int ssl3_setup_key_block(SSL *s);
-__owur int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b);
 __owur int tls_construct_change_cipher_spec(SSL *s);
 __owur int dtls_construct_change_cipher_spec(SSL *s);
 __owur int ssl3_change_cipher_state(SSL *s, int which);
@@ -2078,7 +2020,6 @@ __owur int ssl3_get_req_cert_type(SSL *s, unsigned char *p);
 __owur long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 __owur int tls_get_message_header(SSL *s, int *mt);
 __owur int tls_get_message_body(SSL *s, unsigned long *len);
-__owur int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen);
 __owur int tls_construct_finished(SSL *s, const char *sender, int slen);
 __owur enum WORK_STATE tls_finish_handshake(SSL *s, enum WORK_STATE wst);
 __owur enum WORK_STATE dtls_wait_for_dry(SSL *s);
@@ -2103,6 +2044,8 @@ __owur int ssl3_connect(SSL *s);
 void statem_clear(SSL *s);
 void statem_set_renegotiate(SSL *s);
 void statem_set_error(SSL *s);
+int statem_in_error(const SSL *s);
+void statem_set_in_init(SSL *s, int init);
 __owur int statem_app_data_allowed(SSL *s);
 #ifndef OPENSSL_NO_SCTP
 void statem_set_sctp_read_sock(SSL *s, int read_sock);
@@ -2136,7 +2079,6 @@ void dtls1_set_message_header(SSL *s,
 
 __owur int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
 
-__owur int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
 __owur int dtls1_read_failed(SSL *s, int code);
 __owur int dtls1_buffer_message(SSL *s, int ccs);
 __owur int dtls1_retransmit_message(SSL *s, unsigned short seq,
@@ -2192,31 +2134,21 @@ __owur enum MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s,
                                                          unsigned long n);
 
 /* some server-only functions */
-__owur int ssl3_get_client_hello(SSL *s);
-__owur int ssl3_send_server_hello(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, long n);
 __owur enum WORK_STATE tls_post_process_client_hello(SSL *s,
                                                      enum WORK_STATE wst);
 __owur int tls_construct_server_hello(SSL *s);
-__owur int ssl3_send_hello_request(SSL *s);
 __owur int tls_construct_hello_request(SSL *s);
-__owur int ssl3_send_server_key_exchange(SSL *s);
 __owur int dtls_construct_hello_verify_request(SSL *s);
 __owur int tls_construct_server_key_exchange(SSL *s);
-__owur int ssl3_send_certificate_request(SSL *s);
 __owur int tls_construct_certificate_request(SSL *s);
-__owur int ssl3_send_server_done(SSL *s);
 __owur int tls_construct_server_done(SSL *s);
-__owur int ssl3_get_client_certificate(SSL *s);
-__owur int ssl3_get_client_key_exchange(SSL *s);
-__owur int ssl3_get_cert_verify(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, long n);
 __owur enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, long n);
 __owur enum WORK_STATE tls_post_process_client_key_exchange(SSL *s,
     enum WORK_STATE wst);
 __owur enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, long n);
 #  ifndef OPENSSL_NO_NEXTPROTONEG
-__owur int ssl3_get_next_proto(SSL *s);
 __owur enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, long n);
 #  endif
 
@@ -2234,7 +2166,6 @@ void dtls1_clear(SSL *s);
 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg);
 __owur int dtls1_shutdown(SSL *s);
 
-__owur long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 __owur int dtls_get_message(SSL *s, int *mt, unsigned long *len);
 __owur int dtls1_dispatch_alert(SSL *s);
 
index f59553b..d64ea18 100644 (file)
@@ -89,231 +89,107 @@ const char *SSL_state_string_long(const SSL *s)
 {
     const char *str;
 
-    switch (s->state) {
-    case SSL_ST_BEFORE:
+    if (statem_in_error(s)) {
+        return "error";
+    }
+
+    switch (SSL_state(s)) {
+    case TLS_ST_BEFORE:
         str = "before SSL initialization";
         break;
-    case SSL_ST_ACCEPT:
-        str = "before accept initialization";
-        break;
-    case SSL_ST_CONNECT:
-        str = "before connect initialization";
-        break;
-    case SSL_ST_OK:
+    case TLS_ST_OK:
         str = "SSL negotiation finished successfully";
         break;
-    case SSL_ST_RENEGOTIATE:
-        str = "SSL renegotiate ciphers";
-        break;
-    case SSL_ST_BEFORE | SSL_ST_CONNECT:
-        str = "before/connect initialization";
-        break;
-    case SSL_ST_OK | SSL_ST_CONNECT:
-        str = "ok/connect SSL initialization";
-        break;
-    case SSL_ST_BEFORE | SSL_ST_ACCEPT:
-        str = "before/accept initialization";
-        break;
-    case SSL_ST_OK | SSL_ST_ACCEPT:
-        str = "ok/accept SSL initialization";
-        break;
-    case SSL_ST_ERR:
-        str = "error";
-        break;
 
-#ifndef OPENSSL_NO_SSL3
 /* SSLv3 additions */
-    case SSL3_ST_CW_CLNT_HELLO_A:
-        str = "SSLv3 write client hello A";
-        break;
-    case SSL3_ST_CW_CLNT_HELLO_B:
-        str = "SSLv3 write client hello B";
-        break;
-    case SSL3_ST_CR_SRVR_HELLO_A:
-        str = "SSLv3 read server hello A";
-        break;
-    case SSL3_ST_CR_SRVR_HELLO_B:
-        str = "SSLv3 read server hello B";
-        break;
-    case SSL3_ST_CR_CERT_A:
-        str = "SSLv3 read server certificate A";
-        break;
-    case SSL3_ST_CR_CERT_B:
-        str = "SSLv3 read server certificate B";
-        break;
-    case SSL3_ST_CR_KEY_EXCH_A:
-        str = "SSLv3 read server key exchange A";
-        break;
-    case SSL3_ST_CR_KEY_EXCH_B:
-        str = "SSLv3 read server key exchange B";
-        break;
-    case SSL3_ST_CR_CERT_REQ_A:
-        str = "SSLv3 read server certificate request A";
-        break;
-    case SSL3_ST_CR_CERT_REQ_B:
-        str = "SSLv3 read server certificate request B";
-        break;
-    case SSL3_ST_CR_SESSION_TICKET_A:
-        str = "SSLv3 read server session ticket A";
+    case TLS_ST_CW_CLNT_HELLO:
+        str = "SSLv3/TLS write client hello";
         break;
-    case SSL3_ST_CR_SESSION_TICKET_B:
-        str = "SSLv3 read server session ticket B";
+    case TLS_ST_CR_SRVR_HELLO:
+        str = "SSLv3/TLS read server hello";
         break;
-    case SSL3_ST_CR_SRVR_DONE_A:
-        str = "SSLv3 read server done A";
+    case TLS_ST_CR_CERT:
+        str = "SSLv3/TLS read server certificate";
         break;
-    case SSL3_ST_CR_SRVR_DONE_B:
-        str = "SSLv3 read server done B";
+    case TLS_ST_CR_KEY_EXCH:
+        str = "SSLv3/TLS read server key exchange";
         break;
-    case SSL3_ST_CW_CERT_A:
-        str = "SSLv3 write client certificate A";
+    case TLS_ST_CR_CERT_REQ:
+        str = "SSLv3/TLS read server certificate request";
         break;
-    case SSL3_ST_CW_CERT_B:
-        str = "SSLv3 write client certificate B";
+    case TLS_ST_CR_SESSION_TICKET:
+        str = "SSLv3/TLS read server session ticket";
         break;
-    case SSL3_ST_CW_CERT_C:
-        str = "SSLv3 write client certificate C";
+    case TLS_ST_CR_SRVR_DONE:
+        str = "SSLv3/TLS read server done";
         break;
-    case SSL3_ST_CW_CERT_D:
-        str = "SSLv3 write client certificate D";
+    case TLS_ST_CW_CERT:
+        str = "SSLv3/TLS write client certificate";
         break;
-    case SSL3_ST_CW_KEY_EXCH_A:
-        str = "SSLv3 write client key exchange A";
+    case TLS_ST_CW_KEY_EXCH:
+        str = "SSLv3/TLS write client key exchange";
         break;
-    case SSL3_ST_CW_KEY_EXCH_B:
-        str = "SSLv3 write client key exchange B";
-        break;
-    case SSL3_ST_CW_CERT_VRFY_A:
-        str = "SSLv3 write certificate verify A";
-        break;
-    case SSL3_ST_CW_CERT_VRFY_B:
-        str = "SSLv3 write certificate verify B";
+    case TLS_ST_CW_CERT_VRFY:
+        str = "SSLv3/TLS write certificate verify";
         break;
 
-    case SSL3_ST_CW_CHANGE_A:
-    case SSL3_ST_SW_CHANGE_A:
-        str = "SSLv3 write change cipher spec A";
-        break;
-    case SSL3_ST_CW_CHANGE_B:
-    case SSL3_ST_SW_CHANGE_B:
-        str = "SSLv3 write change cipher spec B";
-        break;
-    case SSL3_ST_CW_FINISHED_A:
-    case SSL3_ST_SW_FINISHED_A:
-        str = "SSLv3 write finished A";
-        break;
-    case SSL3_ST_CW_FINISHED_B:
-    case SSL3_ST_SW_FINISHED_B:
-        str = "SSLv3 write finished B";
+    case TLS_ST_CW_CHANGE:
+    case TLS_ST_SW_CHANGE:
+        str = "SSLv3/TLS write change cipher spec";
         break;
-    case SSL3_ST_CR_CHANGE_A:
-    case SSL3_ST_SR_CHANGE_A:
-        str = "SSLv3 read change cipher spec A";
+    case TLS_ST_CW_FINISHED:
+    case TLS_ST_SW_FINISHED:
+        str = "SSLv3/TLS write finished";
         break;
-    case SSL3_ST_CR_CHANGE_B:
-    case SSL3_ST_SR_CHANGE_B:
-        str = "SSLv3 read change cipher spec B";
+    case TLS_ST_CR_CHANGE:
+    case TLS_ST_SR_CHANGE:
+        str = "SSLv3/TLS read change cipher spec";
         break;
-    case SSL3_ST_CR_FINISHED_A:
-    case SSL3_ST_SR_FINISHED_A:
-        str = "SSLv3 read finished A";
-        break;
-    case SSL3_ST_CR_FINISHED_B:
-    case SSL3_ST_SR_FINISHED_B:
-        str = "SSLv3 read finished B";
-        break;
-
-    case SSL3_ST_CW_FLUSH:
-    case SSL3_ST_SW_FLUSH:
-        str = "SSLv3 flush data";
+    case TLS_ST_CR_FINISHED:
+    case TLS_ST_SR_FINISHED:
+        str = "SSLv3/TLS read finished";
         break;
 
-    case SSL3_ST_SR_CLNT_HELLO_A:
-        str = "SSLv3 read client hello A";
-        break;
-    case SSL3_ST_SR_CLNT_HELLO_B:
-        str = "SSLv3 read client hello B";
-        break;
-    case SSL3_ST_SR_CLNT_HELLO_C:
-        str = "SSLv3 read client hello C";
-        break;
-    case SSL3_ST_SW_HELLO_REQ_A:
-        str = "SSLv3 write hello request A";
-        break;
-    case SSL3_ST_SW_HELLO_REQ_B:
-        str = "SSLv3 write hello request B";
-        break;
-    case SSL3_ST_SW_HELLO_REQ_C:
-        str = "SSLv3 write hello request C";
-        break;
-    case SSL3_ST_SW_SRVR_HELLO_A:
-        str = "SSLv3 write server hello A";
-        break;
-    case SSL3_ST_SW_SRVR_HELLO_B:
-        str = "SSLv3 write server hello B";
-        break;
-    case SSL3_ST_SW_CERT_A:
-        str = "SSLv3 write certificate A";
-        break;
-    case SSL3_ST_SW_CERT_B:
-        str = "SSLv3 write certificate B";
-        break;
-    case SSL3_ST_SW_KEY_EXCH_A:
-        str = "SSLv3 write key exchange A";
-        break;
-    case SSL3_ST_SW_KEY_EXCH_B:
-        str = "SSLv3 write key exchange B";
-        break;
-    case SSL3_ST_SW_CERT_REQ_A:
-        str = "SSLv3 write certificate request A";
+    case TLS_ST_SR_CLNT_HELLO:
+        str = "SSLv3/TLS read client hello";
         break;
-    case SSL3_ST_SW_CERT_REQ_B:
-        str = "SSLv3 write certificate request B";
+    case TLS_ST_SW_HELLO_REQ:
+        str = "SSLv3/TLS write hello request";
         break;
-    case SSL3_ST_SW_SESSION_TICKET_A:
-        str = "SSLv3 write session ticket A";
+    case TLS_ST_SW_SRVR_HELLO:
+        str = "SSLv3/TLS write server hello";
         break;
-    case SSL3_ST_SW_SESSION_TICKET_B:
-        str = "SSLv3 write session ticket B";
+    case TLS_ST_SW_CERT:
+        str = "SSLv3/TLS write certificate";
         break;
-    case SSL3_ST_SW_SRVR_DONE_A:
-        str = "SSLv3 write server done A";
+    case TLS_ST_SW_KEY_EXCH:
+        str = "SSLv3/TLS write key exchange";
         break;
-    case SSL3_ST_SW_SRVR_DONE_B:
-        str = "SSLv3 write server done B";
+    case TLS_ST_SW_CERT_REQ:
+        str = "SSLv3/TLS write certificate request";
         break;
-    case SSL3_ST_SR_CERT_A:
-        str = "SSLv3 read client certificate A";
+    case TLS_ST_SW_SESSION_TICKET:
+        str = "SSLv3/TLS write session ticket";
         break;
-    case SSL3_ST_SR_CERT_B:
-        str = "SSLv3 read client certificate B";
+    case TLS_ST_SW_SRVR_DONE:
+        str = "SSLv3/TLS write server done";
         break;
-    case SSL3_ST_SR_KEY_EXCH_A:
-        str = "SSLv3 read client key exchange A";
+    case TLS_ST_SR_CERT:
+        str = "SSLv3/TLS read client certificate";
         break;
-    case SSL3_ST_SR_KEY_EXCH_B:
-        str = "SSLv3 read client key exchange B";
+    case TLS_ST_SR_KEY_EXCH:
+        str = "SSLv3/TLS read client key exchange";
         break;
-    case SSL3_ST_SR_CERT_VRFY_A:
-        str = "SSLv3 read certificate verify A";
+    case TLS_ST_SR_CERT_VRFY:
+        str = "SSLv3/TLS read certificate verify";
         break;
-    case SSL3_ST_SR_CERT_VRFY_B:
-        str = "SSLv3 read certificate verify B";
-        break;
-#endif
 
 /* DTLS */
-    case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
-        str = "DTLS1 read hello verify request A";
-        break;
-    case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
-        str = "DTLS1 read hello verify request B";
-        break;
-    case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
-        str = "DTLS1 write hello verify request A";
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        str = "DTLS1 read hello verify request";
         break;
-    case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
-        str = "DTLS1 write hello verify request B";
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        str = "DTLS1 write hello verify request";
         break;
 
     default:
@@ -328,203 +204,100 @@ const char *SSL_state_string(const SSL *s)
 {
     const char *str;
 
-    switch (s->state) {
-    case SSL_ST_BEFORE:
+    if (statem_in_error(s)) {
+        return "SSLERR";
+    }
+
+    switch (SSL_state(s)) {
+    case TLS_ST_BEFORE:
         str = "PINIT ";
         break;
-    case SSL_ST_ACCEPT:
-        str = "AINIT ";
-        break;
-    case SSL_ST_CONNECT:
-        str = "CINIT ";
-        break;
-    case SSL_ST_OK:
+    case TLS_ST_OK:
         str = "SSLOK ";
         break;
-    case SSL_ST_ERR:
-        str = "SSLERR";
-        break;
 
-#ifndef OPENSSL_NO_SSL3
-/* SSLv3 additions */
-    case SSL3_ST_SW_FLUSH:
-    case SSL3_ST_CW_FLUSH:
-        str = "3FLUSH";
-        break;
-    case SSL3_ST_CW_CLNT_HELLO_A:
-        str = "3WCH_A";
-        break;
-    case SSL3_ST_CW_CLNT_HELLO_B:
-        str = "3WCH_B";
-        break;
-    case SSL3_ST_CR_SRVR_HELLO_A:
-        str = "3RSH_A";
-        break;
-    case SSL3_ST_CR_SRVR_HELLO_B:
-        str = "3RSH_B";
-        break;
-    case SSL3_ST_CR_CERT_A:
-        str = "3RSC_A";
-        break;
-    case SSL3_ST_CR_CERT_B:
-        str = "3RSC_B";
-        break;
-    case SSL3_ST_CR_KEY_EXCH_A:
-        str = "3RSKEA";
-        break;
-    case SSL3_ST_CR_KEY_EXCH_B:
-        str = "3RSKEB";
-        break;
-    case SSL3_ST_CR_CERT_REQ_A:
-        str = "3RCR_A";
-        break;
-    case SSL3_ST_CR_CERT_REQ_B:
-        str = "3RCR_B";
-        break;
-    case SSL3_ST_CR_SRVR_DONE_A:
-        str = "3RSD_A";
+    case TLS_ST_CW_CLNT_HELLO:
+        str = "3WCH";
         break;
-    case SSL3_ST_CR_SRVR_DONE_B:
-        str = "3RSD_B";
+    case TLS_ST_CR_SRVR_HELLO:
+        str = "3RSH";
         break;
-    case SSL3_ST_CW_CERT_A:
-        str = "3WCC_A";
+    case TLS_ST_CR_CERT:
+        str = "3RSC";
         break;
-    case SSL3_ST_CW_CERT_B:
-        str = "3WCC_B";
+    case TLS_ST_CR_KEY_EXCH:
+        str = "3RSKE";
         break;
-    case SSL3_ST_CW_CERT_C:
-        str = "3WCC_C";
+    case TLS_ST_CR_CERT_REQ:
+        str = "3RCR";
         break;
-    case SSL3_ST_CW_CERT_D:
-        str = "3WCC_D";
+    case TLS_ST_CR_SRVR_DONE:
+        str = "3RSD";
         break;
-    case SSL3_ST_CW_KEY_EXCH_A:
-        str = "3WCKEA";
+    case TLS_ST_CW_CERT:
+        str = "3WCC";
         break;
-    case SSL3_ST_CW_KEY_EXCH_B:
-        str = "3WCKEB";
+    case TLS_ST_CW_KEY_EXCH:
+        str = "3WCKE";
         break;
-    case SSL3_ST_CW_CERT_VRFY_A:
-        str = "3WCV_A";
-        break;
-    case SSL3_ST_CW_CERT_VRFY_B:
-        str = "3WCV_B";
+    case TLS_ST_CW_CERT_VRFY:
+        str = "3WCV";
         break;
 
-    case SSL3_ST_SW_CHANGE_A:
-    case SSL3_ST_CW_CHANGE_A:
-        str = "3WCCSA";
-        break;
-    case SSL3_ST_SW_CHANGE_B:
-    case SSL3_ST_CW_CHANGE_B:
-        str = "3WCCSB";
-        break;
-    case SSL3_ST_SW_FINISHED_A:
-    case SSL3_ST_CW_FINISHED_A:
-        str = "3WFINA";
-        break;
-    case SSL3_ST_SW_FINISHED_B:
-    case SSL3_ST_CW_FINISHED_B:
-        str = "3WFINB";
-        break;
-    case SSL3_ST_SR_CHANGE_A:
-    case SSL3_ST_CR_CHANGE_A:
-        str = "3RCCSA";
+    case TLS_ST_SW_CHANGE:
+    case TLS_ST_CW_CHANGE:
+        str = "3WCCS";
         break;
-    case SSL3_ST_SR_CHANGE_B:
-    case SSL3_ST_CR_CHANGE_B:
-        str = "3RCCSB";
+    case TLS_ST_SW_FINISHED:
+    case TLS_ST_CW_FINISHED:
+        str = "3WFIN";
         break;
-    case SSL3_ST_SR_FINISHED_A:
-    case SSL3_ST_CR_FINISHED_A:
-        str = "3RFINA";
+    case TLS_ST_SR_CHANGE:
+    case TLS_ST_CR_CHANGE:
+        str = "3RCCS";
         break;
-    case SSL3_ST_SR_FINISHED_B:
-    case SSL3_ST_CR_FINISHED_B:
-        str = "3RFINB";
+    case TLS_ST_SR_FINISHED:
+    case TLS_ST_CR_FINISHED:
+        str = "3RFIN";
         break;
 
-    case SSL3_ST_SW_HELLO_REQ_A:
-        str = "3WHR_A";
-        break;
-    case SSL3_ST_SW_HELLO_REQ_B:
-        str = "3WHR_B";
-        break;
-    case SSL3_ST_SW_HELLO_REQ_C:
-        str = "3WHR_C";
-        break;
-    case SSL3_ST_SR_CLNT_HELLO_A:
-        str = "3RCH_A";
-        break;
-    case SSL3_ST_SR_CLNT_HELLO_B:
-        str = "3RCH_B";
-        break;
-    case SSL3_ST_SR_CLNT_HELLO_C:
-        str = "3RCH_C";
+    case TLS_ST_SW_HELLO_REQ:
+        str = "3WHR";
         break;
-    case SSL3_ST_SW_SRVR_HELLO_A:
-        str = "3WSH_A";
+    case TLS_ST_SR_CLNT_HELLO:
+        str = "3RCH";
         break;
-    case SSL3_ST_SW_SRVR_HELLO_B:
-        str = "3WSH_B";
+    case TLS_ST_SW_SRVR_HELLO:
+        str = "3WSH";
         break;
-    case SSL3_ST_SW_CERT_A:
-        str = "3WSC_A";
+    case TLS_ST_SW_CERT:
+        str = "3WSC";
         break;
-    case SSL3_ST_SW_CERT_B:
-        str = "3WSC_B";
+    case TLS_ST_SW_KEY_EXCH:
+        str = "3WSKE";
         break;
-    case SSL3_ST_SW_KEY_EXCH_A:
-        str = "3WSKEA";
+    case TLS_ST_SW_CERT_REQ:
+        str = "3WCR";
         break;
-    case SSL3_ST_SW_KEY_EXCH_B:
-        str = "3WSKEB";
+    case TLS_ST_SW_SRVR_DONE:
+        str = "3WSD";
         break;
-    case SSL3_ST_SW_CERT_REQ_A:
-        str = "3WCR_A";
+    case TLS_ST_SR_CERT:
+        str = "3RCC";
         break;
-    case SSL3_ST_SW_CERT_REQ_B:
-        str = "3WCR_B";
+    case TLS_ST_SR_KEY_EXCH:
+        str = "3RCKE";
         break;
-    case SSL3_ST_SW_SRVR_DONE_A:
-        str = "3WSD_A";
+    case TLS_ST_SR_CERT_VRFY:
+        str = "3RCV";
         break;
-    case SSL3_ST_SW_SRVR_DONE_B:
-        str = "3WSD_B";
-        break;
-    case SSL3_ST_SR_CERT_A:
-        str = "3RCC_A";
-        break;
-    case SSL3_ST_SR_CERT_B:
-        str = "3RCC_B";
-        break;
-    case SSL3_ST_SR_KEY_EXCH_A:
-        str = "3RCKEA";
-        break;
-    case SSL3_ST_SR_KEY_EXCH_B:
-        str = "3RCKEB";
-        break;
-    case SSL3_ST_SR_CERT_VRFY_A:
-        str = "3RCV_A";
-        break;
-    case SSL3_ST_SR_CERT_VRFY_B:
-        str = "3RCV_B";
-        break;
-#endif
 
 /* DTLS */
-    case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
-        str = "DRCHVA";
-        break;
-    case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
-        str = "DRCHVB";
-        break;
-    case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
-        str = "DWCHVA";
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        str = "DRCHV";
         break;
-    case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
-        str = "DWCHVB";
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        str = "DWCHV";
         break;
 
     default:
index 2fe3df4..e30eda9 100644 (file)
@@ -130,12 +130,52 @@ static unsigned long server_max_message_size(SSL *s);
 static enum MSG_PROCESS_RETURN server_process_message(SSL *s, unsigned long len);
 static enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst);
 
+
+enum HANDSHAKE_STATE SSL_state(const SSL *ssl)
+{
+    return ssl->statem.hand_state;
+}
+
+void SSL_set_state(SSL *ssl, enum HANDSHAKE_STATE state)
+{
+    /*
+     * This function seems like a really bad idea. Should we remove it
+     * completely?
+     */
+    ssl->statem.hand_state = state;
+}
+
+int SSL_in_init(SSL *s)
+{
+    return s->statem.in_init;
+}
+
+int SSL_is_init_finished(SSL *s)
+{
+    return !(s->statem.in_init) && (s->statem.hand_state == TLS_ST_OK);
+}
+
+int SSL_in_before(SSL *s)
+{
+    /*
+     * Historically being "in before" meant before anything had happened. In the
+     * current code though we remain in the "before" state for a while after we
+     * have started the handshake process (e.g. as a server waiting for the
+     * first message to arrive). There "in before" is taken to mean "in before"
+     * and not started any handshake process yet.
+     */
+    return (s->statem.hand_state == TLS_ST_BEFORE)
+        && (s->statem.state == MSG_FLOW_UNINITED);
+}
+
 /*
  * Clear the state machine state and reset back to MSG_FLOW_UNINITED
  */
 void statem_clear(SSL *s)
 {
     s->statem.state = MSG_FLOW_UNINITED;
+    s->statem.hand_state = TLS_ST_BEFORE;
+    s->statem.in_init = 1;
 }
 
 /*
@@ -153,8 +193,26 @@ void statem_set_renegotiate(SSL *s)
 void statem_set_error(SSL *s)
 {
     s->statem.state = MSG_FLOW_ERROR;
-    /* TODO: This is temporary - remove me */
-    s->state = SSL_ST_ERR;
+}
+
+/*
+ * Discover whether the current connection is in the error state.
+ *
+ * Valid return values are:
+ *   1: Yes
+ *   0: No
+ */
+int statem_in_error(const SSL *s)
+{
+    if (s->statem.state == MSG_FLOW_ERROR)
+        return 1;
+
+    return 0;
+}
+
+void statem_set_in_init(SSL *s, int init)
+{
+    s->statem.in_init = init;
 }
 
 int ssl3_connect(SSL *s) {
@@ -266,12 +324,6 @@ static int state_machine(SSL *s, int server) {
     }
 
     if (st->state == MSG_FLOW_UNINITED || st->state == MSG_FLOW_RENEGOTIATE) {
-        /* TODO: Temporary - fix this */
-        if (server)
-            s->state = SSL_ST_ACCEPT;
-        else
-            s->state = SSL_ST_CONNECT;
-
         if (st->state == MSG_FLOW_UNINITED) {
             st->hand_state = TLS_ST_BEFORE;
         }
@@ -1123,8 +1175,7 @@ static enum WRITE_TRAN client_write_transition(SSL *s)
         case TLS_ST_CW_FINISHED:
             if (s->hit) {
                 st->hand_state = TLS_ST_OK;
-                /* TODO: This needs removing */
-                s->state = SSL_ST_OK;
+                statem_set_in_init(s, 0);
                 return WRITE_TRAN_CONTINUE;
             } else {
                 return WRITE_TRAN_FINISHED;
@@ -1136,8 +1187,7 @@ static enum WRITE_TRAN client_write_transition(SSL *s)
                 return WRITE_TRAN_CONTINUE;
             } else {
                 st->hand_state = TLS_ST_OK;
-                /* TODO: This needs removing */
-                s->state = SSL_ST_OK;
+                statem_set_in_init(s, 0);
                 return WRITE_TRAN_CONTINUE;
             }
 
@@ -1727,8 +1777,7 @@ static enum WRITE_TRAN server_write_transition(SSL *s)
 
         case TLS_ST_SW_HELLO_REQ:
             st->hand_state = TLS_ST_OK;
-            /* TODO: This needs removing */
-            s->state = SSL_ST_OK;
+            statem_set_in_init(s, 0);
             return WRITE_TRAN_CONTINUE;
 
         case TLS_ST_SR_CLNT_HELLO:
@@ -1795,8 +1844,7 @@ static enum WRITE_TRAN server_write_transition(SSL *s)
         case TLS_ST_SR_FINISHED:
             if (s->hit) {
                 st->hand_state = TLS_ST_OK;
-                /* TODO: This needs removing */
-                s->state = SSL_ST_OK;
+                statem_set_in_init(s, 0);
                 return WRITE_TRAN_CONTINUE;
             } else if (s->tlsext_ticket_expected) {
                 st->hand_state = TLS_ST_SW_SESSION_TICKET;
@@ -1818,8 +1866,7 @@ static enum WRITE_TRAN server_write_transition(SSL *s)
                 return WRITE_TRAN_FINISHED;
             }
             st->hand_state = TLS_ST_OK;
-            /* TODO: This needs removing */
-            s->state = SSL_ST_OK;
+            statem_set_in_init(s, 0);
             return WRITE_TRAN_CONTINUE;
 
         default: