diff options
Diffstat (limited to 'src/lib/libssl/d1_both.c')
| -rw-r--r-- | src/lib/libssl/d1_both.c | 438 |
1 files changed, 217 insertions, 221 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c index e144d8f533..b57c8960c1 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.85 2025/03/09 15:12:18 tb Exp $ */ | 1 | /* $OpenBSD: d1_both.c,v 1.99 2026/07/16 14:43:22 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. |
| @@ -159,8 +159,6 @@ static const unsigned char bitmask_end_values[] = { | |||
| 159 | static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; | 159 | static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; |
| 160 | 160 | ||
| 161 | static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); | 161 | static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); |
| 162 | static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, | ||
| 163 | unsigned long frag_len); | ||
| 164 | static int dtls1_write_message_header(const struct hm_header_st *msg_hdr, | 162 | static int dtls1_write_message_header(const struct hm_header_st *msg_hdr, |
| 165 | unsigned long frag_off, unsigned long frag_len, unsigned char *p); | 163 | unsigned long frag_off, unsigned long frag_len, unsigned char *p); |
| 166 | static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, | 164 | static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, |
| @@ -206,14 +204,49 @@ dtls1_hm_fragment_free(hm_fragment *frag) | |||
| 206 | free(frag); | 204 | free(frag); |
| 207 | } | 205 | } |
| 208 | 206 | ||
| 209 | /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ | 207 | static int |
| 210 | int | 208 | dtls12_create_handshake_msg(SSL *s) |
| 211 | dtls1_do_write(SSL *s, int type) | ||
| 212 | { | 209 | { |
| 213 | int ret; | 210 | CBB cbb; |
| 214 | int curr_mtu; | 211 | |
| 215 | unsigned int len, frag_off; | 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 | ||
| 244 | dtls1_do_write_handshake_message(SSL *s) | ||
| 245 | { | ||
| 246 | int curr_mtu, written; | ||
| 216 | size_t overhead; | 247 | size_t overhead; |
| 248 | CBS cbs; | ||
| 249 | int ret; | ||
| 217 | 250 | ||
| 218 | /* AHA! Figure out the MTU, and stick to the right size */ | 251 | /* AHA! Figure out the MTU, and stick to the right size */ |
| 219 | if (s->d1->mtu < dtls1_min_mtu() && | 252 | if (s->d1->mtu < dtls1_min_mtu() && |
| @@ -237,15 +270,15 @@ dtls1_do_write(SSL *s, int type) | |||
| 237 | OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); | 270 | OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); |
| 238 | /* should have something reasonable now */ | 271 | /* should have something reasonable now */ |
| 239 | 272 | ||
| 240 | if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) | 273 | if (s->d1->hs_msg == NULL) { |
| 241 | OPENSSL_assert(s->init_num == | 274 | if (!dtls12_create_handshake_msg(s)) |
| 242 | (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); | 275 | return -1; |
| 276 | } | ||
| 243 | 277 | ||
| 244 | if (!tls12_record_layer_write_overhead(s->rl, &overhead)) | 278 | if (!tls12_record_layer_write_overhead(s->rl, &overhead)) |
| 245 | return -1; | 279 | return -1; |
| 246 | 280 | ||
| 247 | frag_off = 0; | 281 | do { |
| 248 | while (s->init_num) { | ||
| 249 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - | 282 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - |
| 250 | DTLS1_RT_HEADER_LENGTH - overhead; | 283 | DTLS1_RT_HEADER_LENGTH - overhead; |
| 251 | 284 | ||
| @@ -258,38 +291,14 @@ dtls1_do_write(SSL *s, int type) | |||
| 258 | overhead; | 291 | overhead; |
| 259 | } | 292 | } |
| 260 | 293 | ||
| 261 | if (s->init_num > curr_mtu) | 294 | OPENSSL_assert(curr_mtu >= DTLS1_HM_HEADER_LENGTH); |
| 262 | len = curr_mtu; | ||
| 263 | else | ||
| 264 | len = s->init_num; | ||
| 265 | |||
| 266 | /* XDTLS: this function is too long. split out the CCS part */ | ||
| 267 | if (type == SSL3_RT_HANDSHAKE) { | ||
| 268 | if (s->init_off != 0) { | ||
| 269 | OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); | ||
| 270 | s->init_off -= DTLS1_HM_HEADER_LENGTH; | ||
| 271 | s->init_num += DTLS1_HM_HEADER_LENGTH; | ||
| 272 | |||
| 273 | if (s->init_num > curr_mtu) | ||
| 274 | len = curr_mtu; | ||
| 275 | else | ||
| 276 | len = s->init_num; | ||
| 277 | } | ||
| 278 | |||
| 279 | dtls1_fix_message_header(s, frag_off, | ||
| 280 | len - DTLS1_HM_HEADER_LENGTH); | ||
| 281 | |||
| 282 | if (!dtls1_write_message_header(&s->d1->w_msg_hdr, | ||
| 283 | s->d1->w_msg_hdr.frag_off, s->d1->w_msg_hdr.frag_len, | ||
| 284 | (unsigned char *)&s->init_buf->data[s->init_off])) | ||
| 285 | return -1; | ||
| 286 | 295 | ||
| 287 | OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); | 296 | if (!dtls12_handshake_msg_fragment_build(s->d1->hs_msg, |
| 288 | } | 297 | curr_mtu - DTLS1_HM_HEADER_LENGTH, &cbs)) |
| 298 | return -1; | ||
| 289 | 299 | ||
| 290 | ret = dtls1_write_bytes(s, type, | 300 | if ((written = dtls1_write_bytes(s, SSL3_RT_HANDSHAKE, |
| 291 | &s->init_buf->data[s->init_off], len); | 301 | CBS_data(&cbs), CBS_len(&cbs))) < 0) { |
| 292 | if (ret < 0) { | ||
| 293 | /* | 302 | /* |
| 294 | * Might need to update MTU here, but we don't know | 303 | * Might need to update MTU here, but we don't know |
| 295 | * which previous packet caused the failure -- so | 304 | * which previous packet caused the failure -- so |
| @@ -298,69 +307,83 @@ dtls1_do_write(SSL *s, int type) | |||
| 298 | * handle the retransmit | 307 | * handle the retransmit |
| 299 | */ | 308 | */ |
| 300 | if (BIO_ctrl(SSL_get_wbio(s), | 309 | if (BIO_ctrl(SSL_get_wbio(s), |
| 301 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) | 310 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) <= 0) |
| 302 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), | 311 | return -1; |
| 303 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | ||
| 304 | else | ||
| 305 | return (-1); | ||
| 306 | } else { | ||
| 307 | 312 | ||
| 308 | /* | 313 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), |
| 309 | * Bad if this assert fails, only part of the | 314 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); |
| 310 | * handshake message got sent. but why would | 315 | |
| 311 | * this happen? | 316 | continue; |
| 312 | */ | ||
| 313 | OPENSSL_assert(len == (unsigned int)ret); | ||
| 314 | |||
| 315 | if (type == SSL3_RT_HANDSHAKE && | ||
| 316 | !s->d1->retransmitting) { | ||
| 317 | /* | ||
| 318 | * Should not be done for 'Hello Request's, | ||
| 319 | * but in that case we'll ignore the result | ||
| 320 | * anyway | ||
| 321 | */ | ||
| 322 | unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; | ||
| 323 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
| 324 | int xlen; | ||
| 325 | |||
| 326 | if (frag_off == 0) { | ||
| 327 | /* | ||
| 328 | * Reconstruct message header is if it | ||
| 329 | * is being sent in single fragment | ||
| 330 | */ | ||
| 331 | if (!dtls1_write_message_header(msg_hdr, | ||
| 332 | 0, msg_hdr->msg_len, p)) | ||
| 333 | return (-1); | ||
| 334 | xlen = ret; | ||
| 335 | } else { | ||
| 336 | p += DTLS1_HM_HEADER_LENGTH; | ||
| 337 | xlen = ret - DTLS1_HM_HEADER_LENGTH; | ||
| 338 | } | ||
| 339 | |||
| 340 | tls1_transcript_record(s, p, xlen); | ||
| 341 | } | ||
| 342 | |||
| 343 | if (ret == s->init_num) { | ||
| 344 | if (s->msg_callback) | ||
| 345 | s->msg_callback(1, s->version, type, | ||
| 346 | s->init_buf->data, | ||
| 347 | (size_t)(s->init_off + s->init_num), | ||
| 348 | s, s->msg_callback_arg); | ||
| 349 | |||
| 350 | s->init_off = 0; | ||
| 351 | /* done writing this message */ | ||
| 352 | s->init_num = 0; | ||
| 353 | |||
| 354 | return (1); | ||
| 355 | } | ||
| 356 | s->init_off += ret; | ||
| 357 | s->init_num -= ret; | ||
| 358 | frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); | ||
| 359 | } | 317 | } |
| 318 | |||
| 319 | /* | ||
| 320 | * Bad if this assert fails, only part of the | ||
| 321 | * handshake message got sent. but why would | ||
| 322 | * this happen? | ||
| 323 | */ | ||
| 324 | OPENSSL_assert(CBS_len(&cbs) == (size_t)written); | ||
| 325 | |||
| 326 | if (!dtls12_handshake_msg_fragment_next(s->d1->hs_msg)) | ||
| 327 | return -1; | ||
| 328 | |||
| 329 | } while (dtls12_handshake_msg_fragment_pending(s->d1->hs_msg)); | ||
| 330 | |||
| 331 | dtls12_handshake_msg_data(s->d1->hs_msg, &cbs); | ||
| 332 | |||
| 333 | if (!s->d1->retransmitting) { | ||
| 334 | /* | ||
| 335 | * The TLS transcript is based on each handshake message being | ||
| 336 | * sent as a single fragment - see RFC 6347 section 4.2.6. This | ||
| 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)); | ||
| 360 | } | 341 | } |
| 361 | 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; | ||
| 362 | } | 352 | } |
| 363 | 353 | ||
| 354 | static int | ||
| 355 | dtls1_do_write_ccs(SSL *s) | ||
| 356 | { | ||
| 357 | const uint8_t ccs[] = { SSL3_MT_CCS }; | ||
| 358 | int ret; | ||
| 359 | |||
| 360 | OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); | ||
| 361 | |||
| 362 | if ((ret = dtls1_write_bytes(s, SSL3_RT_CHANGE_CIPHER_SPEC, | ||
| 363 | ccs, sizeof(ccs))) < 0) | ||
| 364 | return -1; | ||
| 365 | |||
| 366 | OPENSSL_assert(sizeof(ccs) == ret); | ||
| 367 | |||
| 368 | ssl_msg_callback(s, 1, SSL3_RT_CHANGE_CIPHER_SPEC, | ||
| 369 | ccs, sizeof(ccs)); | ||
| 370 | |||
| 371 | s->init_off = 0; | ||
| 372 | s->init_num = 0; | ||
| 373 | |||
| 374 | return 1; | ||
| 375 | } | ||
| 376 | |||
| 377 | int | ||
| 378 | dtls1_do_write(SSL *s, int msg_type) | ||
| 379 | { | ||
| 380 | if (msg_type == SSL3_RT_HANDSHAKE) | ||
| 381 | return dtls1_do_write_handshake_message(s); | ||
| 382 | if (msg_type == SSL3_RT_CHANGE_CIPHER_SPEC) | ||
| 383 | return dtls1_do_write_ccs(s); | ||
| 384 | |||
| 385 | return -1; | ||
| 386 | } | ||
| 364 | 387 | ||
| 365 | /* | 388 | /* |
| 366 | * Obtain handshake message of message type 'mt' (any if mt == -1), | 389 | * Obtain handshake message of message type 'mt' (any if mt == -1), |
| @@ -413,9 +436,8 @@ dtls1_get_message(SSL *s, int st1, int stn, int mt, long max) | |||
| 413 | msg_len += DTLS1_HM_HEADER_LENGTH; | 436 | msg_len += DTLS1_HM_HEADER_LENGTH; |
| 414 | 437 | ||
| 415 | tls1_transcript_record(s, p, msg_len); | 438 | tls1_transcript_record(s, p, msg_len); |
| 416 | if (s->msg_callback) | 439 | |
| 417 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len, | 440 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, p, msg_len); |
| 418 | s, s->msg_callback_arg); | ||
| 419 | 441 | ||
| 420 | memset(msg_hdr, 0, sizeof(struct hm_header_st)); | 442 | memset(msg_hdr, 0, sizeof(struct hm_header_st)); |
| 421 | 443 | ||
| @@ -797,11 +819,8 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | |||
| 797 | * 'Finished' MAC. | 819 | * 'Finished' MAC. |
| 798 | */ | 820 | */ |
| 799 | if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { | 821 | if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { |
| 800 | if (s->msg_callback) | 822 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, wire, |
| 801 | s->msg_callback(0, s->version, | 823 | DTLS1_HM_HEADER_LENGTH); |
| 802 | SSL3_RT_HANDSHAKE, wire, | ||
| 803 | DTLS1_HM_HEADER_LENGTH, s, | ||
| 804 | s->msg_callback_arg); | ||
| 805 | 824 | ||
| 806 | s->init_num = 0; | 825 | s->init_num = 0; |
| 807 | goto again; | 826 | goto again; |
| @@ -907,6 +926,46 @@ dtls1_get_queue_priority(unsigned short seq, int is_ccs) | |||
| 907 | return seq * 2 - is_ccs; | 926 | return seq * 2 - is_ccs; |
| 908 | } | 927 | } |
| 909 | 928 | ||
| 929 | static int | ||
| 930 | dtls1_retransmit_message(SSL *s, hm_fragment *frag) | ||
| 931 | { | ||
| 932 | unsigned long header_length; | ||
| 933 | uint16_t epoch; | ||
| 934 | int ret; | ||
| 935 | |||
| 936 | if (frag->msg_header.is_ccs) | ||
| 937 | header_length = DTLS1_CCS_HEADER_LENGTH; | ||
| 938 | else | ||
| 939 | header_length = DTLS1_HM_HEADER_LENGTH; | ||
| 940 | |||
| 941 | memcpy(s->init_buf->data, frag->fragment, | ||
| 942 | frag->msg_header.msg_len + header_length); | ||
| 943 | s->init_num = frag->msg_header.msg_len + header_length; | ||
| 944 | |||
| 945 | dtls1_set_message_header(s, frag->msg_header.type, | ||
| 946 | frag->msg_header.msg_len, frag->msg_header.seq, 0, | ||
| 947 | frag->msg_header.frag_len); | ||
| 948 | |||
| 949 | epoch = tls12_record_layer_write_epoch(s->rl); | ||
| 950 | |||
| 951 | s->d1->retransmitting = 1; | ||
| 952 | |||
| 953 | /* Switch to the epoch that was used to send the message. */ | ||
| 954 | if (!tls12_record_layer_use_write_epoch(s->rl, frag->msg_header.epoch)) | ||
| 955 | return 0; | ||
| 956 | |||
| 957 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? | ||
| 958 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); | ||
| 959 | |||
| 960 | if (!tls12_record_layer_use_write_epoch(s->rl, epoch)) | ||
| 961 | return 0; | ||
| 962 | |||
| 963 | s->d1->retransmitting = 0; | ||
| 964 | |||
| 965 | (void)BIO_flush(SSL_get_wbio(s)); | ||
| 966 | return ret; | ||
| 967 | } | ||
| 968 | |||
| 910 | int | 969 | int |
| 911 | dtls1_retransmit_buffered_messages(SSL *s) | 970 | dtls1_retransmit_buffered_messages(SSL *s) |
| 912 | { | 971 | { |
| @@ -914,17 +973,12 @@ dtls1_retransmit_buffered_messages(SSL *s) | |||
| 914 | piterator iter; | 973 | piterator iter; |
| 915 | pitem *item; | 974 | pitem *item; |
| 916 | hm_fragment *frag; | 975 | hm_fragment *frag; |
| 917 | int found = 0; | ||
| 918 | 976 | ||
| 919 | iter = pqueue_iterator(sent); | 977 | iter = pqueue_iterator(sent); |
| 920 | 978 | ||
| 921 | for (item = pqueue_next(&iter); item != NULL; | 979 | for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { |
| 922 | item = pqueue_next(&iter)) { | ||
| 923 | frag = (hm_fragment *)item->data; | 980 | frag = (hm_fragment *)item->data; |
| 924 | if (dtls1_retransmit_message(s, | 981 | if (dtls1_retransmit_message(s, frag) <= 0) { |
| 925 | (unsigned short)dtls1_get_queue_priority( | ||
| 926 | frag->msg_header.seq, frag->msg_header.is_ccs), 0, | ||
| 927 | &found) <= 0 && found) { | ||
| 928 | #ifdef DEBUG | 982 | #ifdef DEBUG |
| 929 | fprintf(stderr, "dtls1_retransmit_message() failed\n"); | 983 | fprintf(stderr, "dtls1_retransmit_message() failed\n"); |
| 930 | #endif | 984 | #endif |
| @@ -960,6 +1014,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
| 960 | (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == | 1014 | (is_ccs ? DTLS1_CCS_HEADER_LENGTH : DTLS1_HM_HEADER_LENGTH) == |
| 961 | (unsigned int)s->init_num); | 1015 | (unsigned int)s->init_num); |
| 962 | 1016 | ||
| 1017 | frag->msg_header.epoch = tls12_record_layer_write_epoch(s->rl); | ||
| 963 | frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; | 1018 | frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; |
| 964 | frag->msg_header.seq = s->d1->w_msg_hdr.seq; | 1019 | frag->msg_header.seq = s->d1->w_msg_hdr.seq; |
| 965 | frag->msg_header.type = s->d1->w_msg_hdr.type; | 1020 | frag->msg_header.type = s->d1->w_msg_hdr.type; |
| @@ -967,11 +1022,6 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
| 967 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; | 1022 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; |
| 968 | frag->msg_header.is_ccs = is_ccs; | 1023 | frag->msg_header.is_ccs = is_ccs; |
| 969 | 1024 | ||
| 970 | /* save current state*/ | ||
| 971 | frag->msg_header.saved_retransmit_state.session = s->session; | ||
| 972 | frag->msg_header.saved_retransmit_state.epoch = | ||
| 973 | tls12_record_layer_write_epoch(s->rl); | ||
| 974 | |||
| 975 | memset(seq64be, 0, sizeof(seq64be)); | 1025 | memset(seq64be, 0, sizeof(seq64be)); |
| 976 | seq64be[6] = (unsigned char)(dtls1_get_queue_priority( | 1026 | seq64be[6] = (unsigned char)(dtls1_get_queue_priority( |
| 977 | frag->msg_header.seq, frag->msg_header.is_ccs) >> 8); | 1027 | frag->msg_header.seq, frag->msg_header.is_ccs) >> 8); |
| @@ -988,80 +1038,6 @@ dtls1_buffer_message(SSL *s, int is_ccs) | |||
| 988 | return 1; | 1038 | return 1; |
| 989 | } | 1039 | } |
| 990 | 1040 | ||
| 991 | int | ||
| 992 | dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | ||
| 993 | int *found) | ||
| 994 | { | ||
| 995 | int ret; | ||
| 996 | /* XDTLS: for now assuming that read/writes are blocking */ | ||
| 997 | pitem *item; | ||
| 998 | hm_fragment *frag; | ||
| 999 | unsigned long header_length; | ||
| 1000 | unsigned char seq64be[8]; | ||
| 1001 | struct dtls1_retransmit_state saved_state; | ||
| 1002 | |||
| 1003 | /* | ||
| 1004 | OPENSSL_assert(s->init_num == 0); | ||
| 1005 | OPENSSL_assert(s->init_off == 0); | ||
| 1006 | */ | ||
| 1007 | |||
| 1008 | /* XDTLS: the requested message ought to be found, otherwise error */ | ||
| 1009 | memset(seq64be, 0, sizeof(seq64be)); | ||
| 1010 | seq64be[6] = (unsigned char)(seq >> 8); | ||
| 1011 | seq64be[7] = (unsigned char)seq; | ||
| 1012 | |||
| 1013 | item = pqueue_find(s->d1->sent_messages, seq64be); | ||
| 1014 | if (item == NULL) { | ||
| 1015 | #ifdef DEBUG | ||
| 1016 | fprintf(stderr, "retransmit: message %d non-existent\n", seq); | ||
| 1017 | #endif | ||
| 1018 | *found = 0; | ||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | *found = 1; | ||
| 1023 | frag = (hm_fragment *)item->data; | ||
| 1024 | |||
| 1025 | if (frag->msg_header.is_ccs) | ||
| 1026 | header_length = DTLS1_CCS_HEADER_LENGTH; | ||
| 1027 | else | ||
| 1028 | header_length = DTLS1_HM_HEADER_LENGTH; | ||
| 1029 | |||
| 1030 | memcpy(s->init_buf->data, frag->fragment, | ||
| 1031 | frag->msg_header.msg_len + header_length); | ||
| 1032 | s->init_num = frag->msg_header.msg_len + header_length; | ||
| 1033 | |||
| 1034 | dtls1_set_message_header_int(s, frag->msg_header.type, | ||
| 1035 | frag->msg_header.msg_len, frag->msg_header.seq, 0, | ||
| 1036 | frag->msg_header.frag_len); | ||
| 1037 | |||
| 1038 | /* save current state */ | ||
| 1039 | saved_state.session = s->session; | ||
| 1040 | saved_state.epoch = tls12_record_layer_write_epoch(s->rl); | ||
| 1041 | |||
| 1042 | s->d1->retransmitting = 1; | ||
| 1043 | |||
| 1044 | /* restore state in which the message was originally sent */ | ||
| 1045 | s->session = frag->msg_header.saved_retransmit_state.session; | ||
| 1046 | if (!tls12_record_layer_use_write_epoch(s->rl, | ||
| 1047 | frag->msg_header.saved_retransmit_state.epoch)) | ||
| 1048 | return 0; | ||
| 1049 | |||
| 1050 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? | ||
| 1051 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); | ||
| 1052 | |||
| 1053 | /* restore current state */ | ||
| 1054 | s->session = saved_state.session; | ||
| 1055 | if (!tls12_record_layer_use_write_epoch(s->rl, | ||
| 1056 | saved_state.epoch)) | ||
| 1057 | return 0; | ||
| 1058 | |||
| 1059 | s->d1->retransmitting = 0; | ||
| 1060 | |||
| 1061 | (void)BIO_flush(SSL_get_wbio(s)); | ||
| 1062 | return ret; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* call this function when the buffered messages are no longer needed */ | 1041 | /* call this function when the buffered messages are no longer needed */ |
| 1066 | void | 1042 | void |
| 1067 | dtls1_clear_record_buffer(SSL *s) | 1043 | dtls1_clear_record_buffer(SSL *s) |
| @@ -1074,7 +1050,7 @@ dtls1_clear_record_buffer(SSL *s) | |||
| 1074 | frag = item->data; | 1050 | frag = item->data; |
| 1075 | if (frag->msg_header.is_ccs) | 1051 | if (frag->msg_header.is_ccs) |
| 1076 | tls12_record_layer_write_epoch_done(s->rl, | 1052 | tls12_record_layer_write_epoch_done(s->rl, |
| 1077 | frag->msg_header.saved_retransmit_state.epoch); | 1053 | frag->msg_header.epoch); |
| 1078 | dtls1_hm_fragment_free(frag); | 1054 | dtls1_hm_fragment_free(frag); |
| 1079 | pitem_free(item); | 1055 | pitem_free(item); |
| 1080 | } | 1056 | } |
| @@ -1082,21 +1058,6 @@ dtls1_clear_record_buffer(SSL *s) | |||
| 1082 | 1058 | ||
| 1083 | void | 1059 | void |
| 1084 | dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len, | 1060 | dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len, |
| 1085 | unsigned long frag_off, unsigned long frag_len) | ||
| 1086 | { | ||
| 1087 | /* Don't change sequence numbers while listening */ | ||
| 1088 | if (frag_off == 0 && !s->d1->listen) { | ||
| 1089 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | ||
| 1090 | s->d1->next_handshake_write_seq++; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, | ||
| 1094 | frag_off, frag_len); | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | /* don't actually do the writing, wait till the MTU has been retrieved */ | ||
| 1098 | void | ||
| 1099 | dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len, | ||
| 1100 | unsigned short seq_num, unsigned long frag_off, unsigned long frag_len) | 1061 | unsigned short seq_num, unsigned long frag_off, unsigned long frag_len) |
| 1101 | { | 1062 | { |
| 1102 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | 1063 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; |
| @@ -1108,15 +1069,6 @@ dtls1_set_message_header_int(SSL *s, unsigned char mt, unsigned long len, | |||
| 1108 | msg_hdr->frag_len = frag_len; | 1069 | msg_hdr->frag_len = frag_len; |
| 1109 | } | 1070 | } |
| 1110 | 1071 | ||
| 1111 | static void | ||
| 1112 | dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len) | ||
| 1113 | { | ||
| 1114 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
| 1115 | |||
| 1116 | msg_hdr->frag_off = frag_off; | ||
| 1117 | msg_hdr->frag_len = frag_len; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | static int | 1072 | static int |
| 1121 | dtls1_write_message_header(const struct hm_header_st *msg_hdr, | 1073 | dtls1_write_message_header(const struct hm_header_st *msg_hdr, |
| 1122 | unsigned long frag_off, unsigned long frag_len, unsigned char *p) | 1074 | unsigned long frag_off, unsigned long frag_len, unsigned char *p) |
| @@ -1196,3 +1148,47 @@ dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr) | |||
| 1196 | 1148 | ||
| 1197 | return 1; | 1149 | return 1; |
| 1198 | } | 1150 | } |
| 1151 | |||
| 1152 | int | ||
| 1153 | dtls12_ccs_built(SSL *s) | ||
| 1154 | { | ||
| 1155 | dtls1_set_message_header(s, SSL3_MT_CCS, 0, 0, 0, 0); | ||
| 1156 | |||
| 1157 | if (!dtls1_buffer_message(s, 1)) | ||
| 1158 | return 0; | ||
| 1159 | |||
| 1160 | return 1; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | int | ||
| 1164 | dtls12_handshake_msg_built(SSL *s) | ||
| 1165 | { | ||
| 1166 | unsigned long len; | ||
| 1167 | uint8_t msg_type; | ||
| 1168 | CBS cbs; | ||
| 1169 | |||
| 1170 | CBS_init(&cbs, s->init_buf->data, s->init_num); | ||
| 1171 | if (!CBS_get_u8(&cbs, &msg_type)) | ||
| 1172 | return 0; | ||
| 1173 | |||
| 1174 | if (s->init_off != 0) | ||
| 1175 | return 0; | ||
| 1176 | if (s->init_num < DTLS1_HM_HEADER_LENGTH) | ||
| 1177 | return 0; | ||
| 1178 | |||
| 1179 | len = s->init_num - DTLS1_HM_HEADER_LENGTH; | ||
| 1180 | |||
| 1181 | /* Do not change sequence numbers while listening. */ | ||
| 1182 | if (!s->d1->listen) { | ||
| 1183 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | ||
| 1184 | s->d1->next_handshake_write_seq++; | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | dtls1_set_message_header(s, msg_type, len, s->d1->handshake_write_seq, | ||
| 1188 | 0, len); | ||
| 1189 | |||
| 1190 | if (!dtls1_buffer_message(s, 0)) | ||
| 1191 | return 0; | ||
| 1192 | |||
| 1193 | return 1; | ||
| 1194 | } | ||
