diff options
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 136 |
1 files changed, 135 insertions, 1 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index c050224c70..1813d46f41 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.c,v 1.6 2017/08/11 20:14:13 doug Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.7 2017/08/12 21:17:03 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -492,6 +492,131 @@ tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert) | |||
492 | return 1; | 492 | return 1; |
493 | } | 493 | } |
494 | 494 | ||
495 | /* | ||
496 | * SessionTicket extension - RFC 5077 section 3.2 | ||
497 | */ | ||
498 | int | ||
499 | tlsext_sessionticket_clienthello_needs(SSL *s) | ||
500 | { | ||
501 | /* | ||
502 | * Send session ticket extension when enabled and not overridden. | ||
503 | * | ||
504 | * When renegotiating, send an empty session ticket to indicate support. | ||
505 | */ | ||
506 | if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0) | ||
507 | return 0; | ||
508 | |||
509 | if (s->internal->new_session) | ||
510 | return 1; | ||
511 | |||
512 | if (s->internal->tlsext_session_ticket != NULL && | ||
513 | s->internal->tlsext_session_ticket->data == NULL) | ||
514 | return 0; | ||
515 | |||
516 | return 1; | ||
517 | } | ||
518 | |||
519 | int | ||
520 | tlsext_sessionticket_clienthello_build(SSL *s, CBB *cbb) | ||
521 | { | ||
522 | /* | ||
523 | * Signal that we support session tickets by sending an empty | ||
524 | * extension when renegotiating or no session found. | ||
525 | */ | ||
526 | if (s->internal->new_session || s->session == NULL) | ||
527 | return 1; | ||
528 | |||
529 | if (s->session->tlsext_tick != NULL) { | ||
530 | /* Attempt to resume with an existing session ticket */ | ||
531 | if (!CBB_add_bytes(cbb, s->session->tlsext_tick, | ||
532 | s->session->tlsext_ticklen)) | ||
533 | return 0; | ||
534 | |||
535 | } else if (s->internal->tlsext_session_ticket != NULL) { | ||
536 | /* | ||
537 | * Attempt to resume with a custom provided session ticket set | ||
538 | * by SSL_set_session_ticket_ext(). | ||
539 | */ | ||
540 | if (s->internal->tlsext_session_ticket->length > 0) { | ||
541 | size_t ticklen = s->internal->tlsext_session_ticket->length; | ||
542 | |||
543 | if ((s->session->tlsext_tick = malloc(ticklen)) == NULL) | ||
544 | return 0; | ||
545 | memcpy(s->session->tlsext_tick, | ||
546 | s->internal->tlsext_session_ticket->data, | ||
547 | ticklen); | ||
548 | s->session->tlsext_ticklen = ticklen; | ||
549 | |||
550 | if (!CBB_add_bytes(cbb, s->session->tlsext_tick, | ||
551 | s->session->tlsext_ticklen)) | ||
552 | return 0; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | if (!CBB_flush(cbb)) | ||
557 | return 0; | ||
558 | |||
559 | return 1; | ||
560 | } | ||
561 | |||
562 | int | ||
563 | tlsext_sessionticket_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
564 | { | ||
565 | if (s->internal->tls_session_ticket_ext_cb) { | ||
566 | if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs), | ||
567 | (int)CBS_len(cbs), | ||
568 | s->internal->tls_session_ticket_ext_cb_arg)) { | ||
569 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
570 | return 0; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | /* We need to signal that this was processed fully */ | ||
575 | if (!CBS_skip(cbs, CBS_len(cbs))) { | ||
576 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | return 1; | ||
581 | } | ||
582 | |||
583 | int | ||
584 | tlsext_sessionticket_serverhello_needs(SSL *s) | ||
585 | { | ||
586 | return (s->internal->tlsext_ticket_expected && | ||
587 | !(SSL_get_options(s) & SSL_OP_NO_TICKET)); | ||
588 | } | ||
589 | |||
590 | int | ||
591 | tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb) | ||
592 | { | ||
593 | /* Empty ticket */ | ||
594 | |||
595 | return 1; | ||
596 | } | ||
597 | |||
598 | int | ||
599 | tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
600 | { | ||
601 | if (s->internal->tls_session_ticket_ext_cb) { | ||
602 | if (!s->internal->tls_session_ticket_ext_cb(s, CBS_data(cbs), | ||
603 | (int)CBS_len(cbs), | ||
604 | s->internal->tls_session_ticket_ext_cb_arg)) { | ||
605 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
606 | return 0; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | if ((SSL_get_options(s) & SSL_OP_NO_TICKET) != 0 || CBS_len(cbs) > 0) { | ||
611 | *alert = TLS1_AD_UNSUPPORTED_EXTENSION; | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | s->internal->tlsext_ticket_expected = 1; | ||
616 | |||
617 | return 1; | ||
618 | } | ||
619 | |||
495 | struct tls_extension { | 620 | struct tls_extension { |
496 | uint16_t type; | 621 | uint16_t type; |
497 | int (*clienthello_needs)(SSL *s); | 622 | int (*clienthello_needs)(SSL *s); |
@@ -539,6 +664,15 @@ static struct tls_extension tls_extensions[] = { | |||
539 | .serverhello_build = tlsext_ec_serverhello_build, | 664 | .serverhello_build = tlsext_ec_serverhello_build, |
540 | .serverhello_parse = tlsext_ec_serverhello_parse, | 665 | .serverhello_parse = tlsext_ec_serverhello_parse, |
541 | }, | 666 | }, |
667 | { | ||
668 | .type = TLSEXT_TYPE_session_ticket, | ||
669 | .clienthello_needs = tlsext_sessionticket_clienthello_needs, | ||
670 | .clienthello_build = tlsext_sessionticket_clienthello_build, | ||
671 | .clienthello_parse = tlsext_sessionticket_clienthello_parse, | ||
672 | .serverhello_needs = tlsext_sessionticket_serverhello_needs, | ||
673 | .serverhello_build = tlsext_sessionticket_serverhello_build, | ||
674 | .serverhello_parse = tlsext_sessionticket_serverhello_parse, | ||
675 | }, | ||
542 | }; | 676 | }; |
543 | 677 | ||
544 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 678 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |