Transfer the functionality from ssl3_read_n to the new record layer

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)
This commit is contained in:
Matt Caswell 2022-04-07 17:35:36 +01:00
parent 0c974fc754
commit e2d5742b14
17 changed files with 660 additions and 254 deletions

View File

@ -1351,6 +1351,7 @@ SSL_R_EXCESSIVE_MESSAGE_SIZE:152:excessive message size
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
@ -1457,6 +1458,7 @@ SSL_R_PSK_NO_CLIENT_CB:224:psk no client cb
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

View File

@ -555,6 +555,13 @@ extern "C" {
/* 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

View File

@ -1,6 +1,6 @@
/*
* 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
@ -119,6 +119,7 @@
# 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
@ -222,6 +223,7 @@
# 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

View File

@ -490,13 +490,13 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client)
/* 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
*/

View File

@ -20,7 +20,7 @@
*/
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;

View File

@ -130,11 +130,10 @@ static int dtls1_copy_record(SSL_CONNECTION *s, pitem *item)
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 */
@ -165,9 +164,9 @@ int dtls1_buffer_record(SSL_CONNECTION *s, record_pqueue *queue,
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;
@ -182,9 +181,8 @@ int dtls1_buffer_record(SSL_CONNECTION *s, record_pqueue *queue,
}
#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)) {
@ -247,7 +245,7 @@ int dtls1_process_buffered_records(SSL_CONNECTION *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) {
/*
@ -293,7 +291,7 @@ int dtls1_process_buffered_records(SSL_CONNECTION *s)
}
/* dump this record */
rr->length = 0;
RECORD_LAYER_reset_packet_length(&s->rlayer);
s->rrlmethod->reset_packet_length(s->rrl);
continue;
}
@ -356,7 +354,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
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 */
@ -689,7 +687,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
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;
@ -725,7 +723,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
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;
/*

View File

@ -152,8 +152,7 @@ void SSL_set_default_read_buffer_len(SSL *s, size_t len)
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)
@ -194,186 +193,6 @@ const char *SSL_rstate_string(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
@ -1321,7 +1140,7 @@ int ssl3_read_bytes(SSL *ssl, int type, int *recvd_type, unsigned char *buf,
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 */

View File

@ -36,9 +36,6 @@
#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);

View File

@ -69,6 +69,12 @@ typedef struct ossl_record_layer_st OSSL_RECORD_LAYER;
#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
@ -237,4 +243,35 @@ struct ossl_record_method_st {
*/
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;

View File

@ -40,7 +40,7 @@ int ssl3_setup_read_buffer(SSL_CONNECTION *s)
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;
@ -177,7 +177,7 @@ int ssl3_release_read_buffer(SSL_CONNECTION *s)
{
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);

View File

@ -73,7 +73,7 @@ static int ssl3_record_app_data_waiting(SSL_CONNECTION *s)
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)
@ -149,6 +149,54 @@ int ossl_early_data_count_ok(SSL_CONNECTION *s, size_t length,
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
@ -192,7 +240,8 @@ int ssl3_get_record(SSL_CONNECTION *s)
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;
@ -209,14 +258,15 @@ int ssl3_get_record(SSL_CONNECTION *s)
/* 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)
@ -242,9 +292,9 @@ int ssl3_get_record(SSL_CONNECTION *s)
}
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;
}
@ -344,7 +394,7 @@ int ssl3_get_record(SSL_CONNECTION *s)
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 ") ||
@ -449,7 +499,8 @@ int ssl3_get_record(SSL_CONNECTION *s)
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 */
}
@ -464,10 +515,10 @@ int ssl3_get_record(SSL_CONNECTION *s)
*/
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]);
}
/*
@ -493,7 +544,7 @@ int ssl3_get_record(SSL_CONNECTION *s)
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
@ -1543,7 +1594,7 @@ int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
* 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
@ -1624,7 +1675,7 @@ int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
}
/* 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();
@ -1651,7 +1702,7 @@ int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
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;
}
@ -1689,7 +1740,7 @@ int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
*/
/* 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);
@ -1750,9 +1801,10 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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 */
@ -1760,15 +1812,14 @@ int dtls1_get_record(SSL_CONNECTION *s)
}
/* 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,
@ -1798,7 +1849,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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;
}
}
@ -1807,7 +1858,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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;
}
@ -1815,7 +1866,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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;
}
@ -1825,7 +1876,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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;
}
@ -1835,19 +1886,20 @@ int dtls1_get_record(SSL_CONNECTION *s)
/* 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;
}
@ -1863,7 +1915,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
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
@ -1874,7 +1926,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
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
@ -1903,7 +1955,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
}
rr->length = 0;
rr->read = 1;
RECORD_LAYER_reset_packet_length(&s->rlayer);
s->rrlmethod->reset_packet_length(s->rrl);
goto again;
}
@ -1914,7 +1966,7 @@ int dtls1_get_record(SSL_CONNECTION *s)
}
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 */
}
@ -1935,9 +1987,9 @@ int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq,
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) {

View File

@ -9,29 +9,383 @@
#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);
}
@ -97,6 +451,48 @@ static void tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle)
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,
@ -110,5 +506,49 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
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
};

View File

@ -170,6 +170,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"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),
@ -342,6 +344,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
{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"},

View File

@ -885,6 +885,22 @@ SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
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);
@ -1422,6 +1438,7 @@ void SSL_set0_rbio(SSL *s, BIO *rbio)
BIO_free_all(sc->rbio);
sc->rbio = rbio;
sc->rrlmethod->set1_bio(sc->rrl, sc->rbio);
}
void SSL_set0_wbio(SSL *s, BIO *wbio)

View File

@ -28,6 +28,7 @@
# 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"
@ -1762,7 +1763,16 @@ struct ssl_connection_st {
* 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. */

View File

@ -1,6 +1,6 @@
/*
* 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

View File

@ -172,6 +172,27 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
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;