X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_srvr.c;h=f135f9a737303909650296d24efe626d2a79f12b;hp=5f85a8c500c96217025743c49f23df68da3283a4;hb=20dbe585772a18952b730b71cd6722ce62dfe88b;hpb=8ba708e5166b02ab61f2762d36b3e7b7455e9c06 diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 5f85a8c500..f135f9a737 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -151,6 +151,7 @@ #include #include "../ssl_locl.h" +#include "statem_locl.h" #include "internal/constant_time_locl.h" #include #include @@ -169,6 +170,726 @@ static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, STACK_OF(SSL_CIPHER) **skp, int sslv2format, int *al); +/* + * server_read_transition() encapsulates the logic for the allowed handshake + * state transitions when the server is reading messages from the client. The + * message type that the client has sent is provided in |mt|. The current state + * is in |s->statem.hand_state|. + * + * Valid return values are: + * 1: Success (transition allowed) + * 0: Error (transition not allowed) + */ +int server_read_transition(SSL *s, int mt) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_BEFORE: + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + if (mt == SSL3_MT_CLIENT_HELLO) { + st->hand_state = TLS_ST_SR_CLNT_HELLO; + return 1; + } + break; + + case TLS_ST_SW_SRVR_DONE: + /* + * If we get a CKE message after a ServerDone then either + * 1) We didn't request a Certificate + * OR + * 2) If we did request one then + * a) We allow no Certificate to be returned + * AND + * b) We are running SSL3 (in TLS1.0+ the client must return a 0 + * list if we requested a certificate) + */ + if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE + && (!s->s3->tmp.cert_request + || (!((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) + && (s->version == SSL3_VERSION)))) { + st->hand_state = TLS_ST_SR_KEY_EXCH; + return 1; + } else if (s->s3->tmp.cert_request) { + if (mt == SSL3_MT_CERTIFICATE) { + st->hand_state = TLS_ST_SR_CERT; + return 1; + } + } + break; + + case TLS_ST_SR_CERT: + if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE) { + st->hand_state = TLS_ST_SR_KEY_EXCH; + return 1; + } + break; + + case TLS_ST_SR_KEY_EXCH: + /* + * 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 |st->no_cert_verify| should be + * set. + */ + if (s->session->peer == NULL || st->no_cert_verify) { + if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + /* + * 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. + */ + st->hand_state = TLS_ST_SR_CHANGE; + return 1; + } + } else { + if (mt == SSL3_MT_CERTIFICATE_VERIFY) { + st->hand_state = TLS_ST_SR_CERT_VRFY; + return 1; + } + } + break; + + case TLS_ST_SR_CERT_VRFY: + if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + st->hand_state = TLS_ST_SR_CHANGE; + return 1; + } + break; + + case TLS_ST_SR_CHANGE: +#ifndef OPENSSL_NO_NEXTPROTONEG + if (s->s3->next_proto_neg_seen) { + if (mt == SSL3_MT_NEXT_PROTO) { + st->hand_state = TLS_ST_SR_NEXT_PROTO; + return 1; + } + } else { +#endif + if (mt == SSL3_MT_FINISHED) { + st->hand_state = TLS_ST_SR_FINISHED; + return 1; + } +#ifndef OPENSSL_NO_NEXTPROTONEG + } +#endif + break; + +#ifndef OPENSSL_NO_NEXTPROTONEG + case TLS_ST_SR_NEXT_PROTO: + if (mt == SSL3_MT_FINISHED) { + st->hand_state = TLS_ST_SR_FINISHED; + return 1; + } + break; +#endif + + case TLS_ST_SW_FINISHED: + if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + st->hand_state = TLS_ST_SR_CHANGE; + return 1; + } + break; + + default: + break; + } + + /* No valid transition found */ + return 0; +} + +/* + * Should we send a ServerKeyExchange message? + * + * Valid return values are: + * 1: Yes + * 0: No + */ +static inline int send_server_key_exchange(SSL *s) +{ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * only send a ServerKeyExchange if DH, 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 ( (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) + ) + ) + ) + /* + * 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 + ) { + return 1; + } + + return 0; +} + +/* + * Should we send a CertificateRequest message? + * + * Valid return values are: + * 1: Yes + * 0: No + */ +static inline int send_certificate_request(SSL *s) +{ + 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)) { + return 1; + } + + return 0; +} + +/* + * server_write_transition() works out what handshake state to move to next + * when the server is writing messages to be sent to the client. + */ +enum WRITE_TRAN server_write_transition(SSL *s) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_BEFORE: + /* Just go straight to trying to read from the client */; + return WRITE_TRAN_FINISHED; + + case TLS_ST_OK: + /* We must be trying to renegotiate */ + st->hand_state = TLS_ST_SW_HELLO_REQ; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_HELLO_REQ: + st->hand_state = TLS_ST_OK; + ossl_statem_set_in_init(s, 0); + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SR_CLNT_HELLO: + if (SSL_IS_DTLS(s) && !s->d1->cookie_verified + && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) + st->hand_state = DTLS_ST_SW_HELLO_VERIFY_REQUEST; + else + st->hand_state = TLS_ST_SW_SRVR_HELLO; + return WRITE_TRAN_CONTINUE; + + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + return WRITE_TRAN_FINISHED; + + case TLS_ST_SW_SRVR_HELLO: + if (s->hit) { + if (s->tlsext_ticket_expected) + st->hand_state = TLS_ST_SW_SESSION_TICKET; + else + st->hand_state = TLS_ST_SW_CHANGE; + } else { + /* 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))) { + st->hand_state = TLS_ST_SW_CERT; + } else if (send_server_key_exchange(s)) { + st->hand_state = TLS_ST_SW_KEY_EXCH; + } else if (send_certificate_request(s)) { + st->hand_state = TLS_ST_SW_CERT_REQ; + } else { + st->hand_state = TLS_ST_SW_SRVR_DONE; + } + } + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_CERT: + if (s->tlsext_status_expected) { + st->hand_state = TLS_ST_SW_CERT_STATUS; + return WRITE_TRAN_CONTINUE; + } + /* Fall through */ + + case TLS_ST_SW_CERT_STATUS: + if (send_server_key_exchange(s)) { + st->hand_state = TLS_ST_SW_KEY_EXCH; + return WRITE_TRAN_CONTINUE; + } + /* Fall through */ + + case TLS_ST_SW_KEY_EXCH: + if (send_certificate_request(s)) { + st->hand_state = TLS_ST_SW_CERT_REQ; + return WRITE_TRAN_CONTINUE; + } + /* Fall through */ + + case TLS_ST_SW_CERT_REQ: + st->hand_state = TLS_ST_SW_SRVR_DONE; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_SRVR_DONE: + return WRITE_TRAN_FINISHED; + + case TLS_ST_SR_FINISHED: + if (s->hit) { + st->hand_state = TLS_ST_OK; + ossl_statem_set_in_init(s, 0); + return WRITE_TRAN_CONTINUE; + } else if (s->tlsext_ticket_expected) { + st->hand_state = TLS_ST_SW_SESSION_TICKET; + } else { + st->hand_state = TLS_ST_SW_CHANGE; + } + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_SESSION_TICKET: + st->hand_state = TLS_ST_SW_CHANGE; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_CHANGE: + st->hand_state = TLS_ST_SW_FINISHED; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_FINISHED: + if (s->hit) { + return WRITE_TRAN_FINISHED; + } + st->hand_state = TLS_ST_OK; + ossl_statem_set_in_init(s, 0); + return WRITE_TRAN_CONTINUE; + + default: + /* Shouldn't happen */ + return WRITE_TRAN_ERROR; + } +} + +/* + * Perform any pre work that needs to be done prior to sending a message from + * the server to the client. + */ +enum WORK_STATE server_pre_work(SSL *s, enum WORK_STATE wst) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_SW_HELLO_REQ: + s->shutdown = 0; + if (SSL_IS_DTLS(s)) + dtls1_clear_record_buffer(s); + break; + + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + s->shutdown = 0; + if (SSL_IS_DTLS(s)) { + dtls1_clear_record_buffer(s); + /* We don't buffer this message so don't use the timer */ + st->use_timer = 0; + } + break; + + case TLS_ST_SW_SRVR_HELLO: + if (SSL_IS_DTLS(s)) { + /* + * Messages we write from now on should be bufferred and + * retransmitted if necessary, so we need to use the timer now + */ + st->use_timer = 1; + } + break; + + case TLS_ST_SW_SRVR_DONE: +#ifndef OPENSSL_NO_SCTP + if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) + return dtls_wait_for_dry(s); +#endif + return WORK_FINISHED_CONTINUE; + + case TLS_ST_SW_SESSION_TICKET: + if (SSL_IS_DTLS(s)) { + /* + * We're into the last flight. We don't retransmit the last flight + * unless we need to, so we don't use the timer + */ + st->use_timer = 0; + } + break; + + case TLS_ST_SW_CHANGE: + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ossl_statem_set_error(s); + return WORK_ERROR; + } + if (SSL_IS_DTLS(s)) { + /* + * We're into the last flight. We don't retransmit the last flight + * unless we need to, so we don't use the timer. This might have + * already been set to 0 if we sent a NewSessionTicket message, + * but we'll set it again here in case we didn't. + */ + st->use_timer = 0; + } + return WORK_FINISHED_CONTINUE; + + case TLS_ST_OK: + return tls_finish_handshake(s, wst); + + default: + /* No pre work to be done */ + break; + } + + return WORK_FINISHED_CONTINUE; +} + +/* + * Perform any work that needs to be done after sending a message from the + * server to the client. + */ +enum WORK_STATE server_post_work(SSL *s, enum WORK_STATE wst) +{ + OSSL_STATEM *st = &s->statem; + + s->init_num = 0; + + switch(st->hand_state) { + case TLS_ST_SW_HELLO_REQ: + if (statem_flush(s) != 1) + return WORK_MORE_A; + ssl3_init_finished_mac(s); + break; + + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + if (statem_flush(s) != 1) + return WORK_MORE_A; + /* HelloVerifyRequest resets Finished MAC */ + if (s->version != DTLS1_BAD_VER) + ssl3_init_finished_mac(s); + /* + * The next message should be another ClientHello which we need to + * treat like it was the first packet + */ + s->first_packet = 1; + break; + + case TLS_ST_SW_SRVR_HELLO: +#ifndef OPENSSL_NO_SCTP + if (SSL_IS_DTLS(s) && s->hit) { + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; + + /* + * Add new shared key for SCTP-Auth, will be ignored if no + * SCTP used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ossl_statem_set_error(s); + return WORK_ERROR; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); + } +#endif + break; + + case TLS_ST_SW_CHANGE: +#ifndef OPENSSL_NO_SCTP + if (SSL_IS_DTLS(s) && !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 + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) { + ossl_statem_set_error(s); + return WORK_ERROR; + } + + if (SSL_IS_DTLS(s)) + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case TLS_ST_SW_SRVR_DONE: + if (statem_flush(s) != 1) + return WORK_MORE_A; + break; + + case TLS_ST_SW_FINISHED: + if (statem_flush(s) != 1) + return WORK_MORE_A; +#ifndef OPENSSL_NO_SCTP + if (SSL_IS_DTLS(s) && 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 + break; + + default: + /* No post work to be done */ + break; + } + + return WORK_FINISHED_CONTINUE; +} + +/* + * Construct a message to be sent from the server to the client. + * + * Valid return values are: + * 1: Success + * 0: Error + */ +int server_construct_message(SSL *s) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + return dtls_construct_hello_verify_request(s); + + case TLS_ST_SW_HELLO_REQ: + return tls_construct_hello_request(s); + + case TLS_ST_SW_SRVR_HELLO: + return tls_construct_server_hello(s); + + case TLS_ST_SW_CERT: + return tls_construct_server_certificate(s); + + case TLS_ST_SW_KEY_EXCH: + return tls_construct_server_key_exchange(s); + + case TLS_ST_SW_CERT_REQ: + return tls_construct_certificate_request(s); + + case TLS_ST_SW_SRVR_DONE: + return tls_construct_server_done(s); + + case TLS_ST_SW_SESSION_TICKET: + return tls_construct_new_session_ticket(s); + + case TLS_ST_SW_CERT_STATUS: + return tls_construct_cert_status(s); + + case TLS_ST_SW_CHANGE: + if (SSL_IS_DTLS(s)) + return dtls_construct_change_cipher_spec(s); + else + return tls_construct_change_cipher_spec(s); + + case TLS_ST_SW_FINISHED: + return tls_construct_finished(s, + s->method-> + ssl3_enc->server_finished_label, + s->method-> + ssl3_enc->server_finished_label_len); + + default: + /* Shouldn't happen */ + break; + } + + return 0; +} + +#define CLIENT_KEY_EXCH_MAX_LENGTH 2048 +#define NEXT_PROTO_MAX_LENGTH 514 + +/* + * Returns the maximum allowed length for the current message that we are + * reading. Excludes the message header. + */ +unsigned long server_max_message_size(SSL *s) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_SR_CLNT_HELLO: + return SSL3_RT_MAX_PLAIN_LENGTH; + + case TLS_ST_SR_CERT: + return s->max_cert_list; + + case TLS_ST_SR_KEY_EXCH: + return CLIENT_KEY_EXCH_MAX_LENGTH; + + case TLS_ST_SR_CERT_VRFY: + return SSL3_RT_MAX_PLAIN_LENGTH; + +#ifndef OPENSSL_NO_NEXTPROTONEG + case TLS_ST_SR_NEXT_PROTO: + return NEXT_PROTO_MAX_LENGTH; +#endif + + case TLS_ST_SR_CHANGE: + return CCS_MAX_LENGTH; + + case TLS_ST_SR_FINISHED: + return FINISHED_MAX_LENGTH; + + default: + /* Shouldn't happen */ + break; + } + + return 0; +} + +/* + * Process a message that the server has received from the client. + */ +enum MSG_PROCESS_RETURN server_process_message(SSL *s, PACKET *pkt) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_SR_CLNT_HELLO: + return tls_process_client_hello(s, pkt); + + case TLS_ST_SR_CERT: + return tls_process_client_certificate(s, pkt); + + case TLS_ST_SR_KEY_EXCH: + return tls_process_client_key_exchange(s, pkt); + + case TLS_ST_SR_CERT_VRFY: + return tls_process_cert_verify(s, pkt); + +#ifndef OPENSSL_NO_NEXTPROTONEG + case TLS_ST_SR_NEXT_PROTO: + return tls_process_next_proto(s, pkt); +#endif + + case TLS_ST_SR_CHANGE: + return tls_process_change_cipher_spec(s, pkt); + + case TLS_ST_SR_FINISHED: + return tls_process_finished(s, pkt); + + default: + /* Shouldn't happen */ + break; + } + + return MSG_PROCESS_ERROR; +} + +/* + * Perform any further processing required following the receipt of a message + * from the client + */ +enum WORK_STATE server_post_process_message(SSL *s, enum WORK_STATE wst) +{ + OSSL_STATEM *st = &s->statem; + + switch(st->hand_state) { + case TLS_ST_SR_CLNT_HELLO: + return tls_post_process_client_hello(s, wst); + + case TLS_ST_SR_KEY_EXCH: + return tls_post_process_client_key_exchange(s, wst); + + case TLS_ST_SR_CERT_VRFY: +#ifndef OPENSSL_NO_SCTP + if ( /* Is this SCTP? */ + BIO_dgram_is_sctp(SSL_get_wbio(s)) + /* Are we renegotiating? */ + && s->renegotiate + && 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)); + statem_set_sctp_read_sock(s, 1); + return WORK_MORE_A; + } else { + ossl_ossl_statem_set_sctp_read_sock(s, 0); + } +#endif + return WORK_FINISHED_CONTINUE; + + + case TLS_ST_SR_FINISHED: + if (s->hit) + return tls_finish_handshake(s, wst); + else + return WORK_FINISHED_STOP; + default: + break; + } + + /* Shouldn't happen */ + return WORK_ERROR; +} + #ifndef OPENSSL_NO_SRP static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { @@ -197,7 +918,7 @@ int tls_construct_hello_request(SSL *s) { if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -237,7 +958,7 @@ int dtls_construct_hello_verify_request(SSL *s) s->d1->cookie_len > 255) { SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -787,7 +1508,7 @@ enum MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: - statem_set_error(s); + ossl_statem_set_error(s); sk_SSL_CIPHER_free(ciphers); return MSG_PROCESS_ERROR; @@ -889,7 +1610,7 @@ enum WORK_STATE tls_post_process_client_hello(SSL *s, enum WORK_STATE wst) return WORK_FINISHED_STOP; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR; } @@ -940,7 +1661,7 @@ int tls_construct_server_hello(SSL *s) sl = s->session->session_id_length; if (sl > (int)sizeof(s->session->session_id)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } *(p++) = sl; @@ -963,7 +1684,7 @@ int tls_construct_server_hello(SSL *s) if (ssl_prepare_serverhello_tlsext(s) <= 0) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } if ((p = @@ -971,7 +1692,7 @@ int tls_construct_server_hello(SSL *s) &al)) == NULL) { ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -979,7 +1700,7 @@ int tls_construct_server_hello(SSL *s) l = (p - d); if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -990,13 +1711,13 @@ int tls_construct_server_done(SSL *s) { if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_DONE, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } if (!s->s3->tmp.cert_request) { if (!ssl3_digest_cached_records(s, 0)) { - statem_set_error(s); + ossl_statem_set_error(s); } } @@ -1466,7 +2187,7 @@ int tls_construct_server_key_exchange(SSL *s) BN_CTX_free(bn_ctx); #endif EVP_MD_CTX_cleanup(&md_ctx); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -1538,7 +2259,7 @@ int tls_construct_certificate_request(SSL *s) return 1; err: - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -1898,7 +2619,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) goto f_err; } if (dh_clnt) { - s->no_cert_verify = 1; + s->statem.no_cert_verify = 1; return MSG_PROCESS_CONTINUE_PROCESSING; } } else @@ -1976,7 +2697,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } - s->no_cert_verify = 1; + s->statem.no_cert_verify = 1; } else { /* * Get client's public key from encoded point in the @@ -2133,7 +2854,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) /* Check if pubkey from client certificate was used */ if (EVP_PKEY_CTX_ctrl (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) - s->no_cert_verify = 1; + s->statem.no_cert_verify = 1; EVP_PKEY_free(client_pub_pkey); EVP_PKEY_CTX_free(pkey_ctx); @@ -2165,7 +2886,7 @@ enum MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen); s->s3->tmp.psk = NULL; #endif - statem_set_error(s); + ossl_statem_set_error(s); return MSG_PROCESS_ERROR; } @@ -2187,7 +2908,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, if (SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, sizeof(labelbuffer), NULL, 0, 0) <= 0) { - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR;; } @@ -2203,7 +2924,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, /* Are we renegotiating? */ && s->renegotiate /* Are we going to skip the CertificateVerify? */ - && (s->session->peer == NULL || s->no_cert_verify) + && (s->session->peer == NULL || s->statem.no_cert_verify) && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { s->s3->in_read_app_data = 2; s->rwstate = SSL_READING; @@ -2212,11 +2933,11 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, statem_set_sctp_read_sock(s, 1); return WORK_MORE_B; } else { - statem_set_sctp_read_sock(s, 0); + ossl_statem_set_sctp_read_sock(s, 0); } #endif - if (s->no_cert_verify) { + if (s->statem.no_cert_verify) { /* No certificate verify so we no longer need the handshake_buffer */ BIO_free(s->s3->handshake_buffer); return WORK_FINISHED_CONTINUE; @@ -2229,7 +2950,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, if (!s->s3->handshake_buffer) { SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR; } /* @@ -2237,7 +2958,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, * extms we've done this already so this is a no-op */ if (!ssl3_digest_cached_records(s, 1)) { - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR; } } else { @@ -2251,7 +2972,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, * step */ if (!ssl3_digest_cached_records(s, 0)) { - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR; } for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) { @@ -2269,7 +2990,7 @@ enum WORK_STATE tls_post_process_client_key_exchange(SSL *s, dgst_size = EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); if (dgst_size < 0) { - statem_set_error(s); + ossl_statem_set_error(s); return WORK_ERROR; } offset += dgst_size; @@ -2447,7 +3168,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (0) { f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - statem_set_error(s); + ossl_statem_set_error(s); } BIO_free(s->s3->handshake_buffer); s->s3->handshake_buffer = NULL; @@ -2458,7 +3179,7 @@ enum MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) { - int i, al, ret = MSG_PROCESS_ERROR; + int i, al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR; X509 *x = NULL; unsigned long l, llen; const unsigned char *certstart; @@ -2525,7 +3246,6 @@ enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } /* No client certificate so digest cached records */ if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, 0)) { - al = SSL_AD_INTERNAL_ERROR; goto f_err; } } else { @@ -2568,7 +3288,7 @@ enum MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - statem_set_error(s); + ossl_statem_set_error(s); done: X509_free(x); sk_X509_pop_free(sk, X509_free); @@ -2582,13 +3302,13 @@ int tls_construct_server_certificate(SSL *s) cpk = ssl_get_server_send_pkey(s); if (cpk == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } if (!ssl3_output_cert_chain(s, cpk)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -2616,12 +3336,12 @@ int tls_construct_new_session_ticket(SSL *s) * long */ if (slen_full == 0 || slen_full > 0xFF00) { - statem_set_error(s); + ossl_statem_set_error(s); return 0; } senc = OPENSSL_malloc(slen_full); if (!senc) { - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -2735,7 +3455,7 @@ int tls_construct_new_session_ticket(SSL *s) OPENSSL_free(senc); EVP_CIPHER_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&hctx); - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -2749,7 +3469,7 @@ int tls_construct_cert_status(SSL *s) * + (ocsp response) */ if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) { - statem_set_error(s); + ossl_statem_set_error(s); return 0; } @@ -2806,7 +3526,7 @@ enum MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) return MSG_PROCESS_CONTINUE_READING; err: - statem_set_error(s); + ossl_statem_set_error(s); return MSG_PROCESS_ERROR; } #endif