]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
36d16f8e | 2 | * DTLS implementation written by Nagendra Modadugu |
0f113f3e | 3 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
36d16f8e BL |
4 | */ |
5 | /* ==================================================================== | |
6 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
0f113f3e | 13 | * notice, this list of conditions and the following disclaimer. |
36d16f8e BL |
14 | * |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * openssl-core@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <stdio.h> | |
9289f21b | 60 | #define USE_SOCKETS |
36d16f8e | 61 | #include <openssl/objects.h> |
8ba708e5 | 62 | #include <openssl/rand.h> |
36d16f8e BL |
63 | #include "ssl_locl.h" |
64 | ||
a006fef7 | 65 | #if defined(OPENSSL_SYS_VMS) |
0f113f3e | 66 | # include <sys/timeb.h> |
fb456902 MC |
67 | #elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) |
68 | # include <sys/timeval.h> | |
69 | #elif defined(OPENSSL_SYS_VXWORKS) | |
70 | # include <sys/times.h> | |
71 | #elif !defined(OPENSSL_SYS_WIN32) | |
72 | # include <sys/time.h> | |
eb38b26d DSH |
73 | #endif |
74 | ||
75 | static void get_current_time(struct timeval *t); | |
77d514c5 | 76 | static int dtls1_set_handshake_header(SSL *s, int type, unsigned long len); |
173e72e6 | 77 | static int dtls1_handshake_write(SSL *s); |
1fc3ac80 | 78 | int dtls1_listen(SSL *s, struct sockaddr *client); |
3616bb63 | 79 | static unsigned int dtls1_link_min_mtu(void); |
36d16f8e | 80 | |
8ba708e5 MC |
81 | /* XDTLS: figure out the right values */ |
82 | static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; | |
83 | ||
0f113f3e MC |
84 | const SSL3_ENC_METHOD DTLSv1_enc_data = { |
85 | tls1_enc, | |
86 | tls1_mac, | |
87 | tls1_setup_key_block, | |
88 | tls1_generate_master_secret, | |
89 | tls1_change_cipher_state, | |
90 | tls1_final_finish_mac, | |
91 | TLS1_FINISH_MAC_LENGTH, | |
0f113f3e MC |
92 | TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, |
93 | TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, | |
94 | tls1_alert_code, | |
95 | tls1_export_keying_material, | |
96 | SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV, | |
97 | DTLS1_HM_HEADER_LENGTH, | |
98 | dtls1_set_handshake_header, | |
99 | dtls1_handshake_write | |
100 | }; | |
101 | ||
102 | const SSL3_ENC_METHOD DTLSv1_2_enc_data = { | |
103 | tls1_enc, | |
104 | tls1_mac, | |
105 | tls1_setup_key_block, | |
106 | tls1_generate_master_secret, | |
107 | tls1_change_cipher_state, | |
108 | tls1_final_finish_mac, | |
109 | TLS1_FINISH_MAC_LENGTH, | |
0f113f3e MC |
110 | TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, |
111 | TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, | |
112 | tls1_alert_code, | |
113 | tls1_export_keying_material, | |
114 | SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | |
115 | | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS, | |
116 | DTLS1_HM_HEADER_LENGTH, | |
117 | dtls1_set_handshake_header, | |
118 | dtls1_handshake_write | |
119 | }; | |
c3b344e3 | 120 | |
f3b656b2 | 121 | long dtls1_default_timeout(void) |
0f113f3e MC |
122 | { |
123 | /* | |
124 | * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for | |
125 | * http, the cache would over fill | |
126 | */ | |
127 | return (60 * 60 * 2); | |
128 | } | |
36d16f8e | 129 | |
36d16f8e | 130 | int dtls1_new(SSL *s) |
0f113f3e MC |
131 | { |
132 | DTLS1_STATE *d1; | |
133 | ||
61986d32 | 134 | if (!DTLS_RECORD_LAYER_new(&s->rlayer)) { |
5fb6f80c MC |
135 | return 0; |
136 | } | |
137 | ||
0f113f3e MC |
138 | if (!ssl3_new(s)) |
139 | return (0); | |
b51bce94 | 140 | if ((d1 = OPENSSL_zalloc(sizeof(*d1))) == NULL) { |
0f113f3e MC |
141 | ssl3_free(s); |
142 | return (0); | |
143 | } | |
0f113f3e | 144 | |
0f113f3e MC |
145 | d1->buffered_messages = pqueue_new(); |
146 | d1->sent_messages = pqueue_new(); | |
0f113f3e MC |
147 | |
148 | if (s->server) { | |
149 | d1->cookie_len = sizeof(s->d1->cookie); | |
150 | } | |
151 | ||
152 | d1->link_mtu = 0; | |
153 | d1->mtu = 0; | |
154 | ||
a71edf3b | 155 | if (d1->buffered_messages == NULL || d1->sent_messages == NULL) { |
25aaa98a RS |
156 | pqueue_free(d1->buffered_messages); |
157 | pqueue_free(d1->sent_messages); | |
0f113f3e MC |
158 | OPENSSL_free(d1); |
159 | ssl3_free(s); | |
160 | return (0); | |
161 | } | |
162 | ||
163 | s->d1 = d1; | |
164 | s->method->ssl_clear(s); | |
165 | return (1); | |
166 | } | |
36d16f8e | 167 | |
7832d6ab | 168 | static void dtls1_clear_queues(SSL *s) |
0f113f3e | 169 | { |
36d16f8e BL |
170 | pitem *item = NULL; |
171 | hm_fragment *frag = NULL; | |
0f113f3e | 172 | |
0f113f3e | 173 | while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { |
36d16f8e | 174 | frag = (hm_fragment *)item->data; |
8a35dbb6 | 175 | dtls1_hm_fragment_free(frag); |
36d16f8e | 176 | pitem_free(item); |
0f113f3e | 177 | } |
36d16f8e | 178 | |
0f113f3e | 179 | while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { |
36d16f8e | 180 | frag = (hm_fragment *)item->data; |
8a35dbb6 | 181 | dtls1_hm_fragment_free(frag); |
36d16f8e | 182 | pitem_free(item); |
0f113f3e | 183 | } |
0f113f3e | 184 | } |
7832d6ab DSH |
185 | |
186 | void dtls1_free(SSL *s) | |
0f113f3e | 187 | { |
40f37188 MC |
188 | DTLS_RECORD_LAYER_free(&s->rlayer); |
189 | ||
0f113f3e | 190 | ssl3_free(s); |
7832d6ab | 191 | |
0f113f3e | 192 | dtls1_clear_queues(s); |
7832d6ab | 193 | |
7832d6ab | 194 | pqueue_free(s->d1->buffered_messages); |
0f113f3e | 195 | pqueue_free(s->d1->sent_messages); |
e5fa864f | 196 | |
0f113f3e MC |
197 | OPENSSL_free(s->d1); |
198 | s->d1 = NULL; | |
199 | } | |
36d16f8e BL |
200 | |
201 | void dtls1_clear(SSL *s) | |
0f113f3e | 202 | { |
cf2cede4 RS |
203 | pqueue *buffered_messages; |
204 | pqueue *sent_messages; | |
0f113f3e MC |
205 | unsigned int mtu; |
206 | unsigned int link_mtu; | |
207 | ||
40f37188 MC |
208 | DTLS_RECORD_LAYER_clear(&s->rlayer); |
209 | ||
0f113f3e | 210 | if (s->d1) { |
0f113f3e MC |
211 | buffered_messages = s->d1->buffered_messages; |
212 | sent_messages = s->d1->sent_messages; | |
0f113f3e MC |
213 | mtu = s->d1->mtu; |
214 | link_mtu = s->d1->link_mtu; | |
215 | ||
216 | dtls1_clear_queues(s); | |
217 | ||
16f8d4eb | 218 | memset(s->d1, 0, sizeof(*s->d1)); |
0f113f3e MC |
219 | |
220 | if (s->server) { | |
221 | s->d1->cookie_len = sizeof(s->d1->cookie); | |
222 | } | |
223 | ||
224 | if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { | |
225 | s->d1->mtu = mtu; | |
226 | s->d1->link_mtu = link_mtu; | |
227 | } | |
228 | ||
0f113f3e MC |
229 | s->d1->buffered_messages = buffered_messages; |
230 | s->d1->sent_messages = sent_messages; | |
0f113f3e MC |
231 | } |
232 | ||
233 | ssl3_clear(s); | |
234 | if (s->options & SSL_OP_CISCO_ANYCONNECT) | |
f7683aaf | 235 | s->client_version = s->version = DTLS1_BAD_VER; |
0f113f3e | 236 | else if (s->method->version == DTLS_ANY_VERSION) |
4fa52141 | 237 | s->version = DTLS_MAX_VERSION; |
0f113f3e MC |
238 | else |
239 | s->version = s->method->version; | |
240 | } | |
5d58f1bb | 241 | |
b972fbaa | 242 | long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) |
0f113f3e MC |
243 | { |
244 | int ret = 0; | |
245 | ||
246 | switch (cmd) { | |
247 | case DTLS_CTRL_GET_TIMEOUT: | |
248 | if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { | |
249 | ret = 1; | |
250 | } | |
251 | break; | |
252 | case DTLS_CTRL_HANDLE_TIMEOUT: | |
253 | ret = dtls1_handle_timeout(s); | |
254 | break; | |
255 | case DTLS_CTRL_LISTEN: | |
256 | ret = dtls1_listen(s, parg); | |
257 | break; | |
0f113f3e MC |
258 | case DTLS_CTRL_SET_LINK_MTU: |
259 | if (larg < (long)dtls1_link_min_mtu()) | |
260 | return 0; | |
261 | s->d1->link_mtu = larg; | |
262 | return 1; | |
263 | case DTLS_CTRL_GET_LINK_MIN_MTU: | |
264 | return (long)dtls1_link_min_mtu(); | |
265 | case SSL_CTRL_SET_MTU: | |
266 | /* | |
267 | * We may not have a BIO set yet so can't call dtls1_min_mtu() | |
268 | * We'll have to make do with dtls1_link_min_mtu() and max overhead | |
269 | */ | |
270 | if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) | |
271 | return 0; | |
272 | s->d1->mtu = larg; | |
273 | return larg; | |
274 | default: | |
275 | ret = ssl3_ctrl(s, cmd, larg, parg); | |
276 | break; | |
277 | } | |
278 | return (ret); | |
279 | } | |
b972fbaa | 280 | |
5d58f1bb AP |
281 | /* |
282 | * As it's impossible to use stream ciphers in "datagram" mode, this | |
283 | * simple filter is designed to disengage them in DTLS. Unfortunately | |
284 | * there is no universal way to identify stream SSL_CIPHER, so we have | |
285 | * to explicitly list their SSL_* codes. Currently RC4 is the only one | |
286 | * available, but if new ones emerge, they will have to be added... | |
287 | */ | |
babb3798 | 288 | const SSL_CIPHER *dtls1_get_cipher(unsigned int u) |
0f113f3e MC |
289 | { |
290 | const SSL_CIPHER *ciph = ssl3_get_cipher(u); | |
5d58f1bb | 291 | |
0f113f3e MC |
292 | if (ciph != NULL) { |
293 | if (ciph->algorithm_enc == SSL_RC4) | |
294 | return NULL; | |
295 | } | |
5d58f1bb | 296 | |
0f113f3e MC |
297 | return ciph; |
298 | } | |
eb38b26d DSH |
299 | |
300 | void dtls1_start_timer(SSL *s) | |
0f113f3e | 301 | { |
7e159e01 | 302 | #ifndef OPENSSL_NO_SCTP |
0f113f3e MC |
303 | /* Disable timer for SCTP */ |
304 | if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { | |
16f8d4eb | 305 | memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); |
0f113f3e MC |
306 | return; |
307 | } | |
7e159e01 DSH |
308 | #endif |
309 | ||
0f113f3e MC |
310 | /* If timer is not set, initialize duration with 1 second */ |
311 | if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { | |
312 | s->d1->timeout_duration = 1; | |
313 | } | |
314 | ||
315 | /* Set timeout to current time */ | |
316 | get_current_time(&(s->d1->next_timeout)); | |
317 | ||
318 | /* Add duration to current time */ | |
319 | s->d1->next_timeout.tv_sec += s->d1->timeout_duration; | |
320 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, | |
321 | &(s->d1->next_timeout)); | |
322 | } | |
323 | ||
324 | struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) | |
325 | { | |
326 | struct timeval timenow; | |
327 | ||
328 | /* If no timeout is set, just return NULL */ | |
329 | if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { | |
330 | return NULL; | |
331 | } | |
332 | ||
333 | /* Get current time */ | |
334 | get_current_time(&timenow); | |
335 | ||
336 | /* If timer already expired, set remaining time to 0 */ | |
337 | if (s->d1->next_timeout.tv_sec < timenow.tv_sec || | |
338 | (s->d1->next_timeout.tv_sec == timenow.tv_sec && | |
339 | s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { | |
16f8d4eb | 340 | memset(timeleft, 0, sizeof(*timeleft)); |
0f113f3e MC |
341 | return timeleft; |
342 | } | |
343 | ||
344 | /* Calculate time left until timer expires */ | |
345 | memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); | |
346 | timeleft->tv_sec -= timenow.tv_sec; | |
347 | timeleft->tv_usec -= timenow.tv_usec; | |
348 | if (timeleft->tv_usec < 0) { | |
349 | timeleft->tv_sec--; | |
350 | timeleft->tv_usec += 1000000; | |
351 | } | |
352 | ||
353 | /* | |
354 | * If remaining time is less than 15 ms, set it to 0 to prevent issues | |
355 | * because of small devergences with socket timeouts. | |
356 | */ | |
357 | if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { | |
16f8d4eb | 358 | memset(timeleft, 0, sizeof(*timeleft)); |
0f113f3e MC |
359 | } |
360 | ||
361 | return timeleft; | |
362 | } | |
eb38b26d DSH |
363 | |
364 | int dtls1_is_timer_expired(SSL *s) | |
0f113f3e MC |
365 | { |
366 | struct timeval timeleft; | |
eb38b26d | 367 | |
0f113f3e MC |
368 | /* Get time left until timeout, return false if no timer running */ |
369 | if (dtls1_get_timeout(s, &timeleft) == NULL) { | |
370 | return 0; | |
371 | } | |
eb38b26d | 372 | |
0f113f3e MC |
373 | /* Return false if timer is not expired yet */ |
374 | if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { | |
375 | return 0; | |
376 | } | |
eb38b26d | 377 | |
0f113f3e MC |
378 | /* Timer expired, so return true */ |
379 | return 1; | |
380 | } | |
eb38b26d DSH |
381 | |
382 | void dtls1_double_timeout(SSL *s) | |
0f113f3e MC |
383 | { |
384 | s->d1->timeout_duration *= 2; | |
385 | if (s->d1->timeout_duration > 60) | |
386 | s->d1->timeout_duration = 60; | |
387 | dtls1_start_timer(s); | |
388 | } | |
eb38b26d DSH |
389 | |
390 | void dtls1_stop_timer(SSL *s) | |
0f113f3e MC |
391 | { |
392 | /* Reset everything */ | |
16f8d4eb RS |
393 | memset(&s->d1->timeout, 0, sizeof(s->d1->timeout)); |
394 | memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); | |
0f113f3e MC |
395 | s->d1->timeout_duration = 1; |
396 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, | |
397 | &(s->d1->next_timeout)); | |
398 | /* Clear retransmission buffer */ | |
399 | dtls1_clear_record_buffer(s); | |
400 | } | |
eb38b26d | 401 | |
ea6e3860 | 402 | int dtls1_check_timeout_num(SSL *s) |
0f113f3e MC |
403 | { |
404 | unsigned int mtu; | |
405 | ||
406 | s->d1->timeout.num_alerts++; | |
407 | ||
408 | /* Reduce MTU after 2 unsuccessful retransmissions */ | |
409 | if (s->d1->timeout.num_alerts > 2 | |
410 | && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { | |
411 | mtu = | |
412 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, | |
413 | NULL); | |
414 | if (mtu < s->d1->mtu) | |
415 | s->d1->mtu = mtu; | |
416 | } | |
417 | ||
418 | if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { | |
419 | /* fail the connection, enough alerts have been sent */ | |
420 | SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); | |
421 | return -1; | |
422 | } | |
423 | ||
424 | return 0; | |
425 | } | |
ea6e3860 DSH |
426 | |
427 | int dtls1_handle_timeout(SSL *s) | |
0f113f3e MC |
428 | { |
429 | /* if no timer is expired, don't do anything */ | |
430 | if (!dtls1_is_timer_expired(s)) { | |
431 | return 0; | |
432 | } | |
ea6e3860 | 433 | |
0f113f3e | 434 | dtls1_double_timeout(s); |
ea6e3860 | 435 | |
0f113f3e MC |
436 | if (dtls1_check_timeout_num(s) < 0) |
437 | return -1; | |
62b6948a | 438 | |
0f113f3e MC |
439 | s->d1->timeout.read_timeouts++; |
440 | if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { | |
441 | s->d1->timeout.read_timeouts = 1; | |
442 | } | |
4817504d | 443 | #ifndef OPENSSL_NO_HEARTBEATS |
0f113f3e MC |
444 | if (s->tlsext_hb_pending) { |
445 | s->tlsext_hb_pending = 0; | |
446 | return dtls1_heartbeat(s); | |
447 | } | |
4817504d DSH |
448 | #endif |
449 | ||
0f113f3e MC |
450 | dtls1_start_timer(s); |
451 | return dtls1_retransmit_buffered_messages(s); | |
452 | } | |
b972fbaa | 453 | |
eb38b26d DSH |
454 | static void get_current_time(struct timeval *t) |
455 | { | |
a006fef7 | 456 | #if defined(_WIN32) |
0f113f3e MC |
457 | SYSTEMTIME st; |
458 | union { | |
459 | unsigned __int64 ul; | |
460 | FILETIME ft; | |
461 | } now; | |
462 | ||
463 | GetSystemTime(&st); | |
464 | SystemTimeToFileTime(&st, &now.ft); | |
465 | # ifdef __MINGW32__ | |
466 | now.ul -= 116444736000000000ULL; | |
467 | # else | |
d2a0d72f | 468 | now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ |
0f113f3e MC |
469 | # endif |
470 | t->tv_sec = (long)(now.ul / 10000000); | |
471 | t->tv_usec = ((int)(now.ul % 10000000)) / 10; | |
eb38b26d | 472 | #elif defined(OPENSSL_SYS_VMS) |
0f113f3e MC |
473 | struct timeb tb; |
474 | ftime(&tb); | |
475 | t->tv_sec = (long)tb.time; | |
476 | t->tv_usec = (long)tb.millitm * 1000; | |
eb38b26d | 477 | #else |
0f113f3e | 478 | gettimeofday(t, NULL); |
eb38b26d DSH |
479 | #endif |
480 | } | |
1fc3ac80 | 481 | |
e3d0dae7 MC |
482 | |
483 | #define LISTEN_SUCCESS 2 | |
484 | #define LISTEN_SEND_VERIFY_REQUEST 1 | |
485 | ||
486 | ||
1fc3ac80 | 487 | int dtls1_listen(SSL *s, struct sockaddr *client) |
0f113f3e | 488 | { |
e3d0dae7 MC |
489 | int next, n, ret = 0, clearpkt = 0; |
490 | unsigned char cookie[DTLS1_COOKIE_LENGTH]; | |
491 | unsigned char seq[SEQ_NUM_SIZE]; | |
b6981744 EK |
492 | const unsigned char *data; |
493 | unsigned char *p, *buf; | |
e3d0dae7 MC |
494 | unsigned long reclen, fragoff, fraglen, msglen; |
495 | unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen; | |
496 | BIO *rbio, *wbio; | |
497 | BUF_MEM *bufm; | |
498 | struct sockaddr_storage tmpclient; | |
499 | PACKET pkt, msgpkt, msgpayload, session, cookiepkt; | |
0f113f3e | 500 | |
e83ee04b | 501 | /* Ensure there is no state left over from a previous invocation */ |
61986d32 | 502 | if (!SSL_clear(s)) |
c7f5b5d7 | 503 | return -1; |
e83ee04b | 504 | |
e3d0dae7 MC |
505 | ERR_clear_error(); |
506 | ||
507 | rbio = SSL_get_rbio(s); | |
508 | wbio = SSL_get_wbio(s); | |
509 | ||
510 | if(!rbio || !wbio) { | |
511 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_BIO_NOT_SET); | |
512 | return -1; | |
513 | } | |
514 | ||
515 | /* | |
516 | * We only peek at incoming ClientHello's until we're sure we are going to | |
517 | * to respond with a HelloVerifyRequest. If its a ClientHello with a valid | |
aea145e3 | 518 | * cookie then we leave it in the BIO for accept to handle. |
e3d0dae7 MC |
519 | */ |
520 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL); | |
521 | ||
522 | /* | |
523 | * Note: This check deliberately excludes DTLS1_BAD_VER because that version | |
524 | * requires the MAC to be calculated *including* the first ClientHello | |
525 | * (without the cookie). Since DTLSv1_listen is stateless that cannot be | |
526 | * supported. DTLS1_BAD_VER must use cookies in a stateful manner (e.g. via | |
527 | * SSL_accept) | |
528 | */ | |
529 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { | |
530 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION); | |
531 | return -1; | |
532 | } | |
533 | ||
534 | if (s->init_buf == NULL) { | |
535 | if ((bufm = BUF_MEM_new()) == NULL) { | |
536 | SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_MALLOC_FAILURE); | |
537 | return -1; | |
538 | } | |
539 | ||
540 | if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) { | |
541 | BUF_MEM_free(bufm); | |
542 | SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_MALLOC_FAILURE); | |
543 | return -1; | |
544 | } | |
545 | s->init_buf = bufm; | |
546 | } | |
547 | buf = (unsigned char *)s->init_buf->data; | |
548 | ||
549 | do { | |
550 | /* Get a packet */ | |
551 | ||
552 | clear_sys_error(); | |
553 | /* | |
554 | * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH | |
555 | * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store | |
556 | * the record header as well, but we do here. We've set up init_buf to | |
557 | * be the standard size for simplicity. In practice we shouldn't ever | |
558 | * receive a ClientHello as long as this. If we do it will get dropped | |
559 | * in the record length check below. | |
560 | */ | |
561 | n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); | |
562 | ||
563 | if (n <= 0) { | |
564 | if(BIO_should_retry(rbio)) { | |
565 | /* Non-blocking IO */ | |
566 | goto end; | |
567 | } | |
568 | return -1; | |
569 | } | |
570 | ||
571 | /* If we hit any problems we need to clear this packet from the BIO */ | |
572 | clearpkt = 1; | |
573 | ||
574 | if (!PACKET_buf_init(&pkt, buf, n)) { | |
575 | SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); | |
576 | return -1; | |
577 | } | |
578 | ||
579 | /* | |
580 | * Parse the received record. If there are any problems with it we just | |
581 | * dump it - with no alert. RFC6347 says this "Unlike TLS, DTLS is | |
582 | * resilient in the face of invalid records (e.g., invalid formatting, | |
583 | * length, MAC, etc.). In general, invalid records SHOULD be silently | |
584 | * discarded, thus preserving the association; however, an error MAY be | |
585 | * logged for diagnostic purposes." | |
586 | */ | |
587 | ||
588 | /* this packet contained a partial record, dump it */ | |
589 | if (n < DTLS1_RT_HEADER_LENGTH) { | |
590 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_RECORD_TOO_SMALL); | |
591 | goto end; | |
592 | } | |
593 | ||
594 | if (s->msg_callback) | |
595 | s->msg_callback(0, 0, SSL3_RT_HEADER, buf, | |
596 | DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); | |
597 | ||
598 | /* Get the record header */ | |
599 | if (!PACKET_get_1(&pkt, &rectype) | |
600 | || !PACKET_get_1(&pkt, &versmajor)) { | |
601 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); | |
602 | goto end; | |
603 | } | |
604 | ||
605 | if (rectype != SSL3_RT_HANDSHAKE) { | |
606 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); | |
607 | goto end; | |
608 | } | |
609 | ||
610 | /* | |
611 | * Check record version number. We only check that the major version is | |
612 | * the same. | |
613 | */ | |
614 | if (versmajor != DTLS1_VERSION_MAJOR) { | |
615 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); | |
616 | goto end; | |
617 | } | |
618 | ||
619 | if (!PACKET_forward(&pkt, 1) | |
620 | /* Save the sequence number: 64 bits, with top 2 bytes = epoch */ | |
621 | || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE) | |
622 | || !PACKET_get_length_prefixed_2(&pkt, &msgpkt) | |
623 | || PACKET_remaining(&pkt) != 0) { | |
624 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); | |
625 | goto end; | |
626 | } | |
627 | ||
628 | /* This is an initial ClientHello so the epoch has to be 0 */ | |
629 | if (seq[0] != 0 || seq[1] != 0) { | |
630 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); | |
631 | goto end; | |
632 | } | |
633 | ||
634 | /* Get a pointer to the raw message for the later callback */ | |
635 | data = PACKET_data(&msgpkt); | |
636 | ||
637 | /* Finished processing the record header, now process the message */ | |
638 | if (!PACKET_get_1(&msgpkt, &msgtype) | |
639 | || !PACKET_get_net_3(&msgpkt, &msglen) | |
640 | || !PACKET_get_net_2(&msgpkt, &msgseq) | |
641 | || !PACKET_get_net_3(&msgpkt, &fragoff) | |
642 | || !PACKET_get_net_3(&msgpkt, &fraglen) | |
643 | || !PACKET_get_sub_packet(&msgpkt, &msgpayload, msglen) | |
644 | || PACKET_remaining(&msgpkt) != 0) { | |
645 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); | |
646 | goto end; | |
647 | } | |
648 | ||
649 | if (msgtype != SSL3_MT_CLIENT_HELLO) { | |
650 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); | |
651 | goto end; | |
652 | } | |
653 | ||
654 | /* Message sequence number can only be 0 or 1 */ | |
655 | if(msgseq > 2) { | |
656 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER); | |
657 | goto end; | |
658 | } | |
659 | ||
660 | /* We don't support a fragmented ClientHello whilst listening */ | |
661 | if (fragoff != 0 || fraglen != msglen) { | |
662 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO); | |
663 | goto end; | |
664 | } | |
665 | ||
666 | if (s->msg_callback) | |
667 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, data, | |
668 | msglen + DTLS1_HM_HEADER_LENGTH, s, | |
669 | s->msg_callback_arg); | |
670 | ||
671 | if (!PACKET_get_net_2(&msgpayload, &clientvers)) { | |
672 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); | |
673 | goto end; | |
674 | } | |
675 | ||
676 | /* | |
677 | * Verify client version is supported | |
678 | */ | |
4fa52141 VD |
679 | if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) && |
680 | s->method->version != DTLS_ANY_VERSION) { | |
e3d0dae7 MC |
681 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_WRONG_VERSION_NUMBER); |
682 | goto end; | |
683 | } | |
684 | ||
685 | if (!PACKET_forward(&msgpayload, SSL3_RANDOM_SIZE) | |
686 | || !PACKET_get_length_prefixed_1(&msgpayload, &session) | |
687 | || !PACKET_get_length_prefixed_1(&msgpayload, &cookiepkt)) { | |
688 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); | |
689 | goto end; | |
690 | } | |
691 | ||
692 | /* | |
693 | * Check if we have a cookie or not. If not we need to send a | |
694 | * HelloVerifyRequest. | |
695 | */ | |
696 | if (PACKET_remaining(&cookiepkt) == 0) { | |
697 | next = LISTEN_SEND_VERIFY_REQUEST; | |
698 | } else { | |
699 | /* | |
700 | * We have a cookie, so lets check it. | |
701 | */ | |
702 | if (s->ctx->app_verify_cookie_cb == NULL) { | |
703 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK); | |
704 | /* This is fatal */ | |
705 | return -1; | |
706 | } | |
31011544 EK |
707 | if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookiepkt), |
708 | PACKET_remaining(&cookiepkt)) == | |
709 | 0) { | |
e3d0dae7 MC |
710 | /* |
711 | * We treat invalid cookies in the same was as no cookie as | |
712 | * per RFC6347 | |
713 | */ | |
714 | next = LISTEN_SEND_VERIFY_REQUEST; | |
715 | } else { | |
716 | /* Cookie verification succeeded */ | |
717 | next = LISTEN_SUCCESS; | |
718 | } | |
719 | } | |
720 | ||
721 | if (next == LISTEN_SEND_VERIFY_REQUEST) { | |
722 | /* | |
723 | * There was no cookie in the ClientHello so we need to send a | |
724 | * HelloVerifyRequest. If this fails we do not worry about trying | |
725 | * to resend, we just drop it. | |
726 | */ | |
727 | ||
728 | /* | |
729 | * Dump the read packet, we don't need it any more. Ignore return | |
730 | * value | |
731 | */ | |
732 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL); | |
733 | BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); | |
734 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL); | |
735 | ||
736 | /* Generate the cookie */ | |
737 | if (s->ctx->app_gen_cookie_cb == NULL || | |
373dc6e1 MC |
738 | s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || |
739 | cookielen > 255) { | |
e3d0dae7 MC |
740 | SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); |
741 | /* This is fatal */ | |
742 | return -1; | |
743 | } | |
744 | ||
745 | p = &buf[DTLS1_RT_HEADER_LENGTH]; | |
8ba708e5 MC |
746 | msglen = dtls_raw_hello_verify_request(p + DTLS1_HM_HEADER_LENGTH, |
747 | cookie, cookielen); | |
e3d0dae7 MC |
748 | |
749 | *p++ = DTLS1_MT_HELLO_VERIFY_REQUEST; | |
750 | ||
751 | /* Message length */ | |
752 | l2n3(msglen, p); | |
753 | ||
754 | /* Message sequence number is always 0 for a HelloVerifyRequest */ | |
755 | s2n(0, p); | |
756 | ||
757 | /* | |
758 | * We never fragment a HelloVerifyRequest, so fragment offset is 0 | |
759 | * and fragment length is message length | |
760 | */ | |
761 | l2n3(0, p); | |
762 | l2n3(msglen, p); | |
763 | ||
764 | /* Set reclen equal to length of whole handshake message */ | |
765 | reclen = msglen + DTLS1_HM_HEADER_LENGTH; | |
766 | ||
767 | /* Add the record header */ | |
768 | p = buf; | |
769 | ||
770 | *(p++) = SSL3_RT_HANDSHAKE; | |
771 | /* | |
772 | * Special case: for hello verify request, client version 1.0 and we | |
773 | * haven't decided which version to use yet send back using version | |
774 | * 1.0 header: otherwise some clients will ignore it. | |
775 | */ | |
776 | if (s->method->version == DTLS_ANY_VERSION) { | |
777 | *(p++) = DTLS1_VERSION >> 8; | |
778 | *(p++) = DTLS1_VERSION & 0xff; | |
779 | } else { | |
780 | *(p++) = s->version >> 8; | |
781 | *(p++) = s->version & 0xff; | |
782 | } | |
783 | ||
784 | /* | |
785 | * Record sequence number is always the same as in the received | |
786 | * ClientHello | |
787 | */ | |
788 | memcpy(p, seq, SEQ_NUM_SIZE); | |
789 | p += SEQ_NUM_SIZE; | |
790 | ||
791 | /* Length */ | |
792 | s2n(reclen, p); | |
793 | ||
794 | /* | |
795 | * Set reclen equal to length of whole record including record | |
796 | * header | |
797 | */ | |
798 | reclen += DTLS1_RT_HEADER_LENGTH; | |
799 | ||
800 | if (s->msg_callback) | |
801 | s->msg_callback(1, 0, SSL3_RT_HEADER, buf, | |
802 | DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); | |
803 | ||
804 | /* | |
805 | * This is unneccessary if rbio and wbio are one and the same - but | |
806 | * maybe they're not. | |
807 | */ | |
808 | if(BIO_dgram_get_peer(rbio, &tmpclient) <= 0 | |
809 | || BIO_dgram_set_peer(wbio, &tmpclient) <= 0) { | |
810 | SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); | |
811 | goto end; | |
812 | } | |
813 | ||
814 | if (BIO_write(wbio, buf, reclen) < (int)reclen) { | |
815 | if(BIO_should_retry(wbio)) { | |
816 | /* | |
817 | * Non-blocking IO...but we're stateless, so we're just | |
818 | * going to drop this packet. | |
819 | */ | |
820 | goto end; | |
821 | } | |
822 | return -1; | |
823 | } | |
824 | ||
825 | if (BIO_flush(wbio) <= 0) { | |
826 | if(BIO_should_retry(wbio)) { | |
827 | /* | |
828 | * Non-blocking IO...but we're stateless, so we're just | |
829 | * going to drop this packet. | |
830 | */ | |
831 | goto end; | |
832 | } | |
833 | return -1; | |
834 | } | |
835 | } | |
836 | } while (next != LISTEN_SUCCESS); | |
837 | ||
838 | /* | |
839 | * Set expected sequence numbers to continue the handshake. | |
840 | */ | |
841 | s->d1->handshake_read_seq = 1; | |
842 | s->d1->handshake_write_seq = 1; | |
843 | s->d1->next_handshake_write_seq = 1; | |
844 | DTLS_RECORD_LAYER_set_write_sequence(&s->rlayer, seq); | |
845 | ||
846 | /* | |
847 | * We are doing cookie exchange, so make sure we set that option in the | |
848 | * SSL object | |
849 | */ | |
0f113f3e | 850 | SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); |
1fc3ac80 | 851 | |
31fd10e6 MC |
852 | /* |
853 | * Tell the state machine that we've done the initial hello verify | |
854 | * exchange | |
855 | */ | |
856 | ossl_statem_set_hello_verify_done(s); | |
e3d0dae7 MC |
857 | |
858 | if(BIO_dgram_get_peer(rbio, client) <= 0) { | |
859 | SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); | |
860 | return -1; | |
861 | } | |
1fc3ac80 | 862 | |
e3d0dae7 MC |
863 | ret = 1; |
864 | clearpkt = 0; | |
865 | end: | |
866 | BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL); | |
867 | if (clearpkt) { | |
868 | /* Dump this packet. Ignore return value */ | |
869 | BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH); | |
870 | } | |
871 | return ret; | |
0f113f3e | 872 | } |
173e72e6 | 873 | |
77d514c5 | 874 | static int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) |
0f113f3e MC |
875 | { |
876 | unsigned char *p = (unsigned char *)s->init_buf->data; | |
877 | dtls1_set_message_header(s, p, htype, len, 0, len); | |
878 | s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; | |
879 | s->init_off = 0; | |
880 | /* Buffer the message to handle re-xmits */ | |
77d514c5 | 881 | |
61986d32 | 882 | if (!dtls1_buffer_message(s, 0)) |
77d514c5 MC |
883 | return 0; |
884 | ||
885 | return 1; | |
0f113f3e | 886 | } |
173e72e6 DSH |
887 | |
888 | static int dtls1_handshake_write(SSL *s) | |
0f113f3e MC |
889 | { |
890 | return dtls1_do_write(s, SSL3_RT_HANDSHAKE); | |
891 | } | |
8ba708e5 MC |
892 | |
893 | #ifndef OPENSSL_NO_HEARTBEATS | |
894 | int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length) | |
895 | { | |
896 | unsigned char *pl; | |
897 | unsigned short hbtype; | |
898 | unsigned int payload; | |
899 | unsigned int padding = 16; /* Use minimum padding */ | |
900 | ||
901 | if (s->msg_callback) | |
902 | s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, | |
903 | p, length, s, s->msg_callback_arg); | |
904 | ||
905 | /* Read type and payload length first */ | |
906 | if (1 + 2 + 16 > length) | |
907 | return 0; /* silently discard */ | |
908 | if (length > SSL3_RT_MAX_PLAIN_LENGTH) | |
909 | return 0; /* silently discard per RFC 6520 sec. 4 */ | |
910 | ||
911 | hbtype = *p++; | |
912 | n2s(p, payload); | |
913 | if (1 + 2 + payload + 16 > length) | |
914 | return 0; /* silently discard per RFC 6520 sec. 4 */ | |
915 | pl = p; | |
916 | ||
917 | if (hbtype == TLS1_HB_REQUEST) { | |
918 | unsigned char *buffer, *bp; | |
919 | unsigned int write_length = 1 /* heartbeat type */ + | |
920 | 2 /* heartbeat length */ + | |
921 | payload + padding; | |
922 | int r; | |
923 | ||
924 | if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) | |
925 | return 0; | |
926 | ||
927 | /* | |
928 | * Allocate memory for the response, size is 1 byte message type, | |
929 | * plus 2 bytes payload length, plus payload, plus padding | |
930 | */ | |
931 | buffer = OPENSSL_malloc(write_length); | |
932 | if (buffer == NULL) | |
933 | return -1; | |
934 | bp = buffer; | |
935 | ||
936 | /* Enter response type, length and copy payload */ | |
937 | *bp++ = TLS1_HB_RESPONSE; | |
938 | s2n(payload, bp); | |
939 | memcpy(bp, pl, payload); | |
940 | bp += payload; | |
941 | /* Random padding */ | |
942 | if (RAND_bytes(bp, padding) <= 0) { | |
943 | OPENSSL_free(buffer); | |
944 | return -1; | |
945 | } | |
946 | ||
947 | r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); | |
948 | ||
949 | if (r >= 0 && s->msg_callback) | |
950 | s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, | |
951 | buffer, write_length, s, s->msg_callback_arg); | |
952 | ||
953 | OPENSSL_free(buffer); | |
954 | ||
955 | if (r < 0) | |
956 | return r; | |
957 | } else if (hbtype == TLS1_HB_RESPONSE) { | |
958 | unsigned int seq; | |
959 | ||
960 | /* | |
961 | * We only send sequence numbers (2 bytes unsigned int), and 16 | |
962 | * random bytes, so we just try to read the sequence number | |
963 | */ | |
964 | n2s(pl, seq); | |
965 | ||
966 | if (payload == 18 && seq == s->tlsext_hb_seq) { | |
967 | dtls1_stop_timer(s); | |
968 | s->tlsext_hb_seq++; | |
969 | s->tlsext_hb_pending = 0; | |
970 | } | |
971 | } | |
972 | ||
973 | return 0; | |
974 | } | |
975 | ||
976 | int dtls1_heartbeat(SSL *s) | |
977 | { | |
978 | unsigned char *buf, *p; | |
979 | int ret = -1; | |
980 | unsigned int payload = 18; /* Sequence number + random bytes */ | |
981 | unsigned int padding = 16; /* Use minimum padding */ | |
982 | ||
983 | /* Only send if peer supports and accepts HB requests... */ | |
984 | if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || | |
985 | s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { | |
986 | SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); | |
987 | return -1; | |
988 | } | |
989 | ||
990 | /* ...and there is none in flight yet... */ | |
991 | if (s->tlsext_hb_pending) { | |
992 | SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); | |
993 | return -1; | |
994 | } | |
995 | ||
996 | /* ...and no handshake in progress. */ | |
024f543c | 997 | if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) { |
8ba708e5 MC |
998 | SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); |
999 | return -1; | |
1000 | } | |
1001 | ||
8ba708e5 MC |
1002 | /*- |
1003 | * Create HeartBeat message, we just use a sequence number | |
1004 | * as payload to distuingish different messages and add | |
1005 | * some random stuff. | |
1006 | * - Message Type, 1 byte | |
1007 | * - Payload Length, 2 bytes (unsigned int) | |
1008 | * - Payload, the sequence number (2 bytes uint) | |
1009 | * - Payload, random bytes (16 bytes uint) | |
1010 | * - Padding | |
1011 | */ | |
1012 | buf = OPENSSL_malloc(1 + 2 + payload + padding); | |
1013 | if (buf == NULL) { | |
1014 | SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE); | |
1015 | return -1; | |
1016 | } | |
1017 | p = buf; | |
1018 | /* Message Type */ | |
1019 | *p++ = TLS1_HB_REQUEST; | |
1020 | /* Payload length (18 bytes here) */ | |
1021 | s2n(payload, p); | |
1022 | /* Sequence number */ | |
1023 | s2n(s->tlsext_hb_seq, p); | |
1024 | /* 16 random bytes */ | |
1025 | if (RAND_bytes(p, 16) <= 0) { | |
1026 | SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); | |
1027 | goto err; | |
1028 | } | |
1029 | p += 16; | |
1030 | /* Random padding */ | |
1031 | if (RAND_bytes(p, padding) <= 0) { | |
1032 | SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); | |
1033 | goto err; | |
1034 | } | |
1035 | ||
1036 | ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); | |
1037 | if (ret >= 0) { | |
1038 | if (s->msg_callback) | |
1039 | s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, | |
1040 | buf, 3 + payload + padding, | |
1041 | s, s->msg_callback_arg); | |
1042 | ||
1043 | dtls1_start_timer(s); | |
1044 | s->tlsext_hb_pending = 1; | |
1045 | } | |
1046 | ||
1047 | err: | |
1048 | OPENSSL_free(buf); | |
1049 | ||
1050 | return ret; | |
1051 | } | |
1052 | #endif | |
1053 | ||
1054 | int dtls1_shutdown(SSL *s) | |
1055 | { | |
1056 | int ret; | |
1057 | #ifndef OPENSSL_NO_SCTP | |
1058 | BIO *wbio; | |
1059 | ||
1060 | wbio = SSL_get_wbio(s); | |
1061 | if (wbio != NULL && BIO_dgram_is_sctp(wbio) && | |
1062 | !(s->shutdown & SSL_SENT_SHUTDOWN)) { | |
1063 | ret = BIO_dgram_sctp_wait_for_dry(wbio); | |
1064 | if (ret < 0) | |
1065 | return -1; | |
1066 | ||
1067 | if (ret == 0) | |
1068 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, | |
1069 | NULL); | |
1070 | } | |
1071 | #endif | |
1072 | ret = ssl3_shutdown(s); | |
1073 | #ifndef OPENSSL_NO_SCTP | |
1074 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); | |
1075 | #endif | |
1076 | return ret; | |
1077 | } | |
1078 | ||
1079 | int dtls1_query_mtu(SSL *s) | |
1080 | { | |
1081 | if (s->d1->link_mtu) { | |
1082 | s->d1->mtu = | |
1083 | s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); | |
1084 | s->d1->link_mtu = 0; | |
1085 | } | |
1086 | ||
1087 | /* AHA! Figure out the MTU, and stick to the right size */ | |
1088 | if (s->d1->mtu < dtls1_min_mtu(s)) { | |
1089 | if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { | |
1090 | s->d1->mtu = | |
1091 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | |
1092 | ||
1093 | /* | |
1094 | * I've seen the kernel return bogus numbers when it doesn't know | |
1095 | * (initial write), so just make sure we have a reasonable number | |
1096 | */ | |
1097 | if (s->d1->mtu < dtls1_min_mtu(s)) { | |
1098 | /* Set to min mtu */ | |
1099 | s->d1->mtu = dtls1_min_mtu(s); | |
1100 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, | |
1101 | s->d1->mtu, NULL); | |
1102 | } | |
1103 | } else | |
1104 | return 0; | |
1105 | } | |
1106 | return 1; | |
1107 | } | |
1108 | ||
3616bb63 | 1109 | static unsigned int dtls1_link_min_mtu(void) |
8ba708e5 MC |
1110 | { |
1111 | return (g_probable_mtu[(sizeof(g_probable_mtu) / | |
1112 | sizeof(g_probable_mtu[0])) - 1]); | |
1113 | } | |
1114 | ||
1115 | unsigned int dtls1_min_mtu(SSL *s) | |
1116 | { | |
1117 | return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); | |
1118 | } |