From 7cea05dcc7f6f74a18d48102008d53ea9a42c297 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 29 Sep 2016 23:28:29 +0100 Subject: [PATCH] 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 --- ssl/ssl_locl.h | 3 +- ssl/statem/statem.c | 10 +- ssl/statem/statem_clnt.c | 167 ++++++++++++------------------ ssl/statem/statem_dtls.c | 21 +--- ssl/statem/statem_lib.c | 55 +++------- ssl/statem/statem_locl.h | 39 +++---- 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(&pkt)) { + || !WPACKET_close(pkt) + || !WPACKET_get_length(pkt, &msglen) + || !WPACKET_finish(pkt)) { SSLerr(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST, ERR_R_INTERNAL_ERROR); - WPACKET_cleanup(&pkt); - ossl_statem_set_error(s); return 0; } @@ -1497,20 +1487,18 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) return WORK_ERROR; } -int tls_construct_server_hello(SSL *s) +int tls_construct_server_hello(SSL *s, WPACKET *pkt) { int sl, compm, al = SSL_AD_INTERNAL_ERROR; size_t len; - WPACKET pkt; - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_SERVER_HELLO) - || !WPACKET_put_bytes_u16(&pkt, s->version) + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_SERVER_HELLO) + || !WPACKET_put_bytes_u16(pkt, s->version) /* * Random stuff. Filling of the server_random takes place in * tls_process_client_hello() */ - || !WPACKET_memcpy(&pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { + || !WPACKET_memcpy(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); goto err; } @@ -1552,31 +1540,26 @@ int tls_construct_server_hello(SSL *s) compm = s->s3->tmp.new_compression->id; #endif - if (!WPACKET_sub_memcpy_u8(&pkt, s->session->session_id, sl) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &pkt, &len) - || !WPACKET_put_bytes_u8(&pkt, compm) + if (!WPACKET_sub_memcpy_u8(pkt, s->session->session_id, sl) + || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len) + || !WPACKET_put_bytes_u8(pkt, compm) || !ssl_prepare_serverhello_tlsext(s) - || !ssl_add_serverhello_tlsext(s, &pkt, &al) - || !ssl_close_construct_packet(s, &pkt)) { + || !ssl_add_serverhello_tlsext(s, pkt, &al) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); goto err; } return 1; err: - WPACKET_cleanup(&pkt); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } -int tls_construct_server_done(SSL *s) +int tls_construct_server_done(SSL *s, WPACKET *pkt) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_SERVER_DONE) - || !ssl_close_construct_packet(s, &pkt)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_SERVER_DONE) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_DONE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1588,13 +1571,11 @@ int tls_construct_server_done(SSL *s) return 1; err: - WPACKET_cleanup(&pkt); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } -int tls_construct_server_key_exchange(SSL *s) +int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) { #ifndef OPENSSL_NO_DH EVP_PKEY *pkdh = NULL; @@ -1610,13 +1591,11 @@ int tls_construct_server_key_exchange(SSL *s) unsigned long type; const BIGNUM *r[4]; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); - WPACKET pkt; size_t paramlen, paramoffset; - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_SERVER_KEY_EXCHANGE) - || !WPACKET_get_total_written(&pkt, ¶moffset)) { + || !WPACKET_get_total_written(pkt, ¶moffset)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; } @@ -1786,7 +1765,7 @@ int tls_construct_server_key_exchange(SSL *s) * checked this when we set the identity hint - but just in case */ if (len > PSK_MAX_IDENTITY_LEN - || !WPACKET_sub_memcpy_u16(&pkt, s->cert->psk_identity_hint, + || !WPACKET_sub_memcpy_u16(pkt, s->cert->psk_identity_hint, len)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); @@ -1801,10 +1780,10 @@ int tls_construct_server_key_exchange(SSL *s) #ifndef OPENSSL_NO_SRP if ((i == 2) && (type & SSL_kSRP)) { - res = WPACKET_start_sub_packet_u8(&pkt); + res = WPACKET_start_sub_packet_u8(pkt); } else #endif - res = WPACKET_start_sub_packet_u16(&pkt); + res = WPACKET_start_sub_packet_u16(pkt); if (!res) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, @@ -1822,7 +1801,7 @@ int tls_construct_server_key_exchange(SSL *s) size_t len = BN_num_bytes(r[0]) - BN_num_bytes(r[2]); if (len > 0) { - if (!WPACKET_allocate_bytes(&pkt, len, &binval)) { + if (!WPACKET_allocate_bytes(pkt, len, &binval)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -1831,8 +1810,8 @@ int tls_construct_server_key_exchange(SSL *s) } } #endif - if (!WPACKET_allocate_bytes(&pkt, BN_num_bytes(r[i]), &binval) - || !WPACKET_close(&pkt)) { + if (!WPACKET_allocate_bytes(pkt, BN_num_bytes(r[i]), &binval) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -1849,10 +1828,10 @@ int tls_construct_server_key_exchange(SSL *s) * [1 byte length of encoded point], followed by the actual encoded * point itself */ - if (!WPACKET_put_bytes_u8(&pkt, NAMED_CURVE_TYPE) - || !WPACKET_put_bytes_u8(&pkt, 0) - || !WPACKET_put_bytes_u8(&pkt, curve_id) - || !WPACKET_sub_memcpy_u8(&pkt, encodedPoint, encodedlen)) { + if (!WPACKET_put_bytes_u8(pkt, NAMED_CURVE_TYPE) + || !WPACKET_put_bytes_u8(pkt, 0) + || !WPACKET_put_bytes_u8(pkt, curve_id) + || !WPACKET_sub_memcpy_u8(pkt, encodedPoint, encodedlen)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; @@ -1873,14 +1852,14 @@ int tls_construct_server_key_exchange(SSL *s) unsigned int siglen; /* Get length of the parameters we have written above */ - if (!WPACKET_get_length(&pkt, ¶mlen)) { + if (!WPACKET_get_length(pkt, ¶mlen)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; } /* send signature algorithm */ if (SSL_USE_SIGALGS(s)) { - if (!tls12_get_sigandhash(&pkt, pkey, md)) { + if (!tls12_get_sigandhash(pkt, pkey, md)) { /* Should never happen */ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); @@ -1896,7 +1875,7 @@ int tls_construct_server_key_exchange(SSL *s) * up front, and then properly allocate them in the WPACKET * afterwards. */ - if (!WPACKET_sub_reserve_bytes_u16(&pkt, EVP_PKEY_size(pkey), + if (!WPACKET_sub_reserve_bytes_u16(pkt, EVP_PKEY_size(pkey), &sigbytes1) || EVP_SignInit_ex(md_ctx, md, NULL) <= 0 || EVP_SignUpdate(md_ctx, &(s->s3->client_random[0]), @@ -1906,7 +1885,7 @@ int tls_construct_server_key_exchange(SSL *s) || EVP_SignUpdate(md_ctx, s->init_buf->data + paramoffset, paramlen) <= 0 || EVP_SignFinal(md_ctx, sigbytes1, &siglen, pkey) <= 0 - || !WPACKET_sub_allocate_bytes_u16(&pkt, siglen, &sigbytes2) + || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) || sigbytes1 != sigbytes2) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); @@ -1921,7 +1900,7 @@ int tls_construct_server_key_exchange(SSL *s) } } - if (!ssl_close_construct_packet(s, &pkt)) { + if (!ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto f_err; } @@ -1938,19 +1917,15 @@ int tls_construct_server_key_exchange(SSL *s) OPENSSL_free(encodedPoint); #endif EVP_MD_CTX_free(md_ctx); - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); return 0; } -int tls_construct_certificate_request(SSL *s) +int tls_construct_certificate_request(SSL *s, WPACKET *pkt) { int i, nl; STACK_OF(X509_NAME) *sk = NULL; - WPACKET pkt; - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CERTIFICATE_REQUEST)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; @@ -1958,9 +1933,9 @@ int tls_construct_certificate_request(SSL *s) /* get the list of acceptable cert types */ - if (!WPACKET_start_sub_packet_u8(&pkt) - || !ssl3_get_req_cert_type(s, &pkt) - || !WPACKET_close(&pkt)) { + if (!WPACKET_start_sub_packet_u8(pkt) + || !ssl3_get_req_cert_type(s, pkt) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } @@ -1968,9 +1943,9 @@ int tls_construct_certificate_request(SSL *s) if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; nl = tls12_get_psigalgs(s, &psigs); - if (!WPACKET_start_sub_packet_u16(&pkt) - || !tls12_copy_sigalgs(s, &pkt, psigs, nl) - || !WPACKET_close(&pkt)) { + if (!WPACKET_start_sub_packet_u16(pkt) + || !tls12_copy_sigalgs(s, pkt, psigs, nl) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; @@ -1978,7 +1953,7 @@ int tls_construct_certificate_request(SSL *s) } /* Start sub-packet for client CA list */ - if (!WPACKET_start_sub_packet_u16(&pkt)) { + if (!WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } @@ -1992,7 +1967,7 @@ int tls_construct_certificate_request(SSL *s) if (name == NULL || (namelen = i2d_X509_NAME(name, NULL)) < 0 - || !WPACKET_sub_allocate_bytes_u16(&pkt, namelen, + || !WPACKET_sub_allocate_bytes_u16(pkt, namelen, &namebytes) || i2d_X509_NAME(name, &namebytes) != namelen) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, @@ -2003,8 +1978,8 @@ int tls_construct_certificate_request(SSL *s) } /* else no CA names */ - if (!WPACKET_close(&pkt) - || !ssl_close_construct_packet(s, &pkt)) { + if (!WPACKET_close(pkt) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); goto err; } @@ -2013,9 +1988,7 @@ int tls_construct_certificate_request(SSL *s) return 1; err: - WPACKET_cleanup(&pkt); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } @@ -2931,27 +2904,25 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) return ret; } -int tls_construct_server_certificate(SSL *s) +int tls_construct_server_certificate(SSL *s, WPACKET *pkt) { CERT_PKEY *cpk; cpk = ssl_get_server_send_pkey(s); if (cpk == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } - if (!ssl3_output_cert_chain(s, cpk)) { + if (!ssl3_output_cert_chain(s, pkt, cpk)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - ossl_statem_set_error(s); return 0; } return 1; } -int tls_construct_new_session_ticket(SSL *s) +int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) { unsigned char *senc = NULL; EVP_CIPHER_CTX *ctx = NULL; @@ -2966,7 +2937,6 @@ int tls_construct_new_session_ticket(SSL *s) unsigned char key_name[TLSEXT_KEYNAME_LENGTH]; int iv_len; size_t macoffset, macendoffset; - WPACKET pkt; /* get session encoding length */ slen_full = i2d_SSL_SESSION(s->session, NULL); @@ -2984,8 +2954,7 @@ int tls_construct_new_session_ticket(SSL *s) return 0; } - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_NEWSESSION_TICKET)) { + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_NEWSESSION_TICKET)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; } @@ -3034,9 +3003,9 @@ int tls_construct_new_session_ticket(SSL *s) if (ret == 0) { /* Put timeout and length */ - if (!WPACKET_put_bytes_u32(&pkt, 0) - || !WPACKET_put_bytes_u16(&pkt, 0) - || !ssl_close_construct_packet(s, &pkt)) { + if (!WPACKET_put_bytes_u32(pkt, 0) + || !WPACKET_put_bytes_u16(pkt, 0) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; @@ -3071,35 +3040,35 @@ int tls_construct_new_session_ticket(SSL *s) * for resumed session (for simplicity), and guess that tickets for * new sessions will live as long as their sessions. */ - if (!WPACKET_put_bytes_u32(&pkt, s->hit ? 0 : s->session->timeout) + if (!WPACKET_put_bytes_u32(pkt, s->hit ? 0 : s->session->timeout) /* Now the actual ticket data */ - || !WPACKET_start_sub_packet_u16(&pkt) - || !WPACKET_get_total_written(&pkt, &macoffset) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_get_total_written(pkt, &macoffset) /* Output key name */ - || !WPACKET_memcpy(&pkt, key_name, sizeof(key_name)) + || !WPACKET_memcpy(pkt, key_name, sizeof(key_name)) /* output IV */ - || !WPACKET_memcpy(&pkt, iv, iv_len) - || !WPACKET_reserve_bytes(&pkt, slen + EVP_MAX_BLOCK_LENGTH, + || !WPACKET_memcpy(pkt, iv, iv_len) + || !WPACKET_reserve_bytes(pkt, slen + EVP_MAX_BLOCK_LENGTH, &encdata1) /* Encrypt session data */ || !EVP_EncryptUpdate(ctx, encdata1, &len, senc, slen) - || !WPACKET_allocate_bytes(&pkt, len, &encdata2) + || !WPACKET_allocate_bytes(pkt, len, &encdata2) || encdata1 != encdata2 || !EVP_EncryptFinal(ctx, encdata1 + len, &lenfinal) - || !WPACKET_allocate_bytes(&pkt, lenfinal, &encdata2) + || !WPACKET_allocate_bytes(pkt, lenfinal, &encdata2) || encdata1 + len != encdata2 || len + lenfinal > slen + EVP_MAX_BLOCK_LENGTH - || !WPACKET_get_total_written(&pkt, &macendoffset) + || !WPACKET_get_total_written(pkt, &macendoffset) || !HMAC_Update(hctx, (unsigned char *)s->init_buf->data + macoffset, macendoffset - macoffset) - || !WPACKET_reserve_bytes(&pkt, EVP_MAX_MD_SIZE, &macdata1) + || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &macdata1) || !HMAC_Final(hctx, macdata1, &hlen) || hlen > EVP_MAX_MD_SIZE - || !WPACKET_allocate_bytes(&pkt, hlen, &macdata2) + || !WPACKET_allocate_bytes(pkt, hlen, &macdata2) || macdata1 != macdata2 - || !WPACKET_close(&pkt) - || !ssl_close_construct_packet(s, &pkt)) { + || !WPACKET_close(pkt) + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR); goto err; } @@ -3113,25 +3082,18 @@ int tls_construct_new_session_ticket(SSL *s) EVP_CIPHER_CTX_free(ctx); HMAC_CTX_free(hctx); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); return 0; } -int tls_construct_cert_status(SSL *s) +int tls_construct_cert_status(SSL *s, WPACKET *pkt) { - WPACKET pkt; - - if (!WPACKET_init(&pkt, s->init_buf) - || !ssl_set_handshake_header(s, &pkt, SSL3_MT_CERTIFICATE_STATUS) - || !WPACKET_put_bytes_u8(&pkt, s->tlsext_status_type) - || !WPACKET_sub_memcpy_u24(&pkt, s->tlsext_ocsp_resp, + if (!ssl_set_handshake_header(s, pkt, SSL3_MT_CERTIFICATE_STATUS) + || !WPACKET_put_bytes_u8(pkt, s->tlsext_status_type) + || !WPACKET_sub_memcpy_u24(pkt, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen) - || !ssl_close_construct_packet(s, &pkt)) { + || !ssl_close_construct_packet(s, pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERT_STATUS, ERR_R_INTERNAL_ERROR); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - ossl_statem_set_error(s); - WPACKET_cleanup(&pkt); return 0; } -- 2.25.1