diff --git a/ssl/packet.c b/ssl/packet.c index d4f964922d..db301a47f6 100644 --- a/ssl/packet.c +++ b/ssl/packet.c @@ -300,6 +300,20 @@ int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len) return 1; } +/* + * Copy |len| bytes of data from |*src| into the WPACKET and prefix with its + * length (consuming |lenbytes| of data for the length) + */ +int WPACKET_sub_memcpy(WPACKET *pkt, const void *src, size_t len, size_t lenbytes) +{ + if (!WPACKET_start_sub_packet_len(pkt, lenbytes) + || !WPACKET_memcpy(pkt, src, len) + || !WPACKET_close(pkt)) + return 0; + + return 1; +} + /* * Return the total number of bytes written so far to the underlying buffer. * This might includes bytes written by a parent WPACKET. diff --git a/ssl/packet_locl.h b/ssl/packet_locl.h index 5ec5b045f1..65ab15a8d9 100644 --- a/ssl/packet_locl.h +++ b/ssl/packet_locl.h @@ -617,6 +617,8 @@ int WPACKET_allocate_bytes(WPACKET *pkt, size_t bytes, int WPACKET_put_bytes(WPACKET *pkt, unsigned int val, size_t bytes); int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize); int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len); +int WPACKET_sub_memcpy(WPACKET *pkt, const void *src, size_t len, + size_t lenbytes); int WPACKET_get_total_written(WPACKET *pkt, size_t *written); int WPACKET_get_length(WPACKET *pkt, size_t *len); diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index cba0ece62f..b6895f5762 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -804,9 +804,8 @@ int tls_construct_client_hello(SSL *s) /* cookie stuff for DTLS */ if (SSL_IS_DTLS(s)) { if (s->d1->cookie_len > sizeof(s->d1->cookie) - || !WPACKET_start_sub_packet_len(&pkt, 1) - || !WPACKET_memcpy(&pkt, s->d1->cookie, s->d1->cookie_len) - || !WPACKET_close(&pkt)) { + || !WPACKET_sub_memcpy(&pkt, s->d1->cookie, s->d1->cookie_len, + 1)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 41a5035094..d6bc63ae48 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1040,10 +1040,8 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) /* Add RI if renegotiating */ if (s->renegotiate) { if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_renegotiate, 2) - || !WPACKET_start_sub_packet_len(pkt, 2) - || !WPACKET_memcpy(pkt, s->s3->previous_client_finished, - s->s3->previous_client_finished_len) - || !WPACKET_close(pkt)) { + || !WPACKET_sub_memcpy(pkt, s->s3->previous_client_finished, + s->s3->previous_client_finished_len, 2)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return 0; } @@ -1060,11 +1058,8 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) /* Sub-packet for servername list (always 1 hostname)*/ || !WPACKET_start_sub_packet_len(pkt, 2) || !WPACKET_put_bytes(pkt, TLSEXT_NAMETYPE_host_name, 1) - /* Sub-packet for a single hostname host name */ - || !WPACKET_start_sub_packet_len(pkt, 2) - || !WPACKET_memcpy(pkt, s->tlsext_hostname, - strlen(s->tlsext_hostname)) - || !WPACKET_close(pkt) + || !WPACKET_sub_memcpy(pkt, s->tlsext_hostname, + strlen(s->tlsext_hostname), 2) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); @@ -1105,9 +1100,7 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_ec_point_formats, 2) /* Sub-packet for formats extension */ || !WPACKET_start_sub_packet_len(pkt, 2) - || !WPACKET_start_sub_packet_len(pkt, 1) - || !WPACKET_memcpy(pkt, pformats, num_formats) - || !WPACKET_close(pkt) + || !WPACKET_sub_memcpy(pkt, pformats, num_formats, 1) || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return 0; @@ -1169,10 +1162,8 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) goto skip_ext; if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_session_ticket, 2) - /* Sub-packet for ticket extension */ - || !WPACKET_start_sub_packet_len(pkt, 2) - || !WPACKET_memcpy(pkt, s->session->tlsext_tick, ticklen) - || !WPACKET_close(pkt)) { + || !WPACKET_sub_memcpy(pkt, s->session->tlsext_tick, ticklen, + 2)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return 0; } @@ -1302,11 +1293,8 @@ int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) TLSEXT_TYPE_application_layer_protocol_negotiation, 2) /* Sub-packet ALPN extension */ || !WPACKET_start_sub_packet_len(pkt, 2) - /* Sub-packet for ALPN proto list */ - || !WPACKET_start_sub_packet_len(pkt, 2) - || !WPACKET_memcpy(pkt, s->alpn_client_proto_list, - s->alpn_client_proto_list_len) - || !WPACKET_close(pkt) + || !WPACKET_sub_memcpy(pkt, s->alpn_client_proto_list, + s->alpn_client_proto_list_len, 2) || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return 0;