From 33b95d8b2c1cf987bb9a258528e8a1f69ae58210 Mon Sep 17 00:00:00 2001 From: jsing Date: Mon, 27 Aug 2018 16:56:46 +0000 Subject: [PATCH] Dedup DTLS header writing code and convert to CBB. There are three versions of the DTLS header writing code, which primarily differ by the fragment offset and fragment length values that differ. Rework dtls1_write_message_header() such that it can be used in all three cases and convert it to CBB in the process. ok inoguchi@ tb@ --- lib/libssl/d1_both.c | 60 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/libssl/d1_both.c b/lib/libssl/d1_both.c index 42f8cbd5370..074702153c8 100644 --- a/lib/libssl/d1_both.c +++ b/lib/libssl/d1_both.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d1_both.c,v 1.52 2017/10/08 16:24:02 jsing Exp $ */ +/* $OpenBSD: d1_both.c,v 1.53 2018/08/27 16:56:46 jsing Exp $ */ /* * DTLS implementation written by Nagendra Modadugu * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. @@ -161,7 +161,8 @@ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len); -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); +static int dtls1_write_message_header(const struct hm_header_st *msg_hdr, + unsigned long frag_off, unsigned long frag_len, unsigned char *p); static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok); @@ -301,8 +302,10 @@ dtls1_do_write(SSL *s, int type) dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH); - dtls1_write_message_header(s, - (unsigned char *)&s->internal->init_buf->data[s->internal->init_off]); + if (!dtls1_write_message_header(&D1I(s)->w_msg_hdr, + D1I(s)->w_msg_hdr.frag_off, D1I(s)->w_msg_hdr.frag_len, + (unsigned char *)&s->internal->init_buf->data[s->internal->init_off])) + return -1; OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); } @@ -348,12 +351,9 @@ dtls1_do_write(SSL *s, int type) * Reconstruct message header is if it * is being sent in single fragment */ - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - s2n (msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_hdr->msg_len, p); - p -= DTLS1_HM_HEADER_LENGTH; + if (!dtls1_write_message_header(msg_hdr, + 0, msg_hdr->msg_len, p)) + return (-1); xlen = ret; } else { p += DTLS1_HM_HEADER_LENGTH; @@ -431,13 +431,9 @@ again: msg_len = msg_hdr->msg_len; /* reconstruct message header */ - *(p++) = msg_hdr->type; - l2n3(msg_len, p); - s2n (msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_len, p); + if (!dtls1_write_message_header(msg_hdr, 0, msg_len, p)) + return -1; - p -= DTLS1_HM_HEADER_LENGTH; msg_len += DTLS1_HM_HEADER_LENGTH; tls1_finish_mac(s, p, msg_len); @@ -1167,19 +1163,33 @@ dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len) msg_hdr->frag_len = frag_len; } -static unsigned char * -dtls1_write_message_header(SSL *s, unsigned char *p) +static int +dtls1_write_message_header(const struct hm_header_st *msg_hdr, + unsigned long frag_off, unsigned long frag_len, unsigned char *p) { - struct hm_header_st *msg_hdr = &D1I(s)->w_msg_hdr; + CBB cbb; - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); + /* We assume DTLS1_HM_HEADER_LENGTH bytes are available for now... */ + if (!CBB_init_fixed(&cbb, p, DTLS1_HM_HEADER_LENGTH)) + return 0; + if (!CBB_add_u8(&cbb, msg_hdr->type)) + goto err; + if (!CBB_add_u24(&cbb, msg_hdr->msg_len)) + goto err; + if (!CBB_add_u16(&cbb, msg_hdr->seq)) + goto err; + if (!CBB_add_u24(&cbb, frag_off)) + goto err; + if (!CBB_add_u24(&cbb, frag_len)) + goto err; + if (!CBB_finish(&cbb, NULL, NULL)) + goto err; - s2n(msg_hdr->seq, p); - l2n3(msg_hdr->frag_off, p); - l2n3(msg_hdr->frag_len, p); + return 1; - return p; + err: + CBB_cleanup(&cbb); + return 0; } unsigned int -- 2.20.1