Remove redundant code
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>
This commit is contained in:
parent
c130dd8ea4
commit
49ae742398
@ -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);
|
||||
|
@ -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);
|
||||
|
150
ssl/d1_both.c
150
ssl/d1_both.c
@ -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
|
||||
|
706
ssl/d1_srvr.c
706
ssl/d1_srvr.c
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
161
ssl/s3_both.c
161
ssl/s3_both.c
@ -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 */
|
||||
|
@ -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++;
|
||||
|
@ -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 {
|
||||
|
916
ssl/s3_srvr.c
916
ssl/s3_srvr.c
@ -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;
|
||||
@ -3614,52 +2744,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
|
||||
|
@ -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;
|
||||
|
@ -717,58 +717,6 @@ struct ssl_comp_st {
|
||||
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);
|
||||
|
||||
|
497
ssl/ssl_stat.c
497
ssl/ssl_stat.c
@ -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";
|
||||
case TLS_ST_CW_CLNT_HELLO:
|
||||
str = "SSLv3/TLS write client hello";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_B:
|
||||
str = "SSLv3 write client hello B";
|
||||
case TLS_ST_CR_SRVR_HELLO:
|
||||
str = "SSLv3/TLS read server hello";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
str = "SSLv3 read server hello A";
|
||||
case TLS_ST_CR_CERT:
|
||||
str = "SSLv3/TLS read server certificate";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
str = "SSLv3 read server hello B";
|
||||
case TLS_ST_CR_KEY_EXCH:
|
||||
str = "SSLv3/TLS read server key exchange";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_A:
|
||||
str = "SSLv3 read server certificate A";
|
||||
case TLS_ST_CR_CERT_REQ:
|
||||
str = "SSLv3/TLS read server certificate request";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_B:
|
||||
str = "SSLv3 read server certificate B";
|
||||
case TLS_ST_CR_SESSION_TICKET:
|
||||
str = "SSLv3/TLS read server session ticket";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_A:
|
||||
str = "SSLv3 read server key exchange A";
|
||||
case TLS_ST_CR_SRVR_DONE:
|
||||
str = "SSLv3/TLS read server done";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_B:
|
||||
str = "SSLv3 read server key exchange B";
|
||||
case TLS_ST_CW_CERT:
|
||||
str = "SSLv3/TLS write client certificate";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_REQ_A:
|
||||
str = "SSLv3 read server certificate request A";
|
||||
case TLS_ST_CW_KEY_EXCH:
|
||||
str = "SSLv3/TLS write client key exchange";
|
||||
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";
|
||||
break;
|
||||
case SSL3_ST_CR_SESSION_TICKET_B:
|
||||
str = "SSLv3 read server session ticket B";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_A:
|
||||
str = "SSLv3 read server done A";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
str = "SSLv3 read server done B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_A:
|
||||
str = "SSLv3 write client certificate A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_B:
|
||||
str = "SSLv3 write client certificate B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_C:
|
||||
str = "SSLv3 write client certificate C";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_D:
|
||||
str = "SSLv3 write client certificate D";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_A:
|
||||
str = "SSLv3 write client key exchange A";
|
||||
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";
|
||||
case TLS_ST_CW_CHANGE:
|
||||
case TLS_ST_SW_CHANGE:
|
||||
str = "SSLv3/TLS write change cipher spec";
|
||||
break;
|
||||
case SSL3_ST_CW_CHANGE_B:
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
str = "SSLv3 write change cipher spec B";
|
||||
case TLS_ST_CW_FINISHED:
|
||||
case TLS_ST_SW_FINISHED:
|
||||
str = "SSLv3/TLS write finished";
|
||||
break;
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
case SSL3_ST_SW_FINISHED_A:
|
||||
str = "SSLv3 write finished A";
|
||||
case TLS_ST_CR_CHANGE:
|
||||
case TLS_ST_SR_CHANGE:
|
||||
str = "SSLv3/TLS read change cipher spec";
|
||||
break;
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
case SSL3_ST_SW_FINISHED_B:
|
||||
str = "SSLv3 write finished B";
|
||||
break;
|
||||
case SSL3_ST_CR_CHANGE_A:
|
||||
case SSL3_ST_SR_CHANGE_A:
|
||||
str = "SSLv3 read change cipher spec A";
|
||||
break;
|
||||
case SSL3_ST_CR_CHANGE_B:
|
||||
case SSL3_ST_SR_CHANGE_B:
|
||||
str = "SSLv3 read change cipher spec B";
|
||||
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";
|
||||
case TLS_ST_CR_FINISHED:
|
||||
case TLS_ST_SR_FINISHED:
|
||||
str = "SSLv3/TLS read finished";
|
||||
break;
|
||||
|
||||
case SSL3_ST_CW_FLUSH:
|
||||
case SSL3_ST_SW_FLUSH:
|
||||
str = "SSLv3 flush data";
|
||||
case TLS_ST_SR_CLNT_HELLO:
|
||||
str = "SSLv3/TLS read client hello";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
str = "SSLv3 read client hello A";
|
||||
case TLS_ST_SW_HELLO_REQ:
|
||||
str = "SSLv3/TLS write hello request";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
str = "SSLv3 read client hello B";
|
||||
case TLS_ST_SW_SRVR_HELLO:
|
||||
str = "SSLv3/TLS write server hello";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
str = "SSLv3 read client hello C";
|
||||
case TLS_ST_SW_CERT:
|
||||
str = "SSLv3/TLS write certificate";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
str = "SSLv3 write hello request A";
|
||||
case TLS_ST_SW_KEY_EXCH:
|
||||
str = "SSLv3/TLS write key exchange";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_B:
|
||||
str = "SSLv3 write hello request B";
|
||||
case TLS_ST_SW_CERT_REQ:
|
||||
str = "SSLv3/TLS write certificate request";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_C:
|
||||
str = "SSLv3 write hello request C";
|
||||
case TLS_ST_SW_SESSION_TICKET:
|
||||
str = "SSLv3/TLS write session ticket";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
str = "SSLv3 write server hello A";
|
||||
case TLS_ST_SW_SRVR_DONE:
|
||||
str = "SSLv3/TLS write server done";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||
str = "SSLv3 write server hello B";
|
||||
case TLS_ST_SR_CERT:
|
||||
str = "SSLv3/TLS read client certificate";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
str = "SSLv3 write certificate A";
|
||||
case TLS_ST_SR_KEY_EXCH:
|
||||
str = "SSLv3/TLS read client key exchange";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
str = "SSLv3 write certificate B";
|
||||
case TLS_ST_SR_CERT_VRFY:
|
||||
str = "SSLv3/TLS read certificate verify";
|
||||
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";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_B:
|
||||
str = "SSLv3 write certificate request B";
|
||||
break;
|
||||
case SSL3_ST_SW_SESSION_TICKET_A:
|
||||
str = "SSLv3 write session ticket A";
|
||||
break;
|
||||
case SSL3_ST_SW_SESSION_TICKET_B:
|
||||
str = "SSLv3 write session ticket B";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_A:
|
||||
str = "SSLv3 write server done A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_B:
|
||||
str = "SSLv3 write server done B";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
str = "SSLv3 read client certificate A";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
str = "SSLv3 read client certificate B";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_A:
|
||||
str = "SSLv3 read client key exchange A";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B:
|
||||
str = "SSLv3 read client key exchange B";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A:
|
||||
str = "SSLv3 read certificate verify A";
|
||||
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";
|
||||
case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
|
||||
str = "DTLS1 read hello verify request";
|
||||
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";
|
||||
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";
|
||||
|
||||
case TLS_ST_CW_CLNT_HELLO:
|
||||
str = "3WCH";
|
||||
break;
|
||||
case TLS_ST_CR_SRVR_HELLO:
|
||||
str = "3RSH";
|
||||
break;
|
||||
case TLS_ST_CR_CERT:
|
||||
str = "3RSC";
|
||||
break;
|
||||
case TLS_ST_CR_KEY_EXCH:
|
||||
str = "3RSKE";
|
||||
break;
|
||||
case TLS_ST_CR_CERT_REQ:
|
||||
str = "3RCR";
|
||||
break;
|
||||
case TLS_ST_CR_SRVR_DONE:
|
||||
str = "3RSD";
|
||||
break;
|
||||
case TLS_ST_CW_CERT:
|
||||
str = "3WCC";
|
||||
break;
|
||||
case TLS_ST_CW_KEY_EXCH:
|
||||
str = "3WCKE";
|
||||
break;
|
||||
case TLS_ST_CW_CERT_VRFY:
|
||||
str = "3WCV";
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
/* SSLv3 additions */
|
||||
case SSL3_ST_SW_FLUSH:
|
||||
case SSL3_ST_CW_FLUSH:
|
||||
str = "3FLUSH";
|
||||
case TLS_ST_SW_CHANGE:
|
||||
case TLS_ST_CW_CHANGE:
|
||||
str = "3WCCS";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_A:
|
||||
str = "3WCH_A";
|
||||
case TLS_ST_SW_FINISHED:
|
||||
case TLS_ST_CW_FINISHED:
|
||||
str = "3WFIN";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_B:
|
||||
str = "3WCH_B";
|
||||
case TLS_ST_SR_CHANGE:
|
||||
case TLS_ST_CR_CHANGE:
|
||||
str = "3RCCS";
|
||||
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";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
str = "3RSD_B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_A:
|
||||
str = "3WCC_A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_B:
|
||||
str = "3WCC_B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_C:
|
||||
str = "3WCC_C";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_D:
|
||||
str = "3WCC_D";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_A:
|
||||
str = "3WCKEA";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_B:
|
||||
str = "3WCKEB";
|
||||
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_SR_FINISHED:
|
||||
case TLS_ST_CR_FINISHED:
|
||||
str = "3RFIN";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
case SSL3_ST_CW_CHANGE_A:
|
||||
str = "3WCCSA";
|
||||
case TLS_ST_SW_HELLO_REQ:
|
||||
str = "3WHR";
|
||||
break;
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
case SSL3_ST_CW_CHANGE_B:
|
||||
str = "3WCCSB";
|
||||
case TLS_ST_SR_CLNT_HELLO:
|
||||
str = "3RCH";
|
||||
break;
|
||||
case SSL3_ST_SW_FINISHED_A:
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
str = "3WFINA";
|
||||
case TLS_ST_SW_SRVR_HELLO:
|
||||
str = "3WSH";
|
||||
break;
|
||||
case SSL3_ST_SW_FINISHED_B:
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
str = "3WFINB";
|
||||
case TLS_ST_SW_CERT:
|
||||
str = "3WSC";
|
||||
break;
|
||||
case SSL3_ST_SR_CHANGE_A:
|
||||
case SSL3_ST_CR_CHANGE_A:
|
||||
str = "3RCCSA";
|
||||
case TLS_ST_SW_KEY_EXCH:
|
||||
str = "3WSKE";
|
||||
break;
|
||||
case SSL3_ST_SR_CHANGE_B:
|
||||
case SSL3_ST_CR_CHANGE_B:
|
||||
str = "3RCCSB";
|
||||
case TLS_ST_SW_CERT_REQ:
|
||||
str = "3WCR";
|
||||
break;
|
||||
case SSL3_ST_SR_FINISHED_A:
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
str = "3RFINA";
|
||||
case TLS_ST_SW_SRVR_DONE:
|
||||
str = "3WSD";
|
||||
break;
|
||||
case SSL3_ST_SR_FINISHED_B:
|
||||
case SSL3_ST_CR_FINISHED_B:
|
||||
str = "3RFINB";
|
||||
case TLS_ST_SR_CERT:
|
||||
str = "3RCC";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
str = "3WHR_A";
|
||||
case TLS_ST_SR_KEY_EXCH:
|
||||
str = "3RCKE";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_B:
|
||||
str = "3WHR_B";
|
||||
case TLS_ST_SR_CERT_VRFY:
|
||||
str = "3RCV";
|
||||
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";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
str = "3WSH_A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||
str = "3WSH_B";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
str = "3WSC_A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
str = "3WSC_B";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_A:
|
||||
str = "3WSKEA";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
str = "3WSKEB";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_A:
|
||||
str = "3WCR_A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_B:
|
||||
str = "3WCR_B";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_A:
|
||||
str = "3WSD_A";
|
||||
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";
|
||||
case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
|
||||
str = "DRCHV";
|
||||
break;
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DRCHVB";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
||||
str = "DWCHVA";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DWCHVB";
|
||||
case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
|
||||
str = "DWCHV";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
83
ssl/statem.c
83
ssl/statem.c
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user