1 /* $OpenBSD: d1_lib.c,v 1.61 2021/10/23 13:36:03 jsing Exp $ */
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
6 /* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
60 #include <sys/types.h>
61 #include <sys/socket.h>
64 #include <netinet/in.h>
68 #include <openssl/objects.h>
70 #include "dtls_locl.h"
74 void dtls1_hm_fragment_free(hm_fragment
*frag
);
76 static int dtls1_listen(SSL
*s
, struct sockaddr
*client
);
84 if ((s
->d1
= calloc(1, sizeof(*s
->d1
))) == NULL
)
87 if ((s
->d1
->unprocessed_rcds
.q
= pqueue_new()) == NULL
)
89 if ((s
->d1
->buffered_messages
= pqueue_new()) == NULL
)
91 if ((s
->d1
->sent_messages
= pqueue_new()) == NULL
)
93 if ((s
->d1
->buffered_app_data
.q
= pqueue_new()) == NULL
)
97 s
->d1
->cookie_len
= sizeof(s
->d1
->cookie
);
99 s
->method
->ssl_clear(s
);
108 dtls1_drain_records(pqueue queue
)
111 DTLS1_RECORD_DATA_INTERNAL
*rdata
;
116 while ((item
= pqueue_pop(queue
)) != NULL
) {
117 rdata
= (DTLS1_RECORD_DATA_INTERNAL
*)item
->data
;
118 ssl3_release_buffer(&rdata
->rbuf
);
125 dtls1_drain_fragments(pqueue queue
)
132 while ((item
= pqueue_pop(queue
)) != NULL
) {
133 dtls1_hm_fragment_free(item
->data
);
139 dtls1_clear_queues(SSL
*s
)
141 dtls1_drain_records(s
->d1
->unprocessed_rcds
.q
);
142 dtls1_drain_fragments(s
->d1
->buffered_messages
);
143 dtls1_drain_fragments(s
->d1
->sent_messages
);
144 dtls1_drain_records(s
->d1
->buffered_app_data
.q
);
158 dtls1_clear_queues(s
);
160 pqueue_free(s
->d1
->unprocessed_rcds
.q
);
161 pqueue_free(s
->d1
->buffered_messages
);
162 pqueue_free(s
->d1
->sent_messages
);
163 pqueue_free(s
->d1
->buffered_app_data
.q
);
165 freezero(s
->d1
, sizeof(*s
->d1
));
172 pqueue unprocessed_rcds
;
173 pqueue buffered_messages
;
174 pqueue sent_messages
;
175 pqueue buffered_app_data
;
179 unprocessed_rcds
= s
->d1
->unprocessed_rcds
.q
;
180 buffered_messages
= s
->d1
->buffered_messages
;
181 sent_messages
= s
->d1
->sent_messages
;
182 buffered_app_data
= s
->d1
->buffered_app_data
.q
;
185 dtls1_clear_queues(s
);
187 memset(s
->d1
, 0, sizeof(*s
->d1
));
189 s
->d1
->unprocessed_rcds
.epoch
=
190 tls12_record_layer_read_epoch(s
->internal
->rl
) + 1;
193 s
->d1
->cookie_len
= sizeof(s
->d1
->cookie
);
196 if (SSL_get_options(s
) & SSL_OP_NO_QUERY_MTU
) {
200 s
->d1
->unprocessed_rcds
.q
= unprocessed_rcds
;
201 s
->d1
->buffered_messages
= buffered_messages
;
202 s
->d1
->sent_messages
= sent_messages
;
203 s
->d1
->buffered_app_data
.q
= buffered_app_data
;
208 s
->version
= DTLS1_VERSION
;
212 dtls1_ctrl(SSL
*s
, int cmd
, long larg
, void *parg
)
217 case DTLS_CTRL_GET_TIMEOUT
:
218 if (dtls1_get_timeout(s
, (struct timeval
*) parg
) != NULL
) {
222 case DTLS_CTRL_HANDLE_TIMEOUT
:
223 ret
= dtls1_handle_timeout(s
);
225 case DTLS_CTRL_LISTEN
:
226 ret
= dtls1_listen(s
, parg
);
230 ret
= ssl3_ctrl(s
, cmd
, larg
, parg
);
237 * As it's impossible to use stream ciphers in "datagram" mode, this
238 * simple filter is designed to disengage them in DTLS. Unfortunately
239 * there is no universal way to identify stream SSL_CIPHER, so we have
240 * to explicitly list their SSL_* codes. Currently RC4 is the only one
241 * available, but if new ones emerge, they will have to be added...
244 dtls1_get_cipher(unsigned int u
)
246 const SSL_CIPHER
*cipher
;
248 if ((cipher
= ssl3_get_cipher(u
)) == NULL
)
251 if (cipher
->algorithm_enc
== SSL_RC4
)
258 dtls1_start_timer(SSL
*s
)
261 /* If timer is not set, initialize duration with 1 second */
262 if (s
->d1
->next_timeout
.tv_sec
== 0 && s
->d1
->next_timeout
.tv_usec
== 0) {
263 s
->d1
->timeout_duration
= 1;
266 /* Set timeout to current time */
267 gettimeofday(&(s
->d1
->next_timeout
), NULL
);
269 /* Add duration to current time */
270 s
->d1
->next_timeout
.tv_sec
+= s
->d1
->timeout_duration
;
271 BIO_ctrl(SSL_get_rbio(s
), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
, 0,
272 &s
->d1
->next_timeout
);
276 dtls1_get_timeout(SSL
*s
, struct timeval
* timeleft
)
278 struct timeval timenow
;
280 /* If no timeout is set, just return NULL */
281 if (s
->d1
->next_timeout
.tv_sec
== 0 && s
->d1
->next_timeout
.tv_usec
== 0) {
285 /* Get current time */
286 gettimeofday(&timenow
, NULL
);
288 /* If timer already expired, set remaining time to 0 */
289 if (s
->d1
->next_timeout
.tv_sec
< timenow
.tv_sec
||
290 (s
->d1
->next_timeout
.tv_sec
== timenow
.tv_sec
&&
291 s
->d1
->next_timeout
.tv_usec
<= timenow
.tv_usec
)) {
292 memset(timeleft
, 0, sizeof(struct timeval
));
296 /* Calculate time left until timer expires */
297 memcpy(timeleft
, &(s
->d1
->next_timeout
), sizeof(struct timeval
));
298 timeleft
->tv_sec
-= timenow
.tv_sec
;
299 timeleft
->tv_usec
-= timenow
.tv_usec
;
300 if (timeleft
->tv_usec
< 0) {
302 timeleft
->tv_usec
+= 1000000;
305 /* If remaining time is less than 15 ms, set it to 0
306 * to prevent issues because of small devergences with
309 if (timeleft
->tv_sec
== 0 && timeleft
->tv_usec
< 15000) {
310 memset(timeleft
, 0, sizeof(struct timeval
));
318 dtls1_is_timer_expired(SSL
*s
)
320 struct timeval timeleft
;
322 /* Get time left until timeout, return false if no timer running */
323 if (dtls1_get_timeout(s
, &timeleft
) == NULL
) {
327 /* Return false if timer is not expired yet */
328 if (timeleft
.tv_sec
> 0 || timeleft
.tv_usec
> 0) {
332 /* Timer expired, so return true */
337 dtls1_double_timeout(SSL
*s
)
339 s
->d1
->timeout_duration
*= 2;
340 if (s
->d1
->timeout_duration
> 60)
341 s
->d1
->timeout_duration
= 60;
342 dtls1_start_timer(s
);
346 dtls1_stop_timer(SSL
*s
)
348 /* Reset everything */
349 memset(&(s
->d1
->timeout
), 0, sizeof(struct dtls1_timeout_st
));
350 memset(&(s
->d1
->next_timeout
), 0, sizeof(struct timeval
));
351 s
->d1
->timeout_duration
= 1;
352 BIO_ctrl(SSL_get_rbio(s
), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT
, 0,
353 &(s
->d1
->next_timeout
));
354 /* Clear retransmission buffer */
355 dtls1_clear_record_buffer(s
);
359 dtls1_check_timeout_num(SSL
*s
)
361 s
->d1
->timeout
.num_alerts
++;
363 /* Reduce MTU after 2 unsuccessful retransmissions */
364 if (s
->d1
->timeout
.num_alerts
> 2) {
365 s
->d1
->mtu
= BIO_ctrl(SSL_get_wbio(s
),
366 BIO_CTRL_DGRAM_GET_FALLBACK_MTU
, 0, NULL
);
370 if (s
->d1
->timeout
.num_alerts
> DTLS1_TMO_ALERT_COUNT
) {
371 /* fail the connection, enough alerts have been sent */
372 SSLerror(s
, SSL_R_READ_TIMEOUT_EXPIRED
);
380 dtls1_handle_timeout(SSL
*s
)
382 /* if no timer is expired, don't do anything */
383 if (!dtls1_is_timer_expired(s
)) {
387 dtls1_double_timeout(s
);
389 if (dtls1_check_timeout_num(s
) < 0)
392 s
->d1
->timeout
.read_timeouts
++;
393 if (s
->d1
->timeout
.read_timeouts
> DTLS1_TMO_READ_COUNT
) {
394 s
->d1
->timeout
.read_timeouts
= 1;
397 dtls1_start_timer(s
);
398 return dtls1_retransmit_buffered_messages(s
);
402 dtls1_listen(SSL
*s
, struct sockaddr
*client
)
406 /* Ensure there is no state left over from a previous invocation */
409 SSL_set_options(s
, SSL_OP_COOKIE_EXCHANGE
);
416 (void)BIO_dgram_get_peer(SSL_get_rbio(s
), client
);