diff options
Diffstat (limited to 'src')
| -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 | } |
