xref: /dragonfly/crypto/libressl/ssl/d1_lib.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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
dtls1_new(SSL * s)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
dtls1_drain_records(pqueue queue)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
dtls1_drain_fragments(pqueue queue)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
dtls1_clear_queues(SSL * s)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
dtls1_free(SSL * s)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
dtls1_clear(SSL * s)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
dtls1_ctrl(SSL * s,int cmd,long larg,void * parg)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 *
dtls1_get_cipher(unsigned int u)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
dtls1_start_timer(SSL * s)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*
dtls1_get_timeout(SSL * s,struct timeval * timeleft)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
dtls1_is_timer_expired(SSL * s)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
dtls1_double_timeout(SSL * s)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
dtls1_stop_timer(SSL * s)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
dtls1_check_timeout_num(SSL * s)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
dtls1_handle_timeout(SSL * s)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
dtls1_listen(SSL * s,struct sockaddr * client)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