diff options
Diffstat (limited to 'src/lib/libtls/tls_server.c')
-rw-r--r-- | src/lib/libtls/tls_server.c | 96 |
1 files changed, 86 insertions, 10 deletions
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 | } |