diff options
author | Matt Caswell <matt@openssl.org> | 2016-09-29 23:28:29 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-10-03 16:25:48 +0100 |
commit | 7cea05dcc7f6f74a18d48102008d53ea9a42c297 (patch) | |
tree | 062b75919f3bf53e6e4c69ebd1270f094aae756d /ssl | |
parent | b7c9aa645e4eddf5d198d2b20f1c6a74ab96f98e (diff) |
Move init of the WPACKET into write_state_machine()
Instead of initialising, finishing and cleaning up the WPACKET in every
message construction function, we should do it once in
write_state_machine().
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | ssl/statem/statem.c | 10 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 167 | ||||
-rw-r--r-- | ssl/statem/statem_dtls.c | 21 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 55 | ||||
-rw-r--r-- | ssl/statem/statem_locl.h | 39 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 216 |
7 files changed, 205 insertions, 306 deletions
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index eb29740429..06cf6e6d65 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1879,7 +1879,8 @@ __owur int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, unsigned char *p); __owur int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); void ssl3_free_digest_list(SSL *s); -__owur unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk); +__owur unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, + CERT_PKEY *cpk); __owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *srvr); diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index f00480803c..1ad421b07b 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -708,8 +708,9 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) WRITE_TRAN(*transition) (SSL *s); WORK_STATE(*pre_work) (SSL *s, WORK_STATE wst); WORK_STATE(*post_work) (SSL *s, WORK_STATE wst); - int (*construct_message) (SSL *s); + int (*construct_message) (SSL *s, WPACKET *pkt); void (*cb) (const SSL *ssl, int type, int val) = NULL; + WPACKET pkt; cb = get_callback(s); @@ -764,8 +765,13 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) case WORK_FINISHED_STOP: return SUB_STATE_END_HANDSHAKE; } - if (construct_message(s) == 0) + if (!WPACKET_init(&pkt, s->init_buf) + || !construct_message(s, &pkt) + || !WPACKET_finish(&pkt)) { + WPACKET_cleanup(&pkt); + ossl_statem_set_error(s); return SUB_STATE_ERROR; + } /* Fall through */ diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 02d1b7af89..5614d5afcb 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -510,7 +510,7 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) * 1: Success * 0: Error */ -int ossl_statem_client_construct_message(SSL *s) +int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt) { OSSL_STATEM *st = &s->statem; @@ -520,29 +520,29 @@ int ossl_statem_client_construct_message(SSL *s) return 0; case TLS_ST_CW_CLNT_HELLO: - return tls_construct_client_hello(s); + return tls_construct_client_hello(s, pkt); case TLS_ST_CW_CERT: - return tls_construct_client_certificate(s); + return tls_construct_client_certificate(s, pkt); case TLS_ST_CW_KEY_EXCH: - return tls_construct_client_key_exchange(s); + return tls_construct_client_key_exchange(s, pkt); case TLS_ST_CW_CERT_VRFY: - return tls_construct_client_verify(s); + return tls_construct_client_verify(s, pkt); case TLS_ST_CW_CHANGE: if (SSL_IS_DTLS(s)) - return dtls_construct_change_cipher_spec(s); + return dtls_construct_change_cipher_spec(s, pkt); else - return tls_construct_change_cipher_spec(s); + return tls_construct_change_cipher_spec(s, pkt); #if !defined(OPENSSL_NO_NEXTPROTONEG) case TLS_ST_CW_NEXT_PROTO: - return tls_construct_next_proto(s); + return tls_construct_next_proto(s, pkt); #endif case TLS_ST_CW_FINISHED: - return tls_construct_finished(s, + return tls_construct_finished(s, pkt, s->method-> ssl3_enc->client_finished_label, s->method-> @@ -679,7 +679,7 @@ WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst) } } -int tls_construct_client_hello(SSL *s) +int tls_construct_client_hello(SSL *s, WPACKET *pkt) { unsigned char *p; int i; @@ -689,20 +689,18 @@ int tls_construct_client_hello(SSL *s) SSL_COMP *comp; #endif SSL_SESSION *sess = s->session; - WPACKET pkt; - if (!WPACKET_init(&pkt, s->init_buf) - || !WPACKET_set_max_size(&pkt, SSL3_RT_MAX_PLAIN_LENGTH)) { + if (!WPACKET_set_max_size(pkt, SSL3_RT_MAX_PLAIN_LENGTH)) { /* Should not happen */ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* Work out what SSL/TLS/DTLS version to use */ protverr = ssl_set_client_hello_version(s); if (protverr != 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, protverr); - goto err; + return 0; } if ((sess == NULL) || !ssl_version_supported(s, sess->ssl_version) || @@ -713,7 +711,7 @@ int tls_construct_client_hello(SSL *s) (!sess->session_id_length && !sess->tlsext_tick) || (sess->not_resumable)) { if (!ssl_get_new_session(s, 0)) - goto err; + return 0; } /* else use the pre-loaded session */ @@ -736,12 +734,12 @@ int tls_construct_client_hello(SSL *s) i = 1; if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0) - goto err; + return 0; - if (!ssl_set_handshake_header(s, &pkt, SSL3_MT_CLIENT_HELLO)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CLIENT_HELLO)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /*- @@ -774,10 +772,10 @@ int tls_construct_client_hello(SSL *s) * client_version in client hello and not resetting it to * the negotiated version. */ - if (!WPACKET_put_bytes_u16(&pkt, s->client_version) - || !WPACKET_memcpy(&pkt, s->s3->client_random, SSL3_RANDOM_SIZE)) { + if (!WPACKET_put_bytes_u16(pkt, s->client_version) + || !WPACKET_memcpy(pkt, s->s3->client_random, SSL3_RANDOM_SIZE)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* Session ID */ @@ -786,88 +784,83 @@ int tls_construct_client_hello(SSL *s) else i = s->session->session_id_length; if (i > (int)sizeof(s->session->session_id) - || !WPACKET_start_sub_packet_u8(&pkt) - || (i != 0 && !WPACKET_memcpy(&pkt, s->session->session_id, i)) - || !WPACKET_close(&pkt)) { + || !WPACKET_start_sub_packet_u8(pkt) + || (i != 0 && !WPACKET_memcpy(pkt, s->session->session_id, i)) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* cookie stuff for DTLS */ if (SSL_IS_DTLS(s)) { if (s->d1->cookie_len > sizeof(s->d1->cookie) - || !WPACKET_sub_memcpy_u8(&pkt, s->d1->cookie, + || !WPACKET_sub_memcpy_u8(pkt, s->d1->cookie, s->d1->cookie_len)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } } /* Ciphers supported */ - if (!WPACKET_start_sub_packet_u16(&pkt)) { + if (!WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* ssl_cipher_list_to_bytes() raises SSLerr if appropriate */ - if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &pkt)) - goto err; - if (!WPACKET_close(&pkt)) { + if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), pkt)) + return 0; + if (!WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* COMPRESSION */ - if (!WPACKET_start_sub_packet_u8(&pkt)) { + if (!WPACKET_start_sub_packet_u8(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s) && s->ctx->comp_methods) { int compnum = sk_SSL_COMP_num(s->ctx->comp_methods); for (i = 0; i < compnum; i++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); - if (!WPACKET_put_bytes_u8(&pkt, comp->id)) { + if (!WPACKET_put_bytes_u8(pkt, comp->id)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } } } #endif /* Add the NULL method */ - if (!WPACKET_put_bytes_u8(&pkt, 0) || !WPACKET_close(&pkt)) { + if (!WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } /* TLS extensions */ if (ssl_prepare_clienthello_tlsext(s) <= 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; + return 0; } - if (!WPACKET_start_sub_packet_u16(&pkt) + if (!WPACKET_start_sub_packet_u16(pkt) /* * If extensions are of zero length then we don't even add the * extensions length bytes */ - || !WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) - || !ssl_add_clienthello_tlsext(s, &pkt, &al) - || !WPACKET_close(&pkt)) { + || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) + || !ssl_add_clienthello_tlsext(s, pkt, &al) + || !WPACKET_close(pkt)) { ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } - if (!ssl_close_construct_packet(s, &pkt)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + if (!ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } return 1; - err: - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); - return 0; } MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt) @@ -2457,19 +2450,12 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt, int *al) #endif } -int tls_construct_client_key_exchange(SSL *s) +int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) { unsigned long alg_k; int al = -1; - WPACKET pkt; - if (!WPACKET_init(&pkt, s->init_buf)) { - /* Should not happen */ - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!ssl_set_handshake_header(s, &pkt, SSL3_MT_CLIENT_KEY_EXCHANGE)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CLIENT_KEY_EXCHANGE)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; @@ -2478,23 +2464,23 @@ int tls_construct_client_key_exchange(SSL *s) alg_k = s->s3->tmp.new_cipher->algorithm_mkey; if ((alg_k & SSL_PSK) - && !tls_construct_cke_psk_preamble(s, &pkt, &al)) + && !tls_construct_cke_psk_preamble(s, pkt, &al)) goto err; if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) { - if (!tls_construct_cke_rsa(s, &pkt, &al)) + if (!tls_construct_cke_rsa(s, pkt, &al)) goto err; } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) { - if (!tls_construct_cke_dhe(s, &pkt, &al)) + if (!tls_construct_cke_dhe(s, pkt, &al)) goto err; } else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) { - if (!tls_construct_cke_ecdhe(s, &pkt, &al)) + if (!tls_construct_cke_ecdhe(s, pkt, &al)) goto err; } else if (alg_k & SSL_kGOST) { - if (!tls_construct_cke_gost(s, &pkt, &al)) + if (!tls_construct_cke_gost(s, pkt, &al)) goto err; } else if (alg_k & SSL_kSRP) { - if (!tls_construct_cke_srp(s, &pkt, &al)) + if (!tls_construct_cke_srp(s, pkt, &al)) goto err; } else if (!(alg_k & SSL_kPSK)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); @@ -2502,7 +2488,7 @@ int tls_construct_client_key_exchange(SSL *s) goto err; } - if (!ssl_close_construct_packet(s, &pkt)) { + if (!ssl_close_construct_packet(s, pkt)) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; @@ -2518,8 +2504,6 @@ int tls_construct_client_key_exchange(SSL *s) OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen); s->s3->tmp.psk = NULL; #endif - WPACKET_cleanup(&pkt); - ossl_statem_set_error(s); return 0; } @@ -2588,7 +2572,7 @@ int tls_client_key_exchange_post_work(SSL *s) return 0; } -int tls_construct_client_verify(SSL *s) +int tls_construct_client_verify(SSL *s, WPACKET *pkt) { EVP_PKEY *pkey; const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys]; @@ -2597,15 +2581,8 @@ int tls_construct_client_verify(SSL *s) long hdatalen = 0; void *hdata; unsigned char *sig = NULL; - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf)) { - /* Should not happen */ - SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - if (!ssl_set_handshake_header(s, &pkt, SSL3_MT_CERTIFICATE_VERIFY)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CERTIFICATE_VERIFY)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } @@ -2622,7 +2599,7 @@ int tls_construct_client_verify(SSL *s) SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } - if (SSL_USE_SIGALGS(s)&& !tls12_get_sigandhash(&pkt, pkey, md)) { + if (SSL_USE_SIGALGS(s)&& !tls12_get_sigandhash(pkt, pkey, md)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } @@ -2654,7 +2631,7 @@ int tls_construct_client_verify(SSL *s) } #endif - if (!WPACKET_sub_memcpy_u16(&pkt, sig, u)) { + if (!WPACKET_sub_memcpy_u16(pkt, sig, u)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } @@ -2663,7 +2640,7 @@ int tls_construct_client_verify(SSL *s) if (!ssl3_digest_cached_records(s, 0)) goto err; - if (!ssl_close_construct_packet(s, &pkt)) { + if (!ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } @@ -2672,7 +2649,6 @@ int tls_construct_client_verify(SSL *s) EVP_MD_CTX_free(mctx); return 1; err: - WPACKET_cleanup(&pkt); OPENSSL_free(sig); EVP_MD_CTX_free(mctx); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); @@ -2776,14 +2752,13 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) return WORK_ERROR; } -int tls_construct_client_certificate(SSL *s) +int tls_construct_client_certificate(SSL *s, WPACKET *pkt) { - if (!ssl3_output_cert_chain(s, + if (!ssl3_output_cert_chain(s, pkt, (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } @@ -2866,19 +2841,12 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_next_proto(SSL *s) +int tls_construct_next_proto(SSL *s, WPACKET *pkt) { size_t len, padding_len; unsigned char *padding = NULL; - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf)) { - /* Should not happen */ - SSLerr(SSL_F_TLS_CONSTRUCT_NEXT_PROTO, ERR_R_INTERNAL_ERROR); - goto err; - } - if (!ssl_set_handshake_header(s, &pkt, SSL3_MT_NEXT_PROTO)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_NEXT_PROTO)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEXT_PROTO, ERR_R_INTERNAL_ERROR); goto err; } @@ -2886,22 +2854,21 @@ int tls_construct_next_proto(SSL *s) len = s->next_proto_negotiated_len; padding_len = 32 - ((len + 2) % 32); - if (!WPACKET_sub_memcpy_u8(&pkt, s->next_proto_negotiated, len) - || !WPACKET_sub_allocate_bytes_u8(&pkt, padding_len, &padding)) { + if (!WPACKET_sub_memcpy_u8(pkt, s->next_proto_negotiated, len) + || !WPACKET_sub_allocate_bytes_u8(pkt, padding_len, &padding)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEXT_PROTO, ERR_R_INTERNAL_ERROR); goto err; } memset(padding, 0, padding_len); - if (!ssl_close_construct_packet(s, &pkt)) { + if (!ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEXT_PROTO, ERR_R_INTERNAL_ERROR); goto err; } return 1; err: - WPACKET_cleanup(&pkt); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; } diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 0328ab7def..cc016dac25 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -872,12 +872,9 @@ static int dtls_get_reassembled_message(SSL *s, long *len) * ssl->session->read_compression assign * ssl->session->read_hash assign */ -int dtls_construct_change_cipher_spec(SSL *s) +int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf) - || !WPACKET_put_bytes_u8(&pkt, SSL3_MT_CCS)) { + if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); goto err; } @@ -888,7 +885,7 @@ int dtls_construct_change_cipher_spec(SSL *s) if (s->version == DTLS1_BAD_VER) { s->d1->next_handshake_write_seq++; - if (!WPACKET_put_bytes_u16(&pkt, s->d1->handshake_write_seq)) { + if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) { SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); goto err; } @@ -896,11 +893,6 @@ int dtls_construct_change_cipher_spec(SSL *s) s->init_num += 2; } - if (!WPACKET_finish(&pkt)) { - SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); - goto err; - } - s->init_off = 0; dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, @@ -913,11 +905,9 @@ int dtls_construct_change_cipher_spec(SSL *s) } return 1; + err: - WPACKET_cleanup(&pkt); - ossl_statem_set_error(s); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return 0; } @@ -1235,8 +1225,7 @@ int dtls1_close_construct_packet(SSL *s, WPACKET *pkt) if (!WPACKET_close(pkt) || !WPACKET_get_length(pkt, &msglen) - || msglen > INT_MAX - || !WPACKET_finish(pkt)) + || msglen > INT_MAX) return 0; s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH; s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index da26ef8c16..a6b1f6beb9 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -63,8 +63,7 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt) if (!WPACKET_close(pkt) || !WPACKET_get_length(pkt, &msglen) - || msglen > INT_MAX - || !WPACKET_finish(pkt)) + || msglen > INT_MAX) return 0; s->init_num = (int)msglen; s->init_off = 0; @@ -72,13 +71,11 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt) return 1; } -int tls_construct_finished(SSL *s, const char *sender, int slen) +int tls_construct_finished(SSL *s, WPACKET *pkt, const char *sender, int slen) { int i; - WPACKET pkt; - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_FINISHED)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_FINISHED)) { SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); goto err; } @@ -93,7 +90,7 @@ int tls_construct_finished(SSL *s, const char *sender, int slen) s->s3->tmp.finish_md_len = i; - if (!WPACKET_memcpy(&pkt, s->s3->tmp.finish_md, i)) { + if (!WPACKET_memcpy(pkt, s->s3->tmp.finish_md, i)) { SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); goto err; } @@ -111,15 +108,13 @@ int tls_construct_finished(SSL *s, const char *sender, int slen) s->s3->previous_server_finished_len = i; } - if (!ssl_close_construct_packet(s, &pkt)) { + if (!ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); goto err; } return 1; err: - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; } @@ -267,15 +262,9 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -int tls_construct_change_cipher_spec(SSL *s) +int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf) - || !WPACKET_put_bytes_u8(&pkt, SSL3_MT_CCS) - || !WPACKET_finish(&pkt)) { - WPACKET_cleanup(&pkt); - ossl_statem_set_error(s); + if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { SSLerr(SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; @@ -287,33 +276,17 @@ int tls_construct_change_cipher_spec(SSL *s) return 1; } -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) +unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf)) { - /* Should not happen */ + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CERTIFICATE) + || !WPACKET_start_sub_packet_u24(pkt) + || !ssl_add_cert_chain(s, pkt, cpk) + || !WPACKET_close(pkt) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!ssl_set_handshake_header(s, &pkt, SSL3_MT_CERTIFICATE) - || !WPACKET_start_sub_packet_u24(&pkt)) { - SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!ssl_add_cert_chain(s, &pkt, cpk)) - goto err; - - if (!WPACKET_close(&pkt) || !ssl_close_construct_packet(s, &pkt)) { - SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR); - goto err; + return 0; } return 1; - err: - WPACKET_cleanup(&pkt); - return 0; } WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst) diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index a46e6c7971..8d6dd2a042 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -50,7 +50,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt); WRITE_TRAN ossl_statem_client_write_transition(SSL *s); WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst); WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst); -int ossl_statem_client_construct_message(SSL *s); +int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt); unsigned long ossl_statem_client_max_message_size(SSL *s); MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt); WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst); @@ -62,7 +62,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt); WRITE_TRAN ossl_statem_server_write_transition(SSL *s); WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst); WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst); -int ossl_statem_server_construct_message(SSL *s); +int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt); unsigned long ossl_statem_server_max_message_size(SSL *s); MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt); WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst); @@ -75,45 +75,46 @@ __owur int dtls_get_message(SSL *s, int *mt, unsigned long *len); /* Message construction and processing functions */ __owur MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt); -__owur int tls_construct_change_cipher_spec(SSL *s); -__owur int dtls_construct_change_cipher_spec(SSL *s); +__owur int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt); +__owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt); -__owur int tls_construct_finished(SSL *s, const char *sender, int slen); +__owur int tls_construct_finished(SSL *s, WPACKET *pkt, const char *sender, + int slen); __owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst); __owur WORK_STATE dtls_wait_for_dry(SSL *s); /* some client-only functions */ -__owur int tls_construct_client_hello(SSL *s); +__owur int tls_construct_client_hello(SSL *s, WPACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt); -__owur int tls_construct_client_verify(SSL *s); +__owur int tls_construct_client_verify(SSL *s, WPACKET *pkt); __owur WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst); -__owur int tls_construct_client_certificate(SSL *s); +__owur int tls_construct_client_certificate(SSL *s, WPACKET *pkt); __owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); -__owur int tls_construct_client_key_exchange(SSL *s); +__owur int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt); __owur int tls_client_key_exchange_post_work(SSL *s); -__owur int tls_construct_cert_status(SSL *s); +__owur int tls_construct_cert_status(SSL *s, WPACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt); __owur int ssl3_check_cert_and_algorithm(SSL *s); #ifndef OPENSSL_NO_NEXTPROTONEG -__owur int tls_construct_next_proto(SSL *s); +__owur int tls_construct_next_proto(SSL *s, WPACKET *pkt); #endif __owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt); /* some server-only functions */ __owur MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt); __owur WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst); -__owur int tls_construct_server_hello(SSL *s); -__owur int tls_construct_hello_request(SSL *s); -__owur int dtls_construct_hello_verify_request(SSL *s); -__owur int tls_construct_server_certificate(SSL *s); -__owur int tls_construct_server_key_exchange(SSL *s); -__owur int tls_construct_certificate_request(SSL *s); -__owur int tls_construct_server_done(SSL *s); +__owur int tls_construct_server_hello(SSL *s, WPACKET *pkt); +__owur int tls_construct_hello_request(SSL *s, WPACKET *pkt); +__owur int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt); +__owur int tls_construct_server_certificate(SSL *s, WPACKET *pkt); +__owur int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt); +__owur int tls_construct_certificate_request(SSL *s, WPACKET *pkt); +__owur int tls_construct_server_done(SSL *s, WPACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt); __owur WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst); @@ -121,4 +122,4 @@ __owur MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt); #ifndef OPENSSL_NO_NEXTPROTONEG __owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); #endif -__owur int tls_construct_new_session_ticket(SSL *s); +__owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index cc737ba846..17dc9cbf5d 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -619,7 +619,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) * 1: Success * 0: Error */ -int ossl_statem_server_construct_message(SSL *s) +int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt) { OSSL_STATEM *st = &s->statem; @@ -629,40 +629,40 @@ int ossl_statem_server_construct_message(SSL *s) return 0; case DTLS_ST_SW_HELLO_VERIFY_REQUEST: - return dtls_construct_hello_verify_request(s); + return dtls_construct_hello_verify_request(s, pkt); case TLS_ST_SW_HELLO_REQ: - return tls_construct_hello_request(s); + return tls_construct_hello_request(s, pkt); case TLS_ST_SW_SRVR_HELLO: - return tls_construct_server_hello(s); + return tls_construct_server_hello(s, pkt); case TLS_ST_SW_CERT: - return tls_construct_server_certificate(s); + return tls_construct_server_certificate(s, pkt); case TLS_ST_SW_KEY_EXCH: - return tls_construct_server_key_exchange(s); + return tls_construct_server_key_exchange(s, pkt); case TLS_ST_SW_CERT_REQ: - return tls_construct_certificate_request(s); + return tls_construct_certificate_request(s, pkt); case TLS_ST_SW_SRVR_DONE: - return tls_construct_server_done(s); + return tls_construct_server_done(s, pkt); case TLS_ST_SW_SESSION_TICKET: - return tls_construct_new_session_ticket(s); + return tls_construct_new_session_ticket(s, pkt); case TLS_ST_SW_CERT_STATUS: - return tls_construct_cert_status(s); + return tls_construct_cert_status(s, pkt); case TLS_ST_SW_CHANGE: if (SSL_IS_DTLS(s)) - return dtls_construct_change_cipher_spec(s); + return dtls_construct_change_cipher_spec(s, pkt); else - return tls_construct_change_cipher_spec(s); + return tls_construct_change_cipher_spec(s, pkt); case TLS_ST_SW_FINISHED: - return tls_construct_finished(s, + return tls_construct_finished(s, pkt, s->method-> ssl3_enc->server_finished_label, s->method-> @@ -829,16 +829,11 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) } #endif -int tls_construct_hello_request(SSL *s) +int tls_construct_hello_request(SSL *s, WPACKET *pkt) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_HELLO_REQUEST) - || !ssl_close_construct_packet(s, &pkt)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_HELLO_REQUEST) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST, ERR_R_INTERNAL_ERROR); - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); return 0; } @@ -856,10 +851,9 @@ int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, return 1; } -int dtls_construct_hello_verify_request(SSL *s) +int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt) { size_t msglen; - WPACKET pkt; if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, s->d1->cookie, @@ -867,25 +861,21 @@ int dtls_construct_hello_verify_request(SSL *s) s->d1->cookie_len > 255) { SSLerr(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); - ossl_statem_set_error(s); return 0; } - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, + if (!ssl_set_handshake_header(s, pkt, DTLS1_MT_HELLO_VERIFY_REQUEST) - || !dtls_raw_hello_verify_request(&pkt, s->d1->cookie, + || !dtls_raw_hello_verify_request(pkt, s->d1->cookie, s->d1->cookie_len) /* * We don't call close_construct_packet() because we don't want * to buffer this message */ - || !WPACKET_close(&pkt) - || !WPACKET_get_length(&pkt, &msglen) - || !WPACKET_finish(& |