diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/Makefile | 3 | ||||
| -rw-r--r-- | src/lib/libssl/d1_both.c | 148 | ||||
| -rw-r--r-- | src/lib/libssl/d1_lib.c | 7 | ||||
| -rw-r--r-- | src/lib/libssl/dtls12_handshake_msg.c | 231 | ||||
| -rw-r--r-- | src/lib/libssl/dtls12_internal.h | 46 | ||||
| -rw-r--r-- | src/lib/libssl/dtls_local.h | 5 |
6 files changed, 363 insertions, 77 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index 7e423b0b43..0d5934508a 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.86 2026/04/03 07:26:20 jsing Exp $ | 1 | # $OpenBSD: Makefile,v 1.87 2026/05/16 08:20:41 jsing Exp $ |
| 2 | 2 | ||
| 3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
| 4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
| @@ -43,6 +43,7 @@ SRCS= \ | |||
| 43 | d1_lib.c \ | 43 | d1_lib.c \ |
| 44 | d1_pkt.c \ | 44 | d1_pkt.c \ |
| 45 | d1_srtp.c \ | 45 | d1_srtp.c \ |
| 46 | dtls12_handshake_msg.c \ | ||
| 46 | pqueue.c \ | 47 | pqueue.c \ |
| 47 | s3_cbc.c \ | 48 | s3_cbc.c \ |
| 48 | s3_lib.c \ | 49 | s3_lib.c \ |
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c index de915fa4b2..2af307f594 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.93 2026/05/06 15:06:35 jsing Exp $ */ | 1 | /* $OpenBSD: d1_both.c,v 1.94 2026/05/16 08:20:41 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. |
| @@ -205,12 +205,48 @@ dtls1_hm_fragment_free(hm_fragment *frag) | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static int | 207 | static int |
| 208 | dtls12_create_handshake_msg(SSL *s) | ||
| 209 | { | ||
| 210 | CBB cbb; | ||
| 211 | |||
| 212 | OPENSSL_assert(s->init_off == 0); | ||
| 213 | OPENSSL_assert(s->init_num == (int)s->d1->w_msg_hdr.msg_len + | ||
| 214 | DTLS1_HM_HEADER_LENGTH); | ||
| 215 | |||
| 216 | /* Skip over the existing header. */ | ||
| 217 | s->init_off += DTLS1_HM_HEADER_LENGTH; | ||
| 218 | s->init_num -= DTLS1_HM_HEADER_LENGTH; | ||
| 219 | |||
| 220 | if (s->d1->hs_msg != NULL) | ||
| 221 | goto err; | ||
| 222 | |||
| 223 | if ((s->d1->hs_msg = dtls12_handshake_msg_new()) == NULL) | ||
| 224 | goto err; | ||
| 225 | if (!dtls12_handshake_msg_start(s->d1->hs_msg, &cbb, | ||
| 226 | s->d1->w_msg_hdr.type, s->d1->w_msg_hdr.seq)) | ||
| 227 | goto err; | ||
| 228 | if (!CBB_add_bytes(&cbb, &s->init_buf->data[s->init_off], | ||
| 229 | s->init_num)) | ||
| 230 | goto err; | ||
| 231 | if (!dtls12_handshake_msg_finish(s->d1->hs_msg)) | ||
| 232 | goto err; | ||
| 233 | |||
| 234 | return 1; | ||
| 235 | |||
| 236 | err: | ||
| 237 | dtls12_handshake_msg_free(s->d1->hs_msg); | ||
| 238 | s->d1->hs_msg = NULL; | ||
| 239 | |||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int | ||
| 208 | dtls1_do_write_handshake_message(SSL *s) | 244 | dtls1_do_write_handshake_message(SSL *s) |
| 209 | { | 245 | { |
| 210 | int ret; | 246 | int curr_mtu, written; |
| 211 | int curr_mtu; | ||
| 212 | unsigned int len, frag_off; | ||
| 213 | size_t overhead; | 247 | size_t overhead; |
| 248 | CBS cbs; | ||
| 249 | int ret; | ||
| 214 | 250 | ||
| 215 | /* AHA! Figure out the MTU, and stick to the right size */ | 251 | /* AHA! Figure out the MTU, and stick to the right size */ |
| 216 | if (s->d1->mtu < dtls1_min_mtu() && | 252 | if (s->d1->mtu < dtls1_min_mtu() && |
| @@ -234,15 +270,15 @@ dtls1_do_write_handshake_message(SSL *s) | |||
| 234 | OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); | 270 | OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); |
| 235 | /* should have something reasonable now */ | 271 | /* should have something reasonable now */ |
| 236 | 272 | ||
| 237 | if (s->init_off == 0) | 273 | if (s->d1->hs_msg == NULL) { |
| 238 | OPENSSL_assert(s->init_num == | 274 | if (!dtls12_create_handshake_msg(s)) |
| 239 | (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); | 275 | return -1; |
| 276 | } | ||
| 240 | 277 | ||
| 241 | if (!tls12_record_layer_write_overhead(s->rl, &overhead)) | 278 | if (!tls12_record_layer_write_overhead(s->rl, &overhead)) |
| 242 | return -1; | 279 | return -1; |
| 243 | 280 | ||
| 244 | frag_off = 0; | 281 | do { |
| 245 | while (s->init_num > 0) { | ||
| 246 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - | 282 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - |
| 247 | DTLS1_RT_HEADER_LENGTH - overhead; | 283 | DTLS1_RT_HEADER_LENGTH - overhead; |
| 248 | 284 | ||
| @@ -255,35 +291,14 @@ dtls1_do_write_handshake_message(SSL *s) | |||
| 255 | overhead; | 291 | overhead; |
| 256 | } | 292 | } |
| 257 | 293 | ||
| 258 | if (s->init_num > curr_mtu) | 294 | OPENSSL_assert(curr_mtu >= DTLS1_HM_HEADER_LENGTH); |
| 259 | len = curr_mtu; | ||
| 260 | else | ||
| 261 | len = s->init_num; | ||
| 262 | |||
| 263 | if (s->init_off != 0) { | ||
| 264 | OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); | ||
| 265 | s->init_off -= DTLS1_HM_HEADER_LENGTH; | ||
| 266 | s->init_num += DTLS1_HM_HEADER_LENGTH; | ||
| 267 | |||
| 268 | if (s->init_num > curr_mtu) | ||
| 269 | len = curr_mtu; | ||
| 270 | else | ||
| 271 | len = s->init_num; | ||
| 272 | } | ||
| 273 | |||
| 274 | OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); | ||
| 275 | |||
| 276 | s->d1->w_msg_hdr.frag_off = frag_off; | ||
| 277 | s->d1->w_msg_hdr.frag_len = len - DTLS1_HM_HEADER_LENGTH; | ||
| 278 | 295 | ||
| 279 | if (!dtls1_write_message_header(&s->d1->w_msg_hdr, | 296 | if (!dtls12_handshake_msg_fragment_build(s->d1->hs_msg, |
| 280 | s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len, | 297 | curr_mtu - DTLS1_HM_HEADER_LENGTH, &cbs)) |
| 281 | (unsigned char *)&s->init_buf->data[s->init_off])) | ||
| 282 | return -1; | 298 | return -1; |
| 283 | 299 | ||
| 284 | ret = dtls1_write_bytes(s, SSL3_RT_HANDSHAKE, | 300 | if ((written = dtls1_write_bytes(s, SSL3_RT_HANDSHAKE, |
| 285 | &s->init_buf->data[s->init_off], len); | 301 | CBS_data(&cbs), CBS_len(&cbs))) < 0) { |
| 286 | if (ret < 0) { | ||
| 287 | /* | 302 | /* |
| 288 | * Might need to update MTU here, but we don't know | 303 | * Might need to update MTU here, but we don't know |
| 289 | * which previous packet caused the failure -- so | 304 | * which previous packet caused the failure -- so |
| @@ -293,7 +308,7 @@ dtls1_do_write_handshake_message(SSL *s) | |||
| 293 | */ | 308 | */ |
| 294 | if (BIO_ctrl(SSL_get_wbio(s), | 309 | if (BIO_ctrl(SSL_get_wbio(s), |
| 295 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) <= 0) | 310 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) <= 0) |
| 296 | return (-1); | 311 | return -1; |
| 297 | 312 | ||
| 298 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), | 313 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), |
| 299 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | 314 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); |
| @@ -306,49 +321,34 @@ dtls1_do_write_handshake_message(SSL *s) | |||
| 306 | * handshake message got sent. but why would | 321 | * handshake message got sent. but why would |
| 307 | * this happen? | 322 | * this happen? |
| 308 | */ | 323 | */ |
| 309 | OPENSSL_assert(len == (unsigned int)ret); | 324 | OPENSSL_assert(CBS_len(&cbs) == (size_t)written); |
| 310 | 325 | ||
| 311 | if (!s->d1->retransmitting) { | 326 | if (!dtls12_handshake_msg_fragment_next(s->d1->hs_msg)) |
| 312 | /* | 327 | return -1; |
| 313 | * Should not be done for 'Hello Request's, | ||
| 314 | * but in that case we'll ignore the result | ||
| 315 | * anyway | ||
| 316 | */ | ||
| 317 | unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; | ||
| 318 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
| 319 | int xlen; | ||
| 320 | |||
| 321 | if (frag_off == 0) { | ||
| 322 | /* | ||
| 323 | * Reconstruct message header is if it | ||
| 324 | * is being sent in single fragment | ||
| 325 | */ | ||
| 326 | if (!dtls1_write_message_header(msg_hdr, | ||
| 327 | 0, msg_hdr->msg_len, p)) | ||
| 328 | return (-1); | ||
| 329 | xlen = ret; | ||
| 330 | } else { | ||
| 331 | p += DTLS1_HM_HEADER_LENGTH; | ||
| 332 | xlen = ret - DTLS1_HM_HEADER_LENGTH; | ||
| 333 | } | ||
| 334 | |||
| 335 | tls1_transcript_record(s, p, xlen); | ||
| 336 | } | ||
| 337 | 328 | ||
| 338 | if (ret == s->init_num) { | 329 | } while (dtls12_handshake_msg_fragment_pending(s->d1->hs_msg)); |
| 339 | ssl_msg_callback(s, 1, SSL3_RT_HANDSHAKE, | ||
| 340 | s->init_buf->data, s->init_off + s->init_num); | ||
| 341 | 330 | ||
| 342 | s->init_off = 0; | 331 | dtls12_handshake_msg_data(s->d1->hs_msg, &cbs); |
| 343 | s->init_num = 0; | ||
| 344 | 332 | ||
| 345 | return (1); | 333 | if (!s->d1->retransmitting) { |
| 346 | } | 334 | /* |
| 347 | s->init_off += ret; | 335 | * The TLS transcript is based on each handshake message being |
| 348 | s->init_num -= ret; | 336 | * sent as a single fragment - see RFC 6347 section 4.2.6. This |
| 349 | frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); | 337 | * should not be called for a HelloRequest, however the result |
| 338 | * will be ignored. | ||
| 339 | */ | ||
| 340 | tls1_transcript_record(s, CBS_data(&cbs), CBS_len(&cbs)); | ||
| 350 | } | 341 | } |
| 351 | return (0); | 342 | |
| 343 | ssl_msg_callback(s, 1, SSL3_RT_HANDSHAKE, CBS_data(&cbs), CBS_len(&cbs)); | ||
| 344 | |||
| 345 | dtls12_handshake_msg_free(s->d1->hs_msg); | ||
| 346 | s->d1->hs_msg = NULL; | ||
| 347 | |||
| 348 | s->init_off = 0; | ||
| 349 | s->init_num = 0; | ||
| 350 | |||
| 351 | return 1; | ||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | static int | 354 | static int |
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c index 69db8a0df4..fa546b381c 100644 --- a/src/lib/libssl/d1_lib.c +++ b/src/lib/libssl/d1_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: d1_lib.c,v 1.65 2024/07/23 14:40:53 jsing Exp $ */ | 1 | /* $OpenBSD: d1_lib.c,v 1.66 2026/05/16 08:20:41 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. |
| @@ -179,6 +179,8 @@ dtls1_free(SSL *s) | |||
| 179 | pqueue_free(s->d1->sent_messages); | 179 | pqueue_free(s->d1->sent_messages); |
| 180 | pqueue_free(s->d1->buffered_app_data.q); | 180 | pqueue_free(s->d1->buffered_app_data.q); |
| 181 | 181 | ||
| 182 | dtls12_handshake_msg_free(s->d1->hs_msg); | ||
| 183 | |||
| 182 | freezero(s->d1, sizeof(*s->d1)); | 184 | freezero(s->d1, sizeof(*s->d1)); |
| 183 | s->d1 = NULL; | 185 | s->d1 = NULL; |
| 184 | } | 186 | } |
| @@ -199,6 +201,9 @@ dtls1_clear(SSL *s) | |||
| 199 | buffered_app_data = s->d1->buffered_app_data.q; | 201 | buffered_app_data = s->d1->buffered_app_data.q; |
| 200 | mtu = s->d1->mtu; | 202 | mtu = s->d1->mtu; |
| 201 | 203 | ||
| 204 | dtls12_handshake_msg_free(s->d1->hs_msg); | ||
| 205 | s->d1->hs_msg = NULL; | ||
| 206 | |||
| 202 | dtls1_clear_queues(s); | 207 | dtls1_clear_queues(s); |
| 203 | 208 | ||
| 204 | memset(s->d1, 0, sizeof(*s->d1)); | 209 | memset(s->d1, 0, sizeof(*s->d1)); |
diff --git a/src/lib/libssl/dtls12_handshake_msg.c b/src/lib/libssl/dtls12_handshake_msg.c new file mode 100644 index 0000000000..7874aa8598 --- /dev/null +++ b/src/lib/libssl/dtls12_handshake_msg.c | |||
| @@ -0,0 +1,231 @@ | |||
| 1 | /* $OpenBSD: dtls12_handshake_msg.c,v 1.1 2026/05/16 08:20:41 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2026 Joel Sing <jsing@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include <stdlib.h> | ||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | #include "bytestring.h" | ||
| 23 | #include "dtls12_internal.h" | ||
| 24 | |||
| 25 | #define DTLS12_HANDSHAKE_MSG_HEADER_LEN 12 | ||
| 26 | #define DTLS12_HANDSHAKE_MSG_INITIAL_LEN 256 | ||
| 27 | |||
| 28 | #define DTLS12_HANDSHAKE_MSG_FRAGMENT_LENGTH_OFFSET 9 | ||
| 29 | |||
| 30 | struct dtls12_handshake_msg { | ||
| 31 | uint8_t msg_type; | ||
| 32 | uint32_t msg_len; | ||
| 33 | uint16_t msg_seq; | ||
| 34 | |||
| 35 | uint32_t fragment_offset; | ||
| 36 | uint32_t fragment_len; | ||
| 37 | uint8_t *fragment_data; | ||
| 38 | size_t fragment_data_len; | ||
| 39 | int fragment_pending; | ||
| 40 | |||
| 41 | uint8_t *data; | ||
| 42 | size_t data_len; | ||
| 43 | |||
| 44 | CBS cbs; | ||
| 45 | CBB cbb; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct dtls12_handshake_msg * | ||
| 49 | dtls12_handshake_msg_new(void) | ||
| 50 | { | ||
| 51 | struct dtls12_handshake_msg *msg = NULL; | ||
| 52 | |||
| 53 | if ((msg = calloc(1, sizeof(struct dtls12_handshake_msg))) == NULL) | ||
| 54 | return NULL; | ||
| 55 | |||
| 56 | return msg; | ||
| 57 | } | ||
| 58 | |||
| 59 | void | ||
| 60 | dtls12_handshake_msg_free(struct dtls12_handshake_msg *msg) | ||
| 61 | { | ||
| 62 | if (msg == NULL) | ||
| 63 | return; | ||
| 64 | |||
| 65 | CBB_cleanup(&msg->cbb); | ||
| 66 | |||
| 67 | freezero(msg->data, msg->data_len); | ||
| 68 | freezero(msg->fragment_data, msg->fragment_data_len); | ||
| 69 | |||
| 70 | freezero(msg, sizeof(struct dtls12_handshake_msg)); | ||
| 71 | } | ||
| 72 | |||
| 73 | void | ||
| 74 | dtls12_handshake_msg_data(struct dtls12_handshake_msg *msg, CBS *cbs) | ||
| 75 | { | ||
| 76 | CBS_init(cbs, msg->data, msg->data_len); | ||
| 77 | } | ||
| 78 | |||
| 79 | uint8_t | ||
| 80 | dtls12_handshake_msg_type(struct dtls12_handshake_msg *msg) | ||
| 81 | { | ||
| 82 | return msg->msg_type; | ||
| 83 | } | ||
| 84 | |||
| 85 | int | ||
| 86 | dtls12_handshake_msg_content(struct dtls12_handshake_msg *msg, CBS *cbs) | ||
| 87 | { | ||
| 88 | dtls12_handshake_msg_data(msg, cbs); | ||
| 89 | |||
| 90 | return CBS_skip(cbs, DTLS12_HANDSHAKE_MSG_HEADER_LEN); | ||
| 91 | } | ||
| 92 | |||
| 93 | int | ||
| 94 | dtls12_handshake_msg_start(struct dtls12_handshake_msg *msg, CBB *body, | ||
| 95 | uint8_t msg_type, size_t msg_seq) | ||
| 96 | { | ||
| 97 | msg->msg_type = msg_type; | ||
| 98 | msg->msg_seq = msg_seq; | ||
| 99 | |||
| 100 | msg->msg_len = 0; | ||
| 101 | msg->fragment_offset = 0; | ||
| 102 | |||
| 103 | if (!CBB_init(&msg->cbb, DTLS12_HANDSHAKE_MSG_INITIAL_LEN)) | ||
| 104 | return 0; | ||
| 105 | if (!CBB_add_u8(&msg->cbb, msg->msg_type)) | ||
| 106 | return 0; | ||
| 107 | if (!CBB_add_u24(&msg->cbb, msg->msg_len)) | ||
| 108 | return 0; | ||
| 109 | if (!CBB_add_u16(&msg->cbb, msg->msg_seq)) | ||
| 110 | return 0; | ||
| 111 | if (!CBB_add_u24(&msg->cbb, msg->fragment_offset)) | ||
| 112 | return 0; | ||
| 113 | if (!CBB_add_u24_length_prefixed(&msg->cbb, body)) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | return 1; | ||
| 117 | } | ||
| 118 | |||
| 119 | int | ||
| 120 | dtls12_handshake_msg_finish(struct dtls12_handshake_msg *msg) | ||
| 121 | { | ||
| 122 | CBS cbs; | ||
| 123 | |||
| 124 | if (!CBB_finish(&msg->cbb, &msg->data, &msg->data_len)) | ||
| 125 | return 0; | ||
| 126 | |||
| 127 | /* Update message length to match fragment length. */ | ||
| 128 | CBS_init(&cbs, msg->data, msg->data_len); | ||
| 129 | if (!CBS_skip(&cbs, DTLS12_HANDSHAKE_MSG_FRAGMENT_LENGTH_OFFSET)) | ||
| 130 | return 0; | ||
| 131 | if (!CBS_get_u24(&cbs, &msg->msg_len)) | ||
| 132 | return 0; | ||
| 133 | |||
| 134 | if (!CBB_init_fixed(&msg->cbb, msg->data, msg->data_len)) | ||
| 135 | return 0; | ||
| 136 | if (!CBB_add_u8(&msg->cbb, msg->msg_type)) | ||
| 137 | return 0; | ||
| 138 | if (!CBB_add_u24(&msg->cbb, msg->msg_len)) | ||
| 139 | return 0; | ||
| 140 | if (!CBB_finish(&msg->cbb, NULL, NULL)) | ||
| 141 | return 0; | ||
| 142 | |||
| 143 | dtls12_handshake_msg_fragment_reset(msg); | ||
| 144 | |||
| 145 | return 1; | ||
| 146 | } | ||
| 147 | |||
| 148 | int | ||
| 149 | dtls12_handshake_msg_fragment_reset(struct dtls12_handshake_msg *msg) | ||
| 150 | { | ||
| 151 | freezero(msg->fragment_data, msg->fragment_data_len); | ||
| 152 | msg->fragment_data = NULL; | ||
| 153 | msg->fragment_data_len = 0; | ||
| 154 | |||
| 155 | msg->fragment_offset = 0; | ||
| 156 | msg->fragment_pending = 1; | ||
| 157 | |||
| 158 | return dtls12_handshake_msg_content(msg, &msg->cbs); | ||
| 159 | } | ||
| 160 | |||
| 161 | int | ||
| 162 | dtls12_handshake_msg_fragment_build(struct dtls12_handshake_msg *msg, | ||
| 163 | size_t max_fragment_len, CBS *cbs) | ||
| 164 | { | ||
| 165 | CBB body; | ||
| 166 | |||
| 167 | CBS_init(cbs, NULL, 0); | ||
| 168 | |||
| 169 | if (msg->fragment_offset > msg->msg_len) | ||
| 170 | return 0; | ||
| 171 | if (msg->msg_len - msg->fragment_offset > CBS_len(&msg->cbs)) | ||
| 172 | return 0; | ||
| 173 | |||
| 174 | freezero(msg->fragment_data, msg->fragment_data_len); | ||
| 175 | msg->fragment_data = NULL; | ||
| 176 | msg->fragment_data_len = 0; | ||
| 177 | |||
| 178 | if ((msg->fragment_len = CBS_len(&msg->cbs)) > max_fragment_len) | ||
| 179 | msg->fragment_len = max_fragment_len; | ||
| 180 | |||
| 181 | /* Build the fragment. */ | ||
| 182 | if (!CBB_init(&msg->cbb, DTLS12_HANDSHAKE_MSG_INITIAL_LEN)) | ||
| 183 | goto err; | ||
| 184 | if (!CBB_add_u8(&msg->cbb, msg->msg_type)) | ||
| 185 | goto err; | ||
| 186 | if (!CBB_add_u24(&msg->cbb, msg->msg_len)) | ||
| 187 | goto err; | ||
| 188 | if (!CBB_add_u16(&msg->cbb, msg->msg_seq)) | ||
| 189 | goto err; | ||
| 190 | if (!CBB_add_u24(&msg->cbb, msg->fragment_offset)) | ||
| 191 | goto err; | ||
| 192 | if (!CBB_add_u24_length_prefixed(&msg->cbb, &body)) | ||
| 193 | goto err; | ||
| 194 | if (!CBB_add_bytes(&body, CBS_data(&msg->cbs), msg->fragment_len)) | ||
| 195 | goto err; | ||
| 196 | if (!CBB_finish(&msg->cbb, &msg->fragment_data, &msg->fragment_data_len)) | ||
| 197 | goto err; | ||
| 198 | |||
| 199 | CBS_init(cbs, msg->fragment_data, msg->fragment_data_len); | ||
| 200 | |||
| 201 | return 1; | ||
| 202 | |||
| 203 | err: | ||
| 204 | CBB_cleanup(&msg->cbb); | ||
| 205 | |||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | int | ||
| 210 | dtls12_handshake_msg_fragment_next(struct dtls12_handshake_msg *msg) | ||
| 211 | { | ||
| 212 | if (msg->fragment_offset > msg->msg_len) | ||
| 213 | return 0; | ||
| 214 | if (msg->msg_len - msg->fragment_offset < msg->fragment_len) | ||
| 215 | return 0; | ||
| 216 | |||
| 217 | if (!CBS_skip(&msg->cbs, msg->fragment_len)) | ||
| 218 | return 0; | ||
| 219 | |||
| 220 | msg->fragment_offset += msg->fragment_len; | ||
| 221 | |||
| 222 | msg->fragment_pending = (CBS_len(&msg->cbs) > 0); | ||
| 223 | |||
| 224 | return 1; | ||
| 225 | } | ||
| 226 | |||
| 227 | int | ||
| 228 | dtls12_handshake_msg_fragment_pending(struct dtls12_handshake_msg *msg) | ||
| 229 | { | ||
| 230 | return msg->fragment_pending; | ||
| 231 | } | ||
diff --git a/src/lib/libssl/dtls12_internal.h b/src/lib/libssl/dtls12_internal.h new file mode 100644 index 0000000000..f3fa9b7490 --- /dev/null +++ b/src/lib/libssl/dtls12_internal.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* $OpenBSD: dtls12_internal.h,v 1.1 2026/05/16 08:20:41 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2026 Joel Sing <jsing@openbsd.org> | ||
| 4 | * | ||
| 5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 6 | * purpose with or without fee is hereby granted, provided that the above | ||
| 7 | * copyright notice and this permission notice appear in all copies. | ||
| 8 | * | ||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 12 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 14 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 15 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef HEADER_DTLS12_INTERNAL_H | ||
| 19 | #define HEADER_DTLS12_INTERNAL_H | ||
| 20 | |||
| 21 | #include <stddef.h> | ||
| 22 | #include <stdint.h> | ||
| 23 | |||
| 24 | #include "bytestring.h" | ||
| 25 | |||
| 26 | __BEGIN_HIDDEN_DECLS | ||
| 27 | |||
| 28 | struct dtls12_handshake_msg; | ||
| 29 | |||
| 30 | struct dtls12_handshake_msg *dtls12_handshake_msg_new(void); | ||
| 31 | void dtls12_handshake_msg_free(struct dtls12_handshake_msg *msg); | ||
| 32 | void dtls12_handshake_msg_data(struct dtls12_handshake_msg *msg, CBS *cbs); | ||
| 33 | uint8_t dtls12_handshake_msg_type(struct dtls12_handshake_msg *msg); | ||
| 34 | int dtls12_handshake_msg_content(struct dtls12_handshake_msg *msg, CBS *cbs); | ||
| 35 | int dtls12_handshake_msg_start(struct dtls12_handshake_msg *msg, CBB *body, | ||
| 36 | uint8_t msg_type, size_t msg_seq); | ||
| 37 | int dtls12_handshake_msg_finish(struct dtls12_handshake_msg *msg); | ||
| 38 | int dtls12_handshake_msg_fragment_build(struct dtls12_handshake_msg *msg, | ||
| 39 | size_t max_fragment_len, CBS *cbs); | ||
| 40 | int dtls12_handshake_msg_fragment_next(struct dtls12_handshake_msg *msg); | ||
| 41 | int dtls12_handshake_msg_fragment_pending(struct dtls12_handshake_msg *msg); | ||
| 42 | int dtls12_handshake_msg_fragment_reset(struct dtls12_handshake_msg *msg); | ||
| 43 | |||
| 44 | __END_HIDDEN_DECLS | ||
| 45 | |||
| 46 | #endif | ||
diff --git a/src/lib/libssl/dtls_local.h b/src/lib/libssl/dtls_local.h index 5a85bba607..8691663eb3 100644 --- a/src/lib/libssl/dtls_local.h +++ b/src/lib/libssl/dtls_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: dtls_local.h,v 1.4 2026/05/06 15:06:35 jsing Exp $ */ | 1 | /* $OpenBSD: dtls_local.h,v 1.5 2026/05/16 08:20:41 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. |
| @@ -65,6 +65,7 @@ | |||
| 65 | #include <openssl/dtls1.h> | 65 | #include <openssl/dtls1.h> |
| 66 | 66 | ||
| 67 | #include "ssl_local.h" | 67 | #include "ssl_local.h" |
| 68 | #include "dtls12_internal.h" | ||
| 68 | #include "tls_content.h" | 69 | #include "tls_content.h" |
| 69 | 70 | ||
| 70 | __BEGIN_HIDDEN_DECLS | 71 | __BEGIN_HIDDEN_DECLS |
| @@ -179,6 +180,8 @@ struct dtls1_state_st { | |||
| 179 | 180 | ||
| 180 | unsigned int retransmitting; | 181 | unsigned int retransmitting; |
| 181 | unsigned int change_cipher_spec_ok; | 182 | unsigned int change_cipher_spec_ok; |
| 183 | |||
| 184 | struct dtls12_handshake_msg *hs_msg; | ||
| 182 | }; | 185 | }; |
| 183 | 186 | ||
| 184 | int dtls1_do_write(SSL *s, int type); | 187 | int dtls1_do_write(SSL *s, int type); |
