From: Arran Cudbard-Bell Date: Wed, 21 Jun 2023 19:47:57 +0000 (-0400) Subject: tls: Process cache mode early X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3625e0b514655c4e2e8553e0fe932225fe6af564;p=thirdparty%2Ffreeradius-server.git tls: Process cache mode early --- diff --git a/src/lib/tls/conf.c b/src/lib/tls/conf.c index 5e1a3b175ab..de519757f53 100644 --- a/src/lib/tls/conf.c +++ b/src/lib/tls/conf.c @@ -44,6 +44,8 @@ USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */ #include "base.h" #include "log.h" +int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, CONF_PARSER const *rule); + /** Certificate formats * */ @@ -80,7 +82,7 @@ static size_t verify_mode_table_len = NUM_ELEMENTS(verify_mode_table); static CONF_PARSER tls_cache_config[] = { { FR_CONF_OFFSET("mode", FR_TYPE_UINT32, fr_tls_cache_conf_t, mode), - .func = cf_table_parse_int, + .func = tls_conf_parse_cache_mode, .uctx = &(cf_table_parse_ctx_t){ .table = cache_mode_table, .len = &cache_mode_table_len @@ -246,6 +248,109 @@ CONF_PARSER fr_tls_client_config[] = { */ static char const *special_string = "Apple:UsecertAdmin"; +int tls_conf_parse_cache_mode(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, CONF_PARSER const *rule) +{ + fr_tls_conf_t *conf = talloc_get_type_abort(parent, fr_tls_conf_t); + int cache_mode; + + if (cf_table_parse_int(ctx, &cache_mode, parent, ci, rule) < 0) return -1; + + /* + * Ensure our virtual server contains the + * correct sections for the specified + * cache mode. + */ + switch (cache_mode) { + case FR_TLS_CACHE_DISABLED: + case FR_TLS_CACHE_STATELESS: + break; + + case FR_TLS_CACHE_STATEFUL: + if (!conf->virtual_server) { + cf_log_err(ci, "A virtual_server must be set when cache.mode = \"stateful\""); + error: + return -1; + } + + if (!cf_section_find(conf->virtual_server, "load", "session")) { + cf_log_err(ci, "Specified virtual_server must contain a \"load session { ... }\" section " + "when cache.mode = \"stateful\""); + goto error; + } + + if (!cf_section_find(conf->virtual_server, "store", "session")) { + cf_log_err(ci, "Specified virtual_server must contain a \"store session { ... }\" section " + "when cache.mode = \"stateful\""); + goto error; + } + + if (!cf_section_find(conf->virtual_server, "clear", "session")) { + cf_log_err(ci, "Specified virtual_server must contain a \"clear session { ... }\" section " + "when cache.mode = \"stateful\""); + goto error; + } + + if (conf->tls_min_version >= (float)1.3) { + cf_log_err(ci, "cache.mode = \"stateful\" is not supported with tls_min_version >= 1.3"); + goto error; + } + break; + + case FR_TLS_CACHE_AUTO: + if (!conf->virtual_server) { + WARN("A virtual_server must be provided for stateful caching. " + "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); + cache_stateless: + conf->cache.mode = FR_TLS_CACHE_STATELESS; + break; + } + + if (!cf_section_find(conf->virtual_server, "load", "session")) { + cf_log_warn(ci, "Specified virtual_server missing \"load session { ... }\" section. " + "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); + goto cache_stateless; + } + + if (!cf_section_find(conf->virtual_server, "store", "session")) { + cf_log_warn(ci, "Specified virtual_server missing \"store session { ... }\" section. " + "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); + goto cache_stateless; + } + + if (!cf_section_find(conf->virtual_server, "clear", "session")) { + cf_log_warn(ci, "Specified virtual_server missing \"clear cache { ... }\" section. " + "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); + goto cache_stateless; + } + + if (conf->tls_min_version >= (float)1.3) { + cf_log_err(ci, "stateful session-resumption is not supported with tls_min_version >= 1.3. " + "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); + goto error; + } + break; + } + + /* + * Generate random, ephemeral, session-ticket keys. + */ + if (cache_mode & FR_TLS_CACHE_STATELESS) { + /* + * Fill the key with randomness if one + * wasn't specified by the user. + */ + if (!conf->cache.session_ticket_key) { + MEM(conf->cache.session_ticket_key = talloc_array(conf, uint8_t, 256)); + fr_rand_buffer(UNCONST(uint8_t *, conf->cache.session_ticket_key), + talloc_array_length(conf->cache.session_ticket_key)); + } + } + + *((int *)out) = cache_mode; + + return 0; +} + /** Use cert_admin to retrieve the password for the private key * */ @@ -394,96 +499,6 @@ fr_tls_conf_t *fr_tls_conf_parse_server(CONF_SECTION *cs) if (conf_cert_admin_password(conf) < 0) goto error; #endif - /* - * Ensure our virtual server contains the - * correct sections for the specified - * cache mode. - */ - switch (conf->cache.mode) { - case FR_TLS_CACHE_DISABLED: - case FR_TLS_CACHE_STATELESS: - break; - - case FR_TLS_CACHE_STATEFUL: - if (!conf->virtual_server) { - ERROR("A virtual_server must be set when cache.mode = \"stateful\""); - goto error; - } - - if (!cf_section_find(conf->virtual_server, "load", "session")) { - ERROR("Specified virtual_server must contain a \"load session { ... }\" section " - "when cache.mode = \"stateful\""); - goto error; - } - - if (!cf_section_find(conf->virtual_server, "store", "session")) { - ERROR("Specified virtual_server must contain a \"store session { ... }\" section " - "when cache.mode = \"stateful\""); - goto error; - } - - if (!cf_section_find(conf->virtual_server, "clear", "session")) { - ERROR("Specified virtual_server must contain a \"clear session { ... }\" section " - "when cache.mode = \"stateful\""); - goto error; - } - - if (conf->tls_min_version >= (float)1.3) { - ERROR("cache.mode = \"stateful\" is not supported with tls_min_version >= 1.3"); - goto error; - } - break; - - case FR_TLS_CACHE_AUTO: - if (!conf->virtual_server) { - WARN("A virtual_server must be provided for stateful caching. " - "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); - cache_stateless: - conf->cache.mode = FR_TLS_CACHE_STATELESS; - break; - } - - if (!cf_section_find(conf->virtual_server, "load", "session")) { - WARN("Specified virtual_server missing \"load session { ... }\" section. " - "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); - goto cache_stateless; - } - - if (!cf_section_find(conf->virtual_server, "store", "session")) { - WARN("Specified virtual_server missing \"store session { ... }\" section. " - "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); - goto cache_stateless; - } - - if (!cf_section_find(conf->virtual_server, "clear", "session")) { - WARN("Specified virtual_server missing \"clear cache { ... }\" section. " - "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); - goto cache_stateless; - } - - if (conf->tls_min_version >= (float)1.3) { - ERROR("stateful session-resumption is not supported with tls_min_version >= 1.3. " - "cache.mode = \"auto\" rewritten to cache.mode = \"stateless\""); - goto error; - } - break; - } - - /* - * Generate random, ephemeral, session-ticket keys. - */ - if (conf->cache.mode & FR_TLS_CACHE_STATELESS) { - /* - * Fill the key with randomness if one - * wasn't specified by the user. - */ - if (!conf->cache.session_ticket_key) { - MEM(conf->cache.session_ticket_key = talloc_array(conf, uint8_t, 256)); - fr_rand_buffer(UNCONST(uint8_t *, conf->cache.session_ticket_key), - talloc_array_length(conf->cache.session_ticket_key)); - } - } - /* * Cache conf in cs in case we're asked to parse this again. */