summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_tlsext.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r--src/lib/libssl/ssl_tlsext.c136
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 */
498int
499tlsext_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
519int
520tlsext_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
562int
563tlsext_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
583int
584tlsext_sessionticket_serverhello_needs(SSL *s)
585{
586 return (s->internal->tlsext_ticket_expected &&
587 !(SSL_get_options(s) & SSL_OP_NO_TICKET));
588}
589
590int
591tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb)
592{
593 /* Empty ticket */
594
595 return 1;
596}
597
598int
599tlsext_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
495struct tls_extension { 620struct 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))