Remove reliance on the SSL object from the DTLS read record layer code

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-06-08 14:52:44 +01:00
parent eddb067e2c
commit 222cf410d5
13 changed files with 261 additions and 230 deletions

View File

@ -849,7 +849,7 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client)
/* Buffer the record in the processed_rcds queue */
/* TODO(RECLAYER): This is nasty and reaches inside the record layer. FIXME */
if (!dtls_buffer_listen_record(s, reclen, seq, align))
if (!dtls_buffer_listen_record(s->rrl, reclen, seq, align))
return -1;
ret = 1;

View File

@ -36,12 +36,11 @@ static int satsub64be(const unsigned char *v1, const unsigned char *v2)
return (int)ret;
}
static int dtls1_record_replay_check(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
static int dtls1_record_replay_check(OSSL_RECORD_LAYER *rl, DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
const unsigned char *seq = s->rlayer.read_sequence;
OSSL_RECORD_LAYER *rl = (OSSL_RECORD_LAYER *)s->rrl;
const unsigned char *seq = rl->sequence;
cmp = satsub64be(seq, bitmap->max_seq_num);
if (cmp > 0) {
@ -58,11 +57,12 @@ static int dtls1_record_replay_check(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
return 1;
}
static void dtls1_record_bitmap_update(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
static void dtls1_record_bitmap_update(OSSL_RECORD_LAYER *rl,
DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
const unsigned char *seq = rl->sequence;
cmp = satsub64be(seq, bitmap->max_seq_num);
if (cmp > 0) {
@ -79,14 +79,15 @@ static void dtls1_record_bitmap_update(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
}
}
static DTLS1_BITMAP *dtls1_get_bitmap(SSL_CONNECTION *s, SSL3_RECORD *rr,
static DTLS1_BITMAP *dtls1_get_bitmap(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rr,
unsigned int *is_next_epoch)
{
OSSL_RECORD_LAYER *rl = s->rrl;
SSL_CONNECTION *s = (SSL_CONNECTION *)rl->cbarg;
*is_next_epoch = 0;
/* In current epoch, accept HM, CCS, DATA, & ALERT */
if (rr->epoch == s->rlayer.d->r_epoch)
if (rr->epoch == rl->epoch)
return &s->rlayer.d->bitmap;
/*
@ -94,8 +95,8 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL_CONNECTION *s, SSL3_RECORD *rr,
* have already processed all of the unprocessed records from the last
* epoch
*/
else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) &&
rl->unprocessed_rcds.epoch != s->rlayer.d->r_epoch &&
else if (rr->epoch == (unsigned long)(rl->epoch + 1) &&
rl->unprocessed_rcds.epoch != rl->epoch &&
(rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
*is_next_epoch = 1;
return &s->rlayer.d->next_bitmap;
@ -104,32 +105,27 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL_CONNECTION *s, SSL3_RECORD *rr,
return NULL;
}
static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
static int dtls1_process_record(OSSL_RECORD_LAYER *rl, DTLS1_BITMAP *bitmap)
{
int i;
int enc_err;
SSL_SESSION *sess;
SSL3_RECORD *rr;
int imac_size;
size_t mac_size = 0;
unsigned char md[EVP_MAX_MD_SIZE];
size_t max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH;
SSL_MAC_BUF macbuf = { NULL, 0 };
int ret = 0;
OSSL_RECORD_LAYER *rl = (OSSL_RECORD_LAYER *)s->rrl;
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
rr = &rl->rrec[0];
sess = s->session;
/*
* At this point, s->rlayer.packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
* and we have that many bytes in s->rlayer.packet
* At this point, rl->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
* and we have that many bytes in rl->packet
*/
rr->input = &(s->rrlmethod->get0_packet(s->rrl)[DTLS1_RT_HEADER_LENGTH]);
rr->input = &(rl->packet[DTLS1_RT_HEADER_LENGTH]);
/*
* ok, we can now read from 's->rlayer.packet' data into 'rr'. rr->input
* ok, we can now read from 'rl->packet' data into 'rr'. rr->input
* points at rr->length bytes, which need to be copied into rr->data by
* either the decryption or by the decompression. When the data is 'copied'
* into the rr->data buffer, rr->input will be pointed at the new buffer
@ -142,7 +138,7 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
/* check is not needed I believe */
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return 0;
}
@ -150,32 +146,32 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
rr->data = rr->input;
rr->orig_len = rr->length;
if (s->read_hash != NULL) {
const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash);
if (rl->md_ctx != NULL) {
const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(rl->md_ctx);
if (tmpmd != NULL) {
imac_size = EVP_MD_get_size(tmpmd);
if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
mac_size = (size_t)imac_size;
}
}
if (SSL_READ_ETM(s) && s->read_hash) {
if (rl->use_etm && rl->md_ctx) {
unsigned char *mac;
if (rr->orig_len < mac_size) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT);
return 0;
}
rr->length -= mac_size;
mac = rr->data + rr->length;
i = ssl->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ );
i = rl->funcs->mac(rl, rr, md, 0 /* not send */);
if (i == 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
SSLfatal(s, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC,
SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
return 0;
}
/*
@ -191,7 +187,7 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
* errors in the queue from processing bogus junk that we ignored.
*/
ERR_set_mark();
enc_err = ssl->method->ssl3_enc->enc(s, rr, 1, 0, &macbuf, mac_size);
enc_err = rl->funcs->cipher(rl, rr, 1, 0, &macbuf, mac_size);
/*-
* enc_err is:
@ -201,13 +197,13 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
*/
if (enc_err == 0) {
ERR_pop_to_mark();
if (ossl_statem_in_error(s)) {
if (rl->alert != 0) {
/* SSLfatal() got called */
goto end;
}
/* For DTLS we simply ignore bad packets. */
rr->length = 0;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto end;
}
ERR_clear_last_mark();
@ -217,13 +213,12 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
} OSSL_TRACE_END(TLS);
/* r->length is now the compressed data plus mac */
if ((sess != NULL)
&& !SSL_READ_ETM(s)
&& (s->enc_read_ctx != NULL)
&& (EVP_MD_CTX_get0_md(s->read_hash) != NULL)) {
/* s->read_hash != NULL => mac_size != -1 */
if (!rl->use_etm
&& (rl->enc_ctx != NULL)
&& (EVP_MD_CTX_get0_md(rl->md_ctx) != NULL)) {
/* rl->md_ctx != NULL => mac_size != -1 */
i = ssl->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ );
i = rl->funcs->mac(rl, rr, md, 0 /* not send */ );
if (i == 0 || macbuf.mac == NULL
|| CRYPTO_memcmp(md, macbuf.mac, mac_size) != 0)
enc_err = 0;
@ -234,33 +229,33 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
if (enc_err == 0) {
/* decryption failed, silently discard message */
rr->length = 0;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto end;
}
/* r->length is now just compressed */
if (s->expand != NULL) {
if (rl->expand != NULL) {
if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
SSL_R_COMPRESSED_LENGTH_TOO_LONG);
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_COMPRESSED_LENGTH_TOO_LONG);
goto end;
}
if (!ssl3_do_uncompress(s, rr)) {
SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION);
if (!tls_do_uncompress(rl, rr)) {
RLAYERfatal(rl, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION);
goto end;
}
}
/* use current Max Fragment Length setting if applicable */
if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session))
max_plain_length = GET_MAX_FRAGMENT_LENGTH(s->session);
/* send overflow if the plaintext is too long now it has passed MAC */
if (rr->length > max_plain_length) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
/*
* Check if the received packet overflows the current Max Fragment
* Length setting.
*/
if (rl->max_frag_len > 0 && rr->length > rl->max_frag_len) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
goto end;
}
rr->off = 0;
/*-
* So at this point the following is true
@ -272,10 +267,10 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
*/
/* we have pulled in a full packet so zero things */
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
/* Mark receipt of record. */
dtls1_record_bitmap_update(s, bitmap);
dtls1_record_bitmap_update(rl, bitmap);
ret = 1;
end:
@ -284,12 +279,11 @@ static int dtls1_process_record(SSL_CONNECTION *s, DTLS1_BITMAP *bitmap)
return ret;
}
static int dtls_rlayer_buffer_record(SSL_CONNECTION *s, record_pqueue *queue,
static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, record_pqueue *queue,
unsigned char *priority)
{
DTLS_RLAYER_RECORD_DATA *rdata;
pitem *item;
OSSL_RECORD_LAYER *rl = (OSSL_RECORD_LAYER *)s->rrl;
/* Limit the size of the queue to prevent DOS attacks */
if (pqueue_size(queue->q) >= 100)
@ -300,22 +294,24 @@ static int dtls_rlayer_buffer_record(SSL_CONNECTION *s, record_pqueue *queue,
if (rdata == NULL || item == NULL) {
OPENSSL_free(rdata);
pitem_free(item);
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return -1;
}
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));
rdata->packet = rl->packet;
rdata->packet_length = rl->packet_length;
memcpy(&(rdata->rbuf), &rl->rbuf, sizeof(SSL3_BUFFER));
memcpy(&(rdata->rrec), &rl->rrec[0], sizeof(SSL3_RECORD));
item->data = rdata;
s->rrlmethod->set0_packet(s->rrl, NULL, 0);
memset(s->rrlmethod->get0_rbuf(s->rrl), 0, sizeof(SSL3_BUFFER));
rl->packet = NULL;
rl->packet_length = 0;
memset(&rl->rbuf, 0, sizeof(SSL3_BUFFER));
memset(&rl->rrec[0], 0, sizeof(rl->rrec[0]));
if (!ssl3_setup_buffers(s)) {
if (!rlayer_setup_read_buffer(rl)) {
/* SSLfatal() already called */
OPENSSL_free(rdata->rbuf.buf);
OPENSSL_free(rdata);
@ -337,18 +333,18 @@ static int dtls_rlayer_buffer_record(SSL_CONNECTION *s, record_pqueue *queue,
static int dtls_copy_rlayer_record(OSSL_RECORD_LAYER *rl, pitem *item)
{
DTLS_RLAYER_RECORD_DATA *rdata;
SSL_CONNECTION *s = (SSL_CONNECTION *)rl->cbarg;
rdata = (DTLS_RLAYER_RECORD_DATA *)item->data;
SSL3_BUFFER_release(s->rrlmethod->get0_rbuf(s->rrl));
SSL3_BUFFER_release(&rl->rbuf);
s->rrlmethod->set0_packet(s->rrl, rdata->packet, rdata->packet_length);
memcpy(s->rrlmethod->get0_rbuf(s->rrl), &(rdata->rbuf), sizeof(SSL3_BUFFER));
rl->packet = rdata->packet;
rl->packet_length = rdata->packet_length;
memcpy(&rl->rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
memcpy(&rl->rrec[0], &(rdata->rrec), sizeof(SSL3_RECORD));
/* Set proper sequence number for mac calculation */
memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6);
memcpy(&(rl->sequence[2]), &(rdata->packet[5]), 6);
return 1;
}
@ -371,7 +367,7 @@ static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl,
return 0;
}
static int dtls_process_rlayer_buffered_records(SSL_CONNECTION *s)
static int dtls_process_rlayer_buffered_records(OSSL_RECORD_LAYER *rl)
{
pitem *item;
SSL3_BUFFER *rb;
@ -379,17 +375,16 @@ static int dtls_process_rlayer_buffered_records(SSL_CONNECTION *s)
DTLS1_BITMAP *bitmap;
unsigned int is_next_epoch;
int replayok = 1;
OSSL_RECORD_LAYER *rl = s->rrl;
item = pqueue_peek(rl->unprocessed_rcds.q);
if (item) {
/* Check if epoch is current. */
if (rl->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
if (rl->unprocessed_rcds.epoch != rl->epoch)
return 1; /* Nothing to do. */
rr = rl->rrec;
rb = s->rrlmethod->get0_rbuf(s->rrl);
rb = &rl->rbuf;
if (SSL3_BUFFER_get_left(rb) > 0) {
/*
@ -404,19 +399,19 @@ static int dtls_process_rlayer_buffered_records(SSL_CONNECTION *s)
/* Process all the records. */
while (pqueue_peek(rl->unprocessed_rcds.q)) {
dtls_retrieve_rlayer_buffered_record(rl, &(rl->unprocessed_rcds));
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
bitmap = dtls1_get_bitmap(rl, rr, &is_next_epoch);
if (bitmap == NULL) {
/*
* Should not happen. This will only ever be NULL when the
* current record is from a different epoch. But that cannot
* be the case because we already checked the epoch above
*/
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
#ifndef OPENSSL_NO_SCTP
/* Only do replay check if no SCTP bio */
if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
if (!BIO_dgram_is_sctp(rl->bio))
#endif
{
/*
@ -425,21 +420,21 @@ static int dtls_process_rlayer_buffered_records(SSL_CONNECTION *s)
* we might have updated the window since then due to
* records we subsequently processed.
*/
replayok = dtls1_record_replay_check(s, bitmap);
replayok = dtls1_record_replay_check(rl, bitmap);
}
if (!replayok || !dtls1_process_record(s, bitmap)) {
if (ossl_statem_in_error(s)) {
/* dtls1_process_record called SSLfatal() */
if (!replayok || !dtls1_process_record(rl, bitmap)) {
if (rl->alert != 0) {
/* dtls1_process_record called RLAYERfatal() */
return 0;
}
/* dump this record */
rr->length = 0;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
continue;
}
if (dtls_rlayer_buffer_record(s, &(rl->processed_rcds),
if (dtls_rlayer_buffer_record(rl, &(rl->processed_rcds),
SSL3_RECORD_get_seq_num(&rl->rrec[0])) < 0) {
/* SSLfatal() already called */
return 0;
@ -451,16 +446,17 @@ static int dtls_process_rlayer_buffered_records(SSL_CONNECTION *s)
* sync epoch numbers once all the unprocessed records have been
* processed
*/
rl->processed_rcds.epoch = s->rlayer.d->r_epoch;
rl->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1;
rl->processed_rcds.epoch = rl->epoch;
rl->unprocessed_rcds.epoch = rl->epoch + 1;
return 1;
}
int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq, size_t off)
/* TODO(RECLAYER): FIXME. This is called directly from d1_lib.c. It should not be */
int dtls_buffer_listen_record(OSSL_RECORD_LAYER *rl, size_t len,
unsigned char *seq, size_t off)
{
SSL3_RECORD *rr;
OSSL_RECORD_LAYER *rl = s->rrl;
rr = &rl->rrec[0];
memset(rr, 0, sizeof(SSL3_RECORD));
@ -470,11 +466,11 @@ 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->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;
rl->packet = rl->rbuf.buf;
rl->packet_length = DTLS1_RT_HEADER_LENGTH + len;
rr->data = rl->packet + DTLS1_RT_HEADER_LENGTH;
if (dtls_rlayer_buffer_record(s, &(rl->processed_rcds),
if (dtls_rlayer_buffer_record(rl, &(rl->processed_rcds),
SSL3_RECORD_get_seq_num(rr)) <= 0) {
/* SSLfatal() already called */
return 0;
@ -493,7 +489,7 @@ int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq,
* ssl->s3.rrec.length - number of bytes
*/
/* used only by dtls1_read_bytes */
static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
{
int ssl_major, ssl_minor;
int rret;
@ -518,7 +514,7 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
* The epoch may have changed. If so, process all the pending records.
* This is a non-blocking operation.
*/
if (!dtls_process_rlayer_buffered_records(s)) {
if (!dtls_process_rlayer_buffered_records(rl)) {
/* SSLfatal() already called */
return OSSL_RECORD_RETURN_FATAL;
}
@ -532,11 +528,10 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
/* get something from the wire */
/* check if we have the header */
if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
(s->rrlmethod->get_packet_length(s->rrl) < DTLS1_RT_HEADER_LENGTH)) {
rret = s->rrlmethod->read_n(s->rrl, DTLS1_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(s->rrlmethod->get0_rbuf(s->rrl)),
0, 1, &n);
if ((rl->rstate != SSL_ST_READ_BODY) ||
(rl->packet_length < DTLS1_RT_HEADER_LENGTH)) {
rret = rl->funcs->read_n(rl, DTLS1_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(&rl->rbuf), 0, 1, &n);
/* read timeout is handled by dtls1_read_bytes */
if (rret < OSSL_RECORD_RETURN_SUCCESS) {
/* SSLfatal() already called if appropriate */
@ -544,18 +539,17 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
}
/* this packet contained a partial record, dump it */
if (s->rrlmethod->get_packet_length(s->rrl) != DTLS1_RT_HEADER_LENGTH) {
s->rrlmethod->reset_packet_length(s->rrl);
if (rl->packet_length != DTLS1_RT_HEADER_LENGTH) {
rl->packet_length = 0;
goto again;
}
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
rl->rstate = SSL_ST_READ_BODY;
p = s->rrlmethod->get0_packet(s->rrl);
p = rl->packet;
if (s->msg_callback)
s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
ssl, s->msg_callback_arg);
rl->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
rl->cbarg);
/* Pull apart the header into the DTLS1_RECORD */
rr->type = *(p++);
@ -566,7 +560,7 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
/* sequence number is 64 bits, with top 2 bytes = epoch */
n2s(p, rr->epoch);
memcpy(&(RECORD_LAYER_get_read_sequence(&s->rlayer)[2]), p, 6);
memcpy(&(rl->sequence[2]), p, 6);
p += 6;
n2s(p, rr->length);
@ -576,21 +570,24 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
* Lets check the version. We tolerate alerts that don't have the exact
* version number (e.g. because of protocol version errors)
*/
if (!s->first_packet && rr->type != SSL3_RT_ALERT) {
if (version != s->version) {
if (!rl->is_first_record && rr->type != SSL3_RT_ALERT) {
if (version != rl->version) {
/* unexpected version, silently discard */
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
}
if ((version & 0xff00) != (s->version & 0xff00)) {
if (ssl_major !=
(rl->version == DTLS_ANY_VERSION ? DTLS1_VERSION_MAJOR
: rl->version >> 8)) {
/* wrong version, silently discard record */
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
@ -598,66 +595,70 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
/* record too long, silently discard it */
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
/* If received packet overflows own-client Max Fragment Length setting */
if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)
&& rr->length > GET_MAX_FRAGMENT_LENGTH(s->session) + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) {
/*
* If received packet overflows maximum possible fragment length then
* silently discard it
*/
if (rl->max_frag_len > 0
&& rr->length > rl->max_frag_len + SSL3_RT_MAX_ENCRYPTED_OVERHEAD) {
/* record too long, silently discard it */
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
/* now s->rlayer.rstate == SSL_ST_READ_BODY */
/* now rl->rstate == SSL_ST_READ_BODY */
}
/* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
/* rl->rstate == SSL_ST_READ_BODY, get and decode the data */
if (rr->length >
s->rrlmethod->get_packet_length(s->rrl) - DTLS1_RT_HEADER_LENGTH) {
/* now s->rlayer.packet_length == DTLS1_RT_HEADER_LENGTH */
rl->packet_length - DTLS1_RT_HEADER_LENGTH) {
/* now rl->packet_length == DTLS1_RT_HEADER_LENGTH */
more = rr->length;
rret = s->rrlmethod->read_n(s->rrl, more, more, 1, 1, &n);
rret = rl->funcs->read_n(rl, more, more, 1, 1, &n);
/* this packet contained a partial record, dump it */
if (rret < OSSL_RECORD_RETURN_SUCCESS || n != more) {
if (ossl_statem_in_error(s)) {
/* read_n() called SSLfatal() */
if (rl->alert != 0) {
/* read_n() called RLAYERfatal() */
return OSSL_RECORD_RETURN_FATAL;
}
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
/*
* now n == rr->length, and s->rlayer.packet_length ==
* DTLS1_RT_HEADER_LENGTH + rr->length
* now n == rr->length,
* and rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length
*/
}
/* set state for later operations */
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
rl->rstate = SSL_ST_READ_HEADER;
/* match epochs. NULL means the packet is dropped on the floor */
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
bitmap = dtls1_get_bitmap(rl, rr, &is_next_epoch);
if (bitmap == NULL) {
rr->length = 0;
s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
rl->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
/* Only do replay check if no SCTP bio */
if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) {
if (!BIO_dgram_is_sctp(rl->bio)) {
#endif
/* Check whether this is a repeat, or aged record. */
if (!dtls1_record_replay_check(s, bitmap)) {
if (!dtls1_record_replay_check(rl, bitmap)) {
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
rl->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
@ -677,7 +678,7 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
*/
if (is_next_epoch) {
if ((SSL_in_init(ssl) || ossl_statem_get_in_handshake(s))) {
if (dtls_rlayer_buffer_record (s,
if (dtls_rlayer_buffer_record(rl,
&(rl->unprocessed_rcds),
rr->seq_num) < 0) {
/* SSLfatal() already called */
@ -686,18 +687,18 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
}
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl);
rl->packet_length = 0;
goto again;
}
if (!dtls1_process_record(s, bitmap)) {
if (ossl_statem_in_error(s)) {
/* dtls1_process_record() called SSLfatal */
if (!dtls1_process_record(rl, bitmap)) {
if (rl->alert != 0) {
/* dtls1_process_record() called RLAYERfatal */
return OSSL_RECORD_RETURN_FATAL;
}
rr->length = 0;
rr->read = 1;
s->rrlmethod->reset_packet_length(s->rrl); /* dump this record */
rl->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
@ -706,22 +707,6 @@ static int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
}
static int dtls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version)
{
rl->version = version;
return 1;
}
static struct record_functions_st dtls_funcs = {
NULL,
NULL,
dtls_get_more_records,
NULL,
NULL,
dtls_set_protocol_version,
NULL
};
static int dtls_free(OSSL_RECORD_LAYER *rl)
{
pitem *item;
@ -752,9 +737,9 @@ static int dtls_free(OSSL_RECORD_LAYER *rl)
static int
dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, unsigned char *key,
size_t keylen, unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
int role, int direction, int level, unsigned int epoch,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *ciph, size_t taglen,
/* TODO(RECLAYER): This probably should not be an int */
int mactype,
@ -786,9 +771,34 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
}
(*retrl)->isdtls = 1;
(*retrl)->funcs = &dtls_funcs;
(*retrl)->epoch = epoch;
return OSSL_RECORD_RETURN_SUCCESS;
switch (vers) {
case DTLS_ANY_VERSION:
(*retrl)->funcs = &dtls_any_funcs;
break;
case DTLS1_2_VERSION:
case DTLS1_VERSION:
case DTLS1_BAD_VER:
(*retrl)->funcs = &dtls_1_funcs;
break;
default:
/* Should not happen */
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
ret = OSSL_RECORD_RETURN_FATAL;
goto err;
}
ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp);
err:
if (ret != OSSL_RECORD_RETURN_SUCCESS) {
OPENSSL_free(*retrl);
*retrl = NULL;
}
return ret;
}
const OSSL_RECORD_METHOD ossl_dtls_record_method = {

View File

@ -483,9 +483,9 @@ static struct record_functions_st ossl_ktls_funcs = {
static int
ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, unsigned char *key,
size_t keylen, unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
int role, int direction, int level, unsigned int epoch,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *ciph, size_t taglen,
/* TODO(RECLAYER): This probably should not be an int */
int mactype,

View File

@ -68,6 +68,8 @@ struct ossl_record_layer_st
int role;
int direction;
int level;
/* DTLS only */
unsigned int epoch;
/*
* A BIO containing any data read in the previous epoch that was destined
@ -200,6 +202,8 @@ extern struct record_functions_st ssl_3_0_funcs;
extern struct record_functions_st tls_1_funcs;
extern struct record_functions_st tls_1_3_funcs;
extern struct record_functions_st tls_any_funcs;
extern struct record_functions_st dtls_1_funcs;
extern struct record_functions_st dtls_any_funcs;
void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
const char *fmt, ...);
@ -211,7 +215,8 @@ void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason,
ossl_rlayer_fatal)
# define RLAYER_USE_EXPLICIT_IV(rl) ((rl)->version == TLS1_1_VERSION \
|| (rl)->version == TLS1_2_VERSION)
|| (rl)->version == TLS1_2_VERSION \
|| (rl)->isdtls)
int ossl_set_tls_provider_parameters(OSSL_RECORD_LAYER *rl,
EVP_CIPHER_CTX *ctx,
@ -232,9 +237,11 @@ __owur int ssl3_cbc_digest_record(const EVP_MD *md,
int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int clearold, size_t *readbytes);
int tls_get_more_records(OSSL_RECORD_LAYER *rl);
int dtls_get_more_records(OSSL_RECORD_LAYER *rl);
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *re);
int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
@ -281,3 +288,4 @@ void tls_set0_packet(OSSL_RECORD_LAYER *rl, unsigned char *packet,
size_t packetlen);
size_t tls_get_packet_length(OSSL_RECORD_LAYER *rl);
void tls_reset_packet_length(OSSL_RECORD_LAYER *rl);
int rlayer_setup_read_buffer(OSSL_RECORD_LAYER *rl);

View File

@ -148,6 +148,8 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
size_t bs, ctr, padnum, loop;
unsigned char padval;
const EVP_CIPHER *enc;
/* TODO(RECLAYER): FIXME */
SSL_CONNECTION *s = (SSL_CONNECTION *)rl->cbarg;
if (n_recs == 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
@ -226,7 +228,6 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
seq = rl->sequence;
if (rl->isdtls) {
#if 0
/* TODO(RECLAYER): FIXME */
/* DTLS does not support pipelining */
unsigned char dtlsseq[8], *p = dtlsseq;
@ -235,7 +236,6 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs,
DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
memcpy(p, &seq[2], 6);
memcpy(buf[ctr], dtlsseq, 8);
#endif
} else {
memcpy(buf[ctr], seq, 8);
for (i = 7; i >= 0; i--) { /* increment */
@ -452,6 +452,8 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
unsigned char header[13];
int t;
int ret = 0;
/* TODO(RECLAYER): FIXME */
SSL_CONNECTION *ssl = (SSL_CONNECTION *)rl->cbarg;
hash = rl->md_ctx;
@ -477,7 +479,6 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
}
if (rl->isdtls) {
#if 0
/* TODO(RECLAYER): FIX ME */
unsigned char dtlsseq[8], *p = dtlsseq;
@ -486,7 +487,6 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
memcpy(p, &seq[2], 6);
memcpy(header, dtlsseq, 8);
#endif
} else
memcpy(header, seq, 8);
@ -552,3 +552,14 @@ struct record_functions_st tls_1_funcs = {
tls_default_validate_record_header,
tls_default_post_process_record
};
struct record_functions_st dtls_1_funcs = {
tls1_set_crypto_state,
tls_default_read_n,
dtls_get_more_records,
tls1_cipher,
tls1_mac,
tls_default_set_protocol_version,
NULL,
NULL
};

View File

@ -95,7 +95,7 @@ static int rlayer_allow_compression(OSSL_RECORD_LAYER *rl)
}
#endif
static int rlayer_setup_read_buffer(OSSL_RECORD_LAYER *rl)
int rlayer_setup_read_buffer(OSSL_RECORD_LAYER *rl)
{
unsigned char *p;
size_t len, align = 0, headerlen;
@ -879,7 +879,7 @@ int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
return 1;
}
static int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
#ifndef OPENSSL_NO_COMP
int i;
@ -1156,9 +1156,9 @@ tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
static int
tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
int role, int direction, int level, unsigned char *key,
size_t keylen, unsigned char *iv, size_t ivlen,
unsigned char *mackey, size_t mackeylen,
int role, int direction, int level, unsigned int epoch,
unsigned char *key, size_t keylen, unsigned char *iv,
size_t ivlen, unsigned char *mackey, size_t mackeylen,
const EVP_CIPHER *ciph, size_t taglen,
/* TODO(RECLAYER): This probably should not be an int */
int mactype,

View File

@ -151,3 +151,23 @@ struct record_functions_st tls_any_funcs = {
tls_validate_record_header,
tls_default_post_process_record
};
static int dtls_any_set_protocol_version(OSSL_RECORD_LAYER *rl, int vers)
{
if (rl->version != DTLS_ANY_VERSION && rl->version != vers)
return 0;
rl->version = vers;
return 1;
}
struct record_functions_st dtls_any_funcs = {
tls_any_set_crypto_state,
tls_default_read_n,
dtls_get_more_records,
tls_any_cipher,
NULL,
dtls_any_set_protocol_version,
NULL,
NULL
};

View File

@ -1892,6 +1892,11 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
for (;;) {
int rlret;
BIO *prev = s->rrlnext;
unsigned int epoch = 0;;
if (SSL_CONNECTION_IS_DTLS(s)
&& level != OSSL_RECORD_PROTECTION_LEVEL_NONE)
epoch = DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer) + 1; /* new epoch */
s->rrlnext = BIO_new(BIO_s_mem());
@ -1903,12 +1908,12 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version,
rlret = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq,
version, s->server, direction,
level, key, keylen, iv, ivlen,
mackey, mackeylen, ciph, taglen,
mactype, md, comp, prev, s->rbio,
s->rrlnext, NULL, NULL, settings,
options, rlayer_dispatch, s,
&s->rrl);
level, epoch, key, keylen, iv,
ivlen, mackey, mackeylen, ciph,
taglen, mactype, md, comp, prev,
s->rbio, s->rrlnext, NULL, NULL,
settings, options,
rlayer_dispatch, s, &s->rrl);
BIO_free(prev);
switch (rlret) {
case OSSL_RECORD_RETURN_FATAL:

View File

@ -274,8 +274,8 @@ __owur int dtls1_write_bytes(SSL_CONNECTION *s, int type, const void *buf,
int do_dtls1_write(SSL_CONNECTION *s, int type, const unsigned char *buf,
size_t len, int create_empty_fragment, size_t *written);
void dtls1_reset_seq_numbers(SSL_CONNECTION *s, int rw);
int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq,
size_t off);
int dtls_buffer_listen_record(OSSL_RECORD_LAYER *rl, size_t len,
unsigned char *seq, size_t off);
void ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr);
# define HANDLE_RLAYER_RETURN(s, ret) \

View File

@ -146,7 +146,9 @@ struct ossl_record_method_st {
int (*new_record_layer)(OSSL_LIB_CTX *libctx,
const char *propq, int vers,
int role, int direction,
int level, unsigned char *key,
int level,
unsigned int epoch,
unsigned char *key,
size_t keylen,
unsigned char *iv,
size_t ivlen,

View File

@ -665,7 +665,7 @@ int ossl_ssl_connection_reset(SSL *s)
* assign it.
*/
if (!ssl_set_new_record_layer(sc,
TLS_ANY_VERSION,
SSL_CONNECTION_IS_DTLS(sc) ? DTLS_ANY_VERSION : TLS_ANY_VERSION,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_NONE,
NULL, 0, NULL, 0, NULL, 0, NULL, 0,

View File

@ -2196,9 +2196,21 @@ int ssl_set_client_hello_version(SSL_CONNECTION *s)
s->version = ver_max;
/* TLS1.3 always uses TLS1.2 in the legacy_version field */
if (!SSL_CONNECTION_IS_DTLS(s) && ver_max > TLS1_2_VERSION)
if (SSL_CONNECTION_IS_DTLS(s)) {
if (ver_max == DTLS1_BAD_VER) {
/*
* Even though this is technically before version negotiation,
* because we have asked for DTLS1_BAD_VER we will never negotiate
* anything else, and this has impacts on the record layer for when
* we read the ServerHello. So we need to tell the record layer
* about this immediately.
*/
s->rrlmethod->set_protocol_version(s->rrl, ver_max);
}
} else if (ver_max > TLS1_2_VERSION) {
/* TLS1.3 always uses TLS1.2 in the legacy_version field */
ver_max = TLS1_2_VERSION;
}
s->client_version = ver_max;
return 0;

View File

@ -242,55 +242,18 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which)
else
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE;
if (SSL_CONNECTION_IS_DTLS(s)) {
if (s->enc_read_ctx != NULL) {
reuse_dd = 1;
} else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
goto err;
} else {
/*
* make sure it's initialised in case we exit later with an error
*/
EVP_CIPHER_CTX_reset(s->enc_read_ctx);
}
dd = s->enc_read_ctx;
mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
if (mac_ctx == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifndef OPENSSL_NO_COMP
COMP_CTX_free(s->expand);
s->expand = NULL;
if (comp != NULL) {
s->expand = COMP_CTX_new(comp->method);
if (s->expand == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_R_COMPRESSION_LIBRARY_ERROR);
goto err;
}
}
#endif
/*
* this is done by dtls1_reset_seq_numbers for DTLS
*/
if (!SSL_CONNECTION_IS_DTLS(s))
RECORD_LAYER_reset_read_sequence(&s->rlayer);
} else {
if (!ssl_set_new_record_layer(s, s->version,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
key, cl, iv, (size_t)k, mac_secret,
mac_secret_size, c, taglen, mac_type,
m, comp)) {
/* SSLfatal already called */
goto err;
}
/* TODO(RECLAYER): Temporary - remove me */
goto skip_ktls;
if (!ssl_set_new_record_layer(s, s->version,
OSSL_RECORD_DIRECTION_READ,
OSSL_RECORD_PROTECTION_LEVEL_APPLICATION,
key, cl, iv, (size_t)k, mac_secret,
mac_secret_size, c, taglen, mac_type,
m, comp)) {
/* SSLfatal already called */
goto err;
}
/* TODO(RECLAYER): Temporary - remove me */
goto skip_ktls;
} else {
s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
if (s->ext.use_etm)