/* uncompress */
COMP_CTX *expand;
+ /* Only used by SSLv3 */
+ unsigned char mac_secret[EVP_MAX_MD_SIZE];
+
+ /* TLSv1.3 static IV */
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+
+ size_t taglen;
+
/* Function pointers for version specific functions */
/* Function pointers for version specific functions */
struct record_functions_st *funcs;
return 1;
}
-static int tls_fail_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
- unsigned char *key, size_t keylen,
- unsigned char *iv, size_t ivlen,
- unsigned char *mackey, size_t mackeylen,
- const EVP_CIPHER *ciph,
- size_t taglen,
- /* TODO(RECLAYER): This probably should not be an int */
- int mactype,
- const EVP_MD *md,
- const SSL_COMP *comp,
- /* TODO(RECLAYER): Remove me */
- SSL_CONNECTION *s)
-{
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return 0;
-}
-
static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen,
return 1;
}
+/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
+static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+ unsigned char *key, size_t keylen,
+ unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph,
+ size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md,
+ const SSL_COMP *comp,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
+{
+ EVP_CIPHER_CTX *ciph_ctx;
+
+ if (md == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if ((rl->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ciph_ctx = rl->enc_read_ctx;
+
+ rl->read_hash = EVP_MD_CTX_new();
+ if (rl->read_hash == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+#ifndef OPENSSL_NO_COMP
+ if (comp != NULL) {
+ rl->expand = COMP_CTX_new(comp->method);
+ if (rl->expand == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR,
+ SSL_R_COMPRESSION_LIBRARY_ERROR);
+ return 0;
+ }
+ }
+#endif
+
+ if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (EVP_CIPHER_get0_provider(ciph) != NULL
+ && !tls_provider_set_tls_parameters(rl, ciph_ctx, ciph, md, s)) {
+ /* RLAYERfatal already called */
+ return 0;
+ }
+
+ if (mackeylen > sizeof(rl->mac_secret)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ memcpy(rl->mac_secret, mackey, mackeylen);
+
+ return 1;
+}
+
/* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
unsigned char *key, size_t keylen,
}
if (EVP_CIPHER_get0_provider(ciph) != NULL
&& !tls_provider_set_tls_parameters(rl, ciph_ctx, ciph, md, s)) {
- /* SSLfatal already called */
+ /* RLAYERfatal already called */
+ return 0;
+ }
+
+ return 1;
+}
+
+static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
+ unsigned char *key, size_t keylen,
+ unsigned char *iv, size_t ivlen,
+ unsigned char *mackey, size_t mackeylen,
+ const EVP_CIPHER *ciph,
+ size_t taglen,
+ /* TODO(RECLAYER): This probably should not be an int */
+ int mactype,
+ const EVP_MD *md,
+ const SSL_COMP *comp,
+ /* TODO(RECLAYER): Remove me */
+ SSL_CONNECTION *s)
+{
+ EVP_CIPHER_CTX *ciph_ctx;
+ int mode;
+
+ if (ivlen > sizeof(rl->iv)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ memcpy(rl->iv, iv, ivlen);
+
+ ciph_ctx = rl->enc_read_ctx = EVP_CIPHER_CTX_new();
+ if (ciph_ctx == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ RECORD_LAYER_reset_read_sequence(&s->rlayer);
+ rl->taglen = taglen;
+
+ mode = EVP_CIPHER_get_mode(ciph);
+
+ if (EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL) <= 0
+ || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
+ || (mode == EVP_CIPH_CCM_MODE
+ && !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL))
+ || EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL) <= 0) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
return 1;
}
+/*-
+ * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|. Calls SSLfatal on
+ * internal error, but not otherwise. It is the responsibility of the caller to
+ * report a bad_record_mac
+ *
+ * Returns:
+ * 0: if the record is publicly invalid, or an internal error
+ * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised)
+ */
+static int ssl3_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
+ int sending, SSL_MAC_BUF *mac, size_t macsize,
+ /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
+{
+ SSL3_RECORD *rec;
+ EVP_CIPHER_CTX *ds;
+ size_t l, i;
+ size_t bs;
+ const EVP_CIPHER *enc;
+ int provided;
+
+ rec = inrecs;
+ /*
+ * We shouldn't ever be called with more than one record in the SSLv3 case
+ */
+ if (n_recs != 1)
+ return 0;
+ if (sending) {
+ ds = s->enc_write_ctx;
+ if (s->enc_write_ctx == NULL)
+ enc = NULL;
+ else
+ enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx);
+ } else {
+ ds = rl->enc_read_ctx;
+ if (rl->enc_read_ctx == NULL)
+ enc = NULL;
+ else
+ enc = EVP_CIPHER_CTX_get0_cipher(rl->enc_read_ctx);
+ }
+
+ provided = (EVP_CIPHER_get0_provider(enc) != NULL);
+
+ l = rec->length;
+ bs = EVP_CIPHER_CTX_get_block_size(ds);
+
+ /* COMPRESS */
+
+ if ((bs != 1) && sending && !provided) {
+ /*
+ * We only do this for legacy ciphers. Provided ciphers add the
+ * padding on the provider side.
+ */
+ i = bs - (l % bs);
+
+ /* we need to add 'i-1' padding bytes */
+ l += i;
+ /*
+ * the last of these zero bytes will be overwritten with the
+ * padding length.
+ */
+ memset(&rec->input[rec->length], 0, i);
+ rec->length += i;
+ rec->input[l - 1] = (unsigned char)(i - 1);
+ }
+
+ if (!sending) {
+ if (l == 0 || l % bs != 0) {
+ /* Publicly invalid */
+ return 0;
+ }
+ /* otherwise, rec->length >= bs */
+ }
+
+ if (provided) {
+ int outlen;
+
+ if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input,
+ (unsigned int)l))
+ return 0;
+ rec->length = outlen;
+
+ if (!sending && mac != NULL) {
+ /* Now get a pointer to the MAC */
+ OSSL_PARAM params[2], *p = params;
+
+ /* Get the MAC */
+ mac->alloced = 0;
+
+ *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
+ (void **)&mac->mac,
+ macsize);
+ *p = OSSL_PARAM_construct_end();
+
+ if (!EVP_CIPHER_CTX_get_params(ds, params)) {
+ /* Shouldn't normally happen */
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+ } else {
+ if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) {
+ /* Shouldn't happen */
+ RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (!sending)
+ return ssl3_cbc_remove_padding_and_mac(&rec->length,
+ rec->orig_len,
+ rec->data,
+ (mac != NULL) ? &mac->mac : NULL,
+ (mac != NULL) ? &mac->alloced : NULL,
+ bs,
+ macsize,
+ rl->libctx);
+ }
+
+ return 1;
+}
#define MAX_PADDING 256
/*-
return 1;
}
+static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
+ int sending, SSL_MAC_BUF *mac, size_t macsize,
+ /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s)
+{
+ EVP_CIPHER_CTX *ctx;
+ unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH];
+ size_t ivlen, offset, loop, hdrlen;
+ unsigned char *staticiv;
+ unsigned char *seq;
+ int lenu, lenf;
+ SSL3_RECORD *rec = &recs[0];
+ WPACKET wpkt;
+ const EVP_CIPHER *cipher;
+ int mode;
+
+ if (n_recs != 1) {
+ /* Should not happen */
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (sending) {
+ ctx = s->enc_write_ctx;
+ staticiv = s->write_iv;
+ seq = RECORD_LAYER_get_write_sequence(&s->rlayer);
+ } else {
+ ctx = rl->enc_read_ctx;
+ staticiv = rl->iv;
+ seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
+ }
+
+ cipher = EVP_CIPHER_CTX_get0_cipher(ctx);
+ if (cipher == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ mode = EVP_CIPHER_get_mode(cipher);
+
+ /*
+ * If we're sending an alert and ctx != NULL then we must be forcing
+ * plaintext alerts. If we're reading and ctx != NULL then we allow
+ * plaintext alerts at certain points in the handshake. If we've got this
+ * far then we have already validated that a plaintext alert is ok here.
+ */
+ if (ctx == NULL || rec->type == SSL3_RT_ALERT) {
+ memmove(rec->data, rec->input, rec->length);
+ rec->input = rec->data;
+ return 1;
+ }
+
+ ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
+
+ if (!sending) {
+ /*
+ * Take off tag. There must be at least one byte of content type as
+ * well as the tag
+ */
+ if (rec->length < rl->taglen + 1)
+ return 0;
+ rec->length -= rl->taglen;
+ }
+
+ /* Set up IV */
+ if (ivlen < SEQ_NUM_SIZE) {
+ /* Should not happen */
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ offset = ivlen - SEQ_NUM_SIZE;
+ memcpy(iv, staticiv, offset);
+ for (loop = 0; loop < SEQ_NUM_SIZE; loop++)
+ iv[offset + loop] = staticiv[offset + loop] ^ seq[loop];
+
+ /* Increment the sequence counter */
+ for (loop = SEQ_NUM_SIZE; loop > 0; loop--) {
+ ++seq[loop - 1];
+ if (seq[loop - 1] != 0)
+ break;
+ }
+ if (loop == 0) {
+ /* Sequence has wrapped */
+ return 0;
+ }
+
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0
+ || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
+ rl->taglen,
+ rec->data + rec->length) <= 0)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /* Set up the AAD */
+ if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0)
+ || !WPACKET_put_bytes_u8(&wpkt, rec->type)
+ || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)
+ || !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen)
+ || !WPACKET_get_total_written(&wpkt, &hdrlen)
+ || hdrlen != SSL3_RT_HEADER_LENGTH
+ || !WPACKET_finish(&wpkt)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ WPACKET_cleanup(&wpkt);
+ return 0;
+ }
+
+ /*
+ * For CCM we must explicitly set the total plaintext length before we add
+ * any AAD.
+ */
+ if ((mode == EVP_CIPH_CCM_MODE
+ && EVP_CipherUpdate(ctx, NULL, &lenu, NULL,
+ (unsigned int)rec->length) <= 0)
+ || EVP_CipherUpdate(ctx, NULL, &lenu, recheader,
+ sizeof(recheader)) <= 0
+ || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input,
+ (unsigned int)rec->length) <= 0
+ || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0
+ || (size_t)(lenu + lenf) != rec->length) {
+ return 0;
+ }
+ if (sending) {
+ /* Add the tag */
+ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen,
+ rec->data + rec->length) <= 0) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ rec->length += rl->taglen;
+ }
+
+ return 1;
+}
+
+static const unsigned char ssl3_pad_1[48] = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+};
+
+static const unsigned char ssl3_pad_2[48] = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+};
+
+static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
+ int sending, SSL_CONNECTION *ssl)
+{
+ unsigned char *mac_sec, *seq;
+ const EVP_MD_CTX *hash;
+ unsigned char *p, rec_char;
+ size_t md_size;
+ size_t npad;
+ int t;
+
+ if (sending) {
+ mac_sec = &(ssl->s3.write_mac_secret[0]);
+ seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
+ hash = ssl->write_hash;
+ } else {
+ mac_sec = &(rl->mac_secret[0]);
+ seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
+ hash = rl->read_hash;
+ }
+
+ t = EVP_MD_CTX_get_size(hash);
+ if (t < 0)
+ return 0;
+ md_size = t;
+ npad = (48 / md_size) * md_size;
+
+ if (!sending
+ && EVP_CIPHER_CTX_get_mode(rl->enc_read_ctx) == EVP_CIPH_CBC_MODE
+ && ssl3_cbc_record_digest_supported(hash)) {
+#ifdef OPENSSL_NO_DEPRECATED_3_0
+ return 0;
+#else
+ /*
+ * This is a CBC-encrypted record. We must avoid leaking any
+ * timing-side channel information about how many blocks of data we
+ * are hashing because that gives an attacker a timing-oracle.
+ */
+
+ /*-
+ * npad is, at most, 48 bytes and that's with MD5:
+ * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
+ *
+ * With SHA-1 (the largest hash speced for SSLv3) the hash size
+ * goes up 4, but npad goes down by 8, resulting in a smaller
+ * total size.
+ */
+ unsigned char header[75];
+ size_t j = 0;
+ memcpy(header + j, mac_sec, md_size);
+ j += md_size;
+ memcpy(header + j, ssl3_pad_1, npad);
+ j += npad;
+ memcpy(header + j, seq, 8);
+ j += 8;
+ header[j++] = rec->type;
+ header[j++] = (unsigned char)(rec->length >> 8);
+ header[j++] = (unsigned char)(rec->length & 0xff);
+
+ /* Final param == is SSLv3 */
+ if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash),
+ md, &md_size,
+ header, rec->input,
+ rec->length, rec->orig_len,
+ mac_sec, md_size, 1) <= 0)
+ return 0;
+#endif
+ } else {
+ unsigned int md_size_u;
+ /* Chop the digest off the end :-) */
+ EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+
+ if (md_ctx == NULL)
+ return 0;
+
+ rec_char = rec->type;
+ p = md;
+ s2n(rec->length, p);
+ if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
+ || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
+ || EVP_DigestUpdate(md_ctx, md, 2) <= 0
+ || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
+ || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
+ || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
+ EVP_MD_CTX_free(md_ctx);
+ return 0;
+ }
+
+ EVP_MD_CTX_free(md_ctx);
+ }
+
+ ssl3_record_sequence_update(seq);
+ return 1;
+}
+
static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
int sending, SSL_CONNECTION *ssl)
{
return ret;
}
-
struct record_functions_st tls_any_funcs = {
tls_any_set_crypto_state,
tls_any_cipher,
};
struct record_functions_st tls_1_3_funcs = {
- tls_fail_set_crypto_state,
- NULL,
+ tls13_set_crypto_state,
+ tls13_cipher,
NULL
};
};
struct record_functions_st ssl_3_0_funcs = {
- tls_fail_set_crypto_state,
- NULL,
- NULL
+ ssl3_set_crypto_state,
+ ssl3_cipher,
+ ssl3_mac
};
static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
* Ktls always reads full records.
* Also, we always act like read_ahead is set for DTLS.
*/
- if (!BIO_get_ktls_recv(s->rbio) && !rl->read_ahead
+ if (!BIO_get_ktls_recv(rl->bio) && !rl->read_ahead
&& !rl->isdtls) {
/* ignore max parameter */
max = n;
}
if (SSL_CONNECTION_IS_TLS13(s)
- && s->enc_read_ctx != NULL
+ && rl->enc_read_ctx != NULL
&& !using_ktls) {
if (thisrr->type != SSL3_RT_APPLICATION_DATA
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC
* TODO(RECLAYER): Only call rl functions once TLSv1.3/SSLv3 is moved to new
* record layer code
*/
- if (!SSL_CONNECTION_IS_TLS13(s))
- enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
- else
- enc_err = ssl->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size);
+ enc_err = rl->funcs->cipher(rl, rr, num_recs, 0, macbufs, mac_size, s);
/*-
* enc_err is:
}
if (SSL_CONNECTION_IS_TLS13(s)
- && s->enc_read_ctx != NULL
+ && rl->enc_read_ctx != NULL
&& thisrr->type != SSL3_RT_ALERT) {
/*
* The following logic are irrelevant in KTLS: the kernel provides
goto err;
}
+ /*
+ * TODO(RECLAYER): Need to handle the case where the params are updated
+ * after the record layer has been created.
+ */
p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS);
if (p != NULL && !OSSL_PARAM_get_uint64(p, &rl->options)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER);
goto err;
}
-
- p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD);
- if (p != NULL && !OSSL_PARAM_get_int(p, &rl->read_ahead)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER);
- goto err;
+ if (level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION) {
+ /*
+ * We ignore any read_ahead setting prior to the application protection
+ * level. Otherwise we may read ahead data in a lower protection level
+ * that is destined for a higher protection level. To simplify the logic
+ * we don't support that at this stage.
+ */
+ /*
+ * TODO(RECLAYER): Handle the case of read_ahead at the application
+ * level and a key update/reneg occurs.
+ */
+ p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD);
+ if (p != NULL && !OSSL_PARAM_get_int(p, &rl->read_ahead)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER);
+ goto err;
+ }
}
rl->libctx = libctx;
static void tls_free(OSSL_RECORD_LAYER *rl)
{
+ /* TODO(RECLAYER): Cleanse sensitive fields */
BIO_free(rl->bio);
OPENSSL_free(rl);
}