This transfers the low level function ssl3_read_n to the new record layer.
We temporarily make the read_n function a top level record layer function.
Eventually, in later commits in this refactor, we will remove it as a top
level function and it will just be called from read_record.
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)
SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received
SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message
SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch
+SSL_R_FAILED_TO_GET_PARAMETER:316:failed to get parameter
SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async
SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello
SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs
SSL_R_PSK_NO_SERVER_CB:225:psk no server cb
SSL_R_READ_BIO_NOT_SET:211:read bio not set
SSL_R_READ_TIMEOUT_EXPIRED:312:read timeout expired
+SSL_R_RECORD_LAYER_FAILURE:313:record layer failure
SSL_R_RECORD_LENGTH_MISMATCH:213:record length mismatch
SSL_R_RECORD_TOO_SMALL:298:record too small
SSL_R_RENEGOTIATE_EXT_TOO_LONG:335:renegotiate ext too long
/* OSSL_DECODER input type if a decoder is used by the store */
#define OSSL_STORE_PARAM_INPUT_TYPE "input-type" /* UTF8_STRING */
+
+/* Libssl record layer */
+
+#define OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS "options"
+#define OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE "mode"
+#define OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD "read_ahead"
+
# ifdef __cplusplus
}
# endif
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
# define SSL_R_EXTENSION_NOT_RECEIVED 279
# define SSL_R_EXTRA_DATA_IN_MESSAGE 153
# define SSL_R_EXT_LENGTH_MISMATCH 163
+# define SSL_R_FAILED_TO_GET_PARAMETER 316
# define SSL_R_FAILED_TO_INIT_ASYNC 405
# define SSL_R_FRAGMENTED_CLIENT_HELLO 401
# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
# define SSL_R_PSK_NO_SERVER_CB 225
# define SSL_R_READ_BIO_NOT_SET 211
# define SSL_R_READ_TIMEOUT_EXPIRED 312
+# define SSL_R_RECORD_LAYER_FAILURE 313
# define SSL_R_RECORD_LENGTH_MISMATCH 213
# define SSL_R_RECORD_TOO_SMALL 298
# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335
/* ERR_raise() already called */
return -1;
}
- buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
+ buf = s->rrlmethod->get0_rbuf(s->rrl)->buf;
wbuf = RECORD_LAYER_get_wbuf(&s->rlayer)[0].buf;
#if defined(SSL3_ALIGN_PAYLOAD)
# if SSL3_ALIGN_PAYLOAD != 0
/*
* Using SSL3_RT_HEADER_LENGTH here instead of DTLS1_RT_HEADER_LENGTH for
- * consistency with ssl3_read_n. In practice it should make no difference
+ * consistency with read_n. In practice it should make no difference
* for sensible values of SSL3_ALIGN_PAYLOAD because the difference between
* SSL3_RT_HEADER_LENGTH and DTLS1_RT_HEADER_LENGTH is exactly 8
*/
*/
static int count_unprocessed_records(SSL_CONNECTION *s)
{
- SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+ SSL3_BUFFER *rbuf = s->rrlmethod->get0_rbuf(s->rrl);
PACKET pkt, subpkt;
int count = 0;
rdata = (DTLS1_RECORD_DATA *)item->data;
- SSL3_BUFFER_release(&s->rlayer.rbuf);
+ SSL3_BUFFER_release(s->rrlmethod->get0_rbuf(s->rrl));
- s->rlayer.packet = rdata->packet;
- s->rlayer.packet_length = rdata->packet_length;
- memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
+ s->rrlmethod->set0_packet(s->rrl, rdata->packet, rdata->packet_length);
+ memcpy(s->rrlmethod->get0_rbuf(s->rrl), &(rdata->rbuf), sizeof(SSL3_BUFFER));
memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD));
/* Set proper sequence number for mac calculation */
return -1;
}
- rdata->packet = s->rlayer.packet;
- rdata->packet_length = s->rlayer.packet_length;
- memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER));
+ rdata->packet = s->rrlmethod->get0_packet(s->rrl);
+ rdata->packet_length = s->rrlmethod->get_packet_length(s->rrl);
+ memcpy(&(rdata->rbuf), s->rrlmethod->get0_rbuf(s->rrl), sizeof(SSL3_BUFFER));
memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD));
item->data = rdata;
}
#endif
- s->rlayer.packet = NULL;
- s->rlayer.packet_length = 0;
- memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf));
+ s->rrlmethod->set0_packet(s->rrl, NULL, 0);
+ memset(s->rrlmethod->get0_rbuf(s->rrl), 0, sizeof(SSL3_BUFFER));
memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec));
if (!ssl3_setup_buffers(s)) {
rr = RECORD_LAYER_get_rrec(&s->rlayer);
- rb = RECORD_LAYER_get_rbuf(&s->rlayer);
+ rb = s->rrlmethod->get0_rbuf(s->rrl);
if (SSL3_BUFFER_get_left(rb) > 0) {
/*
}
/* dump this record */
rr->length = 0;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
continue;
}
if (sc == NULL)
return -1;
- if (!SSL3_BUFFER_is_initialised(&sc->rlayer.rbuf)) {
+ if (!SSL3_BUFFER_is_initialised(sc->rrlmethod->get0_rbuf(sc->rrl))) {
/* Not initialized yet */
if (!ssl3_setup_buffers(sc)) {
/* SSLfatal() already called */
SSL3_RECORD_set_length(rr, 0);
SSL3_RECORD_set_read(rr);
if (!(sc->mode & SSL_MODE_AUTO_RETRY)) {
- if (SSL3_BUFFER_get_left(&sc->rlayer.rbuf) == 0) {
+ if (SSL3_BUFFER_get_left(sc->rrlmethod->get0_rbuf(sc->rrl)) == 0) {
/* no read-ahead left? */
BIO *bio;
return -1;
if (!(sc->mode & SSL_MODE_AUTO_RETRY)) {
- if (SSL3_BUFFER_get_left(&sc->rlayer.rbuf) == 0) {
+ if (SSL3_BUFFER_get_left(sc->rrlmethod->get0_rbuf(sc->rrl)) == 0) {
/* no read-ahead left? */
BIO *bio;
/*
if (sc == NULL)
return;
-
- SSL3_BUFFER_set_default_len(RECORD_LAYER_get_rbuf(&sc->rlayer), len);
+ SSL3_BUFFER_set_default_len(sc->rrlmethod->get0_rbuf(sc->rrl), len);
}
const char *SSL_rstate_string_long(const SSL *s)
}
}
-/*
- * Return values are as per SSL_read()
- */
-int ssl3_read_n(SSL_CONNECTION *s, size_t n, size_t max, int extend,
- int clearold, size_t *readbytes)
-{
- /*
- * 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->rlayer.rbuf.buf specified by s->rlayer.packet and
- * s->rlayer.packet_length. (If s->rlayer.read_ahead is set, 'max' bytes may
- * be stored in rbuf [plus s->rlayer.packet_length bytes if extend == 1].)
- * if clearold == 1, move the packet to the start of the buffer; if
- * clearold == 0 then leave any old packets where they were
- */
- size_t len, left, align = 0;
- unsigned char *pkt;
- SSL3_BUFFER *rb;
-
- if (n == 0)
- return 0;
-
- rb = &s->rlayer.rbuf;
- if (rb->buf == NULL)
- if (!ssl3_setup_read_buffer(s)) {
- /* SSLfatal() already called */
- return -1;
- }
-
- left = rb->left;
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
- align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
- align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
-#endif
-
- if (!extend) {
- /* start with empty packet ... */
- if (left == 0)
- rb->offset = align;
- else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
- /*
- * check if next packet length is large enough to justify payload
- * alignment...
- */
- pkt = rb->buf + rb->offset;
- if (pkt[0] == SSL3_RT_APPLICATION_DATA
- && (pkt[3] << 8 | pkt[4]) >= 128) {
- /*
- * Note that even if packet is corrupted and its length field
- * is insane, we can only be led to wrong decision about
- * whether memmove will occur or not. Header values has no
- * effect on memmove arguments and therefore no buffer
- * overrun can be triggered.
- */
- memmove(rb->buf + align, pkt, left);
- rb->offset = align;
- }
- }
- s->rlayer.packet = rb->buf + rb->offset;
- s->rlayer.packet_length = 0;
- /* ... now we can act as if 'extend' was set */
- }
-
- len = s->rlayer.packet_length;
- pkt = rb->buf + align;
- /*
- * Move any available bytes to front of buffer: 'len' bytes already
- * pointed to by 'packet', 'left' extra ones at the end
- */
- if (s->rlayer.packet != pkt && clearold == 1) {
- memmove(pkt, s->rlayer.packet, len + left);
- s->rlayer.packet = pkt;
- rb->offset = len + align;
- }
-
- /*
- * For DTLS/UDP reads should not span multiple packets because the read
- * operation returns the whole packet at once (as long as it fits into
- * the buffer).
- */
- if (SSL_CONNECTION_IS_DTLS(s)) {
- if (left == 0 && extend)
- return 0;
- if (left > 0 && n > left)
- n = left;
- }
-
- /* if there is enough in the buffer from a previous read, take some */
- if (left >= n) {
- s->rlayer.packet_length += n;
- rb->left = left - n;
- rb->offset += n;
- *readbytes = n;
- return 1;
- }
-
- /* else we need to read more data */
-
- if (n > rb->len - rb->offset) {
- /* does not happen */
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- /*
- * 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_CONNECTION_IS_DTLS(s)) {
- /* ignore max parameter */
- max = n;
- } else {
- if (max < n)
- max = n;
- if (max > rb->len - rb->offset)
- max = rb->len - rb->offset;
- }
-
- while (left < n) {
- size_t bioread = 0;
- int ret;
-
- /*
- * 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)
- */
-
- clear_sys_error();
- if (s->rbio != NULL) {
- s->rwstate = SSL_READING;
- 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)) {
- if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
- SSL_set_shutdown(SSL_CONNECTION_GET_SSL(s),
- SSL_RECEIVED_SHUTDOWN);
- s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
- } else {
- SSLfatal(s, SSL_AD_DECODE_ERROR,
- SSL_R_UNEXPECTED_EOF_WHILE_READING);
- }
- }
- } else {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET);
- ret = -1;
- }
-
- if (ret <= 0) {
- rb->left = left;
- if ((s->mode & SSL_MODE_RELEASE_BUFFERS) != 0
- && !SSL_CONNECTION_IS_DTLS(s))
- if (len + left == 0)
- ssl3_release_read_buffer(s);
- return ret;
- }
- left += bioread;
- /*
- * reads should *never* span multiple packets for DTLS because the
- * underlying transport protocol is message oriented as opposed to
- * byte oriented as in the TLS case.
- */
- if (SSL_CONNECTION_IS_DTLS(s)) {
- if (n > left)
- n = left; /* makes the while condition false */
- }
- }
-
- /* done reading, now the book-keeping */
- rb->offset += n;
- rb->left = left - n;
- s->rlayer.packet_length += n;
- s->rwstate = SSL_NOTHING;
- *readbytes = n;
- return 1;
-}
/*
* Call this to write data in records of type 'type' It will return <= 0 if
is_tls13 = SSL_CONNECTION_IS_TLS13(s);
- rbuf = &s->rlayer.rbuf;
+ rbuf = s->rrlmethod->get0_rbuf(s->rrl);
if (!SSL3_BUFFER_is_initialised(rbuf)) {
/* Not initialized yet */
#define RECORD_LAYER_clear_first_record(rl) ((rl)->is_first_record = 0)
#define DTLS_RECORD_LAYER_get_r_epoch(rl) ((rl)->d->r_epoch)
-__owur int ssl3_read_n(SSL_CONNECTION *s, size_t n, size_t max, int extend,
- int clearold, size_t *readbytes);
-
DTLS1_BITMAP *dtls1_get_bitmap(SSL_CONNECTION *s, SSL3_RECORD *rr,
unsigned int *is_next_epoch);
int dtls1_process_buffered_records(SSL_CONNECTION *s);
#define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3
+#define OSSL_RECORD_RETURN_SUCCESS 1
+#define OSSL_RECORD_RETURN_RETRY 0
+#define OSSL_RECORD_RETURN_NON_FATAL_ERR -1
+#define OSSL_RECORD_RETURN_FATAL -2
+#define OSSL_RECORD_RETURN_EOF -3
+
/*
* Template for creating a record. A record consists of the |type| of data it
* will contain (e.g. alert, handshake, application data, etc) along with an
*/
void (*release_record)(OSSL_RECORD_LAYER *rl, void *rechandle);
+ /*
+ * In the event that a fatal error is returned from the functions above then
+ * get_alert_code() can be called to obtain a more details identifier for
+ * the error. In (D)TLS this is the alert description code.
+ */
+ int (*get_alert_code)(OSSL_RECORD_LAYER *rl);
+
+ /*
+ * Update the transport BIO from the one originally set in the
+ * new_record_layer call
+ */
+ int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio);
+
+ /*
+ * TODO(RECLAYER): Remove these. These function pointers are temporary hacks
+ * during the record layer refactoring. They need to be removed before the
+ * refactor is complete.
+ */
+ int (*read_n)(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
+ int clearold, size_t *readbytes);
+ SSL3_BUFFER *(*get0_rbuf)(OSSL_RECORD_LAYER *rl);
+ unsigned char *(*get0_packet)(OSSL_RECORD_LAYER *rl);
+ void (*set0_packet)(OSSL_RECORD_LAYER *rl, unsigned char *packet,
+ size_t packetlen);
+ size_t (*get_packet_length)(OSSL_RECORD_LAYER *rl);
+ void (*reset_packet_length)(OSSL_RECORD_LAYER *rl);
};
+
+
+/* Standard built-in record methods */
+extern const OSSL_RECORD_METHOD ossl_tls_record_method;
+extern const OSSL_RECORD_METHOD ossl_dtls_record_method;
\ No newline at end of file
size_t len, align = 0, headerlen;
SSL3_BUFFER *b;
- b = RECORD_LAYER_get_rbuf(&s->rlayer);
+ b = s->rrlmethod->get0_rbuf(s->rrl);
if (SSL_CONNECTION_IS_DTLS(s))
headerlen = DTLS1_RT_HEADER_LENGTH;
{
SSL3_BUFFER *b;
- b = RECORD_LAYER_get_rbuf(&s->rlayer);
+ b = s->rrlmethod->get0_rbuf(s->rrl);
if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
OPENSSL_cleanse(b->buf, b->len);
OPENSSL_free(b->buf);
size_t left, len;
unsigned char *p;
- rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+ rbuf = s->rrlmethod->get0_rbuf(s->rrl);
p = SSL3_BUFFER_get_buf(rbuf);
if (p == NULL)
return 1;
}
+static int tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file,
+ int line)
+{
+ SSL *ssl = SSL_CONNECTION_GET_SSL(s);
+
+ if (ret == OSSL_RECORD_RETURN_RETRY) {
+ s->rwstate = SSL_READING;
+ ret = -1;
+ } else {
+ s->rwstate = SSL_NOTHING;
+ if (ret == OSSL_RECORD_RETURN_EOF) {
+ if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) {
+ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
+ s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY;
+ } else {
+ ERR_new();
+ ERR_set_debug(file, line, 0);
+ ossl_statem_fatal(s, SSL_AD_DECODE_ERROR,
+ SSL_R_UNEXPECTED_EOF_WHILE_READING, NULL);
+ }
+ } else if (ret == OSSL_RECORD_RETURN_FATAL) {
+ ERR_new();
+ ERR_set_debug(file, line, 0);
+ ossl_statem_fatal(s, s->rrlmethod->get_alert_code(s->rrl),
+ SSL_R_RECORD_LAYER_FAILURE, NULL);
+ }
+ /*
+ * The record layer distinguishes the cases of EOF, non-fatal
+ * err and retry. Upper layers do not.
+ * If we got a retry or success then *ret is already correct,
+ * otherwise we need to convert the return value.
+ */
+ /*
+ * TODO(RECLAYER): What does a non fatal err that isn't a retry even
+ * mean???
+ */
+ if (ret == OSSL_RECORD_RETURN_NON_FATAL_ERR || ret == OSSL_RECORD_RETURN_EOF)
+ ret = 0;
+ else if (ret < OSSL_RECORD_RETURN_NON_FATAL_ERR)
+ ret = -1;
+ }
+
+ return ret;
+}
+
+# define HANDLE_RLAYER_RETURN(s, ret) \
+ tls_handle_rlayer_return(s, ret, OPENSSL_FILE, OPENSSL_LINE)
+
/*
* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
* will be processed per call to ssl3_get_record. Without this limit an
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
rr = RECORD_LAYER_get_rrec(&s->rlayer);
- rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+ rbuf = s->rrlmethod->get0_rbuf(s->rrl);
+
max_recs = s->max_pipelines;
if (max_recs == 0)
max_recs = 1;
/* check if we have the header */
if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
- (RECORD_LAYER_get_packet_length(&s->rlayer)
- < SSL3_RT_HEADER_LENGTH)) {
+ (s->rrlmethod->get_packet_length(s->rrl) < SSL3_RT_HEADER_LENGTH)) {
size_t sslv2len;
unsigned int type;
- rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
- SSL3_BUFFER_get_len(rbuf), 0,
- num_recs == 0 ? 1 : 0, &n);
+ rret = HANDLE_RLAYER_RETURN(s,
+ s->rrlmethod->read_n(s->rrl, SSL3_RT_HEADER_LENGTH,
+ SSL3_BUFFER_get_len(rbuf), 0,
+ num_recs == 0 ? 1 : 0, &n));
+
if (rret <= 0) {
#ifndef OPENSSL_NO_KTLS
if (!using_ktls || rret == 0)
}
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
- p = RECORD_LAYER_get_packet(&s->rlayer);
- if (!PACKET_buf_init(&pkt, RECORD_LAYER_get_packet(&s->rlayer),
- RECORD_LAYER_get_packet_length(&s->rlayer))) {
+ p = s->rrlmethod->get0_packet(s->rrl);
+ if (!PACKET_buf_init(&pkt, p,
+ s->rrlmethod->get_packet_length(s->rrl))) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return -1;
}
if (RECORD_LAYER_is_first_record(&s->rlayer)) {
/* Go back to start of packet, look at the five bytes
* that we have. */
- p = RECORD_LAYER_get_packet(&s->rlayer);
+ p = s->rrlmethod->get0_packet(s->rrl);
if (HAS_PREFIX((char *)p, "GET ") ||
HAS_PREFIX((char *)p, "POST ") ||
HAS_PREFIX((char *)p, "HEAD ") ||
if (more > 0) {
/* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */
- rret = ssl3_read_n(s, more, more, 1, 0, &n);
+ rret = HANDLE_RLAYER_RETURN(s,
+ s->rrlmethod->read_n(s->rrl, more, more, 1, 0, &n));
if (rret <= 0)
return rret; /* error or non-blocking io */
}
*/
if (thisrr->rec_version == SSL2_VERSION) {
thisrr->input =
- &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
+ &(s->rrlmethod->get0_packet(s->rrl)[SSL2_RT_HEADER_LENGTH]);
} else {
thisrr->input =
- &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+ &(s->rrlmethod->get0_packet(s->rrl)[SSL3_RT_HEADER_LENGTH]);
}
/*
num_recs++;
/* we have pulled in a full packet so zero things */
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
RECORD_LAYER_clear_first_record(&s->rlayer);
} while (num_recs < max_recs
&& thisrr->type == SSL3_RT_APPLICATION_DATA
* At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
* and we have that many bytes in s->rlayer.packet
*/
- rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]);
+ rr->input = &(s->rrlmethod->get0_packet(s->rrl)[DTLS1_RT_HEADER_LENGTH]);
/*
* ok, we can now read from 's->rlayer.packet' data into 'rr'. rr->input
}
/* For DTLS we simply ignore bad packets. */
rr->length = 0;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto end;
}
ERR_clear_last_mark();
if (enc_err == 0) {
/* decryption failed, silently discard message */
rr->length = 0;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto end;
}
*/
/* we have pulled in a full packet so zero things */
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
/* Mark receipt of record. */
dtls1_record_bitmap_update(s, bitmap);
/* check if we have the header */
if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
- (RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) {
- rret = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH,
- SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0, 1, &n);
+ (s->rrlmethod->get_packet_length(s->rrl) < DTLS1_RT_HEADER_LENGTH)) {
+ rret = HANDLE_RLAYER_RETURN(s,
+ s->rrlmethod->read_n(s->rrl, DTLS1_RT_HEADER_LENGTH,
+ SSL3_BUFFER_get_len(s->rrlmethod->get0_rbuf(s->rrl)), 0, 1, &n));
/* read timeout is handled by dtls1_read_bytes */
if (rret <= 0) {
/* SSLfatal() already called if appropriate */
}
/* this packet contained a partial record, dump it */
- if (RECORD_LAYER_get_packet_length(&s->rlayer) !=
- DTLS1_RT_HEADER_LENGTH) {
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ if (s->rrlmethod->get_packet_length(s->rrl) != DTLS1_RT_HEADER_LENGTH) {
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
- p = RECORD_LAYER_get_packet(&s->rlayer);
+ p = s->rrlmethod->get0_packet(s->rrl);
if (s->msg_callback)
s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
/* unexpected version, silently discard */
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
}
/* wrong version, silently discard record */
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
/* record too long, silently discard it */
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
/* record too long, silently discard it */
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
/* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
if (rr->length >
- RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) {
+ s->rrlmethod->get_packet_length(s->rrl) - DTLS1_RT_HEADER_LENGTH) {
/* now s->rlayer.packet_length == DTLS1_RT_HEADER_LENGTH */
more = rr->length;
- rret = ssl3_read_n(s, more, more, 1, 1, &n);
+ rret = HANDLE_RLAYER_RETURN(s,
+ s->rrlmethod->read_n(s->rrl, more, more, 1, 1, &n));
/* this packet contained a partial record, dump it */
if (rret <= 0 || n != more) {
if (ossl_statem_in_error(s)) {
- /* ssl3_read_n() called SSLfatal() */
+ /* read_n() called SSLfatal() */
return -1;
}
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
if (bitmap == NULL) {
rr->length = 0;
- RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
if (!dtls1_record_replay_check(s, bitmap)) {
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
}
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer);
+ s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
}
rr->length = 0;
rr->read = 1;
- RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
goto again; /* get another record */
}
memcpy(rr->seq_num, seq, sizeof(rr->seq_num));
rr->off = off;
- s->rlayer.packet = RECORD_LAYER_get_rbuf(&s->rlayer)->buf;
- s->rlayer.packet_length = DTLS1_RT_HEADER_LENGTH + len;
- rr->data = s->rlayer.packet + DTLS1_RT_HEADER_LENGTH;
+ s->rrlmethod->set0_packet(s->rrl, s->rrlmethod->get0_rbuf(s->rrl)->buf,
+ DTLS1_RT_HEADER_LENGTH + len);
+ rr->data = s->rrlmethod->get0_packet(s->rrl) + DTLS1_RT_HEADER_LENGTH;
if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
SSL3_RECORD_get_seq_num(s->rlayer.rrec)) <= 0) {
#include <openssl/bio.h>
#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/core_names.h>
+#include "internal/e_os.h"
+#include "record.h"
#include "recordmethod.h"
struct ossl_record_layer_st
{
- /* Placeholder until we have real data to store */
- int dummy;
+ int isdtls;
+ int version;
+ int role;
+ int direction;
+ BIO *bio;
+ /* Types match the equivalent structures in the SSL object */
+ uint64_t options;
+ /*
+ * TODO(RECLAYER): Should we take the opportunity to make this uint64_t
+ * even though upper layer continue to use uint32_t?
+ */
+ uint32_t mode;
+
+ /* read IO goes into here */
+ SSL3_BUFFER rbuf;
+
+ /* used internally to point at a raw packet */
+ unsigned char *packet;
+ size_t packet_length;
+
+ int alert;
+
+ /*
+ * Read as many input bytes as possible (for
+ * non-blocking reads)
+ * TODO(RECLAYER): Why isn't this just an option?
+ */
+ int read_ahead;
};
+static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio);
+
+# define SSL_AD_NO_ALERT -1
+
+static void rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ ERR_vset_error(ERR_LIB_SSL, reason, fmt, args);
+ va_end(args);
+
+ rl->alert = al;
+}
+
+
+# define RLAYERfatal(rl, al, r) RLAYERfatal_data((rl), (al), (r), NULL)
+# define RLAYERfatal_data \
+ (ERR_new(), \
+ ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \
+ rlayer_fatal)
+
+static int rlayer_allow_compression(OSSL_RECORD_LAYER *rl)
+{
+ if (rl->options & SSL_OP_NO_COMPRESSION)
+ return 0;
+#if 0
+ /* TODO(RECLAYER): Implement ssl_security inside the record layer */
+ return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL);
+#else
+ return 1;
+#endif
+}
+
+static int rlayer_setup_read_buffer(OSSL_RECORD_LAYER *rl)
+{
+ unsigned char *p;
+ size_t len, align = 0, headerlen;
+ SSL3_BUFFER *b;
+
+ b = &rl->rbuf;
+
+ if (rl->isdtls)
+ headerlen = DTLS1_RT_HEADER_LENGTH;
+ else
+ headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+#endif
+
+ if (b->buf == NULL) {
+ len = SSL3_RT_MAX_PLAIN_LENGTH
+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+#ifndef OPENSSL_NO_COMP
+ if (rlayer_allow_compression(rl))
+ len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+ if (b->default_len > len)
+ len = b->default_len;
+ if ((p = OPENSSL_malloc(len)) == NULL) {
+ /*
+ * We've got a malloc failure, and we're still initialising buffers.
+ * We assume we're so doomed that we won't even be able to send an
+ * alert.
+ */
+ RLAYERfatal(rl, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ b->buf = p;
+ b->len = len;
+ }
+
+ return 1;
+}
+
+static int rlayer_release_read_buffer(OSSL_RECORD_LAYER *rl)
+{
+ SSL3_BUFFER *b;
+
+ b = &rl->rbuf;
+ if (rl->options & SSL_OP_CLEANSE_PLAINTEXT)
+ OPENSSL_cleanse(b->buf, b->len);
+ OPENSSL_free(b->buf);
+ b->buf = NULL;
+ return 1;
+}
+
+/*
+ * Return values are as per SSL_read()
+ */
+static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
+ int clearold, size_t *readbytes)
+{
+ /*
+ * 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->rlayer.rbuf.buf specified by s->rlayer.packet and
+ * s->rlayer.packet_length. (If s->rlayer.read_ahead is set, 'max' bytes may
+ * be stored in rbuf [plus s->rlayer.packet_length bytes if extend == 1].)
+ * if clearold == 1, move the packet to the start of the buffer; if
+ * clearold == 0 then leave any old packets where they were
+ */
+ size_t len, left, align = 0;
+ unsigned char *pkt;
+ SSL3_BUFFER *rb;
+
+ if (n == 0)
+ return OSSL_RECORD_RETURN_NON_FATAL_ERR;
+
+ rb = &rl->rbuf;
+ if (rb->buf == NULL) {
+ if (!rlayer_setup_read_buffer(rl)) {
+ /* RLAYERfatal() already called */
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+ }
+
+ left = rb->left;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
+ align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+
+ if (!extend) {
+ /* start with empty packet ... */
+ if (left == 0) {
+ rb->offset = align;
+ } else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
+ /*
+ * check if next packet length is large enough to justify payload
+ * alignment...
+ */
+ pkt = rb->buf + rb->offset;
+ if (pkt[0] == SSL3_RT_APPLICATION_DATA
+ && (pkt[3] << 8 | pkt[4]) >= 128) {
+ /*
+ * Note that even if packet is corrupted and its length field
+ * is insane, we can only be led to wrong decision about
+ * whether memmove will occur or not. Header values has no
+ * effect on memmove arguments and therefore no buffer
+ * overrun can be triggered.
+ */
+ memmove(rb->buf + align, pkt, left);
+ rb->offset = align;
+ }
+ }
+ rl->packet = rb->buf + rb->offset;
+ rl->packet_length = 0;
+ /* ... now we can act as if 'extend' was set */
+ }
+
+ len = rl->packet_length;
+ pkt = rb->buf + align;
+ /*
+ * Move any available bytes to front of buffer: 'len' bytes already
+ * pointed to by 'packet', 'left' extra ones at the end
+ */
+ if (rl->packet != pkt && clearold == 1) {
+ memmove(pkt, rl->packet, len + left);
+ rl->packet = pkt;
+ rb->offset = len + align;
+ }
+
+ /*
+ * For DTLS/UDP reads should not span multiple packets because the read
+ * operation returns the whole packet at once (as long as it fits into
+ * the buffer).
+ */
+ if (rl->isdtls) {
+ if (left == 0 && extend)
+ return 0;
+ if (left > 0 && n > left)
+ n = left;
+ }
+
+ /* if there is enough in the buffer from a previous read, take some */
+ if (left >= n) {
+ rl->packet_length += n;
+ rb->left = left - n;
+ rb->offset += n;
+ *readbytes = n;
+ return OSSL_RECORD_RETURN_SUCCESS;
+ }
+
+ /* else we need to read more data */
+
+ if (n > rb->len - rb->offset) {
+ /* does not happen */
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+
+ /*
+ * 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
+ && !rl->isdtls) {
+ /* ignore max parameter */
+ max = n;
+ } else {
+ if (max < n)
+ max = n;
+ if (max > rb->len - rb->offset)
+ max = rb->len - rb->offset;
+ }
+
+ while (left < n) {
+ size_t bioread = 0;
+ int ret;
+
+ /*
+ * 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)
+ */
+
+ clear_sys_error();
+ if (rl->bio != NULL) {
+ ret = BIO_read(rl->bio, pkt + len + left, max - left);
+ if (ret > 0) {
+ bioread = ret;
+ ret = OSSL_RECORD_RETURN_SUCCESS;
+ } else if (BIO_should_retry(rl->bio)) {
+ ret = OSSL_RECORD_RETURN_RETRY;
+ } else if (BIO_eof(rl->bio)) {
+ ret = OSSL_RECORD_RETURN_EOF;
+ } else {
+ ret = OSSL_RECORD_RETURN_FATAL;
+ }
+ } else {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET);
+ ret = OSSL_RECORD_RETURN_FATAL;
+ }
+
+ if (ret <= OSSL_RECORD_RETURN_RETRY) {
+ rb->left = left;
+ if (rl->mode & SSL_MODE_RELEASE_BUFFERS && !rl->isdtls)
+ if (len + left == 0)
+ rlayer_release_read_buffer(rl);
+ return ret;
+ }
+ left += bioread;
+ /*
+ * reads should *never* span multiple packets for DTLS because the
+ * underlying transport protocol is message oriented as opposed to
+ * byte oriented as in the TLS case.
+ */
+ if (rl->isdtls) {
+ if (n > left)
+ n = left; /* makes the while condition false */
+ }
+ }
+
+ /* done reading, now the book-keeping */
+ rb->offset += n;
+ rb->left = left - n;
+ rl->packet_length += n;
+ *readbytes = n;
+ return OSSL_RECORD_RETURN_SUCCESS;
+}
+
static OSSL_RECORD_LAYER *tls_new_record_layer(int vers, int role, int direction,
int level, unsigned char *secret,
size_t secretlen, SSL_CIPHER *c,
BIO *transport, BIO_ADDR *local,
BIO_ADDR *peer,
- OSSL_PARAM *settings,
- OSSL_PARAM *options)
+ const OSSL_PARAM *settings,
+ const OSSL_PARAM *options)
{
OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl));
+ const OSSL_PARAM *p;
+
+ if (rl == NULL) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (transport != NULL && !BIO_up_ref(transport)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ 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_MODE);
+ if (p != NULL && !OSSL_PARAM_get_uint32(p, &rl->mode)) {
+ 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;
+ }
+
+ rl->version = vers;
+ rl->role = role;
+ rl->direction = direction;
+ if (!tls_set1_bio(rl, transport))
+ goto err;
+
+ return rl;
+ err:
+ OPENSSL_free(rl);
+ return NULL;
+}
+
+static OSSL_RECORD_LAYER *dtls_new_record_layer(int vers, int role, int direction,
+ int level, unsigned char *secret,
+ size_t secretlen, SSL_CIPHER *c,
+ BIO *transport, BIO_ADDR *local,
+ BIO_ADDR *peer,
+ const OSSL_PARAM *settings,
+ const OSSL_PARAM *options)
+{
+ OSSL_RECORD_LAYER *rl = tls_new_record_layer(vers, role, direction, level,
+ secret, secretlen, c, transport,
+ local, peer, settings, options);
+
+ if (rl == NULL)
+ return NULL;
+
+ rl->isdtls = 1;
return rl;
}
static void tls_free(OSSL_RECORD_LAYER *rl)
{
+ BIO_free(rl->bio);
OPENSSL_free(rl);
}
return;
}
+static int tls_get_alert_code(OSSL_RECORD_LAYER *rl)
+{
+ return rl->alert;
+}
+
+static int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
+{
+ if (bio != NULL && !BIO_up_ref(bio))
+ return 0;
+ BIO_free(rl->bio);
+ rl->bio = bio;
+
+ return 1;
+}
+
+static SSL3_BUFFER *tls_get0_rbuf(OSSL_RECORD_LAYER *rl)
+{
+ return &rl->rbuf;
+}
+
+static unsigned char *tls_get0_packet(OSSL_RECORD_LAYER *rl)
+{
+ return rl->packet;
+}
+
+static void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
+ size_t packetlen)
+{
+ rl->packet = packet;
+ rl->packet_length = packetlen;
+}
+
+static size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl)
+{
+ return rl->packet_length;
+}
+
+static void tls_reset_packet_length(OSSL_RECORD_LAYER *rl)
+{
+ rl->packet_length = 0;
+}
+
const OSSL_RECORD_METHOD ossl_tls_record_method = {
tls_new_record_layer,
tls_free,
tls_write_records,
tls_retry_write_records,
tls_read_record,
- tls_release_record
+ tls_release_record,
+ tls_get_alert_code,
+ tls_set1_bio,
+
+ /*
+ * TODO(RECLAYER): Remove these. These function pointers are temporary hacks
+ * during the record layer refactoring. They need to be removed before the
+ * refactor is complete.
+ */
+ tls_read_n,
+ tls_get0_rbuf,
+ tls_get0_packet,
+ tls_set0_packet,
+ tls_get_packet_length,
+ tls_reset_packet_length
+};
+
+const OSSL_RECORD_METHOD ossl_dtls_record_method = {
+ dtls_new_record_layer,
+ tls_free,
+ tls_reset,
+ tls_unprocessed_read_pending,
+ tls_processed_read_pending,
+ tls_app_data_pending,
+ tls_write_pending,
+ tls_get_max_record_len,
+ tls_get_max_records,
+ tls_write_records,
+ tls_retry_write_records,
+ tls_read_record,
+ tls_release_record,
+ tls_get_alert_code,
+ tls_set1_bio,
+
+ /*
+ * TODO(RECLAYER): Remove these. These function pointers are temporary hacks
+ * during the record layer refactoring. They need to be removed before the
+ * refactor is complete.
+ */
+ tls_read_n,
+ tls_get0_rbuf,
+ tls_get0_packet,
+ tls_set0_packet,
+ tls_get_packet_length,
+ tls_reset_packet_length
};
"extra data in message"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXT_LENGTH_MISMATCH),
"ext length mismatch"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_GET_PARAMETER),
+ "failed to get parameter"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC),
"failed to init async"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO),
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_BIO_NOT_SET), "read bio not set"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_TIMEOUT_EXPIRED),
"read timeout expired"},
+ {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LAYER_FAILURE),
+ "record layer failure"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LENGTH_MISMATCH),
"record length mismatch"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_TOO_SMALL), "record too small"},
goto err;
#endif
+ /*
+ * TODO(RECLAYER): This assignment should probably initialy come from the
+ * SSL_METHOD, and potentially be updated later. For now though we just
+ * assign it.
+ */
+ if (SSL_CONNECTION_IS_DTLS(s))
+ s->rrlmethod = &ossl_dtls_record_method;
+ else
+ s->rrlmethod = &ossl_tls_record_method;
+
+ /* BIO is NULL initially. It will get updated later */
+ s->rrl = s->rrlmethod->new_record_layer(s->version, s->server,
+ OSSL_RECORD_DIRECTION_READ,
+ 0, 0, 0, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
return ssl;
err:
SSL_free(ssl);
BIO_free_all(sc->rbio);
sc->rbio = rbio;
+ sc->rrlmethod->set1_bio(sc->rrl, sc->rbio);
}
void SSL_set0_wbio(SSL *s, BIO *wbio)
# include <openssl/symhacks.h>
# include <openssl/ct.h>
# include "record/record.h"
+# include "record/recordmethod.h"
# include "statem/statem.h"
# include "internal/packet.h"
# include "internal/dane.h"
* basis, depending on the chosen cipher.
*/
int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure);
+
+ /* Old RECORD_LAYER structure - to be removed eventually */
RECORD_LAYER rlayer;
+
+ /* New read direciton OSSL_RECORD_LAYER - to replace rlayer above */
+ const OSSL_RECORD_METHOD *rrlmethod;
+ /* The read direction record layer */
+ OSSL_RECORD_LAYER *rrl;
+
+
/* Default password callback. */
pem_password_cb *default_passwd_callback;
/* Default password callback user data. */
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
BIO *bio;
#endif
+#if 0
+ if ((which & SSL3_CC_READ) != 0) {
+ /*
+ * TODO(RECLAYER): This is probably not the right place to free this. The
+ * OSSL_RECORD_METHOD might have changed since we created the rl object.
+ * We should free it at the point that we update the OSSL_RECORD_METHOD.
+ * But for now this will do.
+ */
+ s->rrlmethod->free(s->rrl);
+ s->rrl = s->rrlmethod->new_record_layer(s->version, s->server,
+ OSSL_RECORD_DIRECTION_READ,
+ 0, 0, 0, NULL, s->rbio, NULL,
+ NULL, NULL, NULL);
+ }
+#endif
+
+ if (s->rrl == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
c = s->s3.tmp.new_sym_enc;
m = s->s3.tmp.new_hash;
mac_type = s->s3.tmp.new_mac_pkey_type;