mirror of https://github.com/openssl/openssl
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:
parent
0c974fc754
commit
e2d5742b14
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
21
ssl/t1_enc.c
21
ssl/t1_enc.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue