1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <limits.h> 11e1051a39Sopenharmony_ci#include <string.h> 12e1051a39Sopenharmony_ci#include <stdio.h> 13e1051a39Sopenharmony_ci#include "../ssl_local.h" 14e1051a39Sopenharmony_ci#include "statem_local.h" 15e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 16e1051a39Sopenharmony_ci#include <openssl/buffer.h> 17e1051a39Sopenharmony_ci#include <openssl/objects.h> 18e1051a39Sopenharmony_ci#include <openssl/evp.h> 19e1051a39Sopenharmony_ci#include <openssl/x509.h> 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ 24e1051a39Sopenharmony_ci if ((end) - (start) <= 8) { \ 25e1051a39Sopenharmony_ci long ii; \ 26e1051a39Sopenharmony_ci for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ 27e1051a39Sopenharmony_ci } else { \ 28e1051a39Sopenharmony_ci long ii; \ 29e1051a39Sopenharmony_ci bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ 30e1051a39Sopenharmony_ci for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ 31e1051a39Sopenharmony_ci bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ 32e1051a39Sopenharmony_ci } } 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ci#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ 35e1051a39Sopenharmony_ci long ii; \ 36e1051a39Sopenharmony_ci is_complete = 1; \ 37e1051a39Sopenharmony_ci if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ 38e1051a39Sopenharmony_ci if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ 39e1051a39Sopenharmony_ci if (bitmask[ii] != 0xff) { is_complete = 0; break; } } 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_cistatic unsigned char bitmask_start_values[] = 42e1051a39Sopenharmony_ci { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; 43e1051a39Sopenharmony_cistatic unsigned char bitmask_end_values[] = 44e1051a39Sopenharmony_ci { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_cistatic void dtls1_fix_message_header(SSL *s, size_t frag_off, 47e1051a39Sopenharmony_ci size_t frag_len); 48e1051a39Sopenharmony_cistatic unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); 49e1051a39Sopenharmony_cistatic void dtls1_set_message_header_int(SSL *s, unsigned char mt, 50e1051a39Sopenharmony_ci size_t len, 51e1051a39Sopenharmony_ci unsigned short seq_num, 52e1051a39Sopenharmony_ci size_t frag_off, 53e1051a39Sopenharmony_ci size_t frag_len); 54e1051a39Sopenharmony_cistatic int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len); 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_cistatic hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) 57e1051a39Sopenharmony_ci{ 58e1051a39Sopenharmony_ci hm_fragment *frag = NULL; 59e1051a39Sopenharmony_ci unsigned char *buf = NULL; 60e1051a39Sopenharmony_ci unsigned char *bitmask = NULL; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci if ((frag = OPENSSL_zalloc(sizeof(*frag))) == NULL) { 63e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 64e1051a39Sopenharmony_ci return NULL; 65e1051a39Sopenharmony_ci } 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci if (frag_len) { 68e1051a39Sopenharmony_ci if ((buf = OPENSSL_malloc(frag_len)) == NULL) { 69e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 70e1051a39Sopenharmony_ci OPENSSL_free(frag); 71e1051a39Sopenharmony_ci return NULL; 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci } 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci /* zero length fragment gets zero frag->fragment */ 76e1051a39Sopenharmony_ci frag->fragment = buf; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci /* Initialize reassembly bitmask if necessary */ 79e1051a39Sopenharmony_ci if (reassembly) { 80e1051a39Sopenharmony_ci bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len)); 81e1051a39Sopenharmony_ci if (bitmask == NULL) { 82e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); 83e1051a39Sopenharmony_ci OPENSSL_free(buf); 84e1051a39Sopenharmony_ci OPENSSL_free(frag); 85e1051a39Sopenharmony_ci return NULL; 86e1051a39Sopenharmony_ci } 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci frag->reassembly = bitmask; 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci return frag; 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_civoid dtls1_hm_fragment_free(hm_fragment *frag) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci if (!frag) 97e1051a39Sopenharmony_ci return; 98e1051a39Sopenharmony_ci if (frag->msg_header.is_ccs) { 99e1051a39Sopenharmony_ci EVP_CIPHER_CTX_free(frag->msg_header. 100e1051a39Sopenharmony_ci saved_retransmit_state.enc_write_ctx); 101e1051a39Sopenharmony_ci EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash); 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci OPENSSL_free(frag->fragment); 104e1051a39Sopenharmony_ci OPENSSL_free(frag->reassembly); 105e1051a39Sopenharmony_ci OPENSSL_free(frag); 106e1051a39Sopenharmony_ci} 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci/* 109e1051a39Sopenharmony_ci * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or 110e1051a39Sopenharmony_ci * SSL3_RT_CHANGE_CIPHER_SPEC) 111e1051a39Sopenharmony_ci */ 112e1051a39Sopenharmony_ciint dtls1_do_write(SSL *s, int type) 113e1051a39Sopenharmony_ci{ 114e1051a39Sopenharmony_ci int ret; 115e1051a39Sopenharmony_ci size_t written; 116e1051a39Sopenharmony_ci size_t curr_mtu; 117e1051a39Sopenharmony_ci int retry = 1; 118e1051a39Sopenharmony_ci size_t len, frag_off, mac_size, blocksize, used_len; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (!dtls1_query_mtu(s)) 121e1051a39Sopenharmony_ci return -1; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci if (s->d1->mtu < dtls1_min_mtu(s)) 124e1051a39Sopenharmony_ci /* should have something reasonable now */ 125e1051a39Sopenharmony_ci return -1; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) { 128e1051a39Sopenharmony_ci if (!ossl_assert(s->init_num == 129e1051a39Sopenharmony_ci s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH)) 130e1051a39Sopenharmony_ci return -1; 131e1051a39Sopenharmony_ci } 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ci if (s->write_hash) { 134e1051a39Sopenharmony_ci if (s->enc_write_ctx 135e1051a39Sopenharmony_ci && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) & 136e1051a39Sopenharmony_ci EVP_CIPH_FLAG_AEAD_CIPHER) != 0) 137e1051a39Sopenharmony_ci mac_size = 0; 138e1051a39Sopenharmony_ci else 139e1051a39Sopenharmony_ci mac_size = EVP_MD_CTX_get_size(s->write_hash); 140e1051a39Sopenharmony_ci } else 141e1051a39Sopenharmony_ci mac_size = 0; 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ci if (s->enc_write_ctx && 144e1051a39Sopenharmony_ci (EVP_CIPHER_CTX_get_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) 145e1051a39Sopenharmony_ci blocksize = 2 * EVP_CIPHER_CTX_get_block_size(s->enc_write_ctx); 146e1051a39Sopenharmony_ci else 147e1051a39Sopenharmony_ci blocksize = 0; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci frag_off = 0; 150e1051a39Sopenharmony_ci s->rwstate = SSL_NOTHING; 151e1051a39Sopenharmony_ci 152e1051a39Sopenharmony_ci /* s->init_num shouldn't ever be < 0...but just in case */ 153e1051a39Sopenharmony_ci while (s->init_num > 0) { 154e1051a39Sopenharmony_ci if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { 155e1051a39Sopenharmony_ci /* We must be writing a fragment other than the first one */ 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci if (frag_off > 0) { 158e1051a39Sopenharmony_ci /* This is the first attempt at writing out this fragment */ 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { 161e1051a39Sopenharmony_ci /* 162e1051a39Sopenharmony_ci * Each fragment that was already sent must at least have 163e1051a39Sopenharmony_ci * contained the message header plus one other byte. 164e1051a39Sopenharmony_ci * Therefore |init_off| must have progressed by at least 165e1051a39Sopenharmony_ci * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went 166e1051a39Sopenharmony_ci * wrong. 167e1051a39Sopenharmony_ci */ 168e1051a39Sopenharmony_ci return -1; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_ci /* 172e1051a39Sopenharmony_ci * Adjust |init_off| and |init_num| to allow room for a new 173e1051a39Sopenharmony_ci * message header for this fragment. 174e1051a39Sopenharmony_ci */ 175e1051a39Sopenharmony_ci s->init_off -= DTLS1_HM_HEADER_LENGTH; 176e1051a39Sopenharmony_ci s->init_num += DTLS1_HM_HEADER_LENGTH; 177e1051a39Sopenharmony_ci } else { 178e1051a39Sopenharmony_ci /* 179e1051a39Sopenharmony_ci * We must have been called again after a retry so use the 180e1051a39Sopenharmony_ci * fragment offset from our last attempt. We do not need 181e1051a39Sopenharmony_ci * to adjust |init_off| and |init_num| as above, because 182e1051a39Sopenharmony_ci * that should already have been done before the retry. 183e1051a39Sopenharmony_ci */ 184e1051a39Sopenharmony_ci frag_off = s->d1->w_msg_hdr.frag_off; 185e1051a39Sopenharmony_ci } 186e1051a39Sopenharmony_ci } 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH 189e1051a39Sopenharmony_ci + mac_size + blocksize; 190e1051a39Sopenharmony_ci if (s->d1->mtu > used_len) 191e1051a39Sopenharmony_ci curr_mtu = s->d1->mtu - used_len; 192e1051a39Sopenharmony_ci else 193e1051a39Sopenharmony_ci curr_mtu = 0; 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { 196e1051a39Sopenharmony_ci /* 197e1051a39Sopenharmony_ci * grr.. we could get an error if MTU picked was wrong 198e1051a39Sopenharmony_ci */ 199e1051a39Sopenharmony_ci ret = BIO_flush(s->wbio); 200e1051a39Sopenharmony_ci if (ret <= 0) { 201e1051a39Sopenharmony_ci s->rwstate = SSL_WRITING; 202e1051a39Sopenharmony_ci return ret; 203e1051a39Sopenharmony_ci } 204e1051a39Sopenharmony_ci used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; 205e1051a39Sopenharmony_ci if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { 206e1051a39Sopenharmony_ci curr_mtu = s->d1->mtu - used_len; 207e1051a39Sopenharmony_ci } else { 208e1051a39Sopenharmony_ci /* Shouldn't happen */ 209e1051a39Sopenharmony_ci return -1; 210e1051a39Sopenharmony_ci } 211e1051a39Sopenharmony_ci } 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci /* 214e1051a39Sopenharmony_ci * We just checked that s->init_num > 0 so this cast should be safe 215e1051a39Sopenharmony_ci */ 216e1051a39Sopenharmony_ci if (((unsigned int)s->init_num) > curr_mtu) 217e1051a39Sopenharmony_ci len = curr_mtu; 218e1051a39Sopenharmony_ci else 219e1051a39Sopenharmony_ci len = s->init_num; 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci if (len > ssl_get_max_send_fragment(s)) 222e1051a39Sopenharmony_ci len = ssl_get_max_send_fragment(s); 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci /* 225e1051a39Sopenharmony_ci * XDTLS: this function is too long. split out the CCS part 226e1051a39Sopenharmony_ci */ 227e1051a39Sopenharmony_ci if (type == SSL3_RT_HANDSHAKE) { 228e1051a39Sopenharmony_ci if (len < DTLS1_HM_HEADER_LENGTH) { 229e1051a39Sopenharmony_ci /* 230e1051a39Sopenharmony_ci * len is so small that we really can't do anything sensible 231e1051a39Sopenharmony_ci * so fail 232e1051a39Sopenharmony_ci */ 233e1051a39Sopenharmony_ci return -1; 234e1051a39Sopenharmony_ci } 235e1051a39Sopenharmony_ci dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH); 236e1051a39Sopenharmony_ci 237e1051a39Sopenharmony_ci dtls1_write_message_header(s, 238e1051a39Sopenharmony_ci (unsigned char *)&s->init_buf-> 239e1051a39Sopenharmony_ci data[s->init_off]); 240e1051a39Sopenharmony_ci } 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len, 243e1051a39Sopenharmony_ci &written); 244e1051a39Sopenharmony_ci if (ret <= 0) { 245e1051a39Sopenharmony_ci /* 246e1051a39Sopenharmony_ci * might need to update MTU here, but we don't know which 247e1051a39Sopenharmony_ci * previous packet caused the failure -- so can't really 248e1051a39Sopenharmony_ci * retransmit anything. continue as if everything is fine and 249e1051a39Sopenharmony_ci * wait for an alert to handle the retransmit 250e1051a39Sopenharmony_ci */ 251e1051a39Sopenharmony_ci if (retry && BIO_ctrl(SSL_get_wbio(s), 252e1051a39Sopenharmony_ci BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { 253e1051a39Sopenharmony_ci if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { 254e1051a39Sopenharmony_ci if (!dtls1_query_mtu(s)) 255e1051a39Sopenharmony_ci return -1; 256e1051a39Sopenharmony_ci /* Have one more go */ 257e1051a39Sopenharmony_ci retry = 0; 258e1051a39Sopenharmony_ci } else 259e1051a39Sopenharmony_ci return -1; 260e1051a39Sopenharmony_ci } else { 261e1051a39Sopenharmony_ci return -1; 262e1051a39Sopenharmony_ci } 263e1051a39Sopenharmony_ci } else { 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci /* 266e1051a39Sopenharmony_ci * bad if this assert fails, only part of the handshake message 267e1051a39Sopenharmony_ci * got sent. but why would this happen? 268e1051a39Sopenharmony_ci */ 269e1051a39Sopenharmony_ci if (!ossl_assert(len == written)) 270e1051a39Sopenharmony_ci return -1; 271e1051a39Sopenharmony_ci 272e1051a39Sopenharmony_ci if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { 273e1051a39Sopenharmony_ci /* 274e1051a39Sopenharmony_ci * should not be done for 'Hello Request's, but in that case 275e1051a39Sopenharmony_ci * we'll ignore the result anyway 276e1051a39Sopenharmony_ci */ 277e1051a39Sopenharmony_ci unsigned char *p = 278e1051a39Sopenharmony_ci (unsigned char *)&s->init_buf->data[s->init_off]; 279e1051a39Sopenharmony_ci const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; 280e1051a39Sopenharmony_ci size_t xlen; 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci if (frag_off == 0 && s->version != DTLS1_BAD_VER) { 283e1051a39Sopenharmony_ci /* 284e1051a39Sopenharmony_ci * reconstruct message header is if it is being sent in 285e1051a39Sopenharmony_ci * single fragment 286e1051a39Sopenharmony_ci */ 287e1051a39Sopenharmony_ci *p++ = msg_hdr->type; 288e1051a39Sopenharmony_ci l2n3(msg_hdr->msg_len, p); 289e1051a39Sopenharmony_ci s2n(msg_hdr->seq, p); 290e1051a39Sopenharmony_ci l2n3(0, p); 291e1051a39Sopenharmony_ci l2n3(msg_hdr->msg_len, p); 292e1051a39Sopenharmony_ci p -= DTLS1_HM_HEADER_LENGTH; 293e1051a39Sopenharmony_ci xlen = written; 294e1051a39Sopenharmony_ci } else { 295e1051a39Sopenharmony_ci p += DTLS1_HM_HEADER_LENGTH; 296e1051a39Sopenharmony_ci xlen = written - DTLS1_HM_HEADER_LENGTH; 297e1051a39Sopenharmony_ci } 298e1051a39Sopenharmony_ci 299e1051a39Sopenharmony_ci if (!ssl3_finish_mac(s, p, xlen)) 300e1051a39Sopenharmony_ci return -1; 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_ci if (written == s->init_num) { 304e1051a39Sopenharmony_ci if (s->msg_callback) 305e1051a39Sopenharmony_ci s->msg_callback(1, s->version, type, s->init_buf->data, 306e1051a39Sopenharmony_ci (size_t)(s->init_off + s->init_num), s, 307e1051a39Sopenharmony_ci s->msg_callback_arg); 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ci s->init_off = 0; /* done writing this message */ 310e1051a39Sopenharmony_ci s->init_num = 0; 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci return 1; 313e1051a39Sopenharmony_ci } 314e1051a39Sopenharmony_ci s->init_off += written; 315e1051a39Sopenharmony_ci s->init_num -= written; 316e1051a39Sopenharmony_ci written -= DTLS1_HM_HEADER_LENGTH; 317e1051a39Sopenharmony_ci frag_off += written; 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci /* 320e1051a39Sopenharmony_ci * We save the fragment offset for the next fragment so we have it 321e1051a39Sopenharmony_ci * available in case of an IO retry. We don't know the length of the 322e1051a39Sopenharmony_ci * next fragment yet so just set that to 0 for now. It will be 323e1051a39Sopenharmony_ci * updated again later. 324e1051a39Sopenharmony_ci */ 325e1051a39Sopenharmony_ci dtls1_fix_message_header(s, frag_off, 0); 326e1051a39Sopenharmony_ci } 327e1051a39Sopenharmony_ci } 328e1051a39Sopenharmony_ci return 0; 329e1051a39Sopenharmony_ci} 330e1051a39Sopenharmony_ci 331e1051a39Sopenharmony_ciint dtls_get_message(SSL *s, int *mt) 332e1051a39Sopenharmony_ci{ 333e1051a39Sopenharmony_ci struct hm_header_st *msg_hdr; 334e1051a39Sopenharmony_ci unsigned char *p; 335e1051a39Sopenharmony_ci size_t msg_len; 336e1051a39Sopenharmony_ci size_t tmplen; 337e1051a39Sopenharmony_ci int errtype; 338e1051a39Sopenharmony_ci 339e1051a39Sopenharmony_ci msg_hdr = &s->d1->r_msg_hdr; 340e1051a39Sopenharmony_ci memset(msg_hdr, 0, sizeof(*msg_hdr)); 341e1051a39Sopenharmony_ci 342e1051a39Sopenharmony_ci again: 343e1051a39Sopenharmony_ci if (!dtls_get_reassembled_message(s, &errtype, &tmplen)) { 344e1051a39Sopenharmony_ci if (errtype == DTLS1_HM_BAD_FRAGMENT 345e1051a39Sopenharmony_ci || errtype == DTLS1_HM_FRAGMENT_RETRY) { 346e1051a39Sopenharmony_ci /* bad fragment received */ 347e1051a39Sopenharmony_ci goto again; 348e1051a39Sopenharmony_ci } 349e1051a39Sopenharmony_ci return 0; 350e1051a39Sopenharmony_ci } 351e1051a39Sopenharmony_ci 352e1051a39Sopenharmony_ci *mt = s->s3.tmp.message_type; 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci p = (unsigned char *)s->init_buf->data; 355e1051a39Sopenharmony_ci 356e1051a39Sopenharmony_ci if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { 357e1051a39Sopenharmony_ci if (s->msg_callback) { 358e1051a39Sopenharmony_ci s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, 359e1051a39Sopenharmony_ci p, 1, s, s->msg_callback_arg); 360e1051a39Sopenharmony_ci } 361e1051a39Sopenharmony_ci /* 362e1051a39Sopenharmony_ci * This isn't a real handshake message so skip the processing below. 363e1051a39Sopenharmony_ci */ 364e1051a39Sopenharmony_ci return 1; 365e1051a39Sopenharmony_ci } 366e1051a39Sopenharmony_ci 367e1051a39Sopenharmony_ci msg_len = msg_hdr->msg_len; 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_ci /* reconstruct message header */ 370e1051a39Sopenharmony_ci *(p++) = msg_hdr->type; 371e1051a39Sopenharmony_ci l2n3(msg_len, p); 372e1051a39Sopenharmony_ci s2n(msg_hdr->seq, p); 373e1051a39Sopenharmony_ci l2n3(0, p); 374e1051a39Sopenharmony_ci l2n3(msg_len, p); 375e1051a39Sopenharmony_ci 376e1051a39Sopenharmony_ci memset(msg_hdr, 0, sizeof(*msg_hdr)); 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_ci s->d1->handshake_read_seq++; 379e1051a39Sopenharmony_ci 380e1051a39Sopenharmony_ci s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci return 1; 383e1051a39Sopenharmony_ci} 384e1051a39Sopenharmony_ci 385e1051a39Sopenharmony_ci/* 386e1051a39Sopenharmony_ci * Actually we already have the message body - but this is an opportunity for 387e1051a39Sopenharmony_ci * DTLS to do any further processing it wants at the same point that TLS would 388e1051a39Sopenharmony_ci * be asked for the message body. 389e1051a39Sopenharmony_ci */ 390e1051a39Sopenharmony_ciint dtls_get_message_body(SSL *s, size_t *len) 391e1051a39Sopenharmony_ci{ 392e1051a39Sopenharmony_ci unsigned char *msg = (unsigned char *)s->init_buf->data; 393e1051a39Sopenharmony_ci size_t msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { 396e1051a39Sopenharmony_ci /* Nothing to be done */ 397e1051a39Sopenharmony_ci goto end; 398e1051a39Sopenharmony_ci } 399e1051a39Sopenharmony_ci /* 400e1051a39Sopenharmony_ci * If receiving Finished, record MAC of prior handshake messages for 401e1051a39Sopenharmony_ci * Finished verification. 402e1051a39Sopenharmony_ci */ 403e1051a39Sopenharmony_ci if (*(s->init_buf->data) == SSL3_MT_FINISHED && !ssl3_take_mac(s)) { 404e1051a39Sopenharmony_ci /* SSLfatal() already called */ 405e1051a39Sopenharmony_ci return 0; 406e1051a39Sopenharmony_ci } 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_ci if (s->version == DTLS1_BAD_VER) { 409e1051a39Sopenharmony_ci msg += DTLS1_HM_HEADER_LENGTH; 410e1051a39Sopenharmony_ci msg_len -= DTLS1_HM_HEADER_LENGTH; 411e1051a39Sopenharmony_ci } 412e1051a39Sopenharmony_ci 413e1051a39Sopenharmony_ci if (!ssl3_finish_mac(s, msg, msg_len)) 414e1051a39Sopenharmony_ci return 0; 415e1051a39Sopenharmony_ci 416e1051a39Sopenharmony_ci if (s->msg_callback) 417e1051a39Sopenharmony_ci s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 418e1051a39Sopenharmony_ci s->init_buf->data, s->init_num + DTLS1_HM_HEADER_LENGTH, 419e1051a39Sopenharmony_ci s, s->msg_callback_arg); 420e1051a39Sopenharmony_ci 421e1051a39Sopenharmony_ci end: 422e1051a39Sopenharmony_ci *len = s->init_num; 423e1051a39Sopenharmony_ci return 1; 424e1051a39Sopenharmony_ci} 425e1051a39Sopenharmony_ci 426e1051a39Sopenharmony_ci/* 427e1051a39Sopenharmony_ci * dtls1_max_handshake_message_len returns the maximum number of bytes 428e1051a39Sopenharmony_ci * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but 429e1051a39Sopenharmony_ci * may be greater if the maximum certificate list size requires it. 430e1051a39Sopenharmony_ci */ 431e1051a39Sopenharmony_cistatic size_t dtls1_max_handshake_message_len(const SSL *s) 432e1051a39Sopenharmony_ci{ 433e1051a39Sopenharmony_ci size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; 434e1051a39Sopenharmony_ci if (max_len < s->max_cert_list) 435e1051a39Sopenharmony_ci return s->max_cert_list; 436e1051a39Sopenharmony_ci return max_len; 437e1051a39Sopenharmony_ci} 438e1051a39Sopenharmony_ci 439e1051a39Sopenharmony_cistatic int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) 440e1051a39Sopenharmony_ci{ 441e1051a39Sopenharmony_ci size_t frag_off, frag_len, msg_len; 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_ci msg_len = msg_hdr->msg_len; 444e1051a39Sopenharmony_ci frag_off = msg_hdr->frag_off; 445e1051a39Sopenharmony_ci frag_len = msg_hdr->frag_len; 446e1051a39Sopenharmony_ci 447e1051a39Sopenharmony_ci /* sanity checking */ 448e1051a39Sopenharmony_ci if ((frag_off + frag_len) > msg_len 449e1051a39Sopenharmony_ci || msg_len > dtls1_max_handshake_message_len(s)) { 450e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); 451e1051a39Sopenharmony_ci return 0; 452e1051a39Sopenharmony_ci } 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ 455e1051a39Sopenharmony_ci /* 456e1051a39Sopenharmony_ci * msg_len is limited to 2^24, but is effectively checked against 457e1051a39Sopenharmony_ci * dtls_max_handshake_message_len(s) above 458e1051a39Sopenharmony_ci */ 459e1051a39Sopenharmony_ci if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { 460e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); 461e1051a39Sopenharmony_ci return 0; 462e1051a39Sopenharmony_ci } 463e1051a39Sopenharmony_ci 464e1051a39Sopenharmony_ci s->s3.tmp.message_size = msg_len; 465e1051a39Sopenharmony_ci s->d1->r_msg_hdr.msg_len = msg_len; 466e1051a39Sopenharmony_ci s->s3.tmp.message_type = msg_hdr->type; 467e1051a39Sopenharmony_ci s->d1->r_msg_hdr.type = msg_hdr->type; 468e1051a39Sopenharmony_ci s->d1->r_msg_hdr.seq = msg_hdr->seq; 469e1051a39Sopenharmony_ci } else if (msg_len != s->d1->r_msg_hdr.msg_len) { 470e1051a39Sopenharmony_ci /* 471e1051a39Sopenharmony_ci * They must be playing with us! BTW, failure to enforce upper limit 472e1051a39Sopenharmony_ci * would open possibility for buffer overrun. 473e1051a39Sopenharmony_ci */ 474e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); 475e1051a39Sopenharmony_ci return 0; 476e1051a39Sopenharmony_ci } 477e1051a39Sopenharmony_ci 478e1051a39Sopenharmony_ci return 1; 479e1051a39Sopenharmony_ci} 480e1051a39Sopenharmony_ci 481e1051a39Sopenharmony_ci/* 482e1051a39Sopenharmony_ci * Returns 1 if there is a buffered fragment available, 0 if not, or -1 on a 483e1051a39Sopenharmony_ci * fatal error. 484e1051a39Sopenharmony_ci */ 485e1051a39Sopenharmony_cistatic int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) 486e1051a39Sopenharmony_ci{ 487e1051a39Sopenharmony_ci /*- 488e1051a39Sopenharmony_ci * (0) check whether the desired fragment is available 489e1051a39Sopenharmony_ci * if so: 490e1051a39Sopenharmony_ci * (1) copy over the fragment to s->init_buf->data[] 491e1051a39Sopenharmony_ci * (2) update s->init_num 492e1051a39Sopenharmony_ci */ 493e1051a39Sopenharmony_ci pitem *item; 494e1051a39Sopenharmony_ci piterator iter; 495e1051a39Sopenharmony_ci hm_fragment *frag; 496e1051a39Sopenharmony_ci int ret; 497e1051a39Sopenharmony_ci int chretran = 0; 498e1051a39Sopenharmony_ci 499e1051a39Sopenharmony_ci iter = pqueue_iterator(s->d1->buffered_messages); 500e1051a39Sopenharmony_ci do { 501e1051a39Sopenharmony_ci item = pqueue_next(&iter); 502e1051a39Sopenharmony_ci if (item == NULL) 503e1051a39Sopenharmony_ci return 0; 504e1051a39Sopenharmony_ci 505e1051a39Sopenharmony_ci frag = (hm_fragment *)item->data; 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_ci if (frag->msg_header.seq < s->d1->handshake_read_seq) { 508e1051a39Sopenharmony_ci pitem *next; 509e1051a39Sopenharmony_ci hm_fragment *nextfrag; 510e1051a39Sopenharmony_ci 511e1051a39Sopenharmony_ci if (!s->server 512e1051a39Sopenharmony_ci || frag->msg_header.seq != 0 513e1051a39Sopenharmony_ci || s->d1->handshake_read_seq != 1 514e1051a39Sopenharmony_ci || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { 515e1051a39Sopenharmony_ci /* 516e1051a39Sopenharmony_ci * This is a stale message that has been buffered so clear it. 517e1051a39Sopenharmony_ci * It is safe to pop this message from the queue even though 518e1051a39Sopenharmony_ci * we have an active iterator 519e1051a39Sopenharmony_ci */ 520e1051a39Sopenharmony_ci pqueue_pop(s->d1->buffered_messages); 521e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 522e1051a39Sopenharmony_ci pitem_free(item); 523e1051a39Sopenharmony_ci item = NULL; 524e1051a39Sopenharmony_ci frag = NULL; 525e1051a39Sopenharmony_ci } else { 526e1051a39Sopenharmony_ci /* 527e1051a39Sopenharmony_ci * We have fragments for a ClientHello without a cookie, 528e1051a39Sopenharmony_ci * even though we have sent a HelloVerifyRequest. It is possible 529e1051a39Sopenharmony_ci * that the HelloVerifyRequest got lost and this is a 530e1051a39Sopenharmony_ci * retransmission of the original ClientHello 531e1051a39Sopenharmony_ci */ 532e1051a39Sopenharmony_ci next = pqueue_next(&iter); 533e1051a39Sopenharmony_ci if (next != NULL) { 534e1051a39Sopenharmony_ci nextfrag = (hm_fragment *)next->data; 535e1051a39Sopenharmony_ci if (nextfrag->msg_header.seq == s->d1->handshake_read_seq) { 536e1051a39Sopenharmony_ci /* 537e1051a39Sopenharmony_ci * We have fragments for both a ClientHello without 538e1051a39Sopenharmony_ci * cookie and one with. Ditch the one without. 539e1051a39Sopenharmony_ci */ 540e1051a39Sopenharmony_ci pqueue_pop(s->d1->buffered_messages); 541e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 542e1051a39Sopenharmony_ci pitem_free(item); 543e1051a39Sopenharmony_ci item = next; 544e1051a39Sopenharmony_ci frag = nextfrag; 545e1051a39Sopenharmony_ci } else { 546e1051a39Sopenharmony_ci chretran = 1; 547e1051a39Sopenharmony_ci } 548e1051a39Sopenharmony_ci } else { 549e1051a39Sopenharmony_ci chretran = 1; 550e1051a39Sopenharmony_ci } 551e1051a39Sopenharmony_ci } 552e1051a39Sopenharmony_ci } 553e1051a39Sopenharmony_ci } while (item == NULL); 554e1051a39Sopenharmony_ci 555e1051a39Sopenharmony_ci /* Don't return if reassembly still in progress */ 556e1051a39Sopenharmony_ci if (frag->reassembly != NULL) 557e1051a39Sopenharmony_ci return 0; 558e1051a39Sopenharmony_ci 559e1051a39Sopenharmony_ci if (s->d1->handshake_read_seq == frag->msg_header.seq || chretran) { 560e1051a39Sopenharmony_ci size_t frag_len = frag->msg_header.frag_len; 561e1051a39Sopenharmony_ci pqueue_pop(s->d1->buffered_messages); 562e1051a39Sopenharmony_ci 563e1051a39Sopenharmony_ci /* Calls SSLfatal() as required */ 564e1051a39Sopenharmony_ci ret = dtls1_preprocess_fragment(s, &frag->msg_header); 565e1051a39Sopenharmony_ci 566e1051a39Sopenharmony_ci if (ret && frag->msg_header.frag_len > 0) { 567e1051a39Sopenharmony_ci unsigned char *p = 568e1051a39Sopenharmony_ci (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; 569e1051a39Sopenharmony_ci memcpy(&p[frag->msg_header.frag_off], frag->fragment, 570e1051a39Sopenharmony_ci frag->msg_header.frag_len); 571e1051a39Sopenharmony_ci } 572e1051a39Sopenharmony_ci 573e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 574e1051a39Sopenharmony_ci pitem_free(item); 575e1051a39Sopenharmony_ci 576e1051a39Sopenharmony_ci if (ret) { 577e1051a39Sopenharmony_ci if (chretran) { 578e1051a39Sopenharmony_ci /* 579e1051a39Sopenharmony_ci * We got a new ClientHello with a message sequence of 0. 580e1051a39Sopenharmony_ci * Reset the read/write sequences back to the beginning. 581e1051a39Sopenharmony_ci * We process it like this is the first time we've seen a 582e1051a39Sopenharmony_ci * ClientHello from the client. 583e1051a39Sopenharmony_ci */ 584e1051a39Sopenharmony_ci s->d1->handshake_read_seq = 0; 585e1051a39Sopenharmony_ci s->d1->next_handshake_write_seq = 0; 586e1051a39Sopenharmony_ci } 587e1051a39Sopenharmony_ci *len = frag_len; 588e1051a39Sopenharmony_ci return 1; 589e1051a39Sopenharmony_ci } 590e1051a39Sopenharmony_ci 591e1051a39Sopenharmony_ci /* Fatal error */ 592e1051a39Sopenharmony_ci s->init_num = 0; 593e1051a39Sopenharmony_ci return -1; 594e1051a39Sopenharmony_ci } else { 595e1051a39Sopenharmony_ci return 0; 596e1051a39Sopenharmony_ci } 597e1051a39Sopenharmony_ci} 598e1051a39Sopenharmony_ci 599e1051a39Sopenharmony_cistatic int 600e1051a39Sopenharmony_cidtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr) 601e1051a39Sopenharmony_ci{ 602e1051a39Sopenharmony_ci hm_fragment *frag = NULL; 603e1051a39Sopenharmony_ci pitem *item = NULL; 604e1051a39Sopenharmony_ci int i = -1, is_complete; 605e1051a39Sopenharmony_ci unsigned char seq64be[8]; 606e1051a39Sopenharmony_ci size_t frag_len = msg_hdr->frag_len; 607e1051a39Sopenharmony_ci size_t readbytes; 608e1051a39Sopenharmony_ci 609e1051a39Sopenharmony_ci if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || 610e1051a39Sopenharmony_ci msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) 611e1051a39Sopenharmony_ci goto err; 612e1051a39Sopenharmony_ci 613e1051a39Sopenharmony_ci if (frag_len == 0) { 614e1051a39Sopenharmony_ci return DTLS1_HM_FRAGMENT_RETRY; 615e1051a39Sopenharmony_ci } 616e1051a39Sopenharmony_ci 617e1051a39Sopenharmony_ci /* Try to find item in queue */ 618e1051a39Sopenharmony_ci memset(seq64be, 0, sizeof(seq64be)); 619e1051a39Sopenharmony_ci seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); 620e1051a39Sopenharmony_ci seq64be[7] = (unsigned char)msg_hdr->seq; 621e1051a39Sopenharmony_ci item = pqueue_find(s->d1->buffered_messages, seq64be); 622e1051a39Sopenharmony_ci 623e1051a39Sopenharmony_ci if (item == NULL) { 624e1051a39Sopenharmony_ci frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); 625e1051a39Sopenharmony_ci if (frag == NULL) 626e1051a39Sopenharmony_ci goto err; 627e1051a39Sopenharmony_ci memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); 628e1051a39Sopenharmony_ci frag->msg_header.frag_len = frag->msg_header.msg_len; 629e1051a39Sopenharmony_ci frag->msg_header.frag_off = 0; 630e1051a39Sopenharmony_ci } else { 631e1051a39Sopenharmony_ci frag = (hm_fragment *)item->data; 632e1051a39Sopenharmony_ci if (frag->msg_header.msg_len != msg_hdr->msg_len) { 633e1051a39Sopenharmony_ci item = NULL; 634e1051a39Sopenharmony_ci frag = NULL; 635e1051a39Sopenharmony_ci goto err; 636e1051a39Sopenharmony_ci } 637e1051a39Sopenharmony_ci } 638e1051a39Sopenharmony_ci 639e1051a39Sopenharmony_ci /* 640e1051a39Sopenharmony_ci * If message is already reassembled, this must be a retransmit and can 641e1051a39Sopenharmony_ci * be dropped. In this case item != NULL and so frag does not need to be 642e1051a39Sopenharmony_ci * freed. 643e1051a39Sopenharmony_ci */ 644e1051a39Sopenharmony_ci if (frag->reassembly == NULL) { 645e1051a39Sopenharmony_ci unsigned char devnull[256]; 646e1051a39Sopenharmony_ci 647e1051a39Sopenharmony_ci while (frag_len) { 648e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, 649e1051a39Sopenharmony_ci devnull, 650e1051a39Sopenharmony_ci frag_len > 651e1051a39Sopenharmony_ci sizeof(devnull) ? sizeof(devnull) : 652e1051a39Sopenharmony_ci frag_len, 0, &readbytes); 653e1051a39Sopenharmony_ci if (i <= 0) 654e1051a39Sopenharmony_ci goto err; 655e1051a39Sopenharmony_ci frag_len -= readbytes; 656e1051a39Sopenharmony_ci } 657e1051a39Sopenharmony_ci return DTLS1_HM_FRAGMENT_RETRY; 658e1051a39Sopenharmony_ci } 659e1051a39Sopenharmony_ci 660e1051a39Sopenharmony_ci /* read the body of the fragment (header has already been read */ 661e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, 662e1051a39Sopenharmony_ci frag->fragment + msg_hdr->frag_off, 663e1051a39Sopenharmony_ci frag_len, 0, &readbytes); 664e1051a39Sopenharmony_ci if (i <= 0 || readbytes != frag_len) 665e1051a39Sopenharmony_ci i = -1; 666e1051a39Sopenharmony_ci if (i <= 0) 667e1051a39Sopenharmony_ci goto err; 668e1051a39Sopenharmony_ci 669e1051a39Sopenharmony_ci RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, 670e1051a39Sopenharmony_ci (long)(msg_hdr->frag_off + frag_len)); 671e1051a39Sopenharmony_ci 672e1051a39Sopenharmony_ci if (!ossl_assert(msg_hdr->msg_len > 0)) 673e1051a39Sopenharmony_ci goto err; 674e1051a39Sopenharmony_ci RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, 675e1051a39Sopenharmony_ci is_complete); 676e1051a39Sopenharmony_ci 677e1051a39Sopenharmony_ci if (is_complete) { 678e1051a39Sopenharmony_ci OPENSSL_free(frag->reassembly); 679e1051a39Sopenharmony_ci frag->reassembly = NULL; 680e1051a39Sopenharmony_ci } 681e1051a39Sopenharmony_ci 682e1051a39Sopenharmony_ci if (item == NULL) { 683e1051a39Sopenharmony_ci item = pitem_new(seq64be, frag); 684e1051a39Sopenharmony_ci if (item == NULL) { 685e1051a39Sopenharmony_ci i = -1; 686e1051a39Sopenharmony_ci goto err; 687e1051a39Sopenharmony_ci } 688e1051a39Sopenharmony_ci 689e1051a39Sopenharmony_ci item = pqueue_insert(s->d1->buffered_messages, item); 690e1051a39Sopenharmony_ci /* 691e1051a39Sopenharmony_ci * pqueue_insert fails iff a duplicate item is inserted. However, 692e1051a39Sopenharmony_ci * |item| cannot be a duplicate. If it were, |pqueue_find|, above, 693e1051a39Sopenharmony_ci * would have returned it and control would never have reached this 694e1051a39Sopenharmony_ci * branch. 695e1051a39Sopenharmony_ci */ 696e1051a39Sopenharmony_ci if (!ossl_assert(item != NULL)) 697e1051a39Sopenharmony_ci goto err; 698e1051a39Sopenharmony_ci } 699e1051a39Sopenharmony_ci 700e1051a39Sopenharmony_ci return DTLS1_HM_FRAGMENT_RETRY; 701e1051a39Sopenharmony_ci 702e1051a39Sopenharmony_ci err: 703e1051a39Sopenharmony_ci if (item == NULL) 704e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 705e1051a39Sopenharmony_ci return -1; 706e1051a39Sopenharmony_ci} 707e1051a39Sopenharmony_ci 708e1051a39Sopenharmony_cistatic int 709e1051a39Sopenharmony_cidtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr) 710e1051a39Sopenharmony_ci{ 711e1051a39Sopenharmony_ci int i = -1; 712e1051a39Sopenharmony_ci hm_fragment *frag = NULL; 713e1051a39Sopenharmony_ci pitem *item = NULL; 714e1051a39Sopenharmony_ci unsigned char seq64be[8]; 715e1051a39Sopenharmony_ci size_t frag_len = msg_hdr->frag_len; 716e1051a39Sopenharmony_ci size_t readbytes; 717e1051a39Sopenharmony_ci 718e1051a39Sopenharmony_ci if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) 719e1051a39Sopenharmony_ci goto err; 720e1051a39Sopenharmony_ci 721e1051a39Sopenharmony_ci /* Try to find item in queue, to prevent duplicate entries */ 722e1051a39Sopenharmony_ci memset(seq64be, 0, sizeof(seq64be)); 723e1051a39Sopenharmony_ci seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); 724e1051a39Sopenharmony_ci seq64be[7] = (unsigned char)msg_hdr->seq; 725e1051a39Sopenharmony_ci item = pqueue_find(s->d1->buffered_messages, seq64be); 726e1051a39Sopenharmony_ci 727e1051a39Sopenharmony_ci /* 728e1051a39Sopenharmony_ci * If we already have an entry and this one is a fragment, don't discard 729e1051a39Sopenharmony_ci * it and rather try to reassemble it. 730e1051a39Sopenharmony_ci */ 731e1051a39Sopenharmony_ci if (item != NULL && frag_len != msg_hdr->msg_len) 732e1051a39Sopenharmony_ci item = NULL; 733e1051a39Sopenharmony_ci 734e1051a39Sopenharmony_ci /* 735e1051a39Sopenharmony_ci * Discard the message if sequence number was already there, is too far 736e1051a39Sopenharmony_ci * in the future, already in the queue or if we received a FINISHED 737e1051a39Sopenharmony_ci * before the SERVER_HELLO, which then must be a stale retransmit. 738e1051a39Sopenharmony_ci */ 739e1051a39Sopenharmony_ci if (msg_hdr->seq <= s->d1->handshake_read_seq || 740e1051a39Sopenharmony_ci msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || 741e1051a39Sopenharmony_ci (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) { 742e1051a39Sopenharmony_ci unsigned char devnull[256]; 743e1051a39Sopenharmony_ci 744e1051a39Sopenharmony_ci while (frag_len) { 745e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, 746e1051a39Sopenharmony_ci devnull, 747e1051a39Sopenharmony_ci frag_len > 748e1051a39Sopenharmony_ci sizeof(devnull) ? sizeof(devnull) : 749e1051a39Sopenharmony_ci frag_len, 0, &readbytes); 750e1051a39Sopenharmony_ci if (i <= 0) 751e1051a39Sopenharmony_ci goto err; 752e1051a39Sopenharmony_ci frag_len -= readbytes; 753e1051a39Sopenharmony_ci } 754e1051a39Sopenharmony_ci } else { 755e1051a39Sopenharmony_ci if (frag_len != msg_hdr->msg_len) { 756e1051a39Sopenharmony_ci return dtls1_reassemble_fragment(s, msg_hdr); 757e1051a39Sopenharmony_ci } 758e1051a39Sopenharmony_ci 759e1051a39Sopenharmony_ci if (frag_len > dtls1_max_handshake_message_len(s)) 760e1051a39Sopenharmony_ci goto err; 761e1051a39Sopenharmony_ci 762e1051a39Sopenharmony_ci frag = dtls1_hm_fragment_new(frag_len, 0); 763e1051a39Sopenharmony_ci if (frag == NULL) 764e1051a39Sopenharmony_ci goto err; 765e1051a39Sopenharmony_ci 766e1051a39Sopenharmony_ci memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); 767e1051a39Sopenharmony_ci 768e1051a39Sopenharmony_ci if (frag_len) { 769e1051a39Sopenharmony_ci /* 770e1051a39Sopenharmony_ci * read the body of the fragment (header has already been read 771e1051a39Sopenharmony_ci */ 772e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, 773e1051a39Sopenharmony_ci frag->fragment, frag_len, 0, 774e1051a39Sopenharmony_ci &readbytes); 775e1051a39Sopenharmony_ci if (i<=0 || readbytes != frag_len) 776e1051a39Sopenharmony_ci i = -1; 777e1051a39Sopenharmony_ci if (i <= 0) 778e1051a39Sopenharmony_ci goto err; 779e1051a39Sopenharmony_ci } 780e1051a39Sopenharmony_ci 781e1051a39Sopenharmony_ci item = pitem_new(seq64be, frag); 782e1051a39Sopenharmony_ci if (item == NULL) 783e1051a39Sopenharmony_ci goto err; 784e1051a39Sopenharmony_ci 785e1051a39Sopenharmony_ci item = pqueue_insert(s->d1->buffered_messages, item); 786e1051a39Sopenharmony_ci /* 787e1051a39Sopenharmony_ci * pqueue_insert fails iff a duplicate item is inserted. However, 788e1051a39Sopenharmony_ci * |item| cannot be a duplicate. If it were, |pqueue_find|, above, 789e1051a39Sopenharmony_ci * would have returned it. Then, either |frag_len| != 790e1051a39Sopenharmony_ci * |msg_hdr->msg_len| in which case |item| is set to NULL and it will 791e1051a39Sopenharmony_ci * have been processed with |dtls1_reassemble_fragment|, above, or 792e1051a39Sopenharmony_ci * the record will have been discarded. 793e1051a39Sopenharmony_ci */ 794e1051a39Sopenharmony_ci if (!ossl_assert(item != NULL)) 795e1051a39Sopenharmony_ci goto err; 796e1051a39Sopenharmony_ci } 797e1051a39Sopenharmony_ci 798e1051a39Sopenharmony_ci return DTLS1_HM_FRAGMENT_RETRY; 799e1051a39Sopenharmony_ci 800e1051a39Sopenharmony_ci err: 801e1051a39Sopenharmony_ci if (item == NULL) 802e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 803e1051a39Sopenharmony_ci return 0; 804e1051a39Sopenharmony_ci} 805e1051a39Sopenharmony_ci 806e1051a39Sopenharmony_cistatic int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) 807e1051a39Sopenharmony_ci{ 808e1051a39Sopenharmony_ci unsigned char wire[DTLS1_HM_HEADER_LENGTH]; 809e1051a39Sopenharmony_ci size_t mlen, frag_off, frag_len; 810e1051a39Sopenharmony_ci int i, ret, recvd_type; 811e1051a39Sopenharmony_ci struct hm_header_st msg_hdr; 812e1051a39Sopenharmony_ci size_t readbytes; 813e1051a39Sopenharmony_ci int chretran = 0; 814e1051a39Sopenharmony_ci 815e1051a39Sopenharmony_ci *errtype = 0; 816e1051a39Sopenharmony_ci 817e1051a39Sopenharmony_ci redo: 818e1051a39Sopenharmony_ci /* see if we have the required fragment already */ 819e1051a39Sopenharmony_ci ret = dtls1_retrieve_buffered_fragment(s, &frag_len); 820e1051a39Sopenharmony_ci if (ret < 0) { 821e1051a39Sopenharmony_ci /* SSLfatal() already called */ 822e1051a39Sopenharmony_ci return 0; 823e1051a39Sopenharmony_ci } 824e1051a39Sopenharmony_ci if (ret > 0) { 825e1051a39Sopenharmony_ci s->init_num = frag_len; 826e1051a39Sopenharmony_ci *len = frag_len; 827e1051a39Sopenharmony_ci return 1; 828e1051a39Sopenharmony_ci } 829e1051a39Sopenharmony_ci 830e1051a39Sopenharmony_ci /* read handshake message header */ 831e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, wire, 832e1051a39Sopenharmony_ci DTLS1_HM_HEADER_LENGTH, 0, &readbytes); 833e1051a39Sopenharmony_ci if (i <= 0) { /* nbio, or an error */ 834e1051a39Sopenharmony_ci s->rwstate = SSL_READING; 835e1051a39Sopenharmony_ci *len = 0; 836e1051a39Sopenharmony_ci return 0; 837e1051a39Sopenharmony_ci } 838e1051a39Sopenharmony_ci if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { 839e1051a39Sopenharmony_ci if (wire[0] != SSL3_MT_CCS) { 840e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, 841e1051a39Sopenharmony_ci SSL_R_BAD_CHANGE_CIPHER_SPEC); 842e1051a39Sopenharmony_ci goto f_err; 843e1051a39Sopenharmony_ci } 844e1051a39Sopenharmony_ci 845e1051a39Sopenharmony_ci memcpy(s->init_buf->data, wire, readbytes); 846e1051a39Sopenharmony_ci s->init_num = readbytes - 1; 847e1051a39Sopenharmony_ci s->init_msg = s->init_buf->data + 1; 848e1051a39Sopenharmony_ci s->s3.tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC; 849e1051a39Sopenharmony_ci s->s3.tmp.message_size = readbytes - 1; 850e1051a39Sopenharmony_ci *len = readbytes - 1; 851e1051a39Sopenharmony_ci return 1; 852e1051a39Sopenharmony_ci } 853e1051a39Sopenharmony_ci 854e1051a39Sopenharmony_ci /* Handshake fails if message header is incomplete */ 855e1051a39Sopenharmony_ci if (readbytes != DTLS1_HM_HEADER_LENGTH) { 856e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); 857e1051a39Sopenharmony_ci goto f_err; 858e1051a39Sopenharmony_ci } 859e1051a39Sopenharmony_ci 860e1051a39Sopenharmony_ci /* parse the message fragment header */ 861e1051a39Sopenharmony_ci dtls1_get_message_header(wire, &msg_hdr); 862e1051a39Sopenharmony_ci 863e1051a39Sopenharmony_ci mlen = msg_hdr.msg_len; 864e1051a39Sopenharmony_ci frag_off = msg_hdr.frag_off; 865e1051a39Sopenharmony_ci frag_len = msg_hdr.frag_len; 866e1051a39Sopenharmony_ci 867e1051a39Sopenharmony_ci /* 868e1051a39Sopenharmony_ci * We must have at least frag_len bytes left in the record to be read. 869e1051a39Sopenharmony_ci * Fragments must not span records. 870e1051a39Sopenharmony_ci */ 871e1051a39Sopenharmony_ci if (frag_len > RECORD_LAYER_get_rrec_length(&s->rlayer)) { 872e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); 873e1051a39Sopenharmony_ci goto f_err; 874e1051a39Sopenharmony_ci } 875e1051a39Sopenharmony_ci 876e1051a39Sopenharmony_ci /* 877e1051a39Sopenharmony_ci * if this is a future (or stale) message it gets buffered 878e1051a39Sopenharmony_ci * (or dropped)--no further processing at this time 879e1051a39Sopenharmony_ci * While listening, we accept seq 1 (ClientHello with cookie) 880e1051a39Sopenharmony_ci * although we're still expecting seq 0 (ClientHello) 881e1051a39Sopenharmony_ci */ 882e1051a39Sopenharmony_ci if (msg_hdr.seq != s->d1->handshake_read_seq) { 883e1051a39Sopenharmony_ci if (!s->server 884e1051a39Sopenharmony_ci || msg_hdr.seq != 0 885e1051a39Sopenharmony_ci || s->d1->handshake_read_seq != 1 886e1051a39Sopenharmony_ci || wire[0] != SSL3_MT_CLIENT_HELLO 887e1051a39Sopenharmony_ci || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { 888e1051a39Sopenharmony_ci *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); 889e1051a39Sopenharmony_ci return 0; 890e1051a39Sopenharmony_ci } 891e1051a39Sopenharmony_ci /* 892e1051a39Sopenharmony_ci * We received a ClientHello and sent back a HelloVerifyRequest. We 893e1051a39Sopenharmony_ci * now seem to have received a retransmitted initial ClientHello. That 894e1051a39Sopenharmony_ci * is allowed (possibly our HelloVerifyRequest got lost). 895e1051a39Sopenharmony_ci */ 896e1051a39Sopenharmony_ci chretran = 1; 897e1051a39Sopenharmony_ci } 898e1051a39Sopenharmony_ci 899e1051a39Sopenharmony_ci if (frag_len && frag_len < mlen) { 900e1051a39Sopenharmony_ci *errtype = dtls1_reassemble_fragment(s, &msg_hdr); 901e1051a39Sopenharmony_ci return 0; 902e1051a39Sopenharmony_ci } 903e1051a39Sopenharmony_ci 904e1051a39Sopenharmony_ci if (!s->server 905e1051a39Sopenharmony_ci && s->d1->r_msg_hdr.frag_off == 0 906e1051a39Sopenharmony_ci && s->statem.hand_state != TLS_ST_OK 907e1051a39Sopenharmony_ci && wire[0] == SSL3_MT_HELLO_REQUEST) { 908e1051a39Sopenharmony_ci /* 909e1051a39Sopenharmony_ci * The server may always send 'Hello Request' messages -- we are 910e1051a39Sopenharmony_ci * doing a handshake anyway now, so ignore them if their format is 911e1051a39Sopenharmony_ci * correct. Does not count for 'Finished' MAC. 912e1051a39Sopenharmony_ci */ 913e1051a39Sopenharmony_ci if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { 914e1051a39Sopenharmony_ci if (s->msg_callback) 915e1051a39Sopenharmony_ci s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 916e1051a39Sopenharmony_ci wire, DTLS1_HM_HEADER_LENGTH, s, 917e1051a39Sopenharmony_ci s->msg_callback_arg); 918e1051a39Sopenharmony_ci 919e1051a39Sopenharmony_ci s->init_num = 0; 920e1051a39Sopenharmony_ci goto redo; 921e1051a39Sopenharmony_ci } else { /* Incorrectly formatted Hello request */ 922e1051a39Sopenharmony_ci 923e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); 924e1051a39Sopenharmony_ci goto f_err; 925e1051a39Sopenharmony_ci } 926e1051a39Sopenharmony_ci } 927e1051a39Sopenharmony_ci 928e1051a39Sopenharmony_ci if (!dtls1_preprocess_fragment(s, &msg_hdr)) { 929e1051a39Sopenharmony_ci /* SSLfatal() already called */ 930e1051a39Sopenharmony_ci goto f_err; 931e1051a39Sopenharmony_ci } 932e1051a39Sopenharmony_ci 933e1051a39Sopenharmony_ci if (frag_len > 0) { 934e1051a39Sopenharmony_ci unsigned char *p = 935e1051a39Sopenharmony_ci (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; 936e1051a39Sopenharmony_ci 937e1051a39Sopenharmony_ci i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, 938e1051a39Sopenharmony_ci &p[frag_off], frag_len, 0, &readbytes); 939e1051a39Sopenharmony_ci 940e1051a39Sopenharmony_ci /* 941e1051a39Sopenharmony_ci * This shouldn't ever fail due to NBIO because we already checked 942e1051a39Sopenharmony_ci * that we have enough data in the record 943e1051a39Sopenharmony_ci */ 944e1051a39Sopenharmony_ci if (i <= 0) { 945e1051a39Sopenharmony_ci s->rwstate = SSL_READING; 946e1051a39Sopenharmony_ci *len = 0; 947e1051a39Sopenharmony_ci return 0; 948e1051a39Sopenharmony_ci } 949e1051a39Sopenharmony_ci } else { 950e1051a39Sopenharmony_ci readbytes = 0; 951e1051a39Sopenharmony_ci } 952e1051a39Sopenharmony_ci 953e1051a39Sopenharmony_ci /* 954e1051a39Sopenharmony_ci * XDTLS: an incorrectly formatted fragment should cause the handshake 955e1051a39Sopenharmony_ci * to fail 956e1051a39Sopenharmony_ci */ 957e1051a39Sopenharmony_ci if (readbytes != frag_len) { 958e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); 959e1051a39Sopenharmony_ci goto f_err; 960e1051a39Sopenharmony_ci } 961e1051a39Sopenharmony_ci 962e1051a39Sopenharmony_ci if (chretran) { 963e1051a39Sopenharmony_ci /* 964e1051a39Sopenharmony_ci * We got a new ClientHello with a message sequence of 0. 965e1051a39Sopenharmony_ci * Reset the read/write sequences back to the beginning. 966e1051a39Sopenharmony_ci * We process it like this is the first time we've seen a ClientHello 967e1051a39Sopenharmony_ci * from the client. 968e1051a39Sopenharmony_ci */ 969e1051a39Sopenharmony_ci s->d1->handshake_read_seq = 0; 970e1051a39Sopenharmony_ci s->d1->next_handshake_write_seq = 0; 971e1051a39Sopenharmony_ci } 972e1051a39Sopenharmony_ci 973e1051a39Sopenharmony_ci /* 974e1051a39Sopenharmony_ci * Note that s->init_num is *not* used as current offset in 975e1051a39Sopenharmony_ci * s->init_buf->data, but as a counter summing up fragments' lengths: as 976e1051a39Sopenharmony_ci * soon as they sum up to handshake packet length, we assume we have got 977e1051a39Sopenharmony_ci * all the fragments. 978e1051a39Sopenharmony_ci */ 979e1051a39Sopenharmony_ci *len = s->init_num = frag_len; 980e1051a39Sopenharmony_ci return 1; 981e1051a39Sopenharmony_ci 982e1051a39Sopenharmony_ci f_err: 983e1051a39Sopenharmony_ci s->init_num = 0; 984e1051a39Sopenharmony_ci *len = 0; 985e1051a39Sopenharmony_ci return 0; 986e1051a39Sopenharmony_ci} 987e1051a39Sopenharmony_ci 988e1051a39Sopenharmony_ci/*- 989e1051a39Sopenharmony_ci * for these 2 messages, we need to 990e1051a39Sopenharmony_ci * ssl->enc_read_ctx re-init 991e1051a39Sopenharmony_ci * ssl->rlayer.read_sequence zero 992e1051a39Sopenharmony_ci * ssl->s3.read_mac_secret re-init 993e1051a39Sopenharmony_ci * ssl->session->read_sym_enc assign 994e1051a39Sopenharmony_ci * ssl->session->read_compression assign 995e1051a39Sopenharmony_ci * ssl->session->read_hash assign 996e1051a39Sopenharmony_ci */ 997e1051a39Sopenharmony_ciint dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) 998e1051a39Sopenharmony_ci{ 999e1051a39Sopenharmony_ci if (s->version == DTLS1_BAD_VER) { 1000e1051a39Sopenharmony_ci s->d1->next_handshake_write_seq++; 1001e1051a39Sopenharmony_ci 1002e1051a39Sopenharmony_ci if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) { 1003e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 1004e1051a39Sopenharmony_ci return 0; 1005e1051a39Sopenharmony_ci } 1006e1051a39Sopenharmony_ci } 1007e1051a39Sopenharmony_ci 1008e1051a39Sopenharmony_ci return 1; 1009e1051a39Sopenharmony_ci} 1010e1051a39Sopenharmony_ci 1011e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCTP 1012e1051a39Sopenharmony_ci/* 1013e1051a39Sopenharmony_ci * Wait for a dry event. Should only be called at a point in the handshake 1014e1051a39Sopenharmony_ci * where we are not expecting any data from the peer except an alert. 1015e1051a39Sopenharmony_ci */ 1016e1051a39Sopenharmony_ciWORK_STATE dtls_wait_for_dry(SSL *s) 1017e1051a39Sopenharmony_ci{ 1018e1051a39Sopenharmony_ci int ret, errtype; 1019e1051a39Sopenharmony_ci size_t len; 1020e1051a39Sopenharmony_ci 1021e1051a39Sopenharmony_ci /* read app data until dry event */ 1022e1051a39Sopenharmony_ci ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); 1023e1051a39Sopenharmony_ci if (ret < 0) { 1024e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 1025e1051a39Sopenharmony_ci return WORK_ERROR; 1026e1051a39Sopenharmony_ci } 1027e1051a39Sopenharmony_ci 1028e1051a39Sopenharmony_ci if (ret == 0) { 1029e1051a39Sopenharmony_ci /* 1030e1051a39Sopenharmony_ci * We're not expecting any more messages from the peer at this point - 1031e1051a39Sopenharmony_ci * but we could get an alert. If an alert is waiting then we will never 1032e1051a39Sopenharmony_ci * return successfully. Therefore we attempt to read a message. This 1033e1051a39Sopenharmony_ci * should never succeed but will process any waiting alerts. 1034e1051a39Sopenharmony_ci */ 1035e1051a39Sopenharmony_ci if (dtls_get_reassembled_message(s, &errtype, &len)) { 1036e1051a39Sopenharmony_ci /* The call succeeded! This should never happen */ 1037e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); 1038e1051a39Sopenharmony_ci return WORK_ERROR; 1039e1051a39Sopenharmony_ci } 1040e1051a39Sopenharmony_ci 1041e1051a39Sopenharmony_ci s->s3.in_read_app_data = 2; 1042e1051a39Sopenharmony_ci s->rwstate = SSL_READING; 1043e1051a39Sopenharmony_ci BIO_clear_retry_flags(SSL_get_rbio(s)); 1044e1051a39Sopenharmony_ci BIO_set_retry_read(SSL_get_rbio(s)); 1045e1051a39Sopenharmony_ci return WORK_MORE_A; 1046e1051a39Sopenharmony_ci } 1047e1051a39Sopenharmony_ci return WORK_FINISHED_CONTINUE; 1048e1051a39Sopenharmony_ci} 1049e1051a39Sopenharmony_ci#endif 1050e1051a39Sopenharmony_ci 1051e1051a39Sopenharmony_ciint dtls1_read_failed(SSL *s, int code) 1052e1051a39Sopenharmony_ci{ 1053e1051a39Sopenharmony_ci if (code > 0) { 1054e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 1055e1051a39Sopenharmony_ci return 0; 1056e1051a39Sopenharmony_ci } 1057e1051a39Sopenharmony_ci 1058e1051a39Sopenharmony_ci if (!dtls1_is_timer_expired(s) || ossl_statem_in_error(s)) { 1059e1051a39Sopenharmony_ci /* 1060e1051a39Sopenharmony_ci * not a timeout, none of our business, let higher layers handle 1061e1051a39Sopenharmony_ci * this. in fact it's probably an error 1062e1051a39Sopenharmony_ci */ 1063e1051a39Sopenharmony_ci return code; 1064e1051a39Sopenharmony_ci } 1065e1051a39Sopenharmony_ci /* done, no need to send a retransmit */ 1066e1051a39Sopenharmony_ci if (!SSL_in_init(s)) 1067e1051a39Sopenharmony_ci { 1068e1051a39Sopenharmony_ci BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); 1069e1051a39Sopenharmony_ci return code; 1070e1051a39Sopenharmony_ci } 1071e1051a39Sopenharmony_ci 1072e1051a39Sopenharmony_ci return dtls1_handle_timeout(s); 1073e1051a39Sopenharmony_ci} 1074e1051a39Sopenharmony_ci 1075e1051a39Sopenharmony_ciint dtls1_get_queue_priority(unsigned short seq, int is_ccs) 1076e1051a39Sopenharmony_ci{ 1077e1051a39Sopenharmony_ci /* 1078e1051a39Sopenharmony_ci * The index of the retransmission queue actually is the message sequence 1079e1051a39Sopenharmony_ci * number, since the queue only contains messages of a single handshake. 1080e1051a39Sopenharmony_ci * However, the ChangeCipherSpec has no message sequence number and so 1081e1051a39Sopenharmony_ci * using only the sequence will result in the CCS and Finished having the 1082e1051a39Sopenharmony_ci * same index. To prevent this, the sequence number is multiplied by 2. 1083e1051a39Sopenharmony_ci * In case of a CCS 1 is subtracted. This does not only differ CSS and 1084e1051a39Sopenharmony_ci * Finished, it also maintains the order of the index (important for 1085e1051a39Sopenharmony_ci * priority queues) and fits in the unsigned short variable. 1086e1051a39Sopenharmony_ci */ 1087e1051a39Sopenharmony_ci return seq * 2 - is_ccs; 1088e1051a39Sopenharmony_ci} 1089e1051a39Sopenharmony_ci 1090e1051a39Sopenharmony_ciint dtls1_retransmit_buffered_messages(SSL *s) 1091e1051a39Sopenharmony_ci{ 1092e1051a39Sopenharmony_ci pqueue *sent = s->d1->sent_messages; 1093e1051a39Sopenharmony_ci piterator iter; 1094e1051a39Sopenharmony_ci pitem *item; 1095e1051a39Sopenharmony_ci hm_fragment *frag; 1096e1051a39Sopenharmony_ci int found = 0; 1097e1051a39Sopenharmony_ci 1098e1051a39Sopenharmony_ci iter = pqueue_iterator(sent); 1099e1051a39Sopenharmony_ci 1100e1051a39Sopenharmony_ci for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { 1101e1051a39Sopenharmony_ci frag = (hm_fragment *)item->data; 1102e1051a39Sopenharmony_ci if (dtls1_retransmit_message(s, (unsigned short) 1103e1051a39Sopenharmony_ci dtls1_get_queue_priority 1104e1051a39Sopenharmony_ci (frag->msg_header.seq, 1105e1051a39Sopenharmony_ci frag->msg_header.is_ccs), &found) <= 0) 1106e1051a39Sopenharmony_ci return -1; 1107e1051a39Sopenharmony_ci } 1108e1051a39Sopenharmony_ci 1109e1051a39Sopenharmony_ci return 1; 1110e1051a39Sopenharmony_ci} 1111e1051a39Sopenharmony_ci 1112e1051a39Sopenharmony_ciint dtls1_buffer_message(SSL *s, int is_ccs) 1113e1051a39Sopenharmony_ci{ 1114e1051a39Sopenharmony_ci pitem *item; 1115e1051a39Sopenharmony_ci hm_fragment *frag; 1116e1051a39Sopenharmony_ci unsigned char seq64be[8]; 1117e1051a39Sopenharmony_ci 1118e1051a39Sopenharmony_ci /* 1119e1051a39Sopenharmony_ci * this function is called immediately after a message has been 1120e1051a39Sopenharmony_ci * serialized 1121e1051a39Sopenharmony_ci */ 1122e1051a39Sopenharmony_ci if (!ossl_assert(s->init_off == 0)) 1123e1051a39Sopenharmony_ci return 0; 1124e1051a39Sopenharmony_ci 1125e1051a39Sopenharmony_ci frag = dtls1_hm_fragment_new(s->init_num, 0); 1126e1051a39Sopenharmony_ci if (frag == NULL) 1127e1051a39Sopenharmony_ci return 0; 1128e1051a39Sopenharmony_ci 1129e1051a39Sopenharmony_ci memcpy(frag->fragment, s->init_buf->data, s->init_num); 1130e1051a39Sopenharmony_ci 1131e1051a39Sopenharmony_ci if (is_ccs) { 1132e1051a39Sopenharmony_ci /* For DTLS1_BAD_VER the header length is non-standard */ 1133e1051a39Sopenharmony_ci if (!ossl_assert(s->d1->w_msg_hdr.msg_len + 1134e1051a39Sopenharmony_ci ((s->version == 1135e1051a39Sopenharmony_ci DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH) 1136e1051a39Sopenharmony_ci == (unsigned int)s->init_num)) { 1137e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 1138e1051a39Sopenharmony_ci return 0; 1139e1051a39Sopenharmony_ci } 1140e1051a39Sopenharmony_ci } else { 1141e1051a39Sopenharmony_ci if (!ossl_assert(s->d1->w_msg_hdr.msg_len + 1142e1051a39Sopenharmony_ci DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) { 1143e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 1144e1051a39Sopenharmony_ci return 0; 1145e1051a39Sopenharmony_ci } 1146e1051a39Sopenharmony_ci } 1147e1051a39Sopenharmony_ci 1148e1051a39Sopenharmony_ci frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; 1149e1051a39Sopenharmony_ci frag->msg_header.seq = s->d1->w_msg_hdr.seq; 1150e1051a39Sopenharmony_ci frag->msg_header.type = s->d1->w_msg_hdr.type; 1151e1051a39Sopenharmony_ci frag->msg_header.frag_off = 0; 1152e1051a39Sopenharmony_ci frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; 1153e1051a39Sopenharmony_ci frag->msg_header.is_ccs = is_ccs; 1154e1051a39Sopenharmony_ci 1155e1051a39Sopenharmony_ci /* save current state */ 1156e1051a39Sopenharmony_ci frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; 1157e1051a39Sopenharmony_ci frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; 1158e1051a39Sopenharmony_ci frag->msg_header.saved_retransmit_state.compress = s->compress; 1159e1051a39Sopenharmony_ci frag->msg_header.saved_retransmit_state.session = s->session; 1160e1051a39Sopenharmony_ci frag->msg_header.saved_retransmit_state.epoch = 1161e1051a39Sopenharmony_ci DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer); 1162e1051a39Sopenharmony_ci 1163e1051a39Sopenharmony_ci memset(seq64be, 0, sizeof(seq64be)); 1164e1051a39Sopenharmony_ci seq64be[6] = 1165e1051a39Sopenharmony_ci (unsigned 1166e1051a39Sopenharmony_ci char)(dtls1_get_queue_priority(frag->msg_header.seq, 1167e1051a39Sopenharmony_ci frag->msg_header.is_ccs) >> 8); 1168e1051a39Sopenharmony_ci seq64be[7] = 1169e1051a39Sopenharmony_ci (unsigned 1170e1051a39Sopenharmony_ci char)(dtls1_get_queue_priority(frag->msg_header.seq, 1171e1051a39Sopenharmony_ci frag->msg_header.is_ccs)); 1172e1051a39Sopenharmony_ci 1173e1051a39Sopenharmony_ci item = pitem_new(seq64be, frag); 1174e1051a39Sopenharmony_ci if (item == NULL) { 1175e1051a39Sopenharmony_ci dtls1_hm_fragment_free(frag); 1176e1051a39Sopenharmony_ci return 0; 1177e1051a39Sopenharmony_ci } 1178e1051a39Sopenharmony_ci 1179e1051a39Sopenharmony_ci pqueue_insert(s->d1->sent_messages, item); 1180e1051a39Sopenharmony_ci return 1; 1181e1051a39Sopenharmony_ci} 1182e1051a39Sopenharmony_ci 1183e1051a39Sopenharmony_ciint dtls1_retransmit_message(SSL *s, unsigned short seq, int *found) 1184e1051a39Sopenharmony_ci{ 1185e1051a39Sopenharmony_ci int ret; 1186e1051a39Sopenharmony_ci /* XDTLS: for now assuming that read/writes are blocking */ 1187e1051a39Sopenharmony_ci pitem *item; 1188e1051a39Sopenharmony_ci hm_fragment *frag; 1189e1051a39Sopenharmony_ci unsigned long header_length; 1190e1051a39Sopenharmony_ci unsigned char seq64be[8]; 1191e1051a39Sopenharmony_ci struct dtls1_retransmit_state saved_state; 1192e1051a39Sopenharmony_ci 1193e1051a39Sopenharmony_ci /* XDTLS: the requested message ought to be found, otherwise error */ 1194e1051a39Sopenharmony_ci memset(seq64be, 0, sizeof(seq64be)); 1195e1051a39Sopenharmony_ci seq64be[6] = (unsigned char)(seq >> 8); 1196e1051a39Sopenharmony_ci seq64be[7] = (unsigned char)seq; 1197e1051a39Sopenharmony_ci 1198e1051a39Sopenharmony_ci item = pqueue_find(s->d1->sent_messages, seq64be); 1199e1051a39Sopenharmony_ci if (item == NULL) { 1200e1051a39Sopenharmony_ci SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); 1201e1051a39Sopenharmony_ci *found = 0; 1202e1051a39Sopenharmony_ci return 0; 1203e1051a39Sopenharmony_ci } 1204e1051a39Sopenharmony_ci 1205e1051a39Sopenharmony_ci *found = 1; 1206e1051a39Sopenharmony_ci frag = (hm_fragment *)item->data; 1207e1051a39Sopenharmony_ci 1208e1051a39Sopenharmony_ci if (frag->msg_header.is_ccs) 1209e1051a39Sopenharmony_ci header_length = DTLS1_CCS_HEADER_LENGTH; 1210e1051a39Sopenharmony_ci else 1211e1051a39Sopenharmony_ci header_length = DTLS1_HM_HEADER_LENGTH; 1212e1051a39Sopenharmony_ci 1213e1051a39Sopenharmony_ci memcpy(s->init_buf->data, frag->fragment, 1214e1051a39Sopenharmony_ci frag->msg_header.msg_len + header_length); 1215e1051a39Sopenharmony_ci s->init_num = frag->msg_header.msg_len + header_length; 1216e1051a39Sopenharmony_ci 1217e1051a39Sopenharmony_ci dtls1_set_message_header_int(s, frag->msg_header.type, 1218e1051a39Sopenharmony_ci frag->msg_header.msg_len, 1219e1051a39Sopenharmony_ci frag->msg_header.seq, 0, 1220e1051a39Sopenharmony_ci frag->msg_header.frag_len); 1221e1051a39Sopenharmony_ci 1222e1051a39Sopenharmony_ci /* save current state */ 1223e1051a39Sopenharmony_ci saved_state.enc_write_ctx = s->enc_write_ctx; 1224e1051a39Sopenharmony_ci saved_state.write_hash = s->write_hash; 1225e1051a39Sopenharmony_ci saved_state.compress = s->compress; 1226e1051a39Sopenharmony_ci saved_state.session = s->session; 1227e1051a39Sopenharmony_ci saved_state.epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer); 1228e1051a39Sopenharmony_ci 1229e1051a39Sopenharmony_ci s->d1->retransmitting = 1; 1230e1051a39Sopenharmony_ci 1231e1051a39Sopenharmony_ci /* restore state in which the message was originally sent */ 1232e1051a39Sopenharmony_ci s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; 1233e1051a39Sopenharmony_ci s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; 1234e1051a39Sopenharmony_ci s->compress = frag->msg_header.saved_retransmit_state.compress; 1235e1051a39Sopenharmony_ci s->session = frag->msg_header.saved_retransmit_state.session; 1236e1051a39Sopenharmony_ci DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, 1237e1051a39Sopenharmony_ci frag->msg_header. 1238e1051a39Sopenharmony_ci saved_retransmit_state.epoch); 1239e1051a39Sopenharmony_ci 1240e1051a39Sopenharmony_ci ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 1241e1051a39Sopenharmony_ci SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); 1242e1051a39Sopenharmony_ci 1243e1051a39Sopenharmony_ci /* restore current state */ 1244e1051a39Sopenharmony_ci s->enc_write_ctx = saved_state.enc_write_ctx; 1245e1051a39Sopenharmony_ci s->write_hash = saved_state.write_hash; 1246e1051a39Sopenharmony_ci s->compress = saved_state.compress; 1247e1051a39Sopenharmony_ci s->session = saved_state.session; 1248e1051a39Sopenharmony_ci DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, saved_state.epoch); 1249e1051a39Sopenharmony_ci 1250e1051a39Sopenharmony_ci s->d1->retransmitting = 0; 1251e1051a39Sopenharmony_ci 1252e1051a39Sopenharmony_ci (void)BIO_flush(s->wbio); 1253e1051a39Sopenharmony_ci return ret; 1254e1051a39Sopenharmony_ci} 1255e1051a39Sopenharmony_ci 1256e1051a39Sopenharmony_civoid dtls1_set_message_header(SSL *s, 1257e1051a39Sopenharmony_ci unsigned char mt, size_t len, 1258e1051a39Sopenharmony_ci size_t frag_off, size_t frag_len) 1259e1051a39Sopenharmony_ci{ 1260e1051a39Sopenharmony_ci if (frag_off == 0) { 1261e1051a39Sopenharmony_ci s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; 1262e1051a39Sopenharmony_ci s->d1->next_handshake_write_seq++; 1263e1051a39Sopenharmony_ci } 1264e1051a39Sopenharmony_ci 1265e1051a39Sopenharmony_ci dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, 1266e1051a39Sopenharmony_ci frag_off, frag_len); 1267e1051a39Sopenharmony_ci} 1268e1051a39Sopenharmony_ci 1269e1051a39Sopenharmony_ci/* don't actually do the writing, wait till the MTU has been retrieved */ 1270e1051a39Sopenharmony_cistatic void 1271e1051a39Sopenharmony_cidtls1_set_message_header_int(SSL *s, unsigned char mt, 1272e1051a39Sopenharmony_ci size_t len, unsigned short seq_num, 1273e1051a39Sopenharmony_ci size_t frag_off, size_t frag_len) 1274e1051a39Sopenharmony_ci{ 1275e1051a39Sopenharmony_ci struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; 1276e1051a39Sopenharmony_ci 1277e1051a39Sopenharmony_ci msg_hdr->type = mt; 1278e1051a39Sopenharmony_ci msg_hdr->msg_len = len; 1279e1051a39Sopenharmony_ci msg_hdr->seq = seq_num; 1280e1051a39Sopenharmony_ci msg_hdr->frag_off = frag_off; 1281e1051a39Sopenharmony_ci msg_hdr->frag_len = frag_len; 1282e1051a39Sopenharmony_ci} 1283e1051a39Sopenharmony_ci 1284e1051a39Sopenharmony_cistatic void 1285e1051a39Sopenharmony_cidtls1_fix_message_header(SSL *s, size_t frag_off, size_t frag_len) 1286e1051a39Sopenharmony_ci{ 1287e1051a39Sopenharmony_ci struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; 1288e1051a39Sopenharmony_ci 1289e1051a39Sopenharmony_ci msg_hdr->frag_off = frag_off; 1290e1051a39Sopenharmony_ci msg_hdr->frag_len = frag_len; 1291e1051a39Sopenharmony_ci} 1292e1051a39Sopenharmony_ci 1293e1051a39Sopenharmony_cistatic unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) 1294e1051a39Sopenharmony_ci{ 1295e1051a39Sopenharmony_ci struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; 1296e1051a39Sopenharmony_ci 1297e1051a39Sopenharmony_ci *p++ = msg_hdr->type; 1298e1051a39Sopenharmony_ci l2n3(msg_hdr->msg_len, p); 1299e1051a39Sopenharmony_ci 1300e1051a39Sopenharmony_ci s2n(msg_hdr->seq, p); 1301e1051a39Sopenharmony_ci l2n3(msg_hdr->frag_off, p); 1302e1051a39Sopenharmony_ci l2n3(msg_hdr->frag_len, p); 1303e1051a39Sopenharmony_ci 1304e1051a39Sopenharmony_ci return p; 1305e1051a39Sopenharmony_ci} 1306e1051a39Sopenharmony_ci 1307e1051a39Sopenharmony_civoid dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) 1308e1051a39Sopenharmony_ci{ 1309e1051a39Sopenharmony_ci memset(msg_hdr, 0, sizeof(*msg_hdr)); 1310e1051a39Sopenharmony_ci msg_hdr->type = *(data++); 1311e1051a39Sopenharmony_ci n2l3(data, msg_hdr->msg_len); 1312e1051a39Sopenharmony_ci 1313e1051a39Sopenharmony_ci n2s(data, msg_hdr->seq); 1314e1051a39Sopenharmony_ci n2l3(data, msg_hdr->frag_off); 1315e1051a39Sopenharmony_ci n2l3(data, msg_hdr->frag_len); 1316e1051a39Sopenharmony_ci} 1317e1051a39Sopenharmony_ci 1318e1051a39Sopenharmony_ciint dtls1_set_handshake_header(SSL *s, WPACKET *pkt, int htype) 1319e1051a39Sopenharmony_ci{ 1320e1051a39Sopenharmony_ci unsigned char *header; 1321e1051a39Sopenharmony_ci 1322e1051a39Sopenharmony_ci if (htype == SSL3_MT_CHANGE_CIPHER_SPEC) { 1323e1051a39Sopenharmony_ci s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; 1324e1051a39Sopenharmony_ci dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, 1325e1051a39Sopenharmony_ci s->d1->handshake_write_seq, 0, 0); 1326e1051a39Sopenharmony_ci if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) 1327e1051a39Sopenharmony_ci return 0; 1328e1051a39Sopenharmony_ci } else { 1329e1051a39Sopenharmony_ci dtls1_set_message_header(s, htype, 0, 0, 0); 1330e1051a39Sopenharmony_ci /* 1331e1051a39Sopenharmony_ci * We allocate space at the start for the message header. This gets 1332e1051a39Sopenharmony_ci * filled in later 1333e1051a39Sopenharmony_ci */ 1334e1051a39Sopenharmony_ci if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header) 1335e1051a39Sopenharmony_ci || !WPACKET_start_sub_packet(pkt)) 1336e1051a39Sopenharmony_ci return 0; 1337e1051a39Sopenharmony_ci } 1338e1051a39Sopenharmony_ci 1339e1051a39Sopenharmony_ci return 1; 1340e1051a39Sopenharmony_ci} 1341e1051a39Sopenharmony_ci 1342e1051a39Sopenharmony_ciint dtls1_close_construct_packet(SSL *s, WPACKET *pkt, int htype) 1343e1051a39Sopenharmony_ci{ 1344e1051a39Sopenharmony_ci size_t msglen; 1345e1051a39Sopenharmony_ci 1346e1051a39Sopenharmony_ci if ((htype != SSL3_MT_CHANGE_CIPHER_SPEC && !WPACKET_close(pkt)) 1347e1051a39Sopenharmony_ci || !WPACKET_get_length(pkt, &msglen) 1348e1051a39Sopenharmony_ci || msglen > INT_MAX) 1349e1051a39Sopenharmony_ci return 0; 1350e1051a39Sopenharmony_ci 1351e1051a39Sopenharmony_ci if (htype != SSL3_MT_CHANGE_CIPHER_SPEC) { 1352e1051a39Sopenharmony_ci s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH; 1353e1051a39Sopenharmony_ci s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH; 1354e1051a39Sopenharmony_ci } 1355e1051a39Sopenharmony_ci s->init_num = (int)msglen; 1356e1051a39Sopenharmony_ci s->init_off = 0; 1357e1051a39Sopenharmony_ci 1358e1051a39Sopenharmony_ci if (htype != DTLS1_MT_HELLO_VERIFY_REQUEST) { 1359e1051a39Sopenharmony_ci /* Buffer the message to handle re-xmits */ 1360e1051a39Sopenharmony_ci if (!dtls1_buffer_message(s, htype == SSL3_MT_CHANGE_CIPHER_SPEC 1361e1051a39Sopenharmony_ci ? 1 : 0)) 1362e1051a39Sopenharmony_ci return 0; 1363e1051a39Sopenharmony_ci } 1364e1051a39Sopenharmony_ci 1365e1051a39Sopenharmony_ci return 1; 1366e1051a39Sopenharmony_ci} 1367