#include <stdio.h>
#include <limits.h>
#include <errno.h>
-#include "../ssl_locl.h"
+#include "../ssl_local.h"
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/rand.h>
-#include "record_locl.h"
-#include "../packet_locl.h"
+#include "record_local.h"
+#include "internal/packet.h"
#if defined(OPENSSL_SMALL_FOOTPRINT) || \
!( defined(AES_ASM) && ( \
/*
* If extend == 0, obtain new n-byte packet; if extend == 1, increase
* packet by another n bytes. The packet will be in the sub-array of
- * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If
+ * s->s3.rbuf.buf specified by s->packet and s->packet_length. (If
* s->rlayer.read_ahead is set, 'max' bytes may be stored in rbuf [plus
* s->packet_length bytes if extend == 1].)
* if clearold == 1, move the packet to the start of the buffer; if
return -1;
}
- /* We always act like read_ahead is set for DTLS */
- if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s))
+ /*
+ * Ktls always reads full records.
+ * Also, we always act like read_ahead is set for DTLS.
+ */
+ if (!BIO_get_ktls_recv(s->rbio) && !s->rlayer.read_ahead
+ && !SSL_IS_DTLS(s)) {
/* ignore max parameter */
max = n;
- else {
+ } else {
if (max < n)
max = n;
if (max > rb->len - rb->offset)
int ret;
/*
- * Now we have len+left bytes at the front of s->s3->rbuf.buf and
+ * Now we have len+left bytes at the front of s->s3.rbuf.buf and
* need to read in more until we have len+n (up to len+max if
* possible)
*/
ret = BIO_read(s->rbio, pkt + len + left, max - left);
if (ret >= 0)
bioread = ret;
+ if (ret <= 0
+ && !BIO_should_retry(s->rbio)
+ && BIO_eof(s->rbio)) {
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N,
+ SSL_R_UNEXPECTED_EOF_WHILE_READING);
+ }
} else {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N,
SSL_R_READ_BIO_NOT_SET);
s->rlayer.wnum = 0;
+ /*
+ * If we are supposed to be sending a KeyUpdate then go into init unless we
+ * have writes pending - in which case we should finish doing that first.
+ */
+ if (wb->left == 0 && s->key_update != SSL_KEY_UPDATE_NONE)
+ ossl_statem_set_in_init(s, 1);
+
/*
* 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
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) &&
+ (BIO_get_ktls_send(s->wbio) == 0) &&
EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
unsigned char aad[13];
break;
}
- if (s->s3->alert_dispatch) {
+ if (s->s3.alert_dispatch) {
i = s->method->ssl_dispatch_alert(s);
if (i <= 0) {
/* SSLfatal() already called if appropriate */
* next chunk of data should get another prepended empty fragment
* in ciphersuites with known-IV weakness:
*/
- s->s3->empty_fragment_done = 0;
+ s->s3.empty_fragment_done = 0;
- if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS &&
- !SSL_IS_DTLS(s))
+ if (tmpwrit == n
+ && (s->mode & SSL_MODE_RELEASE_BUFFERS) != 0
+ && !SSL_IS_DTLS(s))
ssl3_release_write_buffer(s);
*written = tot + tmpwrit;
}
/* If we have an alert to send, lets send it */
- if (s->s3->alert_dispatch) {
+ if (s->s3.alert_dispatch) {
i = s->method->ssl_dispatch_alert(s);
if (i <= 0) {
/* SSLfatal() already called if appropriate */
/*
* 'create_empty_fragment' is true only when this function calls itself
*/
- if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) {
+ if (!clear && !create_empty_fragment && !s->s3.empty_fragment_done) {
/*
* countermeasure against known-IV weakness in CBC ciphersuites (see
* http://www.openssl.org/~bodo/tls-cbc.txt)
*/
- if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) {
+ if (s->s3.need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) {
/*
* recursive function call with 'create_empty_fragment' set; this
* prepares and buffers the data for an empty fragment (these
}
}
- s->s3->empty_fragment_done = 1;
+ s->s3.empty_fragment_done = 1;
}
if (BIO_get_ktls_send(s->wbio)) {
*/
SSL3_BUFFER_set_buf(&s->rlayer.wbuf[0], (unsigned char *)buf);
SSL3_BUFFER_set_offset(&s->rlayer.wbuf[0], 0);
+ SSL3_BUFFER_set_app_buffer(&s->rlayer.wbuf[0], 1);
goto wpacket_init_complete;
}
* in the wb->buf
*/
- if (!SSL_WRITE_ETM(s) && mac_size != 0) {
+ if (!BIO_get_ktls_send(s->wbio) && !SSL_WRITE_ETM(s) && mac_size != 0) {
unsigned char *mac;
if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
return -1;
}
-/* if s->s3->wbuf.left != 0, we need to call this
+/* if s->s3.wbuf.left != 0, we need to call this
*
* Return values are as per SSL_write()
*/
/* we now have a packet which can be read and processed */
- if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
- * reset by ssl3_get_finished */
+ if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec,
+ * reset by ssl3_get_finished */
&& (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES,
SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
if (alert_level == SSL3_AL_WARNING
|| (is_tls13 && alert_descr == SSL_AD_USER_CANCELLED)) {
- s->s3->warn_alert = alert_descr;
+ s->s3.warn_alert = alert_descr;
SSL3_RECORD_set_read(rr);
s->rlayer.alert_count++;
char tmp[16];
s->rwstate = SSL_NOTHING;
- s->s3->fatal_alert = alert_descr;
+ s->s3.fatal_alert = alert_descr;
SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_READ_BYTES,
SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
* started), we will indulge it.
*/
if (ossl_statem_app_data_allowed(s)) {
- s->s3->in_read_app_data = 2;
+ s->s3.in_read_app_data = 2;
return -1;
} else if (ossl_statem_skip_early_data(s)) {
/*