/*
- * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <limits.h>
#include <string.h>
#include <stdio.h>
-#include "../ssl_locl.h"
-#include "statem_locl.h"
+#include "../ssl_local.h"
+#include "statem_local.h"
#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/objects.h>
unsigned char *buf = NULL;
unsigned char *bitmask = NULL;
- frag = OPENSSL_malloc(sizeof(*frag));
- if (frag == NULL)
+ if ((frag = OPENSSL_malloc(sizeof(*frag))) == NULL) {
+ SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
+ }
if (frag_len) {
- buf = OPENSSL_malloc(frag_len);
- if (buf == NULL) {
+ if ((buf = OPENSSL_malloc(frag_len)) == NULL) {
+ SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(frag);
return NULL;
}
if (reassembly) {
bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len));
if (bitmask == NULL) {
+ SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(buf);
OPENSSL_free(frag);
return NULL;
return 0;
}
- *mt = s->s3->tmp.message_type;
+ *mt = s->s3.tmp.message_type;
p = (unsigned char *)s->init_buf->data;
*len = s->init_num;
return 0;
}
- s->s3->tmp.message_size = msg_len;
+ s->s3.tmp.message_size = msg_len;
s->d1->r_msg_hdr.msg_len = msg_len;
- s->s3->tmp.message_type = msg_hdr->type;
+ s->s3.tmp.message_type = msg_hdr->type;
s->d1->r_msg_hdr.type = msg_hdr->type;
s->d1->r_msg_hdr.seq = msg_hdr->seq;
} else if (msg_len != s->d1->r_msg_hdr.msg_len) {
/* Calls SSLfatal() as required */
ret = dtls1_preprocess_fragment(s, &frag->msg_header);
- if (ret) {
+ if (ret && frag->msg_header.frag_len > 0) {
unsigned char *p =
(unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
memcpy(&p[frag->msg_header.frag_off], frag->fragment,
memcpy(s->init_buf->data, wire, readbytes);
s->init_num = readbytes - 1;
s->init_msg = s->init_buf->data + 1;
- s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
- s->s3->tmp.message_size = readbytes - 1;
+ s->s3.tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
+ s->s3.tmp.message_size = readbytes - 1;
*len = readbytes - 1;
return 1;
}
* for these 2 messages, we need to
* ssl->enc_read_ctx re-init
* ssl->rlayer.read_sequence zero
- * ssl->s3->read_mac_secret re-init
+ * ssl->s3.read_mac_secret re-init
* ssl->session->read_sym_enc assign
* ssl->session->read_compression assign
* ssl->session->read_hash assign
}
#ifndef OPENSSL_NO_SCTP
+/*
+ * Wait for a dry event. Should only be called at a point in the handshake
+ * where we are not expecting any data from the peer except an alert.
+ */
WORK_STATE dtls_wait_for_dry(SSL *s)
{
- int ret;
+ int ret, errtype;
+ size_t len;
/* read app data until dry event */
ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
}
if (ret == 0) {
- s->s3->in_read_app_data = 2;
+ /*
+ * We're not expecting any more messages from the peer at this point -
+ * but we could get an alert. If an alert is waiting then we will never
+ * return successfully. Therefore we attempt to read a message. This
+ * should never succeed but will process any waiting alerts.
+ */
+ if (dtls_get_reassembled_message(s, &errtype, &len)) {
+ /* The call succeeded! This should never happen */
+ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS_WAIT_FOR_DRY,
+ SSL_R_UNEXPECTED_MESSAGE);
+ return WORK_ERROR;
+ }
+
+ s->s3.in_read_app_data = 2;
s->rwstate = SSL_READING;
BIO_clear_retry_flags(SSL_get_rbio(s));
BIO_set_retry_read(SSL_get_rbio(s));