xref: /freebsd-src/crypto/openssl/ssl/record/rec_layer_d1.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim  */
9e71b7053SJung-uk Kim 
10e71b7053SJung-uk Kim #include <stdio.h>
11e71b7053SJung-uk Kim #include <errno.h>
1217f01e99SJung-uk Kim #include "../ssl_local.h"
13e71b7053SJung-uk Kim #include <openssl/evp.h>
14e71b7053SJung-uk Kim #include <openssl/buffer.h>
1517f01e99SJung-uk Kim #include "record_local.h"
16*b077aed3SPierre Pronchery #include "internal/packet.h"
17e71b7053SJung-uk Kim #include "internal/cryptlib.h"
18e71b7053SJung-uk Kim 
DTLS_RECORD_LAYER_new(RECORD_LAYER * rl)19e71b7053SJung-uk Kim int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
20e71b7053SJung-uk Kim {
21e71b7053SJung-uk Kim     DTLS_RECORD_LAYER *d;
22e71b7053SJung-uk Kim 
23e71b7053SJung-uk Kim     if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) {
24*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
25e71b7053SJung-uk Kim         return 0;
26e71b7053SJung-uk Kim     }
27e71b7053SJung-uk Kim 
28e71b7053SJung-uk Kim     rl->d = d;
29e71b7053SJung-uk Kim 
30e71b7053SJung-uk Kim     d->unprocessed_rcds.q = pqueue_new();
31e71b7053SJung-uk Kim     d->processed_rcds.q = pqueue_new();
32e71b7053SJung-uk Kim     d->buffered_app_data.q = pqueue_new();
33e71b7053SJung-uk Kim 
34e71b7053SJung-uk Kim     if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL
35e71b7053SJung-uk Kim         || d->buffered_app_data.q == NULL) {
36e71b7053SJung-uk Kim         pqueue_free(d->unprocessed_rcds.q);
37e71b7053SJung-uk Kim         pqueue_free(d->processed_rcds.q);
38e71b7053SJung-uk Kim         pqueue_free(d->buffered_app_data.q);
39e71b7053SJung-uk Kim         OPENSSL_free(d);
40e71b7053SJung-uk Kim         rl->d = NULL;
41e71b7053SJung-uk Kim         return 0;
42e71b7053SJung-uk Kim     }
43e71b7053SJung-uk Kim 
44e71b7053SJung-uk Kim     return 1;
45e71b7053SJung-uk Kim }
46e71b7053SJung-uk Kim 
DTLS_RECORD_LAYER_free(RECORD_LAYER * rl)47e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl)
48e71b7053SJung-uk Kim {
4988e852c0SJung-uk Kim     if (rl->d == NULL)
5088e852c0SJung-uk Kim         return;
5188e852c0SJung-uk Kim 
52e71b7053SJung-uk Kim     DTLS_RECORD_LAYER_clear(rl);
53e71b7053SJung-uk Kim     pqueue_free(rl->d->unprocessed_rcds.q);
54e71b7053SJung-uk Kim     pqueue_free(rl->d->processed_rcds.q);
55e71b7053SJung-uk Kim     pqueue_free(rl->d->buffered_app_data.q);
56e71b7053SJung-uk Kim     OPENSSL_free(rl->d);
57e71b7053SJung-uk Kim     rl->d = NULL;
58e71b7053SJung-uk Kim }
59e71b7053SJung-uk Kim 
DTLS_RECORD_LAYER_clear(RECORD_LAYER * rl)60e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl)
61e71b7053SJung-uk Kim {
62e71b7053SJung-uk Kim     DTLS_RECORD_LAYER *d;
63e71b7053SJung-uk Kim     pitem *item = NULL;
64e71b7053SJung-uk Kim     DTLS1_RECORD_DATA *rdata;
65e71b7053SJung-uk Kim     pqueue *unprocessed_rcds;
66e71b7053SJung-uk Kim     pqueue *processed_rcds;
67e71b7053SJung-uk Kim     pqueue *buffered_app_data;
68e71b7053SJung-uk Kim 
69e71b7053SJung-uk Kim     d = rl->d;
70e71b7053SJung-uk Kim 
71e71b7053SJung-uk Kim     while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) {
72e71b7053SJung-uk Kim         rdata = (DTLS1_RECORD_DATA *)item->data;
73e71b7053SJung-uk Kim         OPENSSL_free(rdata->rbuf.buf);
74e71b7053SJung-uk Kim         OPENSSL_free(item->data);
75e71b7053SJung-uk Kim         pitem_free(item);
76e71b7053SJung-uk Kim     }
77e71b7053SJung-uk Kim 
78e71b7053SJung-uk Kim     while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) {
79e71b7053SJung-uk Kim         rdata = (DTLS1_RECORD_DATA *)item->data;
80*b077aed3SPierre Pronchery         if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT)
81*b077aed3SPierre Pronchery             OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len);
82e71b7053SJung-uk Kim         OPENSSL_free(rdata->rbuf.buf);
83e71b7053SJung-uk Kim         OPENSSL_free(item->data);
84e71b7053SJung-uk Kim         pitem_free(item);
85e71b7053SJung-uk Kim     }
86e71b7053SJung-uk Kim 
87e71b7053SJung-uk Kim     while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) {
88e71b7053SJung-uk Kim         rdata = (DTLS1_RECORD_DATA *)item->data;
89*b077aed3SPierre Pronchery         if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT)
90*b077aed3SPierre Pronchery             OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len);
91e71b7053SJung-uk Kim         OPENSSL_free(rdata->rbuf.buf);
92e71b7053SJung-uk Kim         OPENSSL_free(item->data);
93e71b7053SJung-uk Kim         pitem_free(item);
94e71b7053SJung-uk Kim     }
95e71b7053SJung-uk Kim 
96e71b7053SJung-uk Kim     unprocessed_rcds = d->unprocessed_rcds.q;
97e71b7053SJung-uk Kim     processed_rcds = d->processed_rcds.q;
98e71b7053SJung-uk Kim     buffered_app_data = d->buffered_app_data.q;
99e71b7053SJung-uk Kim     memset(d, 0, sizeof(*d));
100e71b7053SJung-uk Kim     d->unprocessed_rcds.q = unprocessed_rcds;
101e71b7053SJung-uk Kim     d->processed_rcds.q = processed_rcds;
102e71b7053SJung-uk Kim     d->buffered_app_data.q = buffered_app_data;
103e71b7053SJung-uk Kim }
104e71b7053SJung-uk Kim 
DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER * rl,unsigned short e)105e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e)
106e71b7053SJung-uk Kim {
107e71b7053SJung-uk Kim     if (e == rl->d->w_epoch - 1) {
108e71b7053SJung-uk Kim         memcpy(rl->d->curr_write_sequence,
109e71b7053SJung-uk Kim                rl->write_sequence, sizeof(rl->write_sequence));
110e71b7053SJung-uk Kim         memcpy(rl->write_sequence,
111e71b7053SJung-uk Kim                rl->d->last_write_sequence, sizeof(rl->write_sequence));
112e71b7053SJung-uk Kim     } else if (e == rl->d->w_epoch + 1) {
113e71b7053SJung-uk Kim         memcpy(rl->d->last_write_sequence,
114e71b7053SJung-uk Kim                rl->write_sequence, sizeof(unsigned char[8]));
115e71b7053SJung-uk Kim         memcpy(rl->write_sequence,
116e71b7053SJung-uk Kim                rl->d->curr_write_sequence, sizeof(rl->write_sequence));
117e71b7053SJung-uk Kim     }
118e71b7053SJung-uk Kim     rl->d->w_epoch = e;
119e71b7053SJung-uk Kim }
120e71b7053SJung-uk Kim 
DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER * rl,unsigned char * seq)121e71b7053SJung-uk Kim void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq)
122e71b7053SJung-uk Kim {
123e71b7053SJung-uk Kim     memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE);
124e71b7053SJung-uk Kim }
125e71b7053SJung-uk Kim 
126e71b7053SJung-uk Kim /* copy buffered record into SSL structure */
dtls1_copy_record(SSL * s,pitem * item)127e71b7053SJung-uk Kim static int dtls1_copy_record(SSL *s, pitem *item)
128e71b7053SJung-uk Kim {
129e71b7053SJung-uk Kim     DTLS1_RECORD_DATA *rdata;
130e71b7053SJung-uk Kim 
131e71b7053SJung-uk Kim     rdata = (DTLS1_RECORD_DATA *)item->data;
132e71b7053SJung-uk Kim 
133e71b7053SJung-uk Kim     SSL3_BUFFER_release(&s->rlayer.rbuf);
134e71b7053SJung-uk Kim 
135e71b7053SJung-uk Kim     s->rlayer.packet = rdata->packet;
136e71b7053SJung-uk Kim     s->rlayer.packet_length = rdata->packet_length;
137e71b7053SJung-uk Kim     memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
138e71b7053SJung-uk Kim     memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD));
139e71b7053SJung-uk Kim 
140e71b7053SJung-uk Kim     /* Set proper sequence number for mac calculation */
141e71b7053SJung-uk Kim     memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6);
142e71b7053SJung-uk Kim 
143e71b7053SJung-uk Kim     return 1;
144e71b7053SJung-uk Kim }
145e71b7053SJung-uk Kim 
dtls1_buffer_record(SSL * s,record_pqueue * queue,unsigned char * priority)146e71b7053SJung-uk Kim int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
147e71b7053SJung-uk Kim {
148e71b7053SJung-uk Kim     DTLS1_RECORD_DATA *rdata;
149e71b7053SJung-uk Kim     pitem *item;
150e71b7053SJung-uk Kim 
151e71b7053SJung-uk Kim     /* Limit the size of the queue to prevent DOS attacks */
152e71b7053SJung-uk Kim     if (pqueue_size(queue->q) >= 100)
153e71b7053SJung-uk Kim         return 0;
154e71b7053SJung-uk Kim 
155e71b7053SJung-uk Kim     rdata = OPENSSL_malloc(sizeof(*rdata));
156e71b7053SJung-uk Kim     item = pitem_new(priority, rdata);
157e71b7053SJung-uk Kim     if (rdata == NULL || item == NULL) {
158e71b7053SJung-uk Kim         OPENSSL_free(rdata);
159e71b7053SJung-uk Kim         pitem_free(item);
160*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
161e71b7053SJung-uk Kim         return -1;
162e71b7053SJung-uk Kim     }
163e71b7053SJung-uk Kim 
164e71b7053SJung-uk Kim     rdata->packet = s->rlayer.packet;
165e71b7053SJung-uk Kim     rdata->packet_length = s->rlayer.packet_length;
166e71b7053SJung-uk Kim     memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER));
167e71b7053SJung-uk Kim     memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD));
168e71b7053SJung-uk Kim 
169e71b7053SJung-uk Kim     item->data = rdata;
170e71b7053SJung-uk Kim 
171e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
172e71b7053SJung-uk Kim     /* Store bio_dgram_sctp_rcvinfo struct */
173e71b7053SJung-uk Kim     if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
174e71b7053SJung-uk Kim         (SSL_get_state(s) == TLS_ST_SR_FINISHED
175e71b7053SJung-uk Kim          || SSL_get_state(s) == TLS_ST_CR_FINISHED)) {
176e71b7053SJung-uk Kim         BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
177e71b7053SJung-uk Kim                  sizeof(rdata->recordinfo), &rdata->recordinfo);
178e71b7053SJung-uk Kim     }
179e71b7053SJung-uk Kim #endif
180e71b7053SJung-uk Kim 
181e71b7053SJung-uk Kim     s->rlayer.packet = NULL;
182e71b7053SJung-uk Kim     s->rlayer.packet_length = 0;
183e71b7053SJung-uk Kim     memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf));
184e71b7053SJung-uk Kim     memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec));
185e71b7053SJung-uk Kim 
186e71b7053SJung-uk Kim     if (!ssl3_setup_buffers(s)) {
187e71b7053SJung-uk Kim         /* SSLfatal() already called */
188e71b7053SJung-uk Kim         OPENSSL_free(rdata->rbuf.buf);
189e71b7053SJung-uk Kim         OPENSSL_free(rdata);
190e71b7053SJung-uk Kim         pitem_free(item);
191e71b7053SJung-uk Kim         return -1;
192e71b7053SJung-uk Kim     }
193e71b7053SJung-uk Kim 
194e71b7053SJung-uk Kim     if (pqueue_insert(queue->q, item) == NULL) {
195c9cf7b5cSJung-uk Kim         /* Must be a duplicate so ignore it */
196e71b7053SJung-uk Kim         OPENSSL_free(rdata->rbuf.buf);
197e71b7053SJung-uk Kim         OPENSSL_free(rdata);
198e71b7053SJung-uk Kim         pitem_free(item);
199e71b7053SJung-uk Kim     }
200e71b7053SJung-uk Kim 
201e71b7053SJung-uk Kim     return 1;
202e71b7053SJung-uk Kim }
203e71b7053SJung-uk Kim 
dtls1_retrieve_buffered_record(SSL * s,record_pqueue * queue)204e71b7053SJung-uk Kim int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
205e71b7053SJung-uk Kim {
206e71b7053SJung-uk Kim     pitem *item;
207e71b7053SJung-uk Kim 
208e71b7053SJung-uk Kim     item = pqueue_pop(queue->q);
209e71b7053SJung-uk Kim     if (item) {
210e71b7053SJung-uk Kim         dtls1_copy_record(s, item);
211e71b7053SJung-uk Kim 
212e71b7053SJung-uk Kim         OPENSSL_free(item->data);
213e71b7053SJung-uk Kim         pitem_free(item);
214e71b7053SJung-uk Kim 
215e71b7053SJung-uk Kim         return 1;
216e71b7053SJung-uk Kim     }
217e71b7053SJung-uk Kim 
218e71b7053SJung-uk Kim     return 0;
219e71b7053SJung-uk Kim }
220e71b7053SJung-uk Kim 
221e71b7053SJung-uk Kim /*
222e71b7053SJung-uk Kim  * retrieve a buffered record that belongs to the new epoch, i.e., not
223e71b7053SJung-uk Kim  * processed yet
224e71b7053SJung-uk Kim  */
225e71b7053SJung-uk Kim #define dtls1_get_unprocessed_record(s) \
226e71b7053SJung-uk Kim                    dtls1_retrieve_buffered_record((s), \
227e71b7053SJung-uk Kim                    &((s)->rlayer.d->unprocessed_rcds))
228e71b7053SJung-uk Kim 
dtls1_process_buffered_records(SSL * s)229e71b7053SJung-uk Kim int dtls1_process_buffered_records(SSL *s)
230e71b7053SJung-uk Kim {
231e71b7053SJung-uk Kim     pitem *item;
232e71b7053SJung-uk Kim     SSL3_BUFFER *rb;
233e71b7053SJung-uk Kim     SSL3_RECORD *rr;
234e71b7053SJung-uk Kim     DTLS1_BITMAP *bitmap;
235e71b7053SJung-uk Kim     unsigned int is_next_epoch;
236e71b7053SJung-uk Kim     int replayok = 1;
237e71b7053SJung-uk Kim 
238e71b7053SJung-uk Kim     item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q);
239e71b7053SJung-uk Kim     if (item) {
240e71b7053SJung-uk Kim         /* Check if epoch is current. */
241e71b7053SJung-uk Kim         if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
242e71b7053SJung-uk Kim             return 1;         /* Nothing to do. */
243e71b7053SJung-uk Kim 
244e71b7053SJung-uk Kim         rr = RECORD_LAYER_get_rrec(&s->rlayer);
245e71b7053SJung-uk Kim 
246e71b7053SJung-uk Kim         rb = RECORD_LAYER_get_rbuf(&s->rlayer);
247e71b7053SJung-uk Kim 
248e71b7053SJung-uk Kim         if (SSL3_BUFFER_get_left(rb) > 0) {
249e71b7053SJung-uk Kim             /*
250e71b7053SJung-uk Kim              * We've still got data from the current packet to read. There could
251e71b7053SJung-uk Kim              * be a record from the new epoch in it - so don't overwrite it
252e71b7053SJung-uk Kim              * with the unprocessed records yet (we'll do it when we've
253e71b7053SJung-uk Kim              * finished reading the current packet).
254e71b7053SJung-uk Kim              */
255e71b7053SJung-uk Kim             return 1;
256e71b7053SJung-uk Kim         }
257e71b7053SJung-uk Kim 
258e71b7053SJung-uk Kim         /* Process all the records. */
259e71b7053SJung-uk Kim         while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) {
260e71b7053SJung-uk Kim             dtls1_get_unprocessed_record(s);
261e71b7053SJung-uk Kim             bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
262e71b7053SJung-uk Kim             if (bitmap == NULL) {
263e71b7053SJung-uk Kim                 /*
264e71b7053SJung-uk Kim                  * Should not happen. This will only ever be NULL when the
265e71b7053SJung-uk Kim                  * current record is from a different epoch. But that cannot
266e71b7053SJung-uk Kim                  * be the case because we already checked the epoch above
267e71b7053SJung-uk Kim                  */
268*b077aed3SPierre Pronchery                  SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
269e71b7053SJung-uk Kim                  return 0;
270e71b7053SJung-uk Kim             }
271e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
272e71b7053SJung-uk Kim             /* Only do replay check if no SCTP bio */
273e71b7053SJung-uk Kim             if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
274e71b7053SJung-uk Kim #endif
275e71b7053SJung-uk Kim             {
276e71b7053SJung-uk Kim                 /*
277e71b7053SJung-uk Kim                  * Check whether this is a repeat, or aged record. We did this
278e71b7053SJung-uk Kim                  * check once already when we first received the record - but
279e71b7053SJung-uk Kim                  * we might have updated the window since then due to
280e71b7053SJung-uk Kim                  * records we subsequently processed.
281e71b7053SJung-uk Kim                  */
282e71b7053SJung-uk Kim                 replayok = dtls1_record_replay_check(s, bitmap);
283e71b7053SJung-uk Kim             }
284e71b7053SJung-uk Kim 
285e71b7053SJung-uk Kim             if (!replayok || !dtls1_process_record(s, bitmap)) {
286e71b7053SJung-uk Kim                 if (ossl_statem_in_error(s)) {
287e71b7053SJung-uk Kim                     /* dtls1_process_record called SSLfatal() */
288*b077aed3SPierre Pronchery                     return 0;
289e71b7053SJung-uk Kim                 }
290e71b7053SJung-uk Kim                 /* dump this record */
291e71b7053SJung-uk Kim                 rr->length = 0;
292e71b7053SJung-uk Kim                 RECORD_LAYER_reset_packet_length(&s->rlayer);
293e71b7053SJung-uk Kim                 continue;
294e71b7053SJung-uk Kim             }
295e71b7053SJung-uk Kim 
296e71b7053SJung-uk Kim             if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
297e71b7053SJung-uk Kim                     SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < 0) {
298e71b7053SJung-uk Kim                 /* SSLfatal() already called */
299e71b7053SJung-uk Kim                 return 0;
300e71b7053SJung-uk Kim             }
301e71b7053SJung-uk Kim         }
302e71b7053SJung-uk Kim     }
303e71b7053SJung-uk Kim 
304e71b7053SJung-uk Kim     /*
305e71b7053SJung-uk Kim      * sync epoch numbers once all the unprocessed records have been
306e71b7053SJung-uk Kim      * processed
307e71b7053SJung-uk Kim      */
308e71b7053SJung-uk Kim     s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch;
309e71b7053SJung-uk Kim     s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1;
310e71b7053SJung-uk Kim 
311e71b7053SJung-uk Kim     return 1;
312e71b7053SJung-uk Kim }
313e71b7053SJung-uk Kim 
314e71b7053SJung-uk Kim /*-
315e71b7053SJung-uk Kim  * Return up to 'len' payload bytes received in 'type' records.
316e71b7053SJung-uk Kim  * 'type' is one of the following:
317e71b7053SJung-uk Kim  *
318e71b7053SJung-uk Kim  *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
319e71b7053SJung-uk Kim  *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
320e71b7053SJung-uk Kim  *   -  0 (during a shutdown, no data has to be returned)
321e71b7053SJung-uk Kim  *
322e71b7053SJung-uk Kim  * If we don't have stored data to work from, read a SSL/TLS record first
323e71b7053SJung-uk Kim  * (possibly multiple records if we still don't have anything to return).
324e71b7053SJung-uk Kim  *
325e71b7053SJung-uk Kim  * This function must handle any surprises the peer may have for us, such as
326e71b7053SJung-uk Kim  * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
327e71b7053SJung-uk Kim  * messages are treated as if they were handshake messages *if* the |recd_type|
328e71b7053SJung-uk Kim  * argument is non NULL.
329e71b7053SJung-uk Kim  * Also if record payloads contain fragments too small to process, we store
330e71b7053SJung-uk Kim  * them until there is enough for the respective protocol (the record protocol
331e71b7053SJung-uk Kim  * may use arbitrary fragmentation and even interleaving):
332e71b7053SJung-uk Kim  *     Change cipher spec protocol
333e71b7053SJung-uk Kim  *             just 1 byte needed, no need for keeping anything stored
334e71b7053SJung-uk Kim  *     Alert protocol
335e71b7053SJung-uk Kim  *             2 bytes needed (AlertLevel, AlertDescription)
336e71b7053SJung-uk Kim  *     Handshake protocol
337e71b7053SJung-uk Kim  *             4 bytes needed (HandshakeType, uint24 length) -- we just have
338e71b7053SJung-uk Kim  *             to detect unexpected Client Hello and Hello Request messages
339e71b7053SJung-uk Kim  *             here, anything else is handled by higher layers
340e71b7053SJung-uk Kim  *     Application data protocol
341e71b7053SJung-uk Kim  *             none of our business
342e71b7053SJung-uk Kim  */
dtls1_read_bytes(SSL * s,int type,int * recvd_type,unsigned char * buf,size_t len,int peek,size_t * readbytes)343e71b7053SJung-uk Kim int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
344e71b7053SJung-uk Kim                      size_t len, int peek, size_t *readbytes)
345e71b7053SJung-uk Kim {
346e71b7053SJung-uk Kim     int i, j, iret;
347e71b7053SJung-uk Kim     size_t n;
348e71b7053SJung-uk Kim     SSL3_RECORD *rr;
349e71b7053SJung-uk Kim     void (*cb) (const SSL *ssl, int type2, int val) = NULL;
350e71b7053SJung-uk Kim 
351e71b7053SJung-uk Kim     if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
352e71b7053SJung-uk Kim         /* Not initialized yet */
353e71b7053SJung-uk Kim         if (!ssl3_setup_buffers(s)) {
354e71b7053SJung-uk Kim             /* SSLfatal() already called */
355e71b7053SJung-uk Kim             return -1;
356e71b7053SJung-uk Kim         }
357e71b7053SJung-uk Kim     }
358e71b7053SJung-uk Kim 
359e71b7053SJung-uk Kim     if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
360e71b7053SJung-uk Kim          (type != SSL3_RT_HANDSHAKE)) ||
361e71b7053SJung-uk Kim         (peek && (type != SSL3_RT_APPLICATION_DATA))) {
362*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
363e71b7053SJung-uk Kim         return -1;
364e71b7053SJung-uk Kim     }
365e71b7053SJung-uk Kim 
366e71b7053SJung-uk Kim     if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) {
367e71b7053SJung-uk Kim         /* type == SSL3_RT_APPLICATION_DATA */
368e71b7053SJung-uk Kim         i = s->handshake_func(s);
369e71b7053SJung-uk Kim         /* SSLfatal() already called if appropriate */
370e71b7053SJung-uk Kim         if (i < 0)
371e71b7053SJung-uk Kim             return i;
372e71b7053SJung-uk Kim         if (i == 0)
373e71b7053SJung-uk Kim             return -1;
374e71b7053SJung-uk Kim     }
375e71b7053SJung-uk Kim 
376e71b7053SJung-uk Kim  start:
377e71b7053SJung-uk Kim     s->rwstate = SSL_NOTHING;
378e71b7053SJung-uk Kim 
379e71b7053SJung-uk Kim     /*-
380*b077aed3SPierre Pronchery      * s->s3.rrec.type     - is the type of record
381*b077aed3SPierre Pronchery      * s->s3.rrec.data,    - data
382*b077aed3SPierre Pronchery      * s->s3.rrec.off,     - offset into 'data' for next read
383*b077aed3SPierre Pronchery      * s->s3.rrec.length,  - number of bytes.
384e71b7053SJung-uk Kim      */
385e71b7053SJung-uk Kim     rr = s->rlayer.rrec;
386e71b7053SJung-uk Kim 
387e71b7053SJung-uk Kim     /*
388e71b7053SJung-uk Kim      * We are not handshaking and have no data yet, so process data buffered
389e71b7053SJung-uk Kim      * during the last handshake in advance, if any.
390e71b7053SJung-uk Kim      */
391e71b7053SJung-uk Kim     if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
392e71b7053SJung-uk Kim         pitem *item;
393e71b7053SJung-uk Kim         item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
394e71b7053SJung-uk Kim         if (item) {
395e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
396e71b7053SJung-uk Kim             /* Restore bio_dgram_sctp_rcvinfo struct */
397e71b7053SJung-uk Kim             if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
398e71b7053SJung-uk Kim                 DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
399e71b7053SJung-uk Kim                 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
400e71b7053SJung-uk Kim                          sizeof(rdata->recordinfo), &rdata->recordinfo);
401e71b7053SJung-uk Kim             }
402e71b7053SJung-uk Kim #endif
403e71b7053SJung-uk Kim 
404e71b7053SJung-uk Kim             dtls1_copy_record(s, item);
405e71b7053SJung-uk Kim 
406e71b7053SJung-uk Kim             OPENSSL_free(item->data);
407e71b7053SJung-uk Kim             pitem_free(item);
408e71b7053SJung-uk Kim         }
409e71b7053SJung-uk Kim     }
410e71b7053SJung-uk Kim 
411e71b7053SJung-uk Kim     /* Check for timeout */
412e71b7053SJung-uk Kim     if (dtls1_handle_timeout(s) > 0) {
413e71b7053SJung-uk Kim         goto start;
414e71b7053SJung-uk Kim     } else if (ossl_statem_in_error(s)) {
415e71b7053SJung-uk Kim         /* dtls1_handle_timeout() has failed with a fatal error */
416e71b7053SJung-uk Kim         return -1;
417e71b7053SJung-uk Kim     }
418e71b7053SJung-uk Kim 
419e71b7053SJung-uk Kim     /* get new packet if necessary */
420e71b7053SJung-uk Kim     if ((SSL3_RECORD_get_length(rr) == 0)
421e71b7053SJung-uk Kim         || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
422e71b7053SJung-uk Kim         RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
423e71b7053SJung-uk Kim         iret = dtls1_get_record(s);
424e71b7053SJung-uk Kim         if (iret <= 0) {
425e71b7053SJung-uk Kim             iret = dtls1_read_failed(s, iret);
426e71b7053SJung-uk Kim             /*
427e71b7053SJung-uk Kim              * Anything other than a timeout is an error. SSLfatal() already
428e71b7053SJung-uk Kim              * called if appropriate.
429e71b7053SJung-uk Kim              */
430e71b7053SJung-uk Kim             if (iret <= 0)
431e71b7053SJung-uk Kim                 return iret;
432e71b7053SJung-uk Kim             else
433e71b7053SJung-uk Kim                 goto start;
434e71b7053SJung-uk Kim         }
435e71b7053SJung-uk Kim         RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
436e71b7053SJung-uk Kim     }
437e71b7053SJung-uk Kim 
438e71b7053SJung-uk Kim     /*
439e71b7053SJung-uk Kim      * Reset the count of consecutive warning alerts if we've got a non-empty
440e71b7053SJung-uk Kim      * record that isn't an alert.
441e71b7053SJung-uk Kim      */
442e71b7053SJung-uk Kim     if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
443e71b7053SJung-uk Kim             && SSL3_RECORD_get_length(rr) != 0)
444e71b7053SJung-uk Kim         s->rlayer.alert_count = 0;
445e71b7053SJung-uk Kim 
446e71b7053SJung-uk Kim     /* we now have a packet which can be read and processed */
447e71b7053SJung-uk Kim 
448*b077aed3SPierre Pronchery     if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec,
449e71b7053SJung-uk Kim                                   * reset by ssl3_get_finished */
450e71b7053SJung-uk Kim         && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
451e71b7053SJung-uk Kim         /*
452e71b7053SJung-uk Kim          * We now have application data between CCS and Finished. Most likely
453e71b7053SJung-uk Kim          * the packets were reordered on their way, so buffer the application
454e71b7053SJung-uk Kim          * data for later processing rather than dropping the connection.
455e71b7053SJung-uk Kim          */
456e71b7053SJung-uk Kim         if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
457e71b7053SJung-uk Kim                                 SSL3_RECORD_get_seq_num(rr)) < 0) {
458e71b7053SJung-uk Kim             /* SSLfatal() already called */
459e71b7053SJung-uk Kim             return -1;
460e71b7053SJung-uk Kim         }
461e71b7053SJung-uk Kim         SSL3_RECORD_set_length(rr, 0);
462e71b7053SJung-uk Kim         SSL3_RECORD_set_read(rr);
463e71b7053SJung-uk Kim         goto start;
464e71b7053SJung-uk Kim     }
465e71b7053SJung-uk Kim 
466e71b7053SJung-uk Kim     /*
467e71b7053SJung-uk Kim      * If the other end has shut down, throw anything we read away (even in
468e71b7053SJung-uk Kim      * 'peek' mode)
469e71b7053SJung-uk Kim      */
470e71b7053SJung-uk Kim     if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
471e71b7053SJung-uk Kim         SSL3_RECORD_set_length(rr, 0);
472e71b7053SJung-uk Kim         SSL3_RECORD_set_read(rr);
473e71b7053SJung-uk Kim         s->rwstate = SSL_NOTHING;
474e71b7053SJung-uk Kim         return 0;
475e71b7053SJung-uk Kim     }
476e71b7053SJung-uk Kim 
477e71b7053SJung-uk Kim     if (type == SSL3_RECORD_get_type(rr)
478e71b7053SJung-uk Kim         || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
479e71b7053SJung-uk Kim             && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
480e71b7053SJung-uk Kim         /*
481e71b7053SJung-uk Kim          * SSL3_RT_APPLICATION_DATA or
482e71b7053SJung-uk Kim          * SSL3_RT_HANDSHAKE or
483e71b7053SJung-uk Kim          * SSL3_RT_CHANGE_CIPHER_SPEC
484e71b7053SJung-uk Kim          */
485e71b7053SJung-uk Kim         /*
486e71b7053SJung-uk Kim          * make sure that we are not getting application data when we are
487e71b7053SJung-uk Kim          * doing a handshake for the first time
488e71b7053SJung-uk Kim          */
489e71b7053SJung-uk Kim         if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
490e71b7053SJung-uk Kim             (s->enc_read_ctx == NULL)) {
491*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
492e71b7053SJung-uk Kim                      SSL_R_APP_DATA_IN_HANDSHAKE);
493e71b7053SJung-uk Kim             return -1;
494e71b7053SJung-uk Kim         }
495e71b7053SJung-uk Kim 
496e71b7053SJung-uk Kim         if (recvd_type != NULL)
497e71b7053SJung-uk Kim             *recvd_type = SSL3_RECORD_get_type(rr);
498e71b7053SJung-uk Kim 
499e71b7053SJung-uk Kim         if (len == 0) {
500e71b7053SJung-uk Kim             /*
501e71b7053SJung-uk Kim              * Mark a zero length record as read. This ensures multiple calls to
502e71b7053SJung-uk Kim              * SSL_read() with a zero length buffer will eventually cause
503e71b7053SJung-uk Kim              * SSL_pending() to report data as being available.
504e71b7053SJung-uk Kim              */
505e71b7053SJung-uk Kim             if (SSL3_RECORD_get_length(rr) == 0)
506e71b7053SJung-uk Kim                 SSL3_RECORD_set_read(rr);
507e71b7053SJung-uk Kim             return 0;
508e71b7053SJung-uk Kim         }
509e71b7053SJung-uk Kim 
510e71b7053SJung-uk Kim         if (len > SSL3_RECORD_get_length(rr))
511e71b7053SJung-uk Kim             n = SSL3_RECORD_get_length(rr);
512e71b7053SJung-uk Kim         else
513e71b7053SJung-uk Kim             n = len;
514e71b7053SJung-uk Kim 
515e71b7053SJung-uk Kim         memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
516e71b7053SJung-uk Kim         if (peek) {
517e71b7053SJung-uk Kim             if (SSL3_RECORD_get_length(rr) == 0)
518e71b7053SJung-uk Kim                 SSL3_RECORD_set_read(rr);
519e71b7053SJung-uk Kim         } else {
520*b077aed3SPierre Pronchery             if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
521*b077aed3SPierre Pronchery                 OPENSSL_cleanse(&(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
522e71b7053SJung-uk Kim             SSL3_RECORD_sub_length(rr, n);
523e71b7053SJung-uk Kim             SSL3_RECORD_add_off(rr, n);
524e71b7053SJung-uk Kim             if (SSL3_RECORD_get_length(rr) == 0) {
525e71b7053SJung-uk Kim                 s->rlayer.rstate = SSL_ST_READ_HEADER;
526e71b7053SJung-uk Kim                 SSL3_RECORD_set_off(rr, 0);
527e71b7053SJung-uk Kim                 SSL3_RECORD_set_read(rr);
528e71b7053SJung-uk Kim             }
529e71b7053SJung-uk Kim         }
530e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
531e71b7053SJung-uk Kim         /*
532e71b7053SJung-uk Kim          * We might had to delay a close_notify alert because of reordered
533e71b7053SJung-uk Kim          * app data. If there was an alert and there is no message to read
534e71b7053SJung-uk Kim          * anymore, finally set shutdown.
535e71b7053SJung-uk Kim          */
536e71b7053SJung-uk Kim         if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
537e71b7053SJung-uk Kim             s->d1->shutdown_received
538*b077aed3SPierre Pronchery             && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) <= 0) {
539e71b7053SJung-uk Kim             s->shutdown |= SSL_RECEIVED_SHUTDOWN;
540e71b7053SJung-uk Kim             return 0;
541e71b7053SJung-uk Kim         }
542e71b7053SJung-uk Kim #endif
543e71b7053SJung-uk Kim         *readbytes = n;
544e71b7053SJung-uk Kim         return 1;
545e71b7053SJung-uk Kim     }
546e71b7053SJung-uk Kim 
547e71b7053SJung-uk Kim     /*
548e71b7053SJung-uk Kim      * If we get here, then type != rr->type; if we have a handshake message,
549e71b7053SJung-uk Kim      * then it was unexpected (Hello Request or Client Hello).
550e71b7053SJung-uk Kim      */
551e71b7053SJung-uk Kim 
552e71b7053SJung-uk Kim     if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
553e71b7053SJung-uk Kim         unsigned int alert_level, alert_descr;
554e71b7053SJung-uk Kim         unsigned char *alert_bytes = SSL3_RECORD_get_data(rr)
555e71b7053SJung-uk Kim                                      + SSL3_RECORD_get_off(rr);
556e71b7053SJung-uk Kim         PACKET alert;
557e71b7053SJung-uk Kim 
558e71b7053SJung-uk Kim         if (!PACKET_buf_init(&alert, alert_bytes, SSL3_RECORD_get_length(rr))
559e71b7053SJung-uk Kim                 || !PACKET_get_1(&alert, &alert_level)
560e71b7053SJung-uk Kim                 || !PACKET_get_1(&alert, &alert_descr)
561e71b7053SJung-uk Kim                 || PACKET_remaining(&alert) != 0) {
562*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT);
563e71b7053SJung-uk Kim             return -1;
564e71b7053SJung-uk Kim         }
565e71b7053SJung-uk Kim 
566e71b7053SJung-uk Kim         if (s->msg_callback)
567e71b7053SJung-uk Kim             s->msg_callback(0, s->version, SSL3_RT_ALERT, alert_bytes, 2, s,
568e71b7053SJung-uk Kim                             s->msg_callback_arg);
569e71b7053SJung-uk Kim 
570e71b7053SJung-uk Kim         if (s->info_callback != NULL)
571e71b7053SJung-uk Kim             cb = s->info_callback;
572e71b7053SJung-uk Kim         else if (s->ctx->info_callback != NULL)
573e71b7053SJung-uk Kim             cb = s->ctx->info_callback;
574e71b7053SJung-uk Kim 
575e71b7053SJung-uk Kim         if (cb != NULL) {
576e71b7053SJung-uk Kim             j = (alert_level << 8) | alert_descr;
577e71b7053SJung-uk Kim             cb(s, SSL_CB_READ_ALERT, j);
578e71b7053SJung-uk Kim         }
579e71b7053SJung-uk Kim 
580e71b7053SJung-uk Kim         if (alert_level == SSL3_AL_WARNING) {
581*b077aed3SPierre Pronchery             s->s3.warn_alert = alert_descr;
582e71b7053SJung-uk Kim             SSL3_RECORD_set_read(rr);
583e71b7053SJung-uk Kim 
584e71b7053SJung-uk Kim             s->rlayer.alert_count++;
585e71b7053SJung-uk Kim             if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
586*b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
587e71b7053SJung-uk Kim                          SSL_R_TOO_MANY_WARN_ALERTS);
588e71b7053SJung-uk Kim                 return -1;
589e71b7053SJung-uk Kim             }
590e71b7053SJung-uk Kim 
591e71b7053SJung-uk Kim             if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
592e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP
593e71b7053SJung-uk Kim                 /*
594e71b7053SJung-uk Kim                  * With SCTP and streams the socket may deliver app data
595e71b7053SJung-uk Kim                  * after a close_notify alert. We have to check this first so
596e71b7053SJung-uk Kim                  * that nothing gets discarded.
597e71b7053SJung-uk Kim                  */
598e71b7053SJung-uk Kim                 if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
599*b077aed3SPierre Pronchery                     BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) {
600e71b7053SJung-uk Kim                     s->d1->shutdown_received = 1;
601e71b7053SJung-uk Kim                     s->rwstate = SSL_READING;
602e71b7053SJung-uk Kim                     BIO_clear_retry_flags(SSL_get_rbio(s));
603e71b7053SJung-uk Kim                     BIO_set_retry_read(SSL_get_rbio(s));
604e71b7053SJung-uk Kim                     return -1;
605e71b7053SJung-uk Kim                 }
606e71b7053SJung-uk Kim #endif
607e71b7053SJung-uk Kim                 s->shutdown |= SSL_RECEIVED_SHUTDOWN;
608e71b7053SJung-uk Kim                 return 0;
609e71b7053SJung-uk Kim             }
610e71b7053SJung-uk Kim         } else if (alert_level == SSL3_AL_FATAL) {
611e71b7053SJung-uk Kim             s->rwstate = SSL_NOTHING;
612*b077aed3SPierre Pronchery             s->s3.fatal_alert = alert_descr;
613*b077aed3SPierre Pronchery             SSLfatal_data(s, SSL_AD_NO_ALERT,
614*b077aed3SPierre Pronchery                           SSL_AD_REASON_OFFSET + alert_descr,
615*b077aed3SPierre Pronchery                           "SSL alert number %d", alert_descr);
616e71b7053SJung-uk Kim             s->shutdown |= SSL_RECEIVED_SHUTDOWN;
617e71b7053SJung-uk Kim             SSL3_RECORD_set_read(rr);
618e71b7053SJung-uk Kim             SSL_CTX_remove_session(s->session_ctx, s->session);
619e71b7053SJung-uk Kim             return 0;
620e71b7053SJung-uk Kim         } else {
621*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE);
622e71b7053SJung-uk Kim             return -1;
623e71b7053SJung-uk Kim         }
624e71b7053SJung-uk Kim 
625e71b7053SJung-uk Kim         goto start;
626e71b7053SJung-uk Kim     }
627e71b7053SJung-uk Kim 
628e71b7053SJung-uk Kim     if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
629e71b7053SJung-uk Kim                                             * shutdown */
630e71b7053SJung-uk Kim         s->rwstate = SSL_NOTHING;
631e71b7053SJung-uk Kim         SSL3_RECORD_set_length(rr, 0);
632e71b7053SJung-uk Kim         SSL3_RECORD_set_read(rr);
633e71b7053SJung-uk Kim         return 0;
634e71b7053SJung-uk Kim     }
635e71b7053SJung-uk Kim 
636e71b7053SJung-uk Kim     if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
637e71b7053SJung-uk Kim         /*
638e71b7053SJung-uk Kim          * We can't process a CCS now, because previous handshake messages
639e71b7053SJung-uk Kim          * are still missing, so just drop it.
640e71b7053SJung-uk Kim          */
641e71b7053SJung-uk Kim         SSL3_RECORD_set_length(rr, 0);
642e71b7053SJung-uk Kim         SSL3_RECORD_set_read(rr);
643e71b7053SJung-uk Kim         goto start;
644e71b7053SJung-uk Kim     }
645e71b7053SJung-uk Kim 
646e71b7053SJung-uk Kim     /*
647e71b7053SJung-uk Kim      * Unexpected handshake message (Client Hello, or protocol violation)
648e71b7053SJung-uk Kim      */
649e71b7053SJung-uk Kim     if ((SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) &&
650e71b7053SJung-uk Kim             !ossl_statem_get_in_handshake(s)) {
651e71b7053SJung-uk Kim         struct hm_header_st msg_hdr;
652e71b7053SJung-uk Kim 
653e71b7053SJung-uk Kim         /*
654e71b7053SJung-uk Kim          * This may just be a stale retransmit. Also sanity check that we have
655e71b7053SJung-uk Kim          * at least enough record bytes for a message header
656e71b7053SJung-uk Kim          */
657e71b7053SJung-uk Kim         if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch
658e71b7053SJung-uk Kim                 || SSL3_RECORD_get_length(rr) < DTLS1_HM_HEADER_LENGTH) {
659e71b7053SJung-uk Kim             SSL3_RECORD_set_length(rr, 0);
660e71b7053SJung-uk Kim             SSL3_RECORD_set_read(rr);
661e71b7053SJung-uk Kim             goto start;
662e71b7053SJung-uk Kim         }
663e71b7053SJung-uk Kim 
664e71b7053SJung-uk Kim         dtls1_get_message_header(rr->data, &msg_hdr);
665e71b7053SJung-uk Kim 
666e71b7053SJung-uk Kim         /*
667e71b7053SJung-uk Kim          * If we are server, we may have a repeated FINISHED of the client
668e71b7053SJung-uk Kim          * here, then retransmit our CCS and FINISHED.
669e71b7053SJung-uk Kim          */
670e71b7053SJung-uk Kim         if (msg_hdr.type == SSL3_MT_FINISHED) {
671e71b7053SJung-uk Kim             if (dtls1_check_timeout_num(s) < 0) {
672e71b7053SJung-uk Kim                 /* SSLfatal) already called */
673e71b7053SJung-uk Kim                 return -1;
674e71b7053SJung-uk Kim             }
675e71b7053SJung-uk Kim 
676e71b7053SJung-uk Kim             if (dtls1_retransmit_buffered_messages(s) <= 0) {
677e71b7053SJung-uk Kim                 /* Fail if we encountered a fatal error */
678e71b7053SJung-uk Kim                 if (ossl_statem_in_error(s))
679e71b7053SJung-uk Kim                     return -1;
680e71b7053SJung-uk Kim             }
681e71b7053SJung-uk Kim             SSL3_RECORD_set_length(rr, 0);
682e71b7053SJung-uk Kim             SSL3_RECORD_set_read(rr);
683e71b7053SJung-uk Kim             if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
684e71b7053SJung-uk Kim                 if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
685e71b7053SJung-uk Kim                     /* no read-ahead left? */
686e71b7053SJung-uk Kim                     BIO *bio;
687e71b7053SJung-uk Kim 
688e71b7053SJung-uk Kim                     s->rwstate = SSL_READING;
689e71b7053SJung-uk Kim                     bio = SSL_get_rbio(s);
690e71b7053SJung-uk Kim                     BIO_clear_retry_flags(bio);
691e71b7053SJung-uk Kim                     BIO_set_retry_read(bio);
692e71b7053SJung-uk Kim                     return -1;
693e71b7053SJung-uk Kim                 }
694e71b7053SJung-uk Kim             }
695e71b7053SJung-uk Kim             goto start;
696e71b7053SJung-uk Kim         }
697e71b7053SJung-uk Kim 
698e71b7053SJung-uk Kim         /*
699e71b7053SJung-uk Kim          * To get here we must be trying to read app data but found handshake
700e71b7053SJung-uk Kim          * data. But if we're trying to read app data, and we're not in init
701e71b7053SJung-uk Kim          * (which is tested for at the top of this function) then init must be
702e71b7053SJung-uk Kim          * finished
703e71b7053SJung-uk Kim          */
704e71b7053SJung-uk Kim         if (!ossl_assert(SSL_is_init_finished(s))) {
705*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
706e71b7053SJung-uk Kim             return -1;
707e71b7053SJung-uk Kim         }
708e71b7053SJung-uk Kim 
709e71b7053SJung-uk Kim         /* We found handshake data, so we're going back into init */
710e71b7053SJung-uk Kim         ossl_statem_set_in_init(s, 1);
711e71b7053SJung-uk Kim 
712e71b7053SJung-uk Kim         i = s->handshake_func(s);
713e71b7053SJung-uk Kim         /* SSLfatal() called if appropriate */
714e71b7053SJung-uk Kim         if (i < 0)
715e71b7053SJung-uk Kim             return i;
716e71b7053SJung-uk Kim         if (i == 0)
717e71b7053SJung-uk Kim             return -1;
718e71b7053SJung-uk Kim 
719e71b7053SJung-uk Kim         if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
720e71b7053SJung-uk Kim             if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
721e71b7053SJung-uk Kim                 /* no read-ahead left? */
722e71b7053SJung-uk Kim                 BIO *bio;
723e71b7053SJung-uk Kim                 /*
724e71b7053SJung-uk Kim                  * In the case where we try to read application data, but we
725e71b7053SJung-uk Kim                  * trigger an SSL handshake, we return -1 with the retry
726e71b7053SJung-uk Kim                  * option set.  Otherwise renegotiation may cause nasty
727e71b7053SJung-uk Kim                  * problems in the blocking world
728e71b7053SJung-uk Kim                  */
729e71b7053SJung-uk Kim                 s->rwstate = SSL_READING;
730e71b7053SJung-uk Kim                 bio = SSL_get_rbio(s);
731e71b7053SJung-uk Kim                 BIO_clear_retry_flags(bio);
732e71b7053SJung-uk Kim                 BIO_set_retry_read(bio);
733e71b7053SJung-uk Kim                 return -1;
734e71b7053SJung-uk Kim             }
735e71b7053SJung-uk Kim         }
736e71b7053SJung-uk Kim         goto start;
737e71b7053SJung-uk Kim     }
738e71b7053SJung-uk Kim 
739e71b7053SJung-uk Kim     switch (SSL3_RECORD_get_type(rr)) {
740e71b7053SJung-uk Kim     default:
741*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD);
742e71b7053SJung-uk Kim         return -1;
743e71b7053SJung-uk Kim     case SSL3_RT_CHANGE_CIPHER_SPEC:
744e71b7053SJung-uk Kim     case SSL3_RT_ALERT:
745e71b7053SJung-uk Kim     case SSL3_RT_HANDSHAKE:
746e71b7053SJung-uk Kim         /*
747e71b7053SJung-uk Kim          * we already handled all of these, with the possible exception of
748e71b7053SJung-uk Kim          * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
749e71b7053SJung-uk Kim          * that should not happen when type != rr->type
750e71b7053SJung-uk Kim          */
751*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR);
752e71b7053SJung-uk Kim         return -1;
753e71b7053SJung-uk Kim     case SSL3_RT_APPLICATION_DATA:
754e71b7053SJung-uk Kim         /*
755e71b7053SJung-uk Kim          * At this point, we were expecting handshake data, but have
756e71b7053SJung-uk Kim          * application data.  If the library was running inside ssl3_read()
757e71b7053SJung-uk Kim          * (i.e. in_read_app_data is set) and it makes sense to read
758e71b7053SJung-uk Kim          * application data at this point (session renegotiation not yet
759e71b7053SJung-uk Kim          * started), we will indulge it.
760e71b7053SJung-uk Kim          */
761*b077aed3SPierre Pronchery         if (s->s3.in_read_app_data &&
762*b077aed3SPierre Pronchery             (s->s3.total_renegotiations != 0) &&
763e71b7053SJung-uk Kim             ossl_statem_app_data_allowed(s)) {
764*b077aed3SPierre Pronchery             s->s3.in_read_app_data = 2;
765e71b7053SJung-uk Kim             return -1;
766e71b7053SJung-uk Kim         } else {
767*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD);
768e71b7053SJung-uk Kim             return -1;
769e71b7053SJung-uk Kim         }
770e71b7053SJung-uk Kim     }
771e71b7053SJung-uk Kim     /* not reached */
772e71b7053SJung-uk Kim }
773e71b7053SJung-uk Kim 
774e71b7053SJung-uk Kim /*
775e71b7053SJung-uk Kim  * Call this to write data in records of type 'type' It will return <= 0 if
776e71b7053SJung-uk Kim  * not all data has been sent or non-blocking IO.
777e71b7053SJung-uk Kim  */
dtls1_write_bytes(SSL * s,int type,const void * buf,size_t len,size_t * written)778e71b7053SJung-uk Kim int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len,
779e71b7053SJung-uk Kim                       size_t *written)
780e71b7053SJung-uk Kim {
781e71b7053SJung-uk Kim     int i;
782e71b7053SJung-uk Kim 
783e71b7053SJung-uk Kim     if (!ossl_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH)) {
784*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
785e71b7053SJung-uk Kim         return -1;
786e71b7053SJung-uk Kim     }
787e71b7053SJung-uk Kim     s->rwstate = SSL_NOTHING;
788e71b7053SJung-uk Kim     i = do_dtls1_write(s, type, buf, len, 0, written);
789e71b7053SJung-uk Kim     return i;
790e71b7053SJung-uk Kim }
791e71b7053SJung-uk Kim 
do_dtls1_write(SSL * s,int type,const unsigned char * buf,size_t len,int create_empty_fragment,size_t * written)792e71b7053SJung-uk Kim int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
793e71b7053SJung-uk Kim                    size_t len, int create_empty_fragment, size_t *written)
794e71b7053SJung-uk Kim {
795e71b7053SJung-uk Kim     unsigned char *p, *pseq;
796e71b7053SJung-uk Kim     int i, mac_size, clear = 0;
797e71b7053SJung-uk Kim     size_t prefix_len = 0;
798e71b7053SJung-uk Kim     int eivlen;
799e71b7053SJung-uk Kim     SSL3_RECORD wr;
800e71b7053SJung-uk Kim     SSL3_BUFFER *wb;
801e71b7053SJung-uk Kim     SSL_SESSION *sess;
802e71b7053SJung-uk Kim 
803e71b7053SJung-uk Kim     wb = &s->rlayer.wbuf[0];
804e71b7053SJung-uk Kim 
805e71b7053SJung-uk Kim     /*
806c3c73b4fSJung-uk Kim      * DTLS writes whole datagrams, so there can't be anything left in
807c3c73b4fSJung-uk Kim      * the buffer.
808e71b7053SJung-uk Kim      */
809e71b7053SJung-uk Kim     if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) {
810*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
811e71b7053SJung-uk Kim         return 0;
812e71b7053SJung-uk Kim     }
813e71b7053SJung-uk Kim 
814e71b7053SJung-uk Kim     /* If we have an alert to send, lets send it */
815*b077aed3SPierre Pronchery     if (s->s3.alert_dispatch) {
816e71b7053SJung-uk Kim         i = s->method->ssl_dispatch_alert(s);
817e71b7053SJung-uk Kim         if (i <= 0)
818e71b7053SJung-uk Kim             return i;
819e71b7053SJung-uk Kim         /* if it went, fall through and send more stuff */
820e71b7053SJung-uk Kim     }
821e71b7053SJung-uk Kim 
822e71b7053SJung-uk Kim     if (len == 0 && !create_empty_fragment)
823e71b7053SJung-uk Kim         return 0;
824e71b7053SJung-uk Kim 
825e71b7053SJung-uk Kim     if (len > ssl_get_max_send_fragment(s)) {
826*b077aed3SPierre Pronchery         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
827e71b7053SJung-uk Kim         return 0;
828e71b7053SJung-uk Kim     }
829e71b7053SJung-uk Kim 
830e71b7053SJung-uk Kim     sess = s->session;
831e71b7053SJung-uk Kim 
832*b077aed3SPierre Pronchery     if ((sess == NULL)
833*b077aed3SPierre Pronchery             || (s->enc_write_ctx == NULL)
834*b077aed3SPierre Pronchery             || (EVP_MD_CTX_get0_md(s->write_hash) == NULL))
835e71b7053SJung-uk Kim         clear = 1;
836e71b7053SJung-uk Kim 
837e71b7053SJung-uk Kim     if (clear)
838e71b7053SJung-uk Kim         mac_size = 0;
839e71b7053SJung-uk Kim     else {
840*b077aed3SPierre Pronchery         mac_size = EVP_MD_CTX_get_size(s->write_hash);
841e71b7053SJung-uk Kim         if (mac_size < 0) {
842*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
843e71b7053SJung-uk Kim                      SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
844e71b7053SJung-uk Kim             return -1;
845e71b7053SJung-uk Kim         }
846e71b7053SJung-uk Kim     }
847e71b7053SJung-uk Kim 
848e71b7053SJung-uk Kim     p = SSL3_BUFFER_get_buf(wb) + prefix_len;
849e71b7053SJung-uk Kim 
850e71b7053SJung-uk Kim     /* write the header */
851e71b7053SJung-uk Kim 
852e71b7053SJung-uk Kim     *(p++) = type & 0xff;
853e71b7053SJung-uk Kim     SSL3_RECORD_set_type(&wr, type);
854e71b7053SJung-uk Kim     /*
855e71b7053SJung-uk Kim      * Special case: for hello verify request, client version 1.0 and we
856e71b7053SJung-uk Kim      * haven't decided which version to use yet send back using version 1.0
857e71b7053SJung-uk Kim      * header: otherwise some clients will ignore it.
858e71b7053SJung-uk Kim      */
859e71b7053SJung-uk Kim     if (s->method->version == DTLS_ANY_VERSION &&
860e71b7053SJung-uk Kim         s->max_proto_version != DTLS1_BAD_VER) {
861e71b7053SJung-uk Kim         *(p++) = DTLS1_VERSION >> 8;
862e71b7053SJung-uk Kim         *(p++) = DTLS1_VERSION & 0xff;
863e71b7053SJung-uk Kim     } else {
864e71b7053SJung-uk Kim         *(p++) = s->version >> 8;
865e71b7053SJung-uk Kim         *(p++) = s->version & 0xff;
866e71b7053SJung-uk Kim     }
867e71b7053SJung-uk Kim 
868e71b7053SJung-uk Kim     /* field where we are to write out packet epoch, seq num and len */
869e71b7053SJung-uk Kim     pseq = p;
870e71b7053SJung-uk Kim     p += 10;
871e71b7053SJung-uk Kim 
872e71b7053SJung-uk Kim     /* Explicit IV length, block ciphers appropriate version flag */
873e71b7053SJung-uk Kim     if (s->enc_write_ctx) {
874*b077aed3SPierre Pronchery         int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx);
875e71b7053SJung-uk Kim         if (mode == EVP_CIPH_CBC_MODE) {
876*b077aed3SPierre Pronchery             eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx);
877*b077aed3SPierre Pronchery             if (eivlen < 0) {
878*b077aed3SPierre Pronchery                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG);
879*b077aed3SPierre Pronchery                 return -1;
880*b077aed3SPierre Pronchery             }
881e71b7053SJung-uk Kim             if (eivlen <= 1)
882e71b7053SJung-uk Kim                 eivlen = 0;
883e71b7053SJung-uk Kim         }
884e71b7053SJung-uk Kim         /* Need explicit part of IV for GCM mode */
885e71b7053SJung-uk Kim         else if (mode == EVP_CIPH_GCM_MODE)
886e71b7053SJung-uk Kim             eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
887e71b7053SJung-uk Kim         else if (mode == EVP_CIPH_CCM_MODE)
888e71b7053SJung-uk Kim             eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
889e71b7053SJung-uk Kim         else
890e71b7053SJung-uk Kim             eivlen = 0;
891e71b7053SJung-uk Kim     } else
892e71b7053SJung-uk Kim         eivlen = 0;
893e71b7053SJung-uk Kim 
894e71b7053SJung-uk Kim     /* lets setup the record stuff. */
895e71b7053SJung-uk Kim     SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */
896e71b7053SJung-uk Kim     SSL3_RECORD_set_length(&wr, len);
897e71b7053SJung-uk Kim     SSL3_RECORD_set_input(&wr, (unsigned char *)buf);
898e71b7053SJung-uk Kim 
899e71b7053SJung-uk Kim     /*
900e71b7053SJung-uk Kim      * we now 'read' from wr.input, wr.length bytes into wr.data
901e71b7053SJung-uk Kim      */
902e71b7053SJung-uk Kim 
903e71b7053SJung-uk Kim     /* first we compress */
904e71b7053SJung-uk Kim     if (s->compress != NULL) {
905e71b7053SJung-uk Kim         if (!ssl3_do_compress(s, &wr)) {
906*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE);
907e71b7053SJung-uk Kim             return -1;
908e71b7053SJung-uk Kim         }
909e71b7053SJung-uk Kim     } else {
910e71b7053SJung-uk Kim         memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr),
911e71b7053SJung-uk Kim                SSL3_RECORD_get_length(&wr));
912e71b7053SJung-uk Kim         SSL3_RECORD_reset_input(&wr);
913e71b7053SJung-uk Kim     }
914e71b7053SJung-uk Kim 
915e71b7053SJung-uk Kim     /*
916e71b7053SJung-uk Kim      * we should still have the output to wr.data and the input from
917e71b7053SJung-uk Kim      * wr.input.  Length should be wr.length. wr.data still points in the
918e71b7053SJung-uk Kim      * wb->buf
919e71b7053SJung-uk Kim      */
920e71b7053SJung-uk Kim 
921e71b7053SJung-uk Kim     if (!SSL_WRITE_ETM(s) && mac_size != 0) {
922e71b7053SJung-uk Kim         if (!s->method->ssl3_enc->mac(s, &wr,
923e71b7053SJung-uk Kim                                       &(p[SSL3_RECORD_get_length(&wr) + eivlen]),
924e71b7053SJung-uk Kim                                       1)) {
925*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
926e71b7053SJung-uk Kim             return -1;
927e71b7053SJung-uk Kim         }
928e71b7053SJung-uk Kim         SSL3_RECORD_add_length(&wr, mac_size);
929e71b7053SJung-uk Kim     }
930e71b7053SJung-uk Kim 
931e71b7053SJung-uk Kim     /* this is true regardless of mac size */
932e71b7053SJung-uk Kim     SSL3_RECORD_set_data(&wr, p);
933e71b7053SJung-uk Kim     SSL3_RECORD_reset_input(&wr);
934e71b7053SJung-uk Kim 
935e71b7053SJung-uk Kim     if (eivlen)
936e71b7053SJung-uk Kim         SSL3_RECORD_add_length(&wr, eivlen);
937e71b7053SJung-uk Kim 
938*b077aed3SPierre Pronchery     if (s->method->ssl3_enc->enc(s, &wr, 1, 1, NULL, mac_size) < 1) {
939e71b7053SJung-uk Kim         if (!ossl_statem_in_error(s)) {
940*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
941e71b7053SJung-uk Kim         }
942e71b7053SJung-uk Kim         return -1;
943e71b7053SJung-uk Kim     }
944e71b7053SJung-uk Kim 
945e71b7053SJung-uk Kim     if (SSL_WRITE_ETM(s) && mac_size != 0) {
946e71b7053SJung-uk Kim         if (!s->method->ssl3_enc->mac(s, &wr,
947e71b7053SJung-uk Kim                                       &(p[SSL3_RECORD_get_length(&wr)]), 1)) {
948*b077aed3SPierre Pronchery             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
949e71b7053SJung-uk Kim             return -1;
950e71b7053SJung-uk Kim         }
951e71b7053SJung-uk Kim         SSL3_RECORD_add_length(&wr, mac_size);
952e71b7053SJung-uk Kim     }
953e71b7053SJung-uk Kim 
954e71b7053SJung-uk Kim     /* record length after mac and block padding */
955e71b7053SJung-uk Kim 
956e71b7053SJung-uk Kim     /* there's only one epoch between handshake and app data */
957e71b7053SJung-uk Kim 
958e71b7053SJung-uk Kim     s2n(s->rlayer.d->w_epoch, pseq);
959e71b7053SJung-uk Kim 
960e71b7053SJung-uk Kim     memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
961e71b7053SJung-uk Kim     pseq += 6;
962e71b7053SJung-uk Kim     s2n(SSL3_RECORD_get_length(&wr), pseq);
963e71b7053SJung-uk Kim 
964e71b7053SJung-uk Kim     if (s->msg_callback)
965e71b7053SJung-uk Kim         s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
966e71b7053SJung-uk Kim                         DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
967e71b7053SJung-uk Kim 
968e71b7053SJung-uk Kim     /*
969e71b7053SJung-uk Kim      * we should now have wr.data pointing to the encrypted data, which is
970e71b7053SJung-uk Kim      * wr->length long
971e71b7053SJung-uk Kim      */
972e71b7053SJung-uk Kim     SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */
973e71b7053SJung-uk Kim     SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH);
974e71b7053SJung-uk Kim 
975e71b7053SJung-uk Kim     ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));
976e71b7053SJung-uk Kim 
977e71b7053SJung-uk Kim     if (create_empty_fragment) {
978e71b7053SJung-uk Kim         /*
979e71b7053SJung-uk Kim          * we are in a recursive call; just return the length, don't write
980e71b7053SJung-uk Kim          * out anything here
981e71b7053SJung-uk Kim          */
982e71b7053SJung-uk Kim         *written = wr.length;
983e71b7053SJung-uk Kim         return 1;
984e71b7053SJung-uk Kim     }
985e71b7053SJung-uk Kim 
986e71b7053SJung-uk Kim     /* now let's set up wb */
987e71b7053SJung-uk Kim     SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr));
988e71b7053SJung-uk Kim     SSL3_BUFFER_set_offset(wb, 0);
989e71b7053SJung-uk Kim 
990e71b7053SJung-uk Kim     /*
991e71b7053SJung-uk Kim      * memorize arguments so that ssl3_write_pending can detect bad write
992e71b7053SJung-uk Kim      * retries later
993e71b7053SJung-uk Kim      */
994e71b7053SJung-uk Kim     s->rlayer.wpend_tot = len;
995e71b7053SJung-uk Kim     s->rlayer.wpend_buf = buf;
996e71b7053SJung-uk Kim     s->rlayer.wpend_type = type;
997e71b7053SJung-uk Kim     s->rlayer.wpend_ret = len;
998e71b7053SJung-uk Kim 
999e71b7053SJung-uk Kim     /* we now just need to write the buffer. Calls SSLfatal() as required. */
1000e71b7053SJung-uk Kim     return ssl3_write_pending(s, type, buf, len, written);
1001e71b7053SJung-uk Kim }
1002e71b7053SJung-uk Kim 
dtls1_get_bitmap(SSL * s,SSL3_RECORD * rr,unsigned int * is_next_epoch)1003e71b7053SJung-uk Kim DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
1004e71b7053SJung-uk Kim                                unsigned int *is_next_epoch)
1005e71b7053SJung-uk Kim {
1006e71b7053SJung-uk Kim 
1007e71b7053SJung-uk Kim     *is_next_epoch = 0;
1008e71b7053SJung-uk Kim 
1009e71b7053SJung-uk Kim     /* In current epoch, accept HM, CCS, DATA, & ALERT */
1010e71b7053SJung-uk Kim     if (rr->epoch == s->rlayer.d->r_epoch)
1011e71b7053SJung-uk Kim         return &s->rlayer.d->bitmap;
1012e71b7053SJung-uk Kim 
1013e71b7053SJung-uk Kim     /*
1014*b077aed3SPierre Pronchery      * We can only handle messages from the next epoch if we have already
1015*b077aed3SPierre Pronchery      * processed all of the unprocessed records from the previous epoch
1016e71b7053SJung-uk Kim      */
1017*b077aed3SPierre Pronchery     else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1)
1018*b077aed3SPierre Pronchery              && s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch) {
1019e71b7053SJung-uk Kim         *is_next_epoch = 1;
1020e71b7053SJung-uk Kim         return &s->rlayer.d->next_bitmap;
1021e71b7053SJung-uk Kim     }
1022e71b7053SJung-uk Kim 
1023e71b7053SJung-uk Kim     return NULL;
1024e71b7053SJung-uk Kim }
1025e71b7053SJung-uk Kim 
dtls1_reset_seq_numbers(SSL * s,int rw)1026e71b7053SJung-uk Kim void dtls1_reset_seq_numbers(SSL *s, int rw)
1027e71b7053SJung-uk Kim {
1028e71b7053SJung-uk Kim     unsigned char *seq;
1029e71b7053SJung-uk Kim     unsigned int seq_bytes = sizeof(s->rlayer.read_sequence);
1030e71b7053SJung-uk Kim 
1031e71b7053SJung-uk Kim     if (rw & SSL3_CC_READ) {
1032e71b7053SJung-uk Kim         seq = s->rlayer.read_sequence;
1033e71b7053SJung-uk Kim         s->rlayer.d->r_epoch++;
1034e71b7053SJung-uk Kim         memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap,
1035e71b7053SJung-uk Kim                sizeof(s->rlayer.d->bitmap));
1036e71b7053SJung-uk Kim         memset(&s->rlayer.d->next_bitmap, 0, sizeof(s->rlayer.d->next_bitmap));
1037e71b7053SJung-uk Kim 
1038e71b7053SJung-uk Kim         /*
1039e71b7053SJung-uk Kim          * We must not use any buffered messages received from the previous
1040e71b7053SJung-uk Kim          * epoch
1041e71b7053SJung-uk Kim          */
1042e71b7053SJung-uk Kim         dtls1_clear_received_buffer(s);
1043e71b7053SJung-uk Kim     } else {
1044e71b7053SJung-uk Kim         seq = s->rlayer.write_sequence;
1045e71b7053SJung-uk Kim         memcpy(s->rlayer.d->last_write_sequence, seq,
1046e71b7053SJung-uk Kim                sizeof(s->rlayer.write_sequence));
1047e71b7053SJung-uk Kim         s->rlayer.d->w_epoch++;
1048e71b7053SJung-uk Kim     }
1049e71b7053SJung-uk Kim 
1050e71b7053SJung-uk Kim     memset(seq, 0, seq_bytes);
1051e71b7053SJung-uk Kim }
1052