diff options
author | jsing <> | 2017-10-10 15:13:26 +0000 |
---|---|---|
committer | jsing <> | 2017-10-10 15:13:26 +0000 |
commit | 50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f (patch) | |
tree | f95f7f0c3a406dd1dd25069a69ae5946e7eb8ad5 | |
parent | dd1d617d105867f42195ad190923c6c1fe92e710 (diff) | |
download | openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.tar.gz openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.tar.bz2 openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.zip |
Merge dtls1_connect() into ssl3_connect(), removing a large amount of
duplicated code. For now this is essentially adds a diff of the two
functions with 'if (SSL_IS_DTLS(s))' - further clean up and improvement
will follow.
ok inoguchi@
-rw-r--r-- | src/lib/libssl/d1_clnt.c | 436 | ||||
-rw-r--r-- | src/lib/libssl/d1_meth.c | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 132 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 4 |
4 files changed, 117 insertions, 459 deletions
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c index 5a5e17699d..f3a7e5ff22 100644 --- a/src/lib/libssl/d1_clnt.c +++ b/src/lib/libssl/d1_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_clnt.c,v 1.78 2017/10/08 16:54:28 jsing Exp $ */ | 1 | /* $OpenBSD: d1_clnt.c,v 1.79 2017/10/10 15:13:26 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -127,8 +127,6 @@ | |||
127 | 127 | ||
128 | #include "bytestring.h" | 128 | #include "bytestring.h" |
129 | 129 | ||
130 | static int dtls1_get_hello_verify(SSL *s); | ||
131 | |||
132 | static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { | 130 | static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { |
133 | .version = DTLS1_VERSION, | 131 | .version = DTLS1_VERSION, |
134 | .min_version = DTLS1_VERSION, | 132 | .min_version = DTLS1_VERSION, |
@@ -137,7 +135,7 @@ static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { | |||
137 | .ssl_clear = dtls1_clear, | 135 | .ssl_clear = dtls1_clear, |
138 | .ssl_free = dtls1_free, | 136 | .ssl_free = dtls1_free, |
139 | .ssl_accept = ssl_undefined_function, | 137 | .ssl_accept = ssl_undefined_function, |
140 | .ssl_connect = dtls1_connect, | 138 | .ssl_connect = ssl3_connect, |
141 | .ssl_read = ssl3_read, | 139 | .ssl_read = ssl3_read, |
142 | .ssl_peek = ssl3_peek, | 140 | .ssl_peek = ssl3_peek, |
143 | .ssl_write = ssl3_write, | 141 | .ssl_write = ssl3_write, |
@@ -178,436 +176,6 @@ dtls1_get_client_method(int ver) | |||
178 | } | 176 | } |
179 | 177 | ||
180 | int | 178 | int |
181 | dtls1_connect(SSL *s) | ||
182 | { | ||
183 | void (*cb)(const SSL *ssl, int type, int val) = NULL; | ||
184 | int ret = -1; | ||
185 | int new_state, state, skip = 0; | ||
186 | |||
187 | ERR_clear_error(); | ||
188 | errno = 0; | ||
189 | |||
190 | if (s->internal->info_callback != NULL) | ||
191 | cb = s->internal->info_callback; | ||
192 | else if (s->ctx->internal->info_callback != NULL) | ||
193 | cb = s->ctx->internal->info_callback; | ||
194 | |||
195 | s->internal->in_handshake++; | ||
196 | if (!SSL_in_init(s) || SSL_in_before(s)) | ||
197 | SSL_clear(s); | ||
198 | |||
199 | for (;;) { | ||
200 | state = S3I(s)->hs.state; | ||
201 | |||
202 | switch (S3I(s)->hs.state) { | ||
203 | case SSL_ST_RENEGOTIATE: | ||
204 | s->internal->renegotiate = 1; | ||
205 | S3I(s)->hs.state = SSL_ST_CONNECT; | ||
206 | s->ctx->internal->stats.sess_connect_renegotiate++; | ||
207 | /* break */ | ||
208 | case SSL_ST_BEFORE: | ||
209 | case SSL_ST_CONNECT: | ||
210 | case SSL_ST_BEFORE|SSL_ST_CONNECT: | ||
211 | case SSL_ST_OK|SSL_ST_CONNECT: | ||
212 | |||
213 | s->server = 0; | ||
214 | if (cb != NULL) | ||
215 | cb(s, SSL_CB_HANDSHAKE_START, 1); | ||
216 | |||
217 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { | ||
218 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
219 | ret = -1; | ||
220 | goto end; | ||
221 | } | ||
222 | |||
223 | /* s->version=SSL3_VERSION; */ | ||
224 | s->internal->type = SSL_ST_CONNECT; | ||
225 | |||
226 | if (!ssl3_setup_init_buffer(s)) { | ||
227 | ret = -1; | ||
228 | goto end; | ||
229 | } | ||
230 | if (!ssl3_setup_buffers(s)) { | ||
231 | ret = -1; | ||
232 | goto end; | ||
233 | } | ||
234 | if (!ssl_init_wbio_buffer(s, 0)) { | ||
235 | ret = -1; | ||
236 | goto end; | ||
237 | } | ||
238 | |||
239 | /* don't push the buffering BIO quite yet */ | ||
240 | |||
241 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | ||
242 | s->ctx->internal->stats.sess_connect++; | ||
243 | s->internal->init_num = 0; | ||
244 | /* mark client_random uninitialized */ | ||
245 | memset(s->s3->client_random, 0, | ||
246 | sizeof(s->s3->client_random)); | ||
247 | D1I(s)->send_cookie = 0; | ||
248 | s->internal->hit = 0; | ||
249 | break; | ||
250 | |||
251 | case SSL3_ST_CW_CLNT_HELLO_A: | ||
252 | case SSL3_ST_CW_CLNT_HELLO_B: | ||
253 | |||
254 | s->internal->shutdown = 0; | ||
255 | |||
256 | /* every DTLS ClientHello resets Finished MAC */ | ||
257 | if (!tls1_init_finished_mac(s)) { | ||
258 | ret = -1; | ||
259 | goto end; | ||
260 | } | ||
261 | |||
262 | dtls1_start_timer(s); | ||
263 | ret = ssl3_client_hello(s); | ||
264 | if (ret <= 0) | ||
265 | goto end; | ||
266 | |||
267 | if (D1I(s)->send_cookie) { | ||
268 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | ||
269 | S3I(s)->hs.next_state = SSL3_ST_CR_SRVR_HELLO_A; | ||
270 | } else | ||
271 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | ||
272 | |||
273 | s->internal->init_num = 0; | ||
274 | |||
275 | /* turn on buffering for the next lot of output */ | ||
276 | if (s->bbio != s->wbio) | ||
277 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
278 | |||
279 | break; | ||
280 | |||
281 | case SSL3_ST_CR_SRVR_HELLO_A: | ||
282 | case SSL3_ST_CR_SRVR_HELLO_B: | ||
283 | ret = ssl3_get_server_hello(s); | ||
284 | if (ret <= 0) | ||
285 | goto end; | ||
286 | if (s->internal->hit) | ||
287 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
288 | else | ||
289 | S3I(s)->hs.state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; | ||
290 | s->internal->init_num = 0; | ||
291 | break; | ||
292 | |||
293 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: | ||
294 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: | ||
295 | |||
296 | ret = dtls1_get_hello_verify(s); | ||
297 | if (ret <= 0) | ||
298 | goto end; | ||
299 | dtls1_stop_timer(s); | ||
300 | if ( D1I(s)->send_cookie) /* start again, with a cookie */ | ||
301 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | ||
302 | else | ||
303 | S3I(s)->hs.state = SSL3_ST_CR_CERT_A; | ||
304 | s->internal->init_num = 0; | ||
305 | break; | ||
306 | |||
307 | case SSL3_ST_CR_CERT_A: | ||
308 | case SSL3_ST_CR_CERT_B: | ||
309 | ret = ssl3_check_finished(s); | ||
310 | if (ret <= 0) | ||
311 | goto end; | ||
312 | if (ret == 2) { | ||
313 | s->internal->hit = 1; | ||
314 | if (s->internal->tlsext_ticket_expected) | ||
315 | S3I(s)->hs.state = SSL3_ST_CR_SESSION_TICKET_A; | ||
316 | else | ||
317 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
318 | s->internal->init_num = 0; | ||
319 | break; | ||
320 | } | ||
321 | /* Check if it is anon DH/ECDH. */ | ||
322 | if (!(S3I(s)->hs.new_cipher->algorithm_auth & | ||
323 | SSL_aNULL)) { | ||
324 | ret = ssl3_get_server_certificate(s); | ||
325 | if (ret <= 0) | ||
326 | goto end; | ||
327 | if (s->internal->tlsext_status_expected) | ||
328 | S3I(s)->hs.state = SSL3_ST_CR_CERT_STATUS_A; | ||
329 | else | ||
330 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
331 | } else { | ||
332 | skip = 1; | ||
333 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
334 | } | ||
335 | s->internal->init_num = 0; | ||
336 | break; | ||
337 | |||
338 | case SSL3_ST_CR_KEY_EXCH_A: | ||
339 | case SSL3_ST_CR_KEY_EXCH_B: | ||
340 | ret = ssl3_get_server_key_exchange(s); | ||
341 | if (ret <= 0) | ||
342 | goto end; | ||
343 | S3I(s)->hs.state = SSL3_ST_CR_CERT_REQ_A; | ||
344 | s->internal->init_num = 0; | ||
345 | |||
346 | /* | ||
347 | * At this point we check that we have the | ||
348 | * required stuff from the server. | ||
349 | */ | ||
350 | if (!ssl3_check_cert_and_algorithm(s)) { | ||
351 | ret = -1; | ||
352 | goto end; | ||
353 | } | ||
354 | break; | ||
355 | |||
356 | case SSL3_ST_CR_CERT_REQ_A: | ||
357 | case SSL3_ST_CR_CERT_REQ_B: | ||
358 | ret = ssl3_get_certificate_request(s); | ||
359 | if (ret <= 0) | ||
360 | goto end; | ||
361 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_DONE_A; | ||
362 | s->internal->init_num = 0; | ||
363 | break; | ||
364 | |||
365 | case SSL3_ST_CR_SRVR_DONE_A: | ||
366 | case SSL3_ST_CR_SRVR_DONE_B: | ||
367 | ret = ssl3_get_server_done(s); | ||
368 | if (ret <= 0) | ||
369 | goto end; | ||
370 | dtls1_stop_timer(s); | ||
371 | if (S3I(s)->tmp.cert_req) | ||
372 | S3I(s)->hs.state = SSL3_ST_CW_CERT_A; | ||
373 | else | ||
374 | S3I(s)->hs.state = SSL3_ST_CW_KEY_EXCH_A; | ||
375 | s->internal->init_num = 0; | ||
376 | break; | ||
377 | |||
378 | case SSL3_ST_CW_CERT_A: | ||
379 | case SSL3_ST_CW_CERT_B: | ||
380 | case SSL3_ST_CW_CERT_C: | ||
381 | case SSL3_ST_CW_CERT_D: | ||
382 | dtls1_start_timer(s); | ||
383 | ret = ssl3_send_client_certificate(s); | ||
384 | if (ret <= 0) | ||
385 | goto end; | ||
386 | S3I(s)->hs.state = SSL3_ST_CW_KEY_EXCH_A; | ||
387 | s->internal->init_num = 0; | ||
388 | break; | ||
389 | |||
390 | case SSL3_ST_CW_KEY_EXCH_A: | ||
391 | case SSL3_ST_CW_KEY_EXCH_B: | ||
392 | dtls1_start_timer(s); | ||
393 | ret = ssl3_send_client_key_exchange(s); | ||
394 | if (ret <= 0) | ||
395 | goto end; | ||
396 | /* | ||
397 | * EAY EAY EAY need to check for DH fix cert | ||
398 | * sent back | ||
399 | */ | ||
400 | /* | ||
401 | * For TLS, cert_req is set to 2, so a cert chain | ||
402 | * of nothing is sent, but no verify packet is sent | ||
403 | */ | ||
404 | /* | ||
405 | * XXX: For now, we do not support client | ||
406 | * authentication in ECDH cipher suites with | ||
407 | * ECDH (rather than ECDSA) certificates. | ||
408 | * We need to skip the certificate verify | ||
409 | * message when client's ECDH public key is sent | ||
410 | * inside the client certificate. | ||
411 | */ | ||
412 | if (S3I(s)->tmp.cert_req == 1) { | ||
413 | S3I(s)->hs.state = SSL3_ST_CW_CERT_VRFY_A; | ||
414 | } else { | ||
415 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
416 | S3I(s)->change_cipher_spec = 0; | ||
417 | } | ||
418 | |||
419 | s->internal->init_num = 0; | ||
420 | break; | ||
421 | |||
422 | case SSL3_ST_CW_CERT_VRFY_A: | ||
423 | case SSL3_ST_CW_CERT_VRFY_B: | ||
424 | dtls1_start_timer(s); | ||
425 | ret = ssl3_send_client_verify(s); | ||
426 | if (ret <= 0) | ||
427 | goto end; | ||
428 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
429 | s->internal->init_num = 0; | ||
430 | S3I(s)->change_cipher_spec = 0; | ||
431 | break; | ||
432 | |||
433 | case SSL3_ST_CW_CHANGE_A: | ||
434 | case SSL3_ST_CW_CHANGE_B: | ||
435 | if (!s->internal->hit) | ||
436 | dtls1_start_timer(s); | ||
437 | ret = ssl3_send_change_cipher_spec(s, | ||
438 | SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); | ||
439 | if (ret <= 0) | ||
440 | goto end; | ||
441 | |||
442 | S3I(s)->hs.state = SSL3_ST_CW_FINISHED_A; | ||
443 | s->internal->init_num = 0; | ||
444 | |||
445 | s->session->cipher = S3I(s)->hs.new_cipher; | ||
446 | if (!tls1_setup_key_block(s)) { | ||
447 | ret = -1; | ||
448 | goto end; | ||
449 | } | ||
450 | |||
451 | if (!tls1_change_cipher_state(s, | ||
452 | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { | ||
453 | ret = -1; | ||
454 | goto end; | ||
455 | } | ||
456 | |||
457 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); | ||
458 | break; | ||
459 | |||
460 | case SSL3_ST_CW_FINISHED_A: | ||
461 | case SSL3_ST_CW_FINISHED_B: | ||
462 | if (!s->internal->hit) | ||
463 | dtls1_start_timer(s); | ||
464 | ret = ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, | ||
465 | SSL3_ST_CW_FINISHED_B, TLS_MD_CLIENT_FINISH_CONST, | ||
466 | TLS_MD_CLIENT_FINISH_CONST_SIZE); | ||
467 | if (ret <= 0) | ||
468 | goto end; | ||
469 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | ||
470 | |||
471 | /* clear flags */ | ||
472 | s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; | ||
473 | if (s->internal->hit) { | ||
474 | S3I(s)->hs.next_state = SSL_ST_OK; | ||
475 | if (s->s3->flags & | ||
476 | SSL3_FLAGS_DELAY_CLIENT_FINISHED) { | ||
477 | S3I(s)->hs.state = SSL_ST_OK; | ||
478 | s->s3->flags |= SSL3_FLAGS_POP_BUFFER; | ||
479 | S3I(s)->delay_buf_pop_ret = 0; | ||
480 | } | ||
481 | } else { | ||
482 | /* Allow NewSessionTicket if ticket expected */ | ||
483 | if (s->internal->tlsext_ticket_expected) | ||
484 | S3I(s)->hs.next_state = | ||
485 | SSL3_ST_CR_SESSION_TICKET_A; | ||
486 | else | ||
487 | S3I(s)->hs.next_state = | ||
488 | SSL3_ST_CR_FINISHED_A; | ||
489 | } | ||
490 | s->internal->init_num = 0; | ||
491 | break; | ||
492 | |||
493 | case SSL3_ST_CR_SESSION_TICKET_A: | ||
494 | case SSL3_ST_CR_SESSION_TICKET_B: | ||
495 | ret = ssl3_get_new_session_ticket(s); | ||
496 | if (ret <= 0) | ||
497 | goto end; | ||
498 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
499 | s->internal->init_num = 0; | ||
500 | break; | ||
501 | |||
502 | case SSL3_ST_CR_CERT_STATUS_A: | ||
503 | case SSL3_ST_CR_CERT_STATUS_B: | ||
504 | ret = ssl3_get_cert_status(s); | ||
505 | if (ret <= 0) | ||
506 | goto end; | ||
507 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
508 | s->internal->init_num = 0; | ||
509 | break; | ||
510 | |||
511 | case SSL3_ST_CR_FINISHED_A: | ||
512 | case SSL3_ST_CR_FINISHED_B: | ||
513 | D1I(s)->change_cipher_spec_ok = 1; | ||
514 | ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, | ||
515 | SSL3_ST_CR_FINISHED_B); | ||
516 | if (ret <= 0) | ||
517 | goto end; | ||
518 | dtls1_stop_timer(s); | ||
519 | |||
520 | if (s->internal->hit) | ||
521 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
522 | else | ||
523 | S3I(s)->hs.state = SSL_ST_OK; | ||
524 | |||
525 | s->internal->init_num = 0; | ||
526 | break; | ||
527 | |||
528 | case SSL3_ST_CW_FLUSH: | ||
529 | s->internal->rwstate = SSL_WRITING; | ||
530 | if (BIO_flush(s->wbio) <= 0) { | ||
531 | /* If the write error was fatal, stop trying */ | ||
532 | if (!BIO_should_retry(s->wbio)) { | ||
533 | s->internal->rwstate = SSL_NOTHING; | ||
534 | S3I(s)->hs.state = S3I(s)->hs.next_state; | ||
535 | } | ||
536 | |||
537 | ret = -1; | ||
538 | goto end; | ||
539 | } | ||
540 | s->internal->rwstate = SSL_NOTHING; | ||
541 | S3I(s)->hs.state = S3I(s)->hs.next_state; | ||
542 | break; | ||
543 | |||
544 | case SSL_ST_OK: | ||
545 | /* clean a few things up */ | ||
546 | tls1_cleanup_key_block(s); | ||
547 | |||
548 | /* | ||
549 | * If we are not 'joining' the last two packets, | ||
550 | * remove the buffering now | ||
551 | */ | ||
552 | if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) | ||
553 | ssl_free_wbio_buffer(s); | ||
554 | /* else do it later in ssl3_write */ | ||
555 | |||
556 | s->internal->init_num = 0; | ||
557 | s->internal->renegotiate = 0; | ||
558 | s->internal->new_session = 0; | ||
559 | |||
560 | ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); | ||
561 | if (s->internal->hit) | ||
562 | s->ctx->internal->stats.sess_hit++; | ||
563 | |||
564 | ret = 1; | ||
565 | /* s->server=0; */ | ||
566 | s->internal->handshake_func = dtls1_connect; | ||
567 | s->ctx->internal->stats.sess_connect_good++; | ||
568 | |||
569 | if (cb != NULL) | ||
570 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); | ||
571 | |||
572 | /* done with handshaking */ | ||
573 | D1I(s)->handshake_read_seq = 0; | ||
574 | D1I(s)->next_handshake_write_seq = 0; | ||
575 | goto end; | ||
576 | /* break; */ | ||
577 | |||
578 | default: | ||
579 | SSLerror(s, SSL_R_UNKNOWN_STATE); | ||
580 | ret = -1; | ||
581 | goto end; | ||
582 | /* break; */ | ||
583 | } | ||
584 | |||
585 | /* did we do anything */ | ||
586 | if (!S3I(s)->tmp.reuse_message && !skip) { | ||
587 | if (s->internal->debug) { | ||
588 | if ((ret = BIO_flush(s->wbio)) <= 0) | ||
589 | goto end; | ||
590 | } | ||
591 | |||
592 | if ((cb != NULL) && (S3I(s)->hs.state != state)) { | ||
593 | new_state = S3I(s)->hs.state; | ||
594 | S3I(s)->hs.state = state; | ||
595 | cb(s, SSL_CB_CONNECT_LOOP, 1); | ||
596 | S3I(s)->hs.state = new_state; | ||
597 | } | ||
598 | } | ||
599 | skip = 0; | ||
600 | } | ||
601 | |||
602 | end: | ||
603 | s->internal->in_handshake--; | ||
604 | if (cb != NULL) | ||
605 | cb(s, SSL_CB_CONNECT_EXIT, ret); | ||
606 | |||
607 | return (ret); | ||
608 | } | ||
609 | |||
610 | static int | ||
611 | dtls1_get_hello_verify(SSL *s) | 179 | dtls1_get_hello_verify(SSL *s) |
612 | { | 180 | { |
613 | long n; | 181 | long n; |
diff --git a/src/lib/libssl/d1_meth.c b/src/lib/libssl/d1_meth.c index fcd8906c45..e513c4a9be 100644 --- a/src/lib/libssl/d1_meth.c +++ b/src/lib/libssl/d1_meth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_meth.c,v 1.13 2017/01/23 13:36:13 jsing Exp $ */ | 1 | /* $OpenBSD: d1_meth.c,v 1.14 2017/10/10 15:13:26 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -73,7 +73,7 @@ static const SSL_METHOD_INTERNAL DTLSv1_method_internal_data = { | |||
73 | .ssl_clear = dtls1_clear, | 73 | .ssl_clear = dtls1_clear, |
74 | .ssl_free = dtls1_free, | 74 | .ssl_free = dtls1_free, |
75 | .ssl_accept = dtls1_accept, | 75 | .ssl_accept = dtls1_accept, |
76 | .ssl_connect = dtls1_connect, | 76 | .ssl_connect = ssl3_connect, |
77 | .ssl_read = ssl3_read, | 77 | .ssl_read = ssl3_read, |
78 | .ssl_peek = ssl3_peek, | 78 | .ssl_peek = ssl3_peek, |
79 | .ssl_write = ssl3_write, | 79 | .ssl_write = ssl3_write, |
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index fb4d9da174..dce5a7d008 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_clnt.c,v 1.18 2017/10/08 16:42:21 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.19 2017/10/10 15:13:26 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -210,10 +210,18 @@ ssl3_connect(SSL *s) | |||
210 | if (cb != NULL) | 210 | if (cb != NULL) |
211 | cb(s, SSL_CB_HANDSHAKE_START, 1); | 211 | cb(s, SSL_CB_HANDSHAKE_START, 1); |
212 | 212 | ||
213 | if ((s->version & 0xff00) != 0x0300) { | 213 | if (SSL_IS_DTLS(s)) { |
214 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 214 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { |
215 | ret = -1; | 215 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
216 | goto end; | 216 | ret = -1; |
217 | goto end; | ||
218 | } | ||
219 | } else { | ||
220 | if ((s->version & 0xff00) != 0x0300) { | ||
221 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
222 | ret = -1; | ||
223 | goto end; | ||
224 | } | ||
217 | } | 225 | } |
218 | 226 | ||
219 | /* s->version=SSL3_VERSION; */ | 227 | /* s->version=SSL3_VERSION; */ |
@@ -234,24 +242,50 @@ ssl3_connect(SSL *s) | |||
234 | 242 | ||
235 | /* don't push the buffering BIO quite yet */ | 243 | /* don't push the buffering BIO quite yet */ |
236 | 244 | ||
237 | if (!tls1_init_finished_mac(s)) { | 245 | if (!SSL_IS_DTLS(s)) { |
238 | ret = -1; | 246 | if (!tls1_init_finished_mac(s)) { |
239 | goto end; | 247 | ret = -1; |
248 | goto end; | ||
249 | } | ||
240 | } | 250 | } |
241 | 251 | ||
242 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | 252 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; |
243 | s->ctx->internal->stats.sess_connect++; | 253 | s->ctx->internal->stats.sess_connect++; |
244 | s->internal->init_num = 0; | 254 | s->internal->init_num = 0; |
255 | |||
256 | if (SSL_IS_DTLS(s)) { | ||
257 | /* mark client_random uninitialized */ | ||
258 | memset(s->s3->client_random, 0, | ||
259 | sizeof(s->s3->client_random)); | ||
260 | D1I(s)->send_cookie = 0; | ||
261 | s->internal->hit = 0; | ||
262 | } | ||
245 | break; | 263 | break; |
246 | 264 | ||
247 | case SSL3_ST_CW_CLNT_HELLO_A: | 265 | case SSL3_ST_CW_CLNT_HELLO_A: |
248 | case SSL3_ST_CW_CLNT_HELLO_B: | 266 | case SSL3_ST_CW_CLNT_HELLO_B: |
249 | |||
250 | s->internal->shutdown = 0; | 267 | s->internal->shutdown = 0; |
268 | |||
269 | if (SSL_IS_DTLS(s)) { | ||
270 | /* every DTLS ClientHello resets Finished MAC */ | ||
271 | if (!tls1_init_finished_mac(s)) { | ||
272 | ret = -1; | ||
273 | goto end; | ||
274 | } | ||
275 | |||
276 | dtls1_start_timer(s); | ||
277 | } | ||
278 | |||
251 | ret = ssl3_client_hello(s); | 279 | ret = ssl3_client_hello(s); |
252 | if (ret <= 0) | 280 | if (ret <= 0) |
253 | goto end; | 281 | goto end; |
254 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | 282 | |
283 | if (SSL_IS_DTLS(s) && D1I(s)->send_cookie) { | ||
284 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | ||
285 | S3I(s)->hs.next_state = SSL3_ST_CR_SRVR_HELLO_A; | ||
286 | } else | ||
287 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | ||
288 | |||
255 | s->internal->init_num = 0; | 289 | s->internal->init_num = 0; |
256 | 290 | ||
257 | /* turn on buffering for the next lot of output */ | 291 | /* turn on buffering for the next lot of output */ |
@@ -268,11 +302,29 @@ ssl3_connect(SSL *s) | |||
268 | 302 | ||
269 | if (s->internal->hit) { | 303 | if (s->internal->hit) { |
270 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | 304 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; |
271 | if (s->internal->tlsext_ticket_expected) { | 305 | if (!SSL_IS_DTLS(s)) { |
272 | /* receive renewed session ticket */ | 306 | if (s->internal->tlsext_ticket_expected) { |
273 | S3I(s)->hs.state = SSL3_ST_CR_SESSION_TICKET_A; | 307 | /* receive renewed session ticket */ |
308 | S3I(s)->hs.state = SSL3_ST_CR_SESSION_TICKET_A; | ||
309 | } | ||
274 | } | 310 | } |
275 | } else | 311 | } else if (SSL_IS_DTLS(s)) { |
312 | S3I(s)->hs.state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; | ||
313 | } else { | ||
314 | S3I(s)->hs.state = SSL3_ST_CR_CERT_A; | ||
315 | } | ||
316 | s->internal->init_num = 0; | ||
317 | break; | ||
318 | |||
319 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: | ||
320 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: | ||
321 | ret = dtls1_get_hello_verify(s); | ||
322 | if (ret <= 0) | ||
323 | goto end; | ||
324 | dtls1_stop_timer(s); | ||
325 | if (D1I(s)->send_cookie) /* start again, with a cookie */ | ||
326 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | ||
327 | else | ||
276 | S3I(s)->hs.state = SSL3_ST_CR_CERT_A; | 328 | S3I(s)->hs.state = SSL3_ST_CR_CERT_A; |
277 | s->internal->init_num = 0; | 329 | s->internal->init_num = 0; |
278 | break; | 330 | break; |
@@ -340,6 +392,8 @@ ssl3_connect(SSL *s) | |||
340 | ret = ssl3_get_server_done(s); | 392 | ret = ssl3_get_server_done(s); |
341 | if (ret <= 0) | 393 | if (ret <= 0) |
342 | goto end; | 394 | goto end; |
395 | if (SSL_IS_DTLS(s)) | ||
396 | dtls1_stop_timer(s); | ||
343 | if (S3I(s)->tmp.cert_req) | 397 | if (S3I(s)->tmp.cert_req) |
344 | S3I(s)->hs.state = SSL3_ST_CW_CERT_A; | 398 | S3I(s)->hs.state = SSL3_ST_CW_CERT_A; |
345 | else | 399 | else |
@@ -352,6 +406,8 @@ ssl3_connect(SSL *s) | |||
352 | case SSL3_ST_CW_CERT_B: | 406 | case SSL3_ST_CW_CERT_B: |
353 | case SSL3_ST_CW_CERT_C: | 407 | case SSL3_ST_CW_CERT_C: |
354 | case SSL3_ST_CW_CERT_D: | 408 | case SSL3_ST_CW_CERT_D: |
409 | if (SSL_IS_DTLS(s)) | ||
410 | dtls1_start_timer(s); | ||
355 | ret = ssl3_send_client_certificate(s); | 411 | ret = ssl3_send_client_certificate(s); |
356 | if (ret <= 0) | 412 | if (ret <= 0) |
357 | goto end; | 413 | goto end; |
@@ -361,6 +417,8 @@ ssl3_connect(SSL *s) | |||
361 | 417 | ||
362 | case SSL3_ST_CW_KEY_EXCH_A: | 418 | case SSL3_ST_CW_KEY_EXCH_A: |
363 | case SSL3_ST_CW_KEY_EXCH_B: | 419 | case SSL3_ST_CW_KEY_EXCH_B: |
420 | if (SSL_IS_DTLS(s)) | ||
421 | dtls1_start_timer(s); | ||
364 | ret = ssl3_send_client_key_exchange(s); | 422 | ret = ssl3_send_client_key_exchange(s); |
365 | if (ret <= 0) | 423 | if (ret <= 0) |
366 | goto end; | 424 | goto end; |
@@ -386,9 +444,11 @@ ssl3_connect(SSL *s) | |||
386 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | 444 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; |
387 | S3I(s)->change_cipher_spec = 0; | 445 | S3I(s)->change_cipher_spec = 0; |
388 | } | 446 | } |
389 | if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { | 447 | if (!SSL_IS_DTLS(s)) { |
390 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | 448 | if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { |
391 | S3I(s)->change_cipher_spec = 0; | 449 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; |
450 | S3I(s)->change_cipher_spec = 0; | ||
451 | } | ||
392 | } | 452 | } |
393 | 453 | ||
394 | s->internal->init_num = 0; | 454 | s->internal->init_num = 0; |
@@ -396,6 +456,8 @@ ssl3_connect(SSL *s) | |||
396 | 456 | ||
397 | case SSL3_ST_CW_CERT_VRFY_A: | 457 | case SSL3_ST_CW_CERT_VRFY_A: |
398 | case SSL3_ST_CW_CERT_VRFY_B: | 458 | case SSL3_ST_CW_CERT_VRFY_B: |
459 | if (SSL_IS_DTLS(s)) | ||
460 | dtls1_start_timer(s); | ||
399 | ret = ssl3_send_client_verify(s); | 461 | ret = ssl3_send_client_verify(s); |
400 | if (ret <= 0) | 462 | if (ret <= 0) |
401 | goto end; | 463 | goto end; |
@@ -406,6 +468,8 @@ ssl3_connect(SSL *s) | |||
406 | 468 | ||
407 | case SSL3_ST_CW_CHANGE_A: | 469 | case SSL3_ST_CW_CHANGE_A: |
408 | case SSL3_ST_CW_CHANGE_B: | 470 | case SSL3_ST_CW_CHANGE_B: |
471 | if (SSL_IS_DTLS(s) && !s->internal->hit) | ||
472 | dtls1_start_timer(s); | ||
409 | ret = ssl3_send_change_cipher_spec(s, | 473 | ret = ssl3_send_change_cipher_spec(s, |
410 | SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); | 474 | SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); |
411 | if (ret <= 0) | 475 | if (ret <= 0) |
@@ -426,16 +490,22 @@ ssl3_connect(SSL *s) | |||
426 | goto end; | 490 | goto end; |
427 | } | 491 | } |
428 | 492 | ||
493 | if (SSL_IS_DTLS(s)) | ||
494 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); | ||
495 | |||
429 | break; | 496 | break; |
430 | 497 | ||
431 | case SSL3_ST_CW_FINISHED_A: | 498 | case SSL3_ST_CW_FINISHED_A: |
432 | case SSL3_ST_CW_FINISHED_B: | 499 | case SSL3_ST_CW_FINISHED_B: |
500 | if (SSL_IS_DTLS(s) && !s->internal->hit) | ||
501 | dtls1_start_timer(s); | ||
433 | ret = ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, | 502 | ret = ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, |
434 | SSL3_ST_CW_FINISHED_B, TLS_MD_CLIENT_FINISH_CONST, | 503 | SSL3_ST_CW_FINISHED_B, TLS_MD_CLIENT_FINISH_CONST, |
435 | TLS_MD_CLIENT_FINISH_CONST_SIZE); | 504 | TLS_MD_CLIENT_FINISH_CONST_SIZE); |
436 | if (ret <= 0) | 505 | if (ret <= 0) |
437 | goto end; | 506 | goto end; |
438 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | 507 | if (!SSL_IS_DTLS(s)) |
508 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
439 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | 509 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; |
440 | 510 | ||
441 | /* clear flags */ | 511 | /* clear flags */ |
@@ -480,11 +550,16 @@ ssl3_connect(SSL *s) | |||
480 | 550 | ||
481 | case SSL3_ST_CR_FINISHED_A: | 551 | case SSL3_ST_CR_FINISHED_A: |
482 | case SSL3_ST_CR_FINISHED_B: | 552 | case SSL3_ST_CR_FINISHED_B: |
483 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | 553 | if (SSL_IS_DTLS(s)) |
554 | D1I(s)->change_cipher_spec_ok = 1; | ||
555 | else | ||
556 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
484 | ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, | 557 | ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, |
485 | SSL3_ST_CR_FINISHED_B); | 558 | SSL3_ST_CR_FINISHED_B); |
486 | if (ret <= 0) | 559 | if (ret <= 0) |
487 | goto end; | 560 | goto end; |
561 | if (SSL_IS_DTLS(s)) | ||
562 | dtls1_stop_timer(s); | ||
488 | 563 | ||
489 | if (s->internal->hit) | 564 | if (s->internal->hit) |
490 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | 565 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; |
@@ -496,6 +571,13 @@ ssl3_connect(SSL *s) | |||
496 | case SSL3_ST_CW_FLUSH: | 571 | case SSL3_ST_CW_FLUSH: |
497 | s->internal->rwstate = SSL_WRITING; | 572 | s->internal->rwstate = SSL_WRITING; |
498 | if (BIO_flush(s->wbio) <= 0) { | 573 | if (BIO_flush(s->wbio) <= 0) { |
574 | if (SSL_IS_DTLS(s)) { | ||
575 | /* If the write error was fatal, stop trying */ | ||
576 | if (!BIO_should_retry(s->wbio)) { | ||
577 | s->internal->rwstate = SSL_NOTHING; | ||
578 | S3I(s)->hs.state = S3I(s)->hs.next_state; | ||
579 | } | ||
580 | } | ||
499 | ret = -1; | 581 | ret = -1; |
500 | goto end; | 582 | goto end; |
501 | } | 583 | } |
@@ -507,8 +589,10 @@ ssl3_connect(SSL *s) | |||
507 | /* clean a few things up */ | 589 | /* clean a few things up */ |
508 | tls1_cleanup_key_block(s); | 590 | tls1_cleanup_key_block(s); |
509 | 591 | ||
510 | BUF_MEM_free(s->internal->init_buf); | 592 | if (!SSL_IS_DTLS(s)) { |
511 | s->internal->init_buf = NULL; | 593 | BUF_MEM_free(s->internal->init_buf); |
594 | s->internal->init_buf = NULL; | ||
595 | } | ||
512 | 596 | ||
513 | /* | 597 | /* |
514 | * If we are not 'joining' the last two packets, | 598 | * If we are not 'joining' the last two packets, |
@@ -534,6 +618,12 @@ ssl3_connect(SSL *s) | |||
534 | if (cb != NULL) | 618 | if (cb != NULL) |
535 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); | 619 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); |
536 | 620 | ||
621 | if (SSL_IS_DTLS(s)) { | ||
622 | /* done with handshaking */ | ||
623 | D1I(s)->handshake_read_seq = 0; | ||
624 | D1I(s)->next_handshake_write_seq = 0; | ||
625 | } | ||
626 | |||
537 | goto end; | 627 | goto end; |
538 | /* break; */ | 628 | /* break; */ |
539 | 629 | ||
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 2fec36fba9..eed0803a85 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.194 2017/10/08 16:24:02 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.195 2017/10/10 15:13:26 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1199,6 +1199,7 @@ void dtls1_double_timeout(SSL *s); | |||
1199 | unsigned int dtls1_min_mtu(void); | 1199 | unsigned int dtls1_min_mtu(void); |
1200 | 1200 | ||
1201 | /* some client-only functions */ | 1201 | /* some client-only functions */ |
1202 | int dtls1_get_hello_verify(SSL *s); | ||
1202 | int ssl3_client_hello(SSL *s); | 1203 | int ssl3_client_hello(SSL *s); |
1203 | int ssl3_get_server_hello(SSL *s); | 1204 | int ssl3_get_server_hello(SSL *s); |
1204 | int ssl3_get_certificate_request(SSL *s); | 1205 | int ssl3_get_certificate_request(SSL *s); |
@@ -1236,7 +1237,6 @@ void tls1_clear(SSL *s); | |||
1236 | 1237 | ||
1237 | int dtls1_new(SSL *s); | 1238 | int dtls1_new(SSL *s); |
1238 | int dtls1_accept(SSL *s); | 1239 | int dtls1_accept(SSL *s); |
1239 | int dtls1_connect(SSL *s); | ||
1240 | void dtls1_free(SSL *s); | 1240 | void dtls1_free(SSL *s); |
1241 | void dtls1_clear(SSL *s); | 1241 | void dtls1_clear(SSL *s); |
1242 | long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); | 1242 | long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); |