diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libtls/Symbols.list | 3 | ||||
-rw-r--r-- | src/lib/libtls/tls.h | 11 | ||||
-rw-r--r-- | src/lib/libtls/tls_config.c | 102 | ||||
-rw-r--r-- | src/lib/libtls/tls_init.3 | 29 | ||||
-rw-r--r-- | src/lib/libtls/tls_internal.h | 24 | ||||
-rw-r--r-- | src/lib/libtls/tls_server.c | 96 |
6 files changed, 251 insertions, 14 deletions
diff --git a/src/lib/libtls/Symbols.list b/src/lib/libtls/Symbols.list index 7ed1d58bdc..a033e3e242 100644 --- a/src/lib/libtls/Symbols.list +++ b/src/lib/libtls/Symbols.list | |||
@@ -5,6 +5,7 @@ tls_client | |||
5 | tls_close | 5 | tls_close |
6 | tls_config_add_keypair_file | 6 | tls_config_add_keypair_file |
7 | tls_config_add_keypair_mem | 7 | tls_config_add_keypair_mem |
8 | tls_config_add_ticket_key | ||
8 | tls_config_clear_keys | 9 | tls_config_clear_keys |
9 | tls_config_error | 10 | tls_config_error |
10 | tls_config_free | 11 | tls_config_free |
@@ -32,6 +33,8 @@ tls_config_set_keypair_mem | |||
32 | tls_config_set_ocsp_staple_mem | 33 | tls_config_set_ocsp_staple_mem |
33 | tls_config_set_ocsp_staple_file | 34 | tls_config_set_ocsp_staple_file |
34 | tls_config_set_protocols | 35 | tls_config_set_protocols |
36 | tls_config_set_session_id | ||
37 | tls_config_set_session_lifetime | ||
35 | tls_config_set_verify_depth | 38 | tls_config_set_verify_depth |
36 | tls_config_verify | 39 | tls_config_verify |
37 | tls_config_verify_client | 40 | tls_config_verify_client |
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h index 645204a170..25d7c258e7 100644 --- a/src/lib/libtls/tls.h +++ b/src/lib/libtls/tls.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.h,v 1.44 2017/01/22 03:59:30 jsing Exp $ */ | 1 | /* $OpenBSD: tls.h,v 1.45 2017/01/24 01:48:05 claudio Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -66,6 +66,9 @@ extern "C" { | |||
66 | #define TLS_CRL_REASON_PRIVILEGE_WITHDRAWN 9 | 66 | #define TLS_CRL_REASON_PRIVILEGE_WITHDRAWN 9 |
67 | #define TLS_CRL_REASON_AA_COMPROMISE 10 | 67 | #define TLS_CRL_REASON_AA_COMPROMISE 10 |
68 | 68 | ||
69 | #define TLS_MAX_SESSION_ID_LENGTH 32 | ||
70 | #define TLS_TICKET_KEY_SIZE 48 | ||
71 | |||
69 | struct tls; | 72 | struct tls; |
70 | struct tls_config; | 73 | struct tls_config; |
71 | 74 | ||
@@ -128,6 +131,12 @@ void tls_config_verify_client_optional(struct tls_config *_config); | |||
128 | void tls_config_clear_keys(struct tls_config *_config); | 131 | void tls_config_clear_keys(struct tls_config *_config); |
129 | int tls_config_parse_protocols(uint32_t *_protocols, const char *_protostr); | 132 | int tls_config_parse_protocols(uint32_t *_protocols, const char *_protostr); |
130 | 133 | ||
134 | int tls_config_set_session_id(struct tls_config *_config, | ||
135 | const unsigned char *_session_id, size_t _len); | ||
136 | int tls_config_set_session_lifetime(struct tls_config *_config, int _lifetime); | ||
137 | int tls_config_add_ticket_key(struct tls_config *_config, uint32_t _keyrev, | ||
138 | unsigned char *_key, size_t _keylen); | ||
139 | |||
131 | struct tls *tls_client(void); | 140 | struct tls *tls_client(void); |
132 | struct tls *tls_server(void); | 141 | struct tls *tls_server(void); |
133 | int tls_configure(struct tls *_ctx, struct tls_config *_config); | 142 | int tls_configure(struct tls *_ctx, struct tls_config *_config); |
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c index 5bc671fc99..8fa810461c 100644 --- a/src/lib/libtls/tls_config.c +++ b/src/lib/libtls/tls_config.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_config.c,v 1.33 2016/11/11 14:02:24 jsing Exp $ */ | 1 | /* $OpenBSD: tls_config.c,v 1.34 2017/01/24 01:48:05 claudio Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -177,6 +177,7 @@ struct tls_config * | |||
177 | tls_config_new(void) | 177 | tls_config_new(void) |
178 | { | 178 | { |
179 | struct tls_config *config; | 179 | struct tls_config *config; |
180 | unsigned char sid[TLS_MAX_SESSION_ID_LENGTH]; | ||
180 | 181 | ||
181 | if ((config = calloc(1, sizeof(*config))) == NULL) | 182 | if ((config = calloc(1, sizeof(*config))) == NULL) |
182 | return (NULL); | 183 | return (NULL); |
@@ -199,6 +200,17 @@ tls_config_new(void) | |||
199 | if (tls_config_set_verify_depth(config, 6) != 0) | 200 | if (tls_config_set_verify_depth(config, 6) != 0) |
200 | goto err; | 201 | goto err; |
201 | 202 | ||
203 | /* | ||
204 | * Set session ID context to a random value. For the simple case | ||
205 | * of a single process server this is good enough. For multiprocess | ||
206 | * servers the session ID needs to be set by the caller. | ||
207 | */ | ||
208 | arc4random_buf(sid, sizeof(sid)); | ||
209 | if (tls_config_set_session_id(config, sid, sizeof(sid)) != 0) | ||
210 | goto err; | ||
211 | config->ticket_keyrev = arc4random(); | ||
212 | config->ticket_autorekey = 1; | ||
213 | |||
202 | tls_config_prefer_ciphers_server(config); | 214 | tls_config_prefer_ciphers_server(config); |
203 | 215 | ||
204 | tls_config_verify(config); | 216 | tls_config_verify(config); |
@@ -661,3 +673,91 @@ tls_config_set_ocsp_staple_mem(struct tls_config *config, char *staple, size_t l | |||
661 | { | 673 | { |
662 | return set_mem(&config->ocsp_staple, &config->ocsp_staple_len, staple, len); | 674 | return set_mem(&config->ocsp_staple, &config->ocsp_staple_len, staple, len); |
663 | } | 675 | } |
676 | |||
677 | int | ||
678 | tls_config_set_session_id(struct tls_config *config, | ||
679 | const unsigned char *session_id, size_t len) | ||
680 | { | ||
681 | if (len > TLS_MAX_SESSION_ID_LENGTH) { | ||
682 | tls_config_set_errorx(config, "session ID too large"); | ||
683 | return (-1); | ||
684 | } | ||
685 | memset(config->session_id, 0, sizeof(config->session_id)); | ||
686 | memcpy(config->session_id, session_id, len); | ||
687 | return (0); | ||
688 | } | ||
689 | |||
690 | int | ||
691 | tls_config_set_session_lifetime(struct tls_config *config, int lifetime) | ||
692 | { | ||
693 | if (lifetime > TLS_MAX_SESSION_TIMEOUT) { | ||
694 | tls_config_set_errorx(config, "session lifetime too large"); | ||
695 | return (-1); | ||
696 | } | ||
697 | if (lifetime != 0 && lifetime < TLS_MIN_SESSION_TIMEOUT) { | ||
698 | tls_config_set_errorx(config, "session lifetime too small"); | ||
699 | return (-1); | ||
700 | } | ||
701 | |||
702 | config->session_lifetime = lifetime; | ||
703 | return (0); | ||
704 | } | ||
705 | |||
706 | int | ||
707 | tls_config_add_ticket_key(struct tls_config *config, uint32_t keyrev, | ||
708 | unsigned char *key, size_t keylen) | ||
709 | { | ||
710 | struct tls_ticket_key newkey; | ||
711 | int i; | ||
712 | |||
713 | if (TLS_TICKET_KEY_SIZE != keylen || | ||
714 | sizeof(newkey.aes_key) + sizeof(newkey.hmac_key) > keylen) { | ||
715 | tls_config_set_errorx(config, | ||
716 | "wrong amount of ticket key data"); | ||
717 | return (-1); | ||
718 | } | ||
719 | |||
720 | keyrev = htonl(keyrev); | ||
721 | memset(&newkey, 0, sizeof(newkey)); | ||
722 | memcpy(newkey.key_name, &keyrev, sizeof(keyrev)); | ||
723 | memcpy(newkey.aes_key, key, sizeof(newkey.aes_key)); | ||
724 | memcpy(newkey.hmac_key, key + sizeof(newkey.aes_key), | ||
725 | sizeof(newkey.hmac_key)); | ||
726 | newkey.time = time(NULL); | ||
727 | |||
728 | for (i = 0; i < TLS_NUM_TICKETS; i++) { | ||
729 | struct tls_ticket_key *tk = &config->ticket_keys[i]; | ||
730 | if (memcmp(newkey.key_name, tk->key_name, | ||
731 | sizeof(tk->key_name)) != 0) | ||
732 | continue; | ||
733 | |||
734 | /* allow re-entry of most recent key */ | ||
735 | if (i == 0 && memcmp(newkey.aes_key, tk->aes_key, | ||
736 | sizeof(tk->aes_key)) == 0 && memcmp(newkey.hmac_key, | ||
737 | tk->hmac_key, sizeof(tk->hmac_key)) == 0) | ||
738 | return (0); | ||
739 | tls_config_set_errorx(config, "ticket key already present"); | ||
740 | return (-1); | ||
741 | } | ||
742 | |||
743 | memmove(&config->ticket_keys[1], &config->ticket_keys[0], | ||
744 | sizeof(config->ticket_keys) - sizeof(config->ticket_keys[0])); | ||
745 | config->ticket_keys[0] = newkey; | ||
746 | |||
747 | config->ticket_autorekey = 0; | ||
748 | |||
749 | return (0); | ||
750 | } | ||
751 | |||
752 | int | ||
753 | tls_config_ticket_autorekey(struct tls_config *config) | ||
754 | { | ||
755 | unsigned char key[TLS_TICKET_KEY_SIZE]; | ||
756 | int rv; | ||
757 | |||
758 | arc4random_buf(key, sizeof(key)); | ||
759 | rv = tls_config_add_ticket_key(config, config->ticket_keyrev++, key, | ||
760 | sizeof(key)); | ||
761 | config->ticket_autorekey = 1; | ||
762 | return (rv); | ||
763 | } | ||
diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3 index 05474016f4..f5cada93a5 100644 --- a/src/lib/libtls/tls_init.3 +++ b/src/lib/libtls/tls_init.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: tls_init.3,v 1.84 2017/01/24 01:16:26 claudio Exp $ | 1 | .\" $OpenBSD: tls_init.3,v 1.85 2017/01/24 01:48:05 claudio Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> | 3 | .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> |
4 | .\" | 4 | .\" |
@@ -26,6 +26,7 @@ | |||
26 | .Nm tls_config_parse_protocols , | 26 | .Nm tls_config_parse_protocols , |
27 | .Nm tls_config_add_keypair_file , | 27 | .Nm tls_config_add_keypair_file , |
28 | .Nm tls_config_add_keypair_mem , | 28 | .Nm tls_config_add_keypair_mem , |
29 | .Nm tls_config_add_ticket_key , | ||
29 | .Nm tls_config_set_alpn , | 30 | .Nm tls_config_set_alpn , |
30 | .Nm tls_config_set_ca_file , | 31 | .Nm tls_config_set_ca_file , |
31 | .Nm tls_config_set_ca_path , | 32 | .Nm tls_config_set_ca_path , |
@@ -42,6 +43,8 @@ | |||
42 | .Nm tls_config_set_ocsp_staple_mem , | 43 | .Nm tls_config_set_ocsp_staple_mem , |
43 | .Nm tls_config_set_ocsp_staple_file , | 44 | .Nm tls_config_set_ocsp_staple_file , |
44 | .Nm tls_config_set_protocols , | 45 | .Nm tls_config_set_protocols , |
46 | .Nm tls_config_set_session_id , | ||
47 | .Nm tls_config_set_session_lifetime , | ||
45 | .Nm tls_config_set_verify_depth , | 48 | .Nm tls_config_set_verify_depth , |
46 | .Nm tls_config_prefer_ciphers_client , | 49 | .Nm tls_config_prefer_ciphers_client , |
47 | .Nm tls_config_prefer_ciphers_server , | 50 | .Nm tls_config_prefer_ciphers_server , |
@@ -111,6 +114,8 @@ | |||
111 | .Ft "int" | 114 | .Ft "int" |
112 | .Fn tls_config_add_keypair_mem "struct tls_config *config" "const uint8_t *cert" "size_t cert_len" "const uint8_t *key" "size_t key_len" | 115 | .Fn tls_config_add_keypair_mem "struct tls_config *config" "const uint8_t *cert" "size_t cert_len" "const uint8_t *key" "size_t key_len" |
113 | .Ft "int" | 116 | .Ft "int" |
117 | .Fn tls_config_add_ticket_key "struct tls_config *config" "uint32_t keyrev" "unsigned char *key" "size_t keylen" | ||
118 | .Ft "int" | ||
114 | .Fn tls_config_set_alpn "struct tls_config *config" "const char *alpn" | 119 | .Fn tls_config_set_alpn "struct tls_config *config" "const char *alpn" |
115 | .Ft "int" | 120 | .Ft "int" |
116 | .Fn tls_config_set_ca_file "struct tls_config *config" "const char *ca_file" | 121 | .Fn tls_config_set_ca_file "struct tls_config *config" "const char *ca_file" |
@@ -143,6 +148,10 @@ | |||
143 | .Ft "int" | 148 | .Ft "int" |
144 | .Fn tls_config_set_protocols "struct tls_config *config" "uint32_t protocols" | 149 | .Fn tls_config_set_protocols "struct tls_config *config" "uint32_t protocols" |
145 | .Ft "int" | 150 | .Ft "int" |
151 | .Fn tls_config_set_session_id "struct tls_config *config" "const unsigned char *session_id" "size_t len" | ||
152 | .Ft "int" | ||
153 | .Fn tls_config_set_session_lifetime "struct tls_config *config" "int lifetime" | ||
154 | .Ft "int" | ||
146 | .Fn tls_config_set_verify_depth "struct tls_config *config" "int verify_depth" | 155 | .Fn tls_config_set_verify_depth "struct tls_config *config" "int verify_depth" |
147 | .Ft "void" | 156 | .Ft "void" |
148 | .Fn tls_config_prefer_ciphers_client "struct tls_config *config" | 157 | .Fn tls_config_prefer_ciphers_client "struct tls_config *config" |
@@ -371,6 +380,14 @@ used as an alternative certificate for Server Name Indication (server only). | |||
371 | adds an additional public certificate and private key from memory, | 380 | adds an additional public certificate and private key from memory, |
372 | used as an alternative certificate for Server Name Indication (server only). | 381 | used as an alternative certificate for Server Name Indication (server only). |
373 | .It | 382 | .It |
383 | .Fn tls_config_add_ticket_key | ||
384 | adds a key used for the encryption and authentication of TLS tickets. | ||
385 | By default keys are generated and rotated automatically based on their lifetime. | ||
386 | This function should only be used to synchronise ticket encryption key accross | ||
387 | multiple processes. | ||
388 | Re-adding a known key will result in an error, unless it is the most recently | ||
389 | added key. | ||
390 | .It | ||
374 | .Fn tls_config_set_alpn | 391 | .Fn tls_config_set_alpn |
375 | sets the ALPN protocols that are supported. | 392 | sets the ALPN protocols that are supported. |
376 | The alpn string is a comma separated list of protocols, in order of preference. | 393 | The alpn string is a comma separated list of protocols, in order of preference. |
@@ -447,6 +464,16 @@ Additionally, the values | |||
447 | .Dv TLS_PROTOCOLS_DEFAULT | 464 | .Dv TLS_PROTOCOLS_DEFAULT |
448 | (TLSv1.2 only) may be used. | 465 | (TLSv1.2 only) may be used. |
449 | .It | 466 | .It |
467 | .Fn tls_config_set_session_id | ||
468 | sets the session identifier that will be used by the TLS server when | ||
469 | sessions are enabled. | ||
470 | By default a random value is used. | ||
471 | .It | ||
472 | .Fn tls_config_set_session_lifetime | ||
473 | sets the lifetime to be used for TLS sessions. | ||
474 | Session support is disabled if a lifetime of zero is specified, which is the | ||
475 | default. | ||
476 | .It | ||
450 | .Fn tls_config_set_verify_depth | 477 | .Fn tls_config_set_verify_depth |
451 | limits the number of intermediate certificates that will be followed during | 478 | limits the number of intermediate certificates that will be followed during |
452 | certificate validation. | 479 | certificate validation. |
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h index 1db186a05f..3650ca9462 100644 --- a/src/lib/libtls/tls_internal.h +++ b/src/lib/libtls/tls_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_internal.h,v 1.50 2016/11/05 15:13:26 beck Exp $ */ | 1 | /* $OpenBSD: tls_internal.h,v 1.51 2017/01/24 01:48:05 claudio Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> | 3 | * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> |
4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
@@ -53,6 +53,22 @@ struct tls_keypair { | |||
53 | size_t key_len; | 53 | size_t key_len; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | #define TLS_MIN_SESSION_TIMEOUT (4) | ||
57 | #define TLS_MAX_SESSION_TIMEOUT (24 * 60 * 60) | ||
58 | |||
59 | #define TLS_NUM_TICKETS 4 | ||
60 | #define TLS_TICKET_NAME_SIZE 16 | ||
61 | #define TLS_TICKET_AES_SIZE 32 | ||
62 | #define TLS_TICKET_HMAC_SIZE 16 | ||
63 | |||
64 | struct tls_ticket_key { | ||
65 | /* The key_name must be 16 bytes according to -lssl */ | ||
66 | unsigned char key_name[TLS_TICKET_NAME_SIZE]; | ||
67 | unsigned char aes_key[TLS_TICKET_AES_SIZE]; | ||
68 | unsigned char hmac_key[TLS_TICKET_HMAC_SIZE]; | ||
69 | time_t time; | ||
70 | }; | ||
71 | |||
56 | struct tls_config { | 72 | struct tls_config { |
57 | struct tls_error error; | 73 | struct tls_error error; |
58 | 74 | ||
@@ -70,6 +86,11 @@ struct tls_config { | |||
70 | char *ocsp_staple; | 86 | char *ocsp_staple; |
71 | size_t ocsp_staple_len; | 87 | size_t ocsp_staple_len; |
72 | uint32_t protocols; | 88 | uint32_t protocols; |
89 | unsigned char session_id[TLS_MAX_SESSION_ID_LENGTH]; | ||
90 | int session_lifetime; | ||
91 | struct tls_ticket_key ticket_keys[TLS_NUM_TICKETS]; | ||
92 | uint32_t ticket_keyrev; | ||
93 | int ticket_autorekey; | ||
73 | int verify_cert; | 94 | int verify_cert; |
74 | int verify_client; | 95 | int verify_client; |
75 | int verify_depth; | 96 | int verify_depth; |
@@ -171,6 +192,7 @@ int tls_handshake_server(struct tls *ctx); | |||
171 | 192 | ||
172 | int tls_config_load_file(struct tls_error *error, const char *filetype, | 193 | int tls_config_load_file(struct tls_error *error, const char *filetype, |
173 | const char *filename, char **buf, size_t *len); | 194 | const char *filename, char **buf, size_t *len); |
195 | int tls_config_ticket_autorekey(struct tls_config *config); | ||
174 | int tls_host_port(const char *hostport, char **host, char **port); | 196 | int tls_host_port(const char *hostport, char **host, char **port); |
175 | 197 | ||
176 | int tls_set_cbs(struct tls *ctx, | 198 | int tls_set_cbs(struct tls *ctx, |
diff --git a/src/lib/libtls/tls_server.c b/src/lib/libtls/tls_server.c index 091dd7a153..5bf87552cb 100644 --- a/src/lib/libtls/tls_server.c +++ b/src/lib/libtls/tls_server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls_server.c,v 1.32 2017/01/12 16:15:58 jsing Exp $ */ | 1 | /* $OpenBSD: tls_server.c,v 1.33 2017/01/24 01:48:05 claudio Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -116,6 +116,77 @@ tls_servername_cb(SSL *ssl, int *al, void *arg) | |||
116 | return (SSL_TLSEXT_ERR_ALERT_FATAL); | 116 | return (SSL_TLSEXT_ERR_ALERT_FATAL); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct tls_ticket_key * | ||
120 | tls_server_ticket_key(struct tls_config *config, unsigned char *keyname) | ||
121 | { | ||
122 | struct tls_ticket_key *key = NULL; | ||
123 | time_t now; | ||
124 | int i; | ||
125 | |||
126 | now = time(NULL); | ||
127 | if (config->ticket_autorekey == 1) { | ||
128 | if (now - 3 * (config->session_lifetime / 4) > | ||
129 | config->ticket_keys[0].time) { | ||
130 | if (tls_config_ticket_autorekey(config) == -1) | ||
131 | return (NULL); | ||
132 | } | ||
133 | } | ||
134 | for (i = 0; i < TLS_NUM_TICKETS; i++) { | ||
135 | struct tls_ticket_key *tk = &config->ticket_keys[i]; | ||
136 | if (now - config->session_lifetime > tk->time) | ||
137 | continue; | ||
138 | if (keyname == NULL || timingsafe_memcmp(keyname, | ||
139 | tk->key_name, sizeof(tk->key_name)) == 0) { | ||
140 | key = tk; | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | return (key); | ||
145 | } | ||
146 | |||
147 | static int | ||
148 | tls_server_ticket_cb(SSL *ssl, unsigned char *keyname, unsigned char *iv, | ||
149 | EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int mode) | ||
150 | { | ||
151 | struct tls_ticket_key *key; | ||
152 | struct tls *tls_ctx; | ||
153 | |||
154 | if ((tls_ctx = SSL_get_app_data(ssl)) == NULL) | ||
155 | return (-1); | ||
156 | |||
157 | if (mode == 1) { | ||
158 | /* create new session */ | ||
159 | key = tls_server_ticket_key(tls_ctx->config, NULL); | ||
160 | if (key == NULL) { | ||
161 | tls_set_errorx(tls_ctx, "no valid ticket key found"); | ||
162 | return (-1); | ||
163 | } | ||
164 | |||
165 | memcpy(keyname, key->key_name, sizeof(key->key_name)); | ||
166 | arc4random_buf(iv, EVP_MAX_IV_LENGTH); | ||
167 | EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, | ||
168 | key->aes_key, iv); | ||
169 | HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), | ||
170 | EVP_sha256(), NULL); | ||
171 | return (0); | ||
172 | } else { | ||
173 | /* get key by name */ | ||
174 | key = tls_server_ticket_key(tls_ctx->config, keyname); | ||
175 | if (key == NULL) | ||
176 | return (0); | ||
177 | |||
178 | EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, | ||
179 | key->aes_key, iv); | ||
180 | HMAC_Init_ex(hctx, key->hmac_key, sizeof(key->hmac_key), | ||
181 | EVP_sha256(), NULL); | ||
182 | |||
183 | /* time to renew the ticket? is it the primary key? */ | ||
184 | if (key != &tls_ctx->config->ticket_keys[0]) | ||
185 | return (2); | ||
186 | return (1); | ||
187 | } | ||
188 | } | ||
189 | |||
119 | static int | 190 | static int |
120 | tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error, | 191 | tls_keypair_load_cert(struct tls_keypair *keypair, struct tls_error *error, |
121 | X509 **cert) | 192 | X509 **cert) |
@@ -157,7 +228,6 @@ static int | |||
157 | tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, | 228 | tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, |
158 | struct tls_keypair *keypair) | 229 | struct tls_keypair *keypair) |
159 | { | 230 | { |
160 | unsigned char sid[SSL_MAX_SSL_SESSION_ID_LENGTH]; | ||
161 | EC_KEY *ecdh_key; | 231 | EC_KEY *ecdh_key; |
162 | 232 | ||
163 | SSL_CTX_free(*ssl_ctx); | 233 | SSL_CTX_free(*ssl_ctx); |
@@ -219,14 +289,20 @@ tls_configure_server_ssl(struct tls *ctx, SSL_CTX **ssl_ctx, | |||
219 | goto err; | 289 | goto err; |
220 | } | 290 | } |
221 | 291 | ||
222 | /* | 292 | if (ctx->config->session_lifetime > 0) { |
223 | * Set session ID context to a random value. We don't support | 293 | /* set the session lifetime and enable tickets */ |
224 | * persistent caching of sessions so it is OK to set a temporary | 294 | SSL_CTX_set_timeout(*ssl_ctx, ctx->config->session_lifetime); |
225 | * session ID context that is valid during run time. | 295 | SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET); |
226 | */ | 296 | if (!SSL_CTX_set_tlsext_ticket_key_cb(*ssl_ctx, |
227 | arc4random_buf(sid, sizeof(sid)); | 297 | tls_server_ticket_cb)) { |
228 | if (SSL_CTX_set_session_id_context(*ssl_ctx, sid, | 298 | tls_set_error(ctx, |
229 | sizeof(sid)) != 1) { | 299 | "failed to set the TLS ticket callback"); |
300 | goto err; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | if (SSL_CTX_set_session_id_context(*ssl_ctx, ctx->config->session_id, | ||
305 | sizeof(ctx->config->session_id)) != 1) { | ||
230 | tls_set_error(ctx, "failed to set session id context"); | 306 | tls_set_error(ctx, "failed to set session id context"); |
231 | goto err; | 307 | goto err; |
232 | } | 308 | } |