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 | } |
