xref: /dragonfly/crypto/libressl/ssl/d1_lib.c (revision 6f5ec8b5)
1 /* $OpenBSD: d1_lib.c,v 1.61 2021/10/23 13:36:03 jsing 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_locl.h"
71 #include "pqueue.h"
72 #include "ssl_locl.h"
73 
74 void dtls1_hm_fragment_free(hm_fragment *frag);
75 
76 static int dtls1_listen(SSL *s, struct sockaddr *client);
77 
78 int
79 dtls1_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 
107 static void
108 dtls1_drain_records(pqueue queue)
109 {
110 	pitem *item;
111 	DTLS1_RECORD_DATA_INTERNAL *rdata;
112 
113 	if (queue == NULL)
114 		return;
115 
116 	while ((item = pqueue_pop(queue)) != NULL) {
117 		rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data;
118 		ssl3_release_buffer(&rdata->rbuf);
119 		free(item->data);
120 		pitem_free(item);
121 	}
122 }
123 
124 static void
125 dtls1_drain_fragments(pqueue queue)
126 {
127 	pitem *item;
128 
129 	if (queue == NULL)
130 		return;
131 
132 	while ((item = pqueue_pop(queue)) != NULL) {
133 		dtls1_hm_fragment_free(item->data);
134 		pitem_free(item);
135 	}
136 }
137 
138 static void
139 dtls1_clear_queues(SSL *s)
140 {
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);
145 }
146 
147 void
148 dtls1_free(SSL *s)
149 {
150 	if (s == NULL)
151 		return;
152 
153 	ssl3_free(s);
154 
155 	if (s->d1 == NULL)
156 		return;
157 
158 	dtls1_clear_queues(s);
159 
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);
164 
165 	freezero(s->d1, sizeof(*s->d1));
166 	s->d1 = NULL;
167 }
168 
169 void
170 dtls1_clear(SSL *s)
171 {
172 	pqueue unprocessed_rcds;
173 	pqueue buffered_messages;
174 	pqueue sent_messages;
175 	pqueue buffered_app_data;
176 	unsigned int mtu;
177 
178 	if (s->d1) {
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;
183 		mtu = s->d1->mtu;
184 
185 		dtls1_clear_queues(s);
186 
187 		memset(s->d1, 0, sizeof(*s->d1));
188 
189 		s->d1->unprocessed_rcds.epoch =
190 		    tls12_record_layer_read_epoch(s->internal->rl) + 1;
191 
192 		if (s->server) {
193 			s->d1->cookie_len = sizeof(s->d1->cookie);
194 		}
195 
196 		if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
197 			s->d1->mtu = mtu;
198 		}
199 
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;
204 	}
205 
206 	ssl3_clear(s);
207 
208 	s->version = DTLS1_VERSION;
209 }
210 
211 long
212 dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
213 {
214 	int ret = 0;
215 
216 	switch (cmd) {
217 	case DTLS_CTRL_GET_TIMEOUT:
218 		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) {
219 			ret = 1;
220 		}
221 		break;
222 	case DTLS_CTRL_HANDLE_TIMEOUT:
223 		ret = dtls1_handle_timeout(s);
224 		break;
225 	case DTLS_CTRL_LISTEN:
226 		ret = dtls1_listen(s, parg);
227 		break;
228 
229 	default:
230 		ret = ssl3_ctrl(s, cmd, larg, parg);
231 		break;
232 	}
233 	return (ret);
234 }
235 
236 /*
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...
242  */
243 const SSL_CIPHER *
244 dtls1_get_cipher(unsigned int u)
245 {
246 	const SSL_CIPHER *cipher;
247 
248 	if ((cipher = ssl3_get_cipher(u)) == NULL)
249 		return NULL;
250 
251 	if (cipher->algorithm_enc == SSL_RC4)
252 		return NULL;
253 
254 	return cipher;
255 }
256 
257 void
258 dtls1_start_timer(SSL *s)
259 {
260 
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;
264 	}
265 
266 	/* Set timeout to current time */
267 	gettimeofday(&(s->d1->next_timeout), NULL);
268 
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);
273 }
274 
275 struct timeval*
276 dtls1_get_timeout(SSL *s, struct timeval* timeleft)
277 {
278 	struct timeval timenow;
279 
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) {
282 		return NULL;
283 	}
284 
285 	/* Get current time */
286 	gettimeofday(&timenow, NULL);
287 
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));
293 		return timeleft;
294 	}
295 
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) {
301 		timeleft->tv_sec--;
302 		timeleft->tv_usec += 1000000;
303 	}
304 
305 	/* If remaining time is less than 15 ms, set it to 0
306 	 * to prevent issues because of small devergences with
307 	 * socket timeouts.
308 	 */
309 	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
310 		memset(timeleft, 0, sizeof(struct timeval));
311 	}
312 
313 
314 	return timeleft;
315 }
316 
317 int
318 dtls1_is_timer_expired(SSL *s)
319 {
320 	struct timeval timeleft;
321 
322 	/* Get time left until timeout, return false if no timer running */
323 	if (dtls1_get_timeout(s, &timeleft) == NULL) {
324 		return 0;
325 	}
326 
327 	/* Return false if timer is not expired yet */
328 	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
329 		return 0;
330 	}
331 
332 	/* Timer expired, so return true */
333 	return 1;
334 }
335 
336 void
337 dtls1_double_timeout(SSL *s)
338 {
339 	s->d1->timeout_duration *= 2;
340 	if (s->d1->timeout_duration > 60)
341 		s->d1->timeout_duration = 60;
342 	dtls1_start_timer(s);
343 }
344 
345 void
346 dtls1_stop_timer(SSL *s)
347 {
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);
356 }
357 
358 int
359 dtls1_check_timeout_num(SSL *s)
360 {
361 	s->d1->timeout.num_alerts++;
362 
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);
367 
368 	}
369 
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);
373 		return -1;
374 	}
375 
376 	return 0;
377 }
378 
379 int
380 dtls1_handle_timeout(SSL *s)
381 {
382 	/* if no timer is expired, don't do anything */
383 	if (!dtls1_is_timer_expired(s)) {
384 		return 0;
385 	}
386 
387 	dtls1_double_timeout(s);
388 
389 	if (dtls1_check_timeout_num(s) < 0)
390 		return -1;
391 
392 	s->d1->timeout.read_timeouts++;
393 	if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
394 		s->d1->timeout.read_timeouts = 1;
395 	}
396 
397 	dtls1_start_timer(s);
398 	return dtls1_retransmit_buffered_messages(s);
399 }
400 
401 int
402 dtls1_listen(SSL *s, struct sockaddr *client)
403 {
404 	int ret;
405 
406 	/* Ensure there is no state left over from a previous invocation */
407 	SSL_clear(s);
408 
409 	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
410 	s->d1->listen = 1;
411 
412 	ret = SSL_accept(s);
413 	if (ret <= 0)
414 		return ret;
415 
416 	(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
417 	return 1;
418 }
419