]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
tls: Process cache mode early
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 21 Jun 2023 19:47:57 +0000 (15:47 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 21 Jun 2023 20:25:50 +0000 (16:25 -0400)
src/lib/tls/conf.c

index 5e1a3b175ab1371b01a1fbff84d01aed2bb80ead..de519757f534da9346334b4d93aaed881b233bdd 100644 (file)
@@ -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.
         */