summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2026-04-29 15:13:27 +0000
committerjsing <>2026-04-29 15:13:27 +0000
commitda79a6865de1c92d2576eff815dc5db434d73075 (patch)
tree8df5765d32585b0f15c4cf73ffb99f2260fe1ae3
parentdc2d3a2e58818a1cd2370eb926859e774cda4863 (diff)
downloadopenbsd-da79a6865de1c92d2576eff815dc5db434d73075.tar.gz
openbsd-da79a6865de1c92d2576eff815dc5db434d73075.tar.bz2
openbsd-da79a6865de1c92d2576eff815dc5db434d73075.zip
Split dtls1_do_write() into handshake message and CCS handling.
dtls1_do_write() is currently a single function that handles both handshake messages and CCS. This is a strange mix that only serves to complicate the code - handshake messages have their own headers and may need to be fragmented, while CCS must be sent verbatim (and only contain a single byte). Pull the CCS part out into a separate function, simplifying the code. By definition, when sending a CCS message the MTU will already be set appropriately. ok kenjiro@ tb@
-rw-r--r--src/lib/libssl/d1_both.c92
1 files changed, 59 insertions, 33 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index 6554b0a9b8..2632d100e1 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: d1_both.c,v 1.90 2026/04/29 15:04:15 jsing Exp $ */ 1/* $OpenBSD: d1_both.c,v 1.91 2026/04/29 15:13:27 jsing Exp $ */
2/* 2/*
3 * DTLS implementation written by Nagendra Modadugu 3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -204,9 +204,8 @@ dtls1_hm_fragment_free(hm_fragment *frag)
204 free(frag); 204 free(frag);
205} 205}
206 206
207/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ 207static int
208int 208dtls1_do_write_handshake_message(SSL *s)
209dtls1_do_write(SSL *s, int type)
210{ 209{
211 int ret; 210 int ret;
212 int curr_mtu; 211 int curr_mtu;
@@ -235,7 +234,7 @@ dtls1_do_write(SSL *s, int type)
235 OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); 234 OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());
236 /* should have something reasonable now */ 235 /* should have something reasonable now */
237 236
238 if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) 237 if (s->init_off == 0)
239 OPENSSL_assert(s->init_num == 238 OPENSSL_assert(s->init_num ==
240 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); 239 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
241 240
@@ -243,7 +242,7 @@ dtls1_do_write(SSL *s, int type)
243 return -1; 242 return -1;
244 243
245 frag_off = 0; 244 frag_off = 0;
246 while (s->init_num) { 245 while (s->init_num > 0) {
247 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 246 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
248 DTLS1_RT_HEADER_LENGTH - overhead; 247 DTLS1_RT_HEADER_LENGTH - overhead;
249 248
@@ -261,31 +260,28 @@ dtls1_do_write(SSL *s, int type)
261 else 260 else
262 len = s->init_num; 261 len = s->init_num;
263 262
264 /* XDTLS: this function is too long. split out the CCS part */ 263 if (s->init_off != 0) {
265 if (type == SSL3_RT_HANDSHAKE) { 264 OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
266 if (s->init_off != 0) { 265 s->init_off -= DTLS1_HM_HEADER_LENGTH;
267 OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); 266 s->init_num += DTLS1_HM_HEADER_LENGTH;
268 s->init_off -= DTLS1_HM_HEADER_LENGTH;
269 s->init_num += DTLS1_HM_HEADER_LENGTH;
270
271 if (s->init_num > curr_mtu)
272 len = curr_mtu;
273 else
274 len = s->init_num;
275 }
276 267
277 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); 268 if (s->init_num > curr_mtu)
269 len = curr_mtu;
270 else
271 len = s->init_num;
272 }
278 273
279 s->d1->w_msg_hdr.frag_off = frag_off; 274 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
280 s->d1->w_msg_hdr.frag_len = len - DTLS1_HM_HEADER_LENGTH;
281 275
282 if (!dtls1_write_message_header(&s->d1->w_msg_hdr, 276 s->d1->w_msg_hdr.frag_off = frag_off;
283 s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len, 277 s->d1->w_msg_hdr.frag_len = len - DTLS1_HM_HEADER_LENGTH;
284 (unsigned char *)&s->init_buf->data[s->init_off])) 278
285 return -1; 279 if (!dtls1_write_message_header(&s->d1->w_msg_hdr,
286 } 280 s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len,
281 (unsigned char *)&s->init_buf->data[s->init_off]))
282 return -1;
287 283
288 ret = dtls1_write_bytes(s, type, 284 ret = dtls1_write_bytes(s, SSL3_RT_HANDSHAKE,
289 &s->init_buf->data[s->init_off], len); 285 &s->init_buf->data[s->init_off], len);
290 if (ret < 0) { 286 if (ret < 0) {
291 /* 287 /*
@@ -310,8 +306,7 @@ dtls1_do_write(SSL *s, int type)
310 */ 306 */
311 OPENSSL_assert(len == (unsigned int)ret); 307 OPENSSL_assert(len == (unsigned int)ret);
312 308
313 if (type == SSL3_RT_HANDSHAKE && 309 if (!s->d1->retransmitting) {
314 !s->d1->retransmitting) {
315 /* 310 /*
316 * Should not be done for 'Hello Request's, 311 * Should not be done for 'Hello Request's,
317 * but in that case we'll ignore the result 312 * but in that case we'll ignore the result
@@ -339,14 +334,13 @@ dtls1_do_write(SSL *s, int type)
339 } 334 }
340 335
341 if (ret == s->init_num) { 336 if (ret == s->init_num) {
342 ssl_msg_callback(s, 1, type, s->init_buf->data, 337 ssl_msg_callback(s, 1, SSL3_RT_HANDSHAKE,
343 s->init_off + s->init_num); 338 s->init_buf->data, s->init_off + s->init_num);
344 339
345 s->init_off = 0; 340 s->init_off = 0;
346 /* done writing this message */
347 s->init_num = 0; 341 s->init_num = 0;
348 342
349 return (1); 343 return 1;
350 } 344 }
351 s->init_off += ret; 345 s->init_off += ret;
352 s->init_num -= ret; 346 s->init_num -= ret;
@@ -356,6 +350,38 @@ dtls1_do_write(SSL *s, int type)
356 return (0); 350 return (0);
357} 351}
358 352
353static int
354dtls1_do_write_ccs(SSL *s)
355{
356 int ret;
357
358 OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());
359
360 if ((ret = dtls1_write_bytes(s, SSL3_RT_CHANGE_CIPHER_SPEC,
361 &s->init_buf->data[s->init_off], s->init_num)) < 0)
362 return -1;
363
364 OPENSSL_assert(s->init_num == ret);
365
366 ssl_msg_callback(s, 1, SSL3_RT_CHANGE_CIPHER_SPEC,
367 s->init_buf->data, s->init_num);
368
369 s->init_off = 0;
370 s->init_num = 0;
371
372 return 1;
373}
374
375int
376dtls1_do_write(SSL *s, int msg_type)
377{
378 if (msg_type == SSL3_RT_HANDSHAKE)
379 return dtls1_do_write_handshake_message(s);
380 if (msg_type == SSL3_RT_CHANGE_CIPHER_SPEC)
381 return dtls1_do_write_ccs(s);
382
383 return -1;
384}
359 385
360/* 386/*
361 * Obtain handshake message of message type 'mt' (any if mt == -1), 387 * Obtain handshake message of message type 'mt' (any if mt == -1),