1 |
|
|
/* $OpenBSD: d1_lib.c,v 1.42 2017/04/10 17:27:33 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 "pqueue.h" |
71 |
|
|
#include "ssl_locl.h" |
72 |
|
|
|
73 |
|
|
static int dtls1_listen(SSL *s, struct sockaddr *client); |
74 |
|
|
|
75 |
|
|
SSL3_ENC_METHOD DTLSv1_enc_data = { |
76 |
|
|
.enc = dtls1_enc, |
77 |
|
|
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV, |
78 |
|
|
}; |
79 |
|
|
|
80 |
|
|
long |
81 |
|
|
dtls1_default_timeout(void) |
82 |
|
|
{ |
83 |
|
|
/* 2 hours, the 24 hours mentioned in the DTLSv1 spec |
84 |
|
|
* is way too long for http, the cache would over fill */ |
85 |
|
250 |
return (60*60*2); |
86 |
|
|
} |
87 |
|
|
|
88 |
|
|
int |
89 |
|
|
dtls1_new(SSL *s) |
90 |
|
|
{ |
91 |
|
|
DTLS1_STATE *d1; |
92 |
|
|
|
93 |
✗✓ |
250 |
if (!ssl3_new(s)) |
94 |
|
|
return (0); |
95 |
✗✓ |
125 |
if ((d1 = calloc(1, sizeof(*d1))) == NULL) { |
96 |
|
|
ssl3_free(s); |
97 |
|
|
return (0); |
98 |
|
|
} |
99 |
✗✓ |
125 |
if ((d1->internal = calloc(1, sizeof(*d1->internal))) == NULL) { |
100 |
|
|
free(d1); |
101 |
|
|
ssl3_free(s); |
102 |
|
|
return (0); |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
/* d1->handshake_epoch=0; */ |
106 |
|
|
|
107 |
|
125 |
d1->internal->unprocessed_rcds.q = pqueue_new(); |
108 |
|
125 |
d1->internal->processed_rcds.q = pqueue_new(); |
109 |
|
125 |
d1->internal->buffered_messages = pqueue_new(); |
110 |
|
125 |
d1->sent_messages = pqueue_new(); |
111 |
|
125 |
d1->internal->buffered_app_data.q = pqueue_new(); |
112 |
|
|
|
113 |
✗✓ |
125 |
if (s->server) { |
114 |
|
|
d1->internal->cookie_len = sizeof(D1I(s)->cookie); |
115 |
|
|
} |
116 |
|
|
|
117 |
✓✗✓✗ ✗✓ |
375 |
if (!d1->internal->unprocessed_rcds.q || !d1->internal->processed_rcds.q || |
118 |
✓✗✓✗
|
250 |
!d1->internal->buffered_messages || !d1->sent_messages || |
119 |
|
125 |
!d1->internal->buffered_app_data.q) { |
120 |
|
|
pqueue_free(d1->internal->unprocessed_rcds.q); |
121 |
|
|
pqueue_free(d1->internal->processed_rcds.q); |
122 |
|
|
pqueue_free(d1->internal->buffered_messages); |
123 |
|
|
pqueue_free(d1->sent_messages); |
124 |
|
|
pqueue_free(d1->internal->buffered_app_data.q); |
125 |
|
|
free(d1); |
126 |
|
|
ssl3_free(s); |
127 |
|
|
return (0); |
128 |
|
|
} |
129 |
|
|
|
130 |
|
125 |
s->d1 = d1; |
131 |
|
125 |
s->method->internal->ssl_clear(s); |
132 |
|
125 |
return (1); |
133 |
|
125 |
} |
134 |
|
|
|
135 |
|
|
static void |
136 |
|
|
dtls1_clear_queues(SSL *s) |
137 |
|
|
{ |
138 |
|
|
pitem *item = NULL; |
139 |
|
|
hm_fragment *frag = NULL; |
140 |
|
|
DTLS1_RECORD_DATA *rdata; |
141 |
|
|
|
142 |
✗✓ |
1422 |
while ((item = pqueue_pop(D1I(s)->unprocessed_rcds.q)) != NULL) { |
143 |
|
|
rdata = (DTLS1_RECORD_DATA *) item->data; |
144 |
|
|
free(rdata->rbuf.buf); |
145 |
|
|
free(item->data); |
146 |
|
|
pitem_free(item); |
147 |
|
|
} |
148 |
|
|
|
149 |
✗✓ |
474 |
while ((item = pqueue_pop(D1I(s)->processed_rcds.q)) != NULL) { |
150 |
|
|
rdata = (DTLS1_RECORD_DATA *) item->data; |
151 |
|
|
free(rdata->rbuf.buf); |
152 |
|
|
free(item->data); |
153 |
|
|
pitem_free(item); |
154 |
|
|
} |
155 |
|
|
|
156 |
✗✓ |
474 |
while ((item = pqueue_pop(D1I(s)->buffered_messages)) != NULL) { |
157 |
|
|
frag = (hm_fragment *)item->data; |
158 |
|
|
free(frag->fragment); |
159 |
|
|
free(frag); |
160 |
|
|
pitem_free(item); |
161 |
|
|
} |
162 |
|
|
|
163 |
✓✓ |
770 |
while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { |
164 |
|
148 |
frag = (hm_fragment *)item->data; |
165 |
|
148 |
free(frag->fragment); |
166 |
|
148 |
free(frag); |
167 |
|
148 |
pitem_free(item); |
168 |
|
|
} |
169 |
|
|
|
170 |
✗✓ |
474 |
while ((item = pqueue_pop(D1I(s)->buffered_app_data.q)) != NULL) { |
171 |
|
|
rdata = (DTLS1_RECORD_DATA *) item->data; |
172 |
|
|
free(rdata->rbuf.buf); |
173 |
|
|
free(item->data); |
174 |
|
|
pitem_free(item); |
175 |
|
|
} |
176 |
|
474 |
} |
177 |
|
|
|
178 |
|
|
void |
179 |
|
|
dtls1_free(SSL *s) |
180 |
|
|
{ |
181 |
✓✗ |
248 |
if (s == NULL) |
182 |
|
|
return; |
183 |
|
|
|
184 |
|
124 |
ssl3_free(s); |
185 |
|
|
|
186 |
|
124 |
dtls1_clear_queues(s); |
187 |
|
|
|
188 |
|
124 |
pqueue_free(D1I(s)->unprocessed_rcds.q); |
189 |
|
124 |
pqueue_free(D1I(s)->processed_rcds.q); |
190 |
|
124 |
pqueue_free(D1I(s)->buffered_messages); |
191 |
|
124 |
pqueue_free(s->d1->sent_messages); |
192 |
|
124 |
pqueue_free(D1I(s)->buffered_app_data.q); |
193 |
|
|
|
194 |
|
124 |
freezero(s->d1->internal, sizeof(*s->d1->internal)); |
195 |
|
124 |
freezero(s->d1, sizeof(*s->d1)); |
196 |
|
|
|
197 |
|
124 |
s->d1 = NULL; |
198 |
|
248 |
} |
199 |
|
|
|
200 |
|
|
void |
201 |
|
|
dtls1_clear(SSL *s) |
202 |
|
|
{ |
203 |
|
|
struct dtls1_state_internal_st *internal; |
204 |
|
|
pqueue unprocessed_rcds; |
205 |
|
|
pqueue processed_rcds; |
206 |
|
|
pqueue buffered_messages; |
207 |
|
|
pqueue sent_messages; |
208 |
|
|
pqueue buffered_app_data; |
209 |
|
|
unsigned int mtu; |
210 |
|
|
|
211 |
✓✓ |
950 |
if (s->d1) { |
212 |
|
350 |
unprocessed_rcds = D1I(s)->unprocessed_rcds.q; |
213 |
|
350 |
processed_rcds = D1I(s)->processed_rcds.q; |
214 |
|
350 |
buffered_messages = D1I(s)->buffered_messages; |
215 |
|
350 |
sent_messages = s->d1->sent_messages; |
216 |
|
350 |
buffered_app_data = D1I(s)->buffered_app_data.q; |
217 |
|
350 |
mtu = D1I(s)->mtu; |
218 |
|
|
|
219 |
|
350 |
dtls1_clear_queues(s); |
220 |
|
|
|
221 |
|
350 |
memset(s->d1->internal, 0, sizeof(*s->d1->internal)); |
222 |
|
350 |
internal = s->d1->internal; |
223 |
|
350 |
memset(s->d1, 0, sizeof(*s->d1)); |
224 |
|
350 |
s->d1->internal = internal; |
225 |
|
|
|
226 |
✓✓ |
350 |
if (s->server) { |
227 |
|
157 |
D1I(s)->cookie_len = sizeof(D1I(s)->cookie); |
228 |
|
157 |
} |
229 |
|
|
|
230 |
✗✓ |
350 |
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { |
231 |
|
|
D1I(s)->mtu = mtu; |
232 |
|
|
} |
233 |
|
|
|
234 |
|
350 |
D1I(s)->unprocessed_rcds.q = unprocessed_rcds; |
235 |
|
350 |
D1I(s)->processed_rcds.q = processed_rcds; |
236 |
|
350 |
D1I(s)->buffered_messages = buffered_messages; |
237 |
|
350 |
s->d1->sent_messages = sent_messages; |
238 |
|
350 |
D1I(s)->buffered_app_data.q = buffered_app_data; |
239 |
|
350 |
} |
240 |
|
|
|
241 |
|
475 |
ssl3_clear(s); |
242 |
|
|
|
243 |
|
475 |
s->version = DTLS1_VERSION; |
244 |
|
475 |
} |
245 |
|
|
|
246 |
|
|
long |
247 |
|
|
dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) |
248 |
|
|
{ |
249 |
|
|
int ret = 0; |
250 |
|
|
|
251 |
|
|
switch (cmd) { |
252 |
|
|
case DTLS_CTRL_GET_TIMEOUT: |
253 |
|
|
if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) { |
254 |
|
|
ret = 1; |
255 |
|
|
} |
256 |
|
|
break; |
257 |
|
|
case DTLS_CTRL_HANDLE_TIMEOUT: |
258 |
|
|
ret = dtls1_handle_timeout(s); |
259 |
|
|
break; |
260 |
|
|
case DTLS_CTRL_LISTEN: |
261 |
|
|
ret = dtls1_listen(s, parg); |
262 |
|
|
break; |
263 |
|
|
|
264 |
|
|
default: |
265 |
|
|
ret = ssl3_ctrl(s, cmd, larg, parg); |
266 |
|
|
break; |
267 |
|
|
} |
268 |
|
|
return (ret); |
269 |
|
|
} |
270 |
|
|
|
271 |
|
|
/* |
272 |
|
|
* As it's impossible to use stream ciphers in "datagram" mode, this |
273 |
|
|
* simple filter is designed to disengage them in DTLS. Unfortunately |
274 |
|
|
* there is no universal way to identify stream SSL_CIPHER, so we have |
275 |
|
|
* to explicitly list their SSL_* codes. Currently RC4 is the only one |
276 |
|
|
* available, but if new ones emerge, they will have to be added... |
277 |
|
|
*/ |
278 |
|
|
const SSL_CIPHER * |
279 |
|
|
dtls1_get_cipher(unsigned int u) |
280 |
|
|
{ |
281 |
|
27216 |
const SSL_CIPHER *ciph = ssl3_get_cipher(u); |
282 |
|
|
|
283 |
✓✗ |
13608 |
if (ciph != NULL) { |
284 |
✓✓ |
13608 |
if (ciph->algorithm_enc == SSL_RC4) |
285 |
|
1134 |
return NULL; |
286 |
|
|
} |
287 |
|
|
|
288 |
|
12474 |
return ciph; |
289 |
|
13608 |
} |
290 |
|
|
|
291 |
|
|
void |
292 |
|
|
dtls1_start_timer(SSL *s) |
293 |
|
|
{ |
294 |
|
|
|
295 |
|
|
/* If timer is not set, initialize duration with 1 second */ |
296 |
✓✓✓✗
|
908 |
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { |
297 |
|
148 |
s->d1->timeout_duration = 1; |
298 |
|
148 |
} |
299 |
|
|
|
300 |
|
|
/* Set timeout to current time */ |
301 |
|
380 |
gettimeofday(&(s->d1->next_timeout), NULL); |
302 |
|
|
|
303 |
|
|
/* Add duration to current time */ |
304 |
|
380 |
s->d1->next_timeout.tv_sec += s->d1->timeout_duration; |
305 |
|
760 |
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, |
306 |
|
380 |
&s->d1->next_timeout); |
307 |
|
380 |
} |
308 |
|
|
|
309 |
|
|
struct timeval* |
310 |
|
|
dtls1_get_timeout(SSL *s, struct timeval* timeleft) |
311 |
|
|
{ |
312 |
|
2944 |
struct timeval timenow; |
313 |
|
|
|
314 |
|
|
/* If no timeout is set, just return NULL */ |
315 |
✓✓✓✗
|
1864 |
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { |
316 |
|
392 |
return NULL; |
317 |
|
|
} |
318 |
|
|
|
319 |
|
|
/* Get current time */ |
320 |
|
1080 |
gettimeofday(&timenow, NULL); |
321 |
|
|
|
322 |
|
|
/* If timer already expired, set remaining time to 0 */ |
323 |
✓✗✗✗
|
1080 |
if (s->d1->next_timeout.tv_sec < timenow.tv_sec || |
324 |
✗✓ |
1080 |
(s->d1->next_timeout.tv_sec == timenow.tv_sec && |
325 |
|
|
s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { |
326 |
|
|
memset(timeleft, 0, sizeof(struct timeval)); |
327 |
|
|
return timeleft; |
328 |
|
|
} |
329 |
|
|
|
330 |
|
|
/* Calculate time left until timer expires */ |
331 |
|
1080 |
memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); |
332 |
|
1080 |
timeleft->tv_sec -= timenow.tv_sec; |
333 |
|
1080 |
timeleft->tv_usec -= timenow.tv_usec; |
334 |
✓✓ |
1080 |
if (timeleft->tv_usec < 0) { |
335 |
|
1050 |
timeleft->tv_sec--; |
336 |
|
1050 |
timeleft->tv_usec += 1000000; |
337 |
|
1050 |
} |
338 |
|
|
|
339 |
|
|
/* If remaining time is less than 15 ms, set it to 0 |
340 |
|
|
* to prevent issues because of small devergences with |
341 |
|
|
* socket timeouts. |
342 |
|
|
*/ |
343 |
✓✓✗✓
|
2130 |
if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { |
344 |
|
|
memset(timeleft, 0, sizeof(struct timeval)); |
345 |
|
|
} |
346 |
|
|
|
347 |
|
|
|
348 |
|
1080 |
return timeleft; |
349 |
|
1472 |
} |
350 |
|
|
|
351 |
|
|
int |
352 |
|
|
dtls1_is_timer_expired(SSL *s) |
353 |
|
|
{ |
354 |
|
2944 |
struct timeval timeleft; |
355 |
|
|
|
356 |
|
|
/* Get time left until timeout, return false if no timer running */ |
357 |
✓✓ |
1472 |
if (dtls1_get_timeout(s, &timeleft) == NULL) { |
358 |
|
392 |
return 0; |
359 |
|
|
} |
360 |
|
|
|
361 |
|
|
/* Return false if timer is not expired yet */ |
362 |
✓✓✓✗
|
2130 |
if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { |
363 |
|
1080 |
return 0; |
364 |
|
|
} |
365 |
|
|
|
366 |
|
|
/* Timer expired, so return true */ |
367 |
|
|
return 1; |
368 |
|
1472 |
} |
369 |
|
|
|
370 |
|
|
void |
371 |
|
|
dtls1_double_timeout(SSL *s) |
372 |
|
|
{ |
373 |
|
|
s->d1->timeout_duration *= 2; |
374 |
|
|
if (s->d1->timeout_duration > 60) |
375 |
|
|
s->d1->timeout_duration = 60; |
376 |
|
|
dtls1_start_timer(s); |
377 |
|
|
} |
378 |
|
|
|
379 |
|
|
void |
380 |
|
|
dtls1_stop_timer(SSL *s) |
381 |
|
|
{ |
382 |
|
|
/* Reset everything */ |
383 |
|
480 |
memset(&(D1I(s)->timeout), 0, sizeof(struct dtls1_timeout_st)); |
384 |
|
240 |
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); |
385 |
|
240 |
s->d1->timeout_duration = 1; |
386 |
|
480 |
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, |
387 |
|
240 |
&(s->d1->next_timeout)); |
388 |
|
|
/* Clear retransmission buffer */ |
389 |
|
240 |
dtls1_clear_record_buffer(s); |
390 |
|
240 |
} |
391 |
|
|
|
392 |
|
|
int |
393 |
|
|
dtls1_check_timeout_num(SSL *s) |
394 |
|
|
{ |
395 |
|
|
D1I(s)->timeout.num_alerts++; |
396 |
|
|
|
397 |
|
|
/* Reduce MTU after 2 unsuccessful retransmissions */ |
398 |
|
|
if (D1I(s)->timeout.num_alerts > 2) { |
399 |
|
|
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s), |
400 |
|
|
BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); |
401 |
|
|
|
402 |
|
|
} |
403 |
|
|
|
404 |
|
|
if (D1I(s)->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { |
405 |
|
|
/* fail the connection, enough alerts have been sent */ |
406 |
|
|
SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED); |
407 |
|
|
return -1; |
408 |
|
|
} |
409 |
|
|
|
410 |
|
|
return 0; |
411 |
|
|
} |
412 |
|
|
|
413 |
|
|
int |
414 |
|
|
dtls1_handle_timeout(SSL *s) |
415 |
|
|
{ |
416 |
|
|
/* if no timer is expired, don't do anything */ |
417 |
✓✗ |
2552 |
if (!dtls1_is_timer_expired(s)) { |
418 |
|
1276 |
return 0; |
419 |
|
|
} |
420 |
|
|
|
421 |
|
|
dtls1_double_timeout(s); |
422 |
|
|
|
423 |
|
|
if (dtls1_check_timeout_num(s) < 0) |
424 |
|
|
return -1; |
425 |
|
|
|
426 |
|
|
D1I(s)->timeout.read_timeouts++; |
427 |
|
|
if (D1I(s)->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { |
428 |
|
|
D1I(s)->timeout.read_timeouts = 1; |
429 |
|
|
} |
430 |
|
|
|
431 |
|
|
dtls1_start_timer(s); |
432 |
|
|
return dtls1_retransmit_buffered_messages(s); |
433 |
|
1276 |
} |
434 |
|
|
|
435 |
|
|
int |
436 |
|
|
dtls1_listen(SSL *s, struct sockaddr *client) |
437 |
|
|
{ |
438 |
|
|
int ret; |
439 |
|
|
|
440 |
|
|
/* Ensure there is no state left over from a previous invocation */ |
441 |
|
|
SSL_clear(s); |
442 |
|
|
|
443 |
|
|
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); |
444 |
|
|
D1I(s)->listen = 1; |
445 |
|
|
|
446 |
|
|
ret = SSL_accept(s); |
447 |
|
|
if (ret <= 0) |
448 |
|
|
return ret; |
449 |
|
|
|
450 |
|
|
(void)BIO_dgram_get_peer(SSL_get_rbio(s), client); |
451 |
|
|
return 1; |
452 |
|
|
} |
453 |
|
|
|
454 |
|
|
void |
455 |
|
|
dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq, |
456 |
|
|
unsigned short epoch) |
457 |
|
|
{ |
458 |
|
960 |
unsigned char dtlsseq[SSL3_SEQUENCE_SIZE]; |
459 |
|
|
unsigned char *p; |
460 |
|
|
|
461 |
|
|
p = dtlsseq; |
462 |
|
480 |
s2n(epoch, p); |
463 |
|
480 |
memcpy(p, &seq[2], SSL3_SEQUENCE_SIZE - 2); |
464 |
|
480 |
memcpy(dst, dtlsseq, SSL3_SEQUENCE_SIZE); |
465 |
|
480 |
} |