1/* $OpenBSD: d1_lib.c,v 1.64 2022/11/26 16:08:55 tb Exp $ */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 *
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
19 *    distribution.
20 *
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/)"
25 *
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.
30 *
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.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 *    acknowledgment:
37 *    "This product includes software developed by the OpenSSL Project
38 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
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 * ====================================================================
53 *
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).
57 *
58 */
59
60#include <sys/types.h>
61#include <sys/socket.h>
62#include <sys/time.h>
63
64#include <netinet/in.h>
65
66#include <stdio.h>
67
68#include <openssl/objects.h>
69
70#include "dtls_local.h"
71#include "pqueue.h"
72#include "ssl_local.h"
73
74void dtls1_hm_fragment_free(hm_fragment *frag);
75
76static int dtls1_listen(SSL *s, struct sockaddr *client);
77
78int
79dtls1_new(SSL *s)
80{
81	if (!ssl3_new(s))
82		goto err;
83
84	if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL)
85		goto err;
86
87	if ((s->d1->unprocessed_rcds.q = pqueue_new()) == NULL)
88		goto err;
89	if ((s->d1->buffered_messages = pqueue_new()) == NULL)
90		goto err;
91	if ((s->d1->sent_messages = pqueue_new()) == NULL)
92		goto err;
93	if ((s->d1->buffered_app_data.q = pqueue_new()) == NULL)
94		goto err;
95
96	if (s->server)
97		s->d1->cookie_len = sizeof(s->d1->cookie);
98
99	s->method->ssl_clear(s);
100	return (1);
101
102 err:
103	dtls1_free(s);
104	return (0);
105}
106
107static void
108dtls1_drain_rcontents(pqueue queue)
109{
110	DTLS1_RCONTENT_DATA_INTERNAL *rdata;
111	pitem *item;
112
113	if (queue == NULL)
114		return;
115
116	while ((item = pqueue_pop(queue)) != NULL) {
117		rdata = (DTLS1_RCONTENT_DATA_INTERNAL *)item->data;
118		tls_content_free(rdata->rcontent);
119		free(item->data);
120		pitem_free(item);
121	}
122}
123
124static void
125dtls1_drain_records(pqueue queue)
126{
127	pitem *item;
128	DTLS1_RECORD_DATA_INTERNAL *rdata;
129
130	if (queue == NULL)
131		return;
132
133	while ((item = pqueue_pop(queue)) != NULL) {
134		rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data;
135		ssl3_release_buffer(&rdata->rbuf);
136		free(item->data);
137		pitem_free(item);
138	}
139}
140
141static void
142dtls1_drain_fragments(pqueue queue)
143{
144	pitem *item;
145
146	if (queue == NULL)
147		return;
148
149	while ((item = pqueue_pop(queue)) != NULL) {
150		dtls1_hm_fragment_free(item->data);
151		pitem_free(item);
152	}
153}
154
155static void
156dtls1_clear_queues(SSL *s)
157{
158	dtls1_drain_records(s->d1->unprocessed_rcds.q);
159	dtls1_drain_fragments(s->d1->buffered_messages);
160	dtls1_drain_fragments(s->d1->sent_messages);
161	dtls1_drain_rcontents(s->d1->buffered_app_data.q);
162}
163
164void
165dtls1_free(SSL *s)
166{
167	if (s == NULL)
168		return;
169
170	ssl3_free(s);
171
172	if (s->d1 == NULL)
173		return;
174
175	dtls1_clear_queues(s);
176
177	pqueue_free(s->d1->unprocessed_rcds.q);
178	pqueue_free(s->d1->buffered_messages);
179	pqueue_free(s->d1->sent_messages);
180	pqueue_free(s->d1->buffered_app_data.q);
181
182	freezero(s->d1, sizeof(*s->d1));
183	s->d1 = NULL;
184}
185
186void
187dtls1_clear(SSL *s)
188{
189	pqueue unprocessed_rcds;
190	pqueue buffered_messages;
191	pqueue sent_messages;
192	pqueue buffered_app_data;
193	unsigned int mtu;
194
195	if (s->d1) {
196		unprocessed_rcds = s->d1->unprocessed_rcds.q;
197		buffered_messages = s->d1->buffered_messages;
198		sent_messages = s->d1->sent_messages;
199		buffered_app_data = s->d1->buffered_app_data.q;
200		mtu = s->d1->mtu;
201
202		dtls1_clear_queues(s);
203
204		memset(s->d1, 0, sizeof(*s->d1));
205
206		s->d1->unprocessed_rcds.epoch =
207		    tls12_record_layer_read_epoch(s->rl) + 1;
208
209		if (s->server) {
210			s->d1->cookie_len = sizeof(s->d1->cookie);
211		}
212
213		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
214			s->d1->mtu = mtu;
215		}
216
217		s->d1->unprocessed_rcds.q = unprocessed_rcds;
218		s->d1->buffered_messages = buffered_messages;
219		s->d1->sent_messages = sent_messages;
220		s->d1->buffered_app_data.q = buffered_app_data;
221	}
222
223	ssl3_clear(s);
224
225	s->version = DTLS1_VERSION;
226}
227
228long
229dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
230{
231	int ret = 0;
232
233	switch (cmd) {
234	case DTLS_CTRL_GET_TIMEOUT:
235		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) {
236			ret = 1;
237		}
238		break;
239	case DTLS_CTRL_HANDLE_TIMEOUT:
240		ret = dtls1_handle_timeout(s);
241		break;
242	case DTLS_CTRL_LISTEN:
243		ret = dtls1_listen(s, parg);
244		break;
245
246	default:
247		ret = ssl3_ctrl(s, cmd, larg, parg);
248		break;
249	}
250	return (ret);
251}
252
253/*
254 * As it's impossible to use stream ciphers in "datagram" mode, this
255 * simple filter is designed to disengage them in DTLS. Unfortunately
256 * there is no universal way to identify stream SSL_CIPHER, so we have
257 * to explicitly list their SSL_* codes. Currently RC4 is the only one
258 * available, but if new ones emerge, they will have to be added...
259 */
260const SSL_CIPHER *
261dtls1_get_cipher(unsigned int u)
262{
263	const SSL_CIPHER *cipher;
264
265	if ((cipher = ssl3_get_cipher(u)) == NULL)
266		return NULL;
267
268	if (cipher->algorithm_enc == SSL_RC4)
269		return NULL;
270
271	return cipher;
272}
273
274void
275dtls1_start_timer(SSL *s)
276{
277
278	/* If timer is not set, initialize duration with 1 second */
279	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
280		s->d1->timeout_duration = 1;
281	}
282
283	/* Set timeout to current time */
284	gettimeofday(&(s->d1->next_timeout), NULL);
285
286	/* Add duration to current time */
287	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
288	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
289	    &s->d1->next_timeout);
290}
291
292struct timeval*
293dtls1_get_timeout(SSL *s, struct timeval* timeleft)
294{
295	struct timeval timenow;
296
297	/* If no timeout is set, just return NULL */
298	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
299		return NULL;
300	}
301
302	/* Get current time */
303	gettimeofday(&timenow, NULL);
304
305	/* If timer already expired, set remaining time to 0 */
306	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
307	    (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
308	     s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
309		memset(timeleft, 0, sizeof(struct timeval));
310		return timeleft;
311	}
312
313	/* Calculate time left until timer expires */
314	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
315	timeleft->tv_sec -= timenow.tv_sec;
316	timeleft->tv_usec -= timenow.tv_usec;
317	if (timeleft->tv_usec < 0) {
318		timeleft->tv_sec--;
319		timeleft->tv_usec += 1000000;
320	}
321
322	/* If remaining time is less than 15 ms, set it to 0
323	 * to prevent issues because of small devergences with
324	 * socket timeouts.
325	 */
326	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
327		memset(timeleft, 0, sizeof(struct timeval));
328	}
329
330
331	return timeleft;
332}
333
334int
335dtls1_is_timer_expired(SSL *s)
336{
337	struct timeval timeleft;
338
339	/* Get time left until timeout, return false if no timer running */
340	if (dtls1_get_timeout(s, &timeleft) == NULL) {
341		return 0;
342	}
343
344	/* Return false if timer is not expired yet */
345	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
346		return 0;
347	}
348
349	/* Timer expired, so return true */
350	return 1;
351}
352
353void
354dtls1_double_timeout(SSL *s)
355{
356	s->d1->timeout_duration *= 2;
357	if (s->d1->timeout_duration > 60)
358		s->d1->timeout_duration = 60;
359	dtls1_start_timer(s);
360}
361
362void
363dtls1_stop_timer(SSL *s)
364{
365	/* Reset everything */
366	memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
367	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
368	s->d1->timeout_duration = 1;
369	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
370	    &(s->d1->next_timeout));
371	/* Clear retransmission buffer */
372	dtls1_clear_record_buffer(s);
373}
374
375int
376dtls1_check_timeout_num(SSL *s)
377{
378	s->d1->timeout.num_alerts++;
379
380	/* Reduce MTU after 2 unsuccessful retransmissions */
381	if (s->d1->timeout.num_alerts > 2) {
382		s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
383		    BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
384
385	}
386
387	if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
388		/* fail the connection, enough alerts have been sent */
389		SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED);
390		return -1;
391	}
392
393	return 0;
394}
395
396int
397dtls1_handle_timeout(SSL *s)
398{
399	/* if no timer is expired, don't do anything */
400	if (!dtls1_is_timer_expired(s)) {
401		return 0;
402	}
403
404	dtls1_double_timeout(s);
405
406	if (dtls1_check_timeout_num(s) < 0)
407		return -1;
408
409	s->d1->timeout.read_timeouts++;
410	if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
411		s->d1->timeout.read_timeouts = 1;
412	}
413
414	dtls1_start_timer(s);
415	return dtls1_retransmit_buffered_messages(s);
416}
417
418int
419dtls1_listen(SSL *s, struct sockaddr *client)
420{
421	int ret;
422
423	/* Ensure there is no state left over from a previous invocation */
424	SSL_clear(s);
425
426	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
427	s->d1->listen = 1;
428
429	ret = SSL_accept(s);
430	if (ret <= 0)
431		return ret;
432
433	(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
434	return 1;
435}
436