/*
- * 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 <assert.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"
+#include "../packet_locl.h"
#if defined(OPENSSL_SMALL_FOOTPRINT) || \
!( defined(AES_ASM) && ( \
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;
{
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;
* 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_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
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 */
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 */
}
totlen = 0;
/* Clear our SSL3_RECORD structures */
- memset(wr, 0, sizeof wr);
+ memset(wr, 0, sizeof(wr));
for (j = 0; j < numpipes; j++) {
unsigned int version = SSL_TREAT_AS_TLS13(s) ? TLS1_VERSION : s->version;
unsigned char *compressdata = NULL;
/* first we compress */
if (s->compress != NULL) {
- /*
- * TODO(TLS1.3): Make sure we prevent compression!!!
- */
if (!ssl3_do_compress(s, thiswr)
|| !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) {
SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE);
}
if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
- size_t padding = 0;
+ size_t rlen, max_send_fragment;
if (!WPACKET_put_bytes_u8(thispkt, type)) {
SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
SSL3_RECORD_add_length(thiswr, 1);
/* Add TLS1.3 padding */
- if (s->record_padding_cb != NULL) {
- size_t rlen = SSL3_RECORD_get_length(thiswr);
-
- padding = s->record_padding_cb(s, type, rlen, s->record_padding_arg);
- /* do not allow the record to exceed max plaintext length */
- if (padding > (SSL3_RT_MAX_PLAIN_LENGTH - rlen))
- padding = SSL3_RT_MAX_PLAIN_LENGTH - rlen;
- } 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 = SSL3_RECORD_get_length(thiswr) & mask;
- else
- remainder = SSL3_RECORD_get_length(thiswr) % 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) {
- if (!WPACKET_memset(thispkt, 0, padding)) {
- SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
- goto err;
+ 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);
}
- SSL3_RECORD_add_length(thiswr, padding);
}
}
* 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)
+ 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
|| 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 the tls13enc function.
+ * send early data - so we need to use the tls13enc function.
*/
if (tls13_enc(s, wr, numpipes, 1) < 1)
goto err;
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)) {
*/
SSL3_BUFFER_set_left(&wb[currbuf], 0);
}
- return (i);
+ return i;
}
SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit);
SSL3_BUFFER_sub_left(&wb[currbuf], tmpwrit);
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) {
memcpy(dest + *dest_len,
SSL3_RECORD_get_data(rr) + SSL3_RECORD_get_off(rr), n);
SSL3_RECORD_add_off(rr, n);
- SSL3_RECORD_add_length(rr, -n);
+ SSL3_RECORD_sub_length(rr, n);
*dest_len += n;
if (SSL3_RECORD_get_length(rr) == 0)
SSL3_RECORD_set_read(rr);
/*-
* 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 (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;
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);