/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <stdio.h>
#include <limits.h>
#include <errno.h>
-#define USE_SOCKETS
#include "../ssl_locl.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include "record_locl.h"
-
-#ifndef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
-# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
-#endif
+#include "../packet_locl.h"
#if defined(OPENSSL_SMALL_FOOTPRINT) || \
!( defined(AES_ASM) && ( \
void RECORD_LAYER_clear(RECORD_LAYER *rl)
{
- unsigned int pipes;
-
rl->rstate = SSL_ST_READ_HEADER;
/*
rl->packet = NULL;
rl->packet_length = 0;
rl->wnum = 0;
- memset(rl->alert_fragment, 0, sizeof(rl->alert_fragment));
- rl->alert_fragment_len = 0;
memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment));
rl->handshake_fragment_len = 0;
rl->wpend_tot = 0;
rl->wpend_buf = NULL;
SSL3_BUFFER_clear(&rl->rbuf);
- for (pipes = 0; pipes < rl->numwpipes; pipes++)
- SSL3_BUFFER_clear(&rl->wbuf[pipes]);
- rl->numwpipes = 0;
+ ssl3_release_write_buffer(rl->s);
rl->numrpipes = 0;
SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES);
SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES);
}
+/* Checks if we have unprocessed read ahead data pending */
int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
{
return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
}
-int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
+/* Checks if we have decrypted unread record data pending */
+int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl)
{
- return (rl->numwpipes > 0)
- && SSL3_BUFFER_get_left(&rl->wbuf[rl->numwpipes - 1]) != 0;
-}
+ size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl);
+ const SSL3_RECORD *rr = rl->rrec;
-int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf,
- size_t len)
-{
- rl->packet_length = len;
- if (len != 0) {
- rl->rstate = SSL_ST_READ_HEADER;
- if (!SSL3_BUFFER_is_initialised(&rl->rbuf))
- if (!ssl3_setup_read_buffer(rl->s))
- return 0;
- }
+ while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]))
+ curr_rec++;
- rl->packet = SSL3_BUFFER_get_buf(&rl->rbuf);
- SSL3_BUFFER_set_data(&rl->rbuf, buf, len);
+ return curr_rec < num_recs;
+}
- return 1;
+int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
+{
+ return (rl->numwpipes > 0)
+ && SSL3_BUFFER_get_left(&rl->wbuf[rl->numwpipes - 1]) != 0;
}
void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl)
}
/*
- * Return values are as per SSL_read(), i.e.
- * 1 Success
- * 0 Failure (not retryable)
- * <0 Failure (may be retryable)
+ * Return values are as per SSL_read()
*/
int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold,
size_t *readbytes)
/* else we need to read more data */
- if (n > (rb->len - rb->offset)) { /* does not happen */
+ if (n > rb->len - rb->offset) { /* does not happen */
SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR);
return -1;
}
else {
if (max < n)
max = n;
- if (max > (rb->len - rb->offset))
+ if (max > rb->len - rb->offset)
max = rb->len - rb->offset;
}
if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
if (len + left == 0)
ssl3_release_read_buffer(s);
- return -1;
+ return ret;
}
left += bioread;
/*
{
const unsigned char *buf = buf_;
size_t tot;
- size_t n, split_send_fragment, maxpipes;
+ size_t n, max_send_fragment, split_send_fragment, maxpipes;
#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
- size_t max_send_fragment, nw;
+ size_t nw;
#endif
SSL3_BUFFER *wb = &s->rlayer.wbuf[0];
int i;
tot = s->rlayer.wnum;
/*
* ensure that if we end up with a smaller value of data to write out
- * than the the original len from a write which didn't complete for
+ * than the original len from a write which didn't complete for
* non-blocking I/O and also somehow ended up avoiding the check for
* this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be
* possible to end up with (len-tot) as a large number that will then
* promptly send beyond the end of the users buffer ... so we trap and
* report the error in a way the user will notice
*/
- if (len < s->rlayer.wnum) {
+ if ((len < s->rlayer.wnum)
+ || ((wb->left != 0) && (len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) {
SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH);
return -1;
}
+ if (s->early_data_state == SSL_EARLY_DATA_WRITING
+ && !early_data_count_ok(s, len, 0, NULL))
+ return -1;
+
s->rlayer.wnum = 0;
- if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) {
+ /*
+ * When writing early data on the server side we could be "in_init" in
+ * between receiving the EoED and the CF - but we don't want to handle those
+ * messages yet.
+ */
+ if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)
+ && s->early_data_state != SSL_EARLY_DATA_UNAUTH_WRITING) {
i = s->handshake_func(s);
if (i < 0)
return i;
* compromise is considered worthy.
*/
if (type == SSL3_RT_APPLICATION_DATA &&
- len >= 4 * (max_send_fragment = s->max_send_fragment) &&
+ len >= 4 * (max_send_fragment = ssl_get_max_send_fragment(s)) &&
s->compress == NULL && s->msg_callback == NULL &&
- !SSL_USE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
+ !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
unsigned char aad[13];
tot += tmpwrit;
}
} else
-#endif
+#endif /* !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK */
if (tot == len) { /* done? */
if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
ssl3_release_write_buffer(s);
n = (len - tot);
- split_send_fragment = s->split_send_fragment;
+ max_send_fragment = ssl_get_max_send_fragment(s);
+ split_send_fragment = ssl_get_split_send_fragment(s);
/*
* If max_pipelines is 0 then this means "undefined" and we default to
* 1 pipeline. Similarly if the cipher does not support pipelined
& EVP_CIPH_FLAG_PIPELINE)
|| !SSL_USE_EXPLICIT_IV(s))
maxpipes = 1;
- if (s->max_send_fragment == 0 || split_send_fragment > s->max_send_fragment
- || split_send_fragment == 0) {
+ if (max_send_fragment == 0 || split_send_fragment == 0
+ || split_send_fragment > max_send_fragment) {
/*
- * We should have prevented this when we set the split and max send
+ * We should have prevented this when we set/get the split and max send
* fragments so we shouldn't get here
*/
SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR);
if (numpipes > maxpipes)
numpipes = maxpipes;
- if (n / numpipes >= s->max_send_fragment) {
+ if (n / numpipes >= max_send_fragment) {
/*
* We have enough data to completely fill all available
* pipelines
*/
for (j = 0; j < numpipes; j++) {
- pipelens[j] = s->max_send_fragment;
+ pipelens[j] = max_send_fragment;
}
} else {
/* We can partially fill all available pipelines */
return i;
}
- if ((tmpwrit == n) ||
+ if (tmpwrit == n ||
(type == SSL3_RT_APPLICATION_DATA &&
(s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
/*
size_t *pipelens, size_t numpipes,
int create_empty_fragment, size_t *written)
{
- unsigned char *outbuf[SSL_MAX_PIPELINES], *plen[SSL_MAX_PIPELINES];
+ WPACKET pkt[SSL_MAX_PIPELINES];
SSL3_RECORD wr[SSL_MAX_PIPELINES];
+ WPACKET *thispkt;
+ SSL3_RECORD *thiswr;
+ unsigned char *recordstart;
int i, mac_size, clear = 0;
size_t prefix_len = 0;
- int eivlen;
+ int eivlen = 0;
size_t align = 0;
SSL3_BUFFER *wb;
SSL_SESSION *sess;
- size_t totlen = 0;
+ size_t totlen = 0, len, wpinited = 0;
size_t j;
for (j = 0; j < numpipes; j++)
if (s->s3->alert_dispatch) {
i = s->method->ssl_dispatch_alert(s);
if (i <= 0)
- return (i);
+ return i;
/* if it went, fall through and send more stuff */
}
align = (size_t)SSL3_BUFFER_get_buf(wb) + 2 * SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
#endif
- outbuf[0] = SSL3_BUFFER_get_buf(wb) + align;
SSL3_BUFFER_set_offset(wb, align);
+ if (!WPACKET_init_static_len(&pkt[0], SSL3_BUFFER_get_buf(wb),
+ SSL3_BUFFER_get_len(wb), 0)
+ || !WPACKET_allocate_bytes(&pkt[0], align, NULL)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ wpinited = 1;
} else if (prefix_len) {
wb = &s->rlayer.wbuf[0];
- outbuf[0] = SSL3_BUFFER_get_buf(wb) + SSL3_BUFFER_get_offset(wb)
- + prefix_len;
+ if (!WPACKET_init_static_len(&pkt[0],
+ SSL3_BUFFER_get_buf(wb),
+ SSL3_BUFFER_get_len(wb), 0)
+ || !WPACKET_allocate_bytes(&pkt[0], SSL3_BUFFER_get_offset(wb)
+ + prefix_len, NULL)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ wpinited = 1;
} else {
for (j = 0; j < numpipes; j++) {
+ thispkt = &pkt[j];
+
wb = &s->rlayer.wbuf[j];
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
#endif
- outbuf[j] = SSL3_BUFFER_get_buf(wb) + align;
SSL3_BUFFER_set_offset(wb, align);
+ if (!WPACKET_init_static_len(thispkt, SSL3_BUFFER_get_buf(wb),
+ SSL3_BUFFER_get_len(wb), 0)
+ || !WPACKET_allocate_bytes(thispkt, align, NULL)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ wpinited++;
}
}
/* Explicit IV length, block ciphers appropriate version flag */
- if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
+ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) {
int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
if (mode == EVP_CIPH_CBC_MODE) {
/* TODO(size_t): Convert me */
eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
if (eivlen <= 1)
eivlen = 0;
- }
- /* Need explicit part of IV for GCM mode */
- else if (mode == EVP_CIPH_GCM_MODE)
+ } else if (mode == EVP_CIPH_GCM_MODE) {
+ /* Need explicit part of IV for GCM mode */
eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
- else if (mode == EVP_CIPH_CCM_MODE)
+ } else if (mode == EVP_CIPH_CCM_MODE) {
eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
- else
- eivlen = 0;
- } else
- eivlen = 0;
+ }
+ }
totlen = 0;
/* Clear our SSL3_RECORD structures */
- memset(wr, 0, sizeof wr);
+ memset(wr, 0, sizeof(wr));
for (j = 0; j < numpipes; j++) {
- /* write the header */
- *(outbuf[j]++) = type & 0xff;
- SSL3_RECORD_set_type(&wr[j], type);
+ unsigned int version = SSL_TREAT_AS_TLS13(s) ? TLS1_VERSION : s->version;
+ unsigned char *compressdata = NULL;
+ size_t maxcomplen;
+ unsigned int rectype;
- *(outbuf[j]++) = (s->version >> 8);
+ thispkt = &pkt[j];
+ thiswr = &wr[j];
+
+ SSL3_RECORD_set_type(thiswr, type);
+ /*
+ * In TLSv1.3, once encrypting, we always use application data for the
+ * record type
+ */
+ if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL)
+ rectype = SSL3_RT_APPLICATION_DATA;
+ else
+ rectype = type;
/*
* Some servers hang if initial client hello is larger than 256 bytes
* and record version number > TLS 1.0
*/
if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO
&& !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION)
- *(outbuf[j]++) = 0x1;
- else
- *(outbuf[j]++) = s->version & 0xff;
+ version = TLS1_VERSION;
+
+ maxcomplen = pipelens[j];
+ if (s->compress != NULL)
+ maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
- /* field where we are to write out packet length */
- plen[j] = outbuf[j];
- outbuf[j] += 2;
+ /* write the header */
+ if (!WPACKET_put_bytes_u8(thispkt, rectype)
+ || !WPACKET_put_bytes_u16(thispkt, version)
+ || !WPACKET_start_sub_packet_u16(thispkt)
+ || (eivlen > 0
+ && !WPACKET_allocate_bytes(thispkt, eivlen, NULL))
+ || (maxcomplen > 0
+ && !WPACKET_reserve_bytes(thispkt, maxcomplen,
+ &compressdata))) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
/* lets setup the record stuff. */
- SSL3_RECORD_set_data(&wr[j], outbuf[j] + eivlen);
- SSL3_RECORD_set_length(&wr[j], pipelens[j]);
- SSL3_RECORD_set_input(&wr[j], (unsigned char *)&buf[totlen]);
+ SSL3_RECORD_set_data(thiswr, compressdata);
+ SSL3_RECORD_set_length(thiswr, pipelens[j]);
+ SSL3_RECORD_set_input(thiswr, (unsigned char *)&buf[totlen]);
totlen += pipelens[j];
/*
- * we now 'read' from wr->input, wr->length bytes into wr->data
+ * we now 'read' from thiswr->input, thiswr->length bytes into
+ * thiswr->data
*/
/* first we compress */
if (s->compress != NULL) {
- if (!ssl3_do_compress(s, &wr[j])) {
+ if (!ssl3_do_compress(s, thiswr)
+ || !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) {
SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE);
goto err;
}
} else {
- memcpy(wr[j].data, wr[j].input, wr[j].length);
+ if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
SSL3_RECORD_reset_input(&wr[j]);
}
+ if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
+ size_t rlen, max_send_fragment;
+
+ if (!WPACKET_put_bytes_u8(thispkt, type)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ SSL3_RECORD_add_length(thiswr, 1);
+
+ /* Add TLS1.3 padding */
+ max_send_fragment = ssl_get_max_send_fragment(s);
+ rlen = SSL3_RECORD_get_length(thiswr);
+ if (rlen < max_send_fragment) {
+ size_t padding = 0;
+ size_t max_padding = max_send_fragment - rlen;
+ if (s->record_padding_cb != NULL) {
+ padding = s->record_padding_cb(s, type, rlen, s->record_padding_arg);
+ } else if (s->block_padding > 0) {
+ size_t mask = s->block_padding - 1;
+ size_t remainder;
+
+ /* optimize for power of 2 */
+ if ((s->block_padding & mask) == 0)
+ remainder = rlen & mask;
+ else
+ remainder = rlen % s->block_padding;
+ /* don't want to add a block of padding if we don't have to */
+ if (remainder == 0)
+ padding = 0;
+ else
+ padding = s->block_padding - remainder;
+ }
+ if (padding > 0) {
+ /* do not allow the record to exceed max plaintext length */
+ if (padding > max_padding)
+ padding = max_padding;
+ if (!WPACKET_memset(thispkt, 0, padding)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ SSL3_RECORD_add_length(thiswr, padding);
+ }
+ }
+ }
+
/*
- * we should still have the output to wr->data and the input from
- * wr->input. Length should be wr->length. wr->data still points in the
- * wb->buf
+ * we should still have the output to thiswr->data and the input from
+ * wr->input. Length should be thiswr->length. thiswr->data still points
+ * in the wb->buf
*/
- if (!SSL_USE_ETM(s) && mac_size != 0) {
- if (!s->method->ssl3_enc->mac(s, &wr[j],
- &(outbuf[j][wr[j].length + eivlen]),
- 1))
+ if (!SSL_WRITE_ETM(s) && mac_size != 0) {
+ unsigned char *mac;
+
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
goto err;
- SSL3_RECORD_add_length(&wr[j], mac_size);
+ }
}
- SSL3_RECORD_set_data(&wr[j], outbuf[j]);
- SSL3_RECORD_reset_input(&wr[j]);
-
- if (eivlen) {
- /*
- * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err;
- */
- SSL3_RECORD_add_length(&wr[j], eivlen);
+ /*
+ * Reserve some bytes for any growth that may occur during encryption.
+ * This will be at most one cipher block or the tag length if using
+ * AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
+ */
+ if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE,
+ NULL)
+ /*
+ * We also need next the amount of bytes written to this
+ * sub-packet
+ */
+ || !WPACKET_get_length(thispkt, &len)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
}
+
+ /* Get a pointer to the start of this record excluding header */
+ recordstart = WPACKET_get_curr(thispkt) - len;
+
+ SSL3_RECORD_set_data(thiswr, recordstart);
+ SSL3_RECORD_reset_input(thiswr);
+ SSL3_RECORD_set_length(thiswr, len);
}
- if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
- goto err;
+ if (s->early_data_state == SSL_EARLY_DATA_WRITING
+ || s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
+ /*
+ * We haven't actually negotiated the version yet, but we're trying to
+ * send early data - so we need to use the tls13enc function.
+ */
+ if (tls13_enc(s, wr, numpipes, 1) < 1)
+ goto err;
+ } else {
+ if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
+ goto err;
+ }
for (j = 0; j < numpipes; j++) {
- if (SSL_USE_ETM(s) && mac_size != 0) {
- if (!s->method->ssl3_enc->mac(s, &wr[j],
- outbuf[j] + wr[j].length, 1))
+ size_t origlen;
+
+ thispkt = &pkt[j];
+ thiswr = &wr[j];
+
+ /* Allocate bytes for the encryption overhead */
+ if (!WPACKET_get_length(thispkt, &origlen)
+ /* Encryption should never shrink the data! */
+ || origlen > thiswr->length
+ || (thiswr->length > origlen
+ && !WPACKET_allocate_bytes(thispkt,
+ thiswr->length - origlen, NULL))) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (SSL_WRITE_ETM(s) && mac_size != 0) {
+ unsigned char *mac;
+
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
goto err;
- SSL3_RECORD_add_length(&wr[j], mac_size);
+ }
+ SSL3_RECORD_add_length(thiswr, mac_size);
}
- /* record length after mac and block padding */
- s2n(SSL3_RECORD_get_length(&wr[j]), plen[j]);
+ if (!WPACKET_get_length(thispkt, &len)
+ || !WPACKET_close(thispkt)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
- if (s->msg_callback)
- s->msg_callback(1, 0, SSL3_RT_HEADER, plen[j] - 5, 5, s,
+ if (s->msg_callback) {
+ recordstart = WPACKET_get_curr(thispkt) - len
+ - SSL3_RT_HEADER_LENGTH;
+ s->msg_callback(1, 0, SSL3_RT_HEADER, recordstart,
+ SSL3_RT_HEADER_LENGTH, s,
s->msg_callback_arg);
+ if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
+ unsigned char ctype = type;
+
+ s->msg_callback(1, s->version, SSL3_RT_INNER_CONTENT_TYPE,
+ &ctype, 1, s, s->msg_callback_arg);
+ }
+ }
+
+ if (!WPACKET_finish(thispkt)) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
/*
- * we should now have wr->data pointing to the encrypted data, which is
- * wr->length long
+ * we should now have thiswr->data pointing to the encrypted data, which
+ * is thiswr->length long
*/
- SSL3_RECORD_set_type(&wr[j], type); /* not needed but helps for
+ SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for
* debugging */
- SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH);
+ SSL3_RECORD_add_length(thiswr, SSL3_RT_HEADER_LENGTH);
if (create_empty_fragment) {
/*
SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
goto err;
}
- *written = SSL3_RECORD_get_length(wr);
+ *written = SSL3_RECORD_get_length(thiswr);
return 1;
}
/* now let's set up wb */
SSL3_BUFFER_set_left(&s->rlayer.wbuf[j],
- prefix_len + SSL3_RECORD_get_length(&wr[j]));
+ prefix_len + SSL3_RECORD_get_length(thiswr));
}
/*
/* we now just need to write the buffer */
return ssl3_write_pending(s, type, buf, totlen, written);
err:
+ for (j = 0; j < wpinited; j++)
+ WPACKET_cleanup(&pkt[j]);
return -1;
}
/* if s->s3->wbuf.left != 0, we need to call this
*
- * Return values are as per SSL_read(), i.e.
- * 1 Success
- * 0 Failure (not retryable)
- * <0 Failure (may be retryable)
+ * Return values are as per SSL_write()
*/
int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len,
size_t *written)
*/
SSL3_BUFFER_set_left(&wb[currbuf], 0);
}
- return -1;
+ return i;
}
SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit);
SSL3_BUFFER_sub_left(&wb[currbuf], tmpwrit);
if (type == SSL3_RECORD_get_type(rr)
|| (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
- && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
+ && type == SSL3_RT_HANDSHAKE && recvd_type != NULL
+ && !SSL_IS_TLS13(s))) {
/*
* SSL3_RT_APPLICATION_DATA or
* SSL3_RT_HANDSHAKE or
if (recvd_type != NULL)
*recvd_type = SSL3_RECORD_get_type(rr);
- if (len == 0)
+ if (len == 0) {
+ /*
+ * Mark a zero length record as read. This ensures multiple calls to
+ * SSL_read() with a zero length buffer will eventually cause
+ * SSL_pending() to report data as being available.
+ */
+ if (SSL3_RECORD_get_length(rr) == 0)
+ SSL3_RECORD_set_read(rr);
return 0;
+ }
totalbytes = 0;
do {
size_t *dest_len = NULL;
if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
- dest_maxlen = sizeof s->rlayer.handshake_fragment;
+ dest_maxlen = sizeof(s->rlayer.handshake_fragment);
dest = s->rlayer.handshake_fragment;
dest_len = &s->rlayer.handshake_fragment_len;
- } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
- dest_maxlen = sizeof s->rlayer.alert_fragment;
- dest = s->rlayer.alert_fragment;
- dest_len = &s->rlayer.alert_fragment_len;
}
if (dest_maxlen > 0) {
n = SSL3_RECORD_get_length(rr); /* available bytes */
/* now move 'n' bytes: */
- while (n-- > 0) {
- dest[(*dest_len)++] =
- SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
- SSL3_RECORD_add_off(rr, 1);
- SSL3_RECORD_add_length(rr, -1);
- }
-
- if (*dest_len < dest_maxlen) {
+ memcpy(dest + *dest_len,
+ SSL3_RECORD_get_data(rr) + SSL3_RECORD_get_off(rr), n);
+ SSL3_RECORD_add_off(rr, n);
+ SSL3_RECORD_sub_length(rr, n);
+ *dest_len += n;
+ if (SSL3_RECORD_get_length(rr) == 0)
SSL3_RECORD_set_read(rr);
+
+ if (*dest_len < dest_maxlen)
goto start; /* fragment was too small */
- }
}
}
/*-
* s->rlayer.handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE;
- * s->rlayer.alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT.
* (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
*/
- /* If we are a client, check for an incoming 'Hello Request': */
- if ((!s->server) &&
- (s->rlayer.handshake_fragment_len >= 4) &&
- (s->rlayer.handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
- (s->session != NULL) && (s->session->cipher != NULL)) {
- s->rlayer.handshake_fragment_len = 0;
-
- if ((s->rlayer.handshake_fragment[1] != 0) ||
- (s->rlayer.handshake_fragment[2] != 0) ||
- (s->rlayer.handshake_fragment[3] != 0)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
- goto f_err;
- }
-
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
- s->rlayer.handshake_fragment, 4, s,
- s->msg_callback_arg);
-
- if (SSL_is_init_finished(s) &&
- !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
- !s->s3->renegotiate) {
- ssl3_renegotiate(s);
- if (ssl3_renegotiate_check(s)) {
- i = s->handshake_func(s);
- if (i < 0)
- return i;
- if (i == 0) {
- SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
-
- if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
- if (SSL3_BUFFER_get_left(rbuf) == 0) {
- /* no read-ahead left? */
- BIO *bio;
- /*
- * In the case where we try to read application data,
- * but we trigger an SSL handshake, we return -1 with
- * the retry option set. Otherwise renegotiation may
- * cause nasty problems in the blocking world
- */
- s->rwstate = SSL_READING;
- bio = SSL_get_rbio(s);
- BIO_clear_retry_flags(bio);
- BIO_set_retry_read(bio);
- return -1;
- }
- }
- }
- }
- /*
- * we either finished a handshake or ignored the request, now try
- * again to obtain the (application) data we were asked for
- */
- goto start;
- }
/*
* If we are a server and get a client hello when renegotiation isn't
* allowed send back a no renegotiation alert and carry on. WARNING:
*/
if (s->server &&
SSL_is_init_finished(s) &&
- !s->s3->send_connection_binding &&
(s->version > SSL3_VERSION) &&
+ !SSL_IS_TLS13(s) &&
+ (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) &&
(s->rlayer.handshake_fragment_len >= 4) &&
(s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
(s->session != NULL) && (s->session->cipher != NULL) &&
- !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+ ((!s->s3->send_connection_binding &&
+ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) ||
+ (s->options & SSL_OP_NO_RENEGOTIATION))) {
SSL3_RECORD_set_length(rr, 0);
SSL3_RECORD_set_read(rr);
ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
goto start;
}
- if (s->rlayer.alert_fragment_len >= 2) {
- int alert_level = s->rlayer.alert_fragment[0];
- int alert_descr = s->rlayer.alert_fragment[1];
-
- s->rlayer.alert_fragment_len = 0;
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+ unsigned int alert_level, alert_descr;
+ unsigned char *alert_bytes = SSL3_RECORD_get_data(rr)
+ + SSL3_RECORD_get_off(rr);
+ PACKET alert;
+
+ if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr))
+ || !PACKET_get_1(&alert, &alert_level)
+ || !PACKET_get_1(&alert, &alert_descr)
+ || PACKET_remaining(&alert) != 0) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_INVALID_ALERT);
+ goto f_err;
+ }
if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_ALERT,
- s->rlayer.alert_fragment, 2, s,
+ s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s,
s->msg_callback_arg);
if (s->info_callback != NULL)
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return 0;
}
+ /*
+ * Apart from close_notify the only other warning alert in TLSv1.3
+ * is user_cancelled - which we just ignore.
+ */
+ if (SSL_IS_TLS13(s) && alert_descr != SSL_AD_USER_CANCELLED) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
+ goto f_err;
+ }
/*
* This is a warning but we receive it if we requested
* renegotiation and the peer denied it. Terminate with a fatal
* future we might have a renegotiation where we don't care if
* the peer refused it where we carry on.
*/
- else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
+ if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
-#ifdef SSL_AD_MISSING_SRP_USERNAME
- else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
- return (0);
-#endif
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
s->rwstate = SSL_NOTHING;
s->s3->fatal_alert = alert_descr;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
- BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
+ BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
SSL3_RECORD_set_read(rr);
}
/*
- * Unexpected handshake message (Client Hello, or protocol violation)
+ * Unexpected handshake message (ClientHello, NewSessionTicket (TLS1.3) or
+ * protocol violation)
*/
if ((s->rlayer.handshake_fragment_len >= 4)
- && !ossl_statem_get_in_handshake(s)) {
- if (SSL_is_init_finished(s) &&
- !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
- ossl_statem_set_in_init(s, 1);
- s->renegotiate = 1;
- s->new_session = 1;
- }
+ && !ossl_statem_get_in_handshake(s)) {
+ int ined = (s->early_data_state == SSL_EARLY_DATA_READING);
+
+ /* We found handshake data, so we're going back into init */
+ ossl_statem_set_in_init(s, 1);
+
i = s->handshake_func(s);
if (i < 0)
return i;
return -1;
}
+ /*
+ * If we were actually trying to read early data and we found a
+ * handshake message, then we don't want to continue to try and read
+ * the application data any more. It won't be "early" now.
+ */
+ if (ined)
+ return -1;
+
if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
if (SSL3_BUFFER_get_left(rbuf) == 0) {
/* no read-ahead left? */
if (ossl_statem_app_data_allowed(s)) {
s->s3->in_read_app_data = 2;
return -1;
+ } else if (ossl_statem_skip_early_data(s)) {
+ /*
+ * This can happen after a client sends a CH followed by early_data,
+ * but the server responds with a HelloRetryRequest. The server
+ * reads the next record from the client expecting to find a
+ * plaintext ClientHello but gets a record which appears to be
+ * application data. The trial decrypt "works" because null
+ * decryption was applied. We just skip it and move on to the next
+ * record.
+ */
+ if (!early_data_count_ok(s, rr->length,
+ EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
+ goto f_err;
+ SSL3_RECORD_set_read(rr);
+ goto start;
} else {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);