Remove reliance on the SSL object from the DTLS read record layer code
authorMatt Caswell <matt@openssl.org>
Wed, 8 Jun 2022 13:52:44 +0000 (14:52 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 18 Aug 2022 15:38:13 +0000 (16:38 +0100)
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)

13 files changed:
ssl/d1_lib.c
ssl/record/methods/dtls_meth.c
ssl/record/methods/ktls_meth.c
ssl/record/methods/recmethod_local.h
ssl/record/methods/tls1_meth.c
ssl/record/methods/tls_common.c
ssl/record/methods/tlsany_meth.c
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/record/recordmethod.h
ssl/ssl_lib.c
ssl/statem/statem_lib.c
ssl/t1_enc.c

index 904a19a28ad7d11ee40c44ff08599c5775bfd6d8..e888a4f488c592d6f461869cc69db965638a9f62 100644 (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;
index 3c6274664d649b8f56505179a6266cc613322521..cffe82b24e899865269fcd4c25cd656b622f6e60 100644 (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;
+
+    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;
+    }
 
-    return OSSL_RECORD_RETURN_SUCCESS;
+    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 = {
index 460501c9d38dcb03e7ffa61b5f27000119edfb32..3a99e2d9eb24198b632f49df679b3715cba90340 100644 (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,
index 01590626a7508bff0263c376e941be68032e0a09..b203c44cf633e1729a49b1b32c4c1dd892ea3898 100644 (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);
\ No newline at end of file
index 8268d004fc149dd6e627a4d0ee4c392e78969ea0..5379e64abaf4c89106516be8f5377fccf12b83b5 100644 (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
+};
index c3198b23b0446b1bb1e55fcd87521cb10b61c160..72be209f7f896a3ee8fd5a6cfad15f228ed7af5c 100644 (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,
index 1953b7fed056760d867c90cea101ac25a404a7e5..ecc833a7f191c3dfc86b8cb6d22698fd266e8335 100644 (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
+};
index b51615c396b4059169f54d2e2fbbfb2582b8670b..dada7ba9f51671b89aa81c61522f65cb4c7e5319 100644 (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:
index 0b15e55fbc41c05f5ddecbf4324d03bf34fd30c6..c07493b0e868598bb08480052df654844947754a 100644 (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) \
index f1c372b982ea0f96747cc79134240200e0a7b59c..b92c72ac4a0b67052127487fab0f7ce883b9f7c2 100644 (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,
index 9e4d689c23c32cc14b4a4471ccf3c12a7b25c1ea..737550f050780a21b6423a523e8933cd95fcd74c 100644 (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,
index d1614a56d886cf9feb2b10363ad2e362c2ad8b04..6651c269358840f098e4d0b3b948baf99262b375 100644 (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;
index ab8acd71f8010f657eb268f27622c36c6300d2f5..b1f91ed60e2824e0983a48eb0bbc110b1e86baa8 100644 (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)