blob: ce7c9a5c5a50d798d85680f246807e76cf9afe57 [file] [log] [blame]
William Lallemanddad31052020-05-14 17:47:32 +02001/*
2 *
3 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
4 * Copyright (C) 2020 HAProxy Technologies, William Lallemand <wlallemand@haproxy.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 *
12 * Configuration parsing for SSL.
13 * This file is split in 3 parts:
14 * - global section parsing
15 * - bind keyword parsing
16 * - server keyword parsing
17 *
18 * Please insert the new keywords at the right place
19 */
20
21#define _GNU_SOURCE
22#include <ctype.h>
23#include <dirent.h>
24#include <errno.h>
William Lallemanddad31052020-05-14 17:47:32 +020025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29
30#include <sys/stat.h>
31#include <sys/types.h>
32
Willy Tarreau4c7e4b72020-05-27 12:58:42 +020033#include <haproxy/api.h>
Willy Tarreau8d366972020-05-27 16:10:29 +020034#include <haproxy/base64.h>
Willy Tarreau6be78492020-06-05 00:00:29 +020035#include <haproxy/cfgparse.h>
Willy Tarreau0d1dd0e2021-10-06 19:00:49 +020036#include <haproxy/errors.h>
Willy Tarreau213e9902020-06-04 14:58:24 +020037#include <haproxy/listener.h>
Willy Tarreau6019fab2020-05-27 16:26:00 +020038#include <haproxy/openssl-compat.h>
Willy Tarreau209108d2020-06-04 20:30:20 +020039#include <haproxy/ssl_sock.h>
William Lallemand960fb742022-11-03 16:31:50 +010040#include <haproxy/ssl_utils.h>
Willy Tarreaucc81eca2021-05-08 12:54:42 +020041#include <haproxy/tools.h>
Remi Tricot-Le Bretonaf8820a2021-04-13 10:10:37 +020042#include <haproxy/ssl_ckch.h>
Remi Tricot-Le Bretonc8d814e2022-12-20 11:11:17 +010043#include <haproxy/ssl_ocsp.h>
William Lallemanddad31052020-05-14 17:47:32 +020044
45
46/****************** Global Section Parsing ********************************************/
47
48static int ssl_load_global_issuers_from_path(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +010049 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +020050 char **err)
51{
52 char *path;
53 struct dirent **de_list;
54 int i, n;
55 struct stat buf;
56 char *end;
57 char fp[MAXPATHLEN+1];
58
59 if (too_many_args(1, args, err, NULL))
60 return -1;
61
62 path = args[1];
63 if (*path == 0 || stat(path, &buf)) {
64 memprintf(err, "%sglobal statement '%s' expects a directory path as an argument.\n",
65 err && *err ? *err : "", args[0]);
66 return -1;
67 }
68 if (S_ISDIR(buf.st_mode) == 0) {
69 memprintf(err, "%sglobal statement '%s': %s is not a directory.\n",
70 err && *err ? *err : "", args[0], path);
71 return -1;
72 }
73
74 /* strip trailing slashes, including first one */
75 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
76 *end = 0;
77 /* path already parsed? */
78 if (global_ssl.issuers_chain_path && strcmp(global_ssl.issuers_chain_path, path) == 0)
79 return 0;
80 /* overwrite old issuers_chain_path */
81 free(global_ssl.issuers_chain_path);
82 global_ssl.issuers_chain_path = strdup(path);
83 ssl_free_global_issuers();
84
85 n = scandir(path, &de_list, 0, alphasort);
86 if (n < 0) {
87 memprintf(err, "%sglobal statement '%s': unable to scan directory '%s' : %s.\n",
88 err && *err ? *err : "", args[0], path, strerror(errno));
89 return -1;
90 }
91 for (i = 0; i < n; i++) {
92 struct dirent *de = de_list[i];
93 BIO *in = NULL;
94 char *warn = NULL;
95
96 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
97 free(de);
98 if (stat(fp, &buf) != 0) {
99 ha_warning("unable to stat certificate from file '%s' : %s.\n", fp, strerror(errno));
100 goto next;
101 }
102 if (!S_ISREG(buf.st_mode))
103 goto next;
104
105 in = BIO_new(BIO_s_file());
106 if (in == NULL)
107 goto next;
108 if (BIO_read_filename(in, fp) <= 0)
109 goto next;
110 ssl_load_global_issuer_from_BIO(in, fp, &warn);
111 if (warn) {
112 ha_warning("%s", warn);
Willy Tarreau61cfdf42021-02-20 10:46:51 +0100113 ha_free(&warn);
William Lallemanddad31052020-05-14 17:47:32 +0200114 }
115 next:
116 if (in)
117 BIO_free(in);
118 }
119 free(de_list);
120
121 return 0;
122}
123
William Lallemanddad31052020-05-14 17:47:32 +0200124/* parse the "ssl-mode-async" keyword in global section.
125 * Returns <0 on alert, >0 on warning, 0 on success.
126 */
127static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100128 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200129 char **err)
130{
Ilya Shipitsinbdec3ba2020-11-14 01:56:34 +0500131#ifdef SSL_MODE_ASYNC
William Lallemanddad31052020-05-14 17:47:32 +0200132 global_ssl.async = 1;
133 global.ssl_used_async_engines = nb_engines;
134 return 0;
135#else
136 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
137 return -1;
138#endif
139}
140
William Lallemandd7bfbe22022-04-11 18:41:24 +0200141#if defined(USE_ENGINE) && !defined(OPENSSL_NO_ENGINE)
William Lallemanddad31052020-05-14 17:47:32 +0200142/* parse the "ssl-engine" keyword in global section.
143 * Returns <0 on alert, >0 on warning, 0 on success.
144 */
145static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100146 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200147 char **err)
148{
149 char *algo;
150 int ret = -1;
151
152 if (*(args[1]) == 0) {
153 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
154 return ret;
155 }
156
157 if (*(args[2]) == 0) {
158 /* if no list of algorithms is given, it defaults to ALL */
159 algo = strdup("ALL");
160 goto add_engine;
161 }
162
163 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
164 if (strcmp(args[2], "algo") != 0) {
165 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
166 return ret;
167 }
168
169 if (*(args[3]) == 0) {
170 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
171 return ret;
172 }
173 algo = strdup(args[3]);
174
175add_engine:
176 if (ssl_init_single_engine(args[1], algo)==0) {
177 openssl_engines_initialized++;
178 ret = 0;
179 }
180 free(algo);
181 return ret;
182}
183#endif
184
Remi Tricot-Le Bretone8097652022-05-16 16:24:32 +0200185#ifdef HAVE_SSL_PROVIDERS
186/* parse the "ssl-propquery" keyword in global section.
187 * Returns <0 on alert, >0 on warning, 0 on success.
188 */
189static int ssl_parse_global_ssl_propquery(char **args, int section_type, struct proxy *curpx,
190 const struct proxy *defpx, const char *file, int line,
191 char **err)
192{
193 int ret = -1;
194
195 if (*(args[1]) == 0) {
196 memprintf(err, "global statement '%s' expects a property string as an argument.", args[0]);
197 return ret;
198 }
199
200 if (EVP_set_default_properties(NULL, args[1]))
201 ret = 0;
202
203 return ret;
204}
Remi Tricot-Le Breton1746a382022-05-16 16:24:33 +0200205
206/* parse the "ssl-provider" keyword in global section.
207 * Returns <0 on alert, >0 on warning, 0 on success.
208 */
209static int ssl_parse_global_ssl_provider(char **args, int section_type, struct proxy *curpx,
210 const struct proxy *defpx, const char *file, int line,
211 char **err)
212{
213 int ret = -1;
214
215 if (*(args[1]) == 0) {
216 memprintf(err, "global statement '%s' expects a valid engine provider name as an argument.", args[0]);
217 return ret;
218 }
219
220 if (ssl_init_provider(args[1]) == 0)
221 ret = 0;
222
223 return ret;
224}
Remi Tricot-Le Bretonccc03552022-05-17 15:18:37 +0200225
226/* parse the "ssl-provider-path" keyword in global section.
227 * Returns <0 on alert, >0 on warning, 0 on success.
228 */
229static int ssl_parse_global_ssl_provider_path(char **args, int section_type, struct proxy *curpx,
230 const struct proxy *defpx, const char *file, int line,
231 char **err)
232{
233 if (*(args[1]) == 0) {
234 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
235 return -1;
236 }
237
238 OSSL_PROVIDER_set_default_search_path(NULL, args[1]);
239
240 return 0;
241}
Remi Tricot-Le Bretone8097652022-05-16 16:24:32 +0200242#endif
243
William Lallemanddad31052020-05-14 17:47:32 +0200244/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
245 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
246 */
247static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100248 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200249 char **err)
250{
251 char **target;
252
253 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
254
255 if (too_many_args(1, args, err, NULL))
256 return -1;
257
258 if (*(args[1]) == 0) {
259 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
260 return -1;
261 }
262
263 free(*target);
264 *target = strdup(args[1]);
265 return 0;
266}
267
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +0500268#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +0200269/* parse the "ssl-default-bind-ciphersuites" / "ssl-default-server-ciphersuites" keywords
270 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
271 */
272static int ssl_parse_global_ciphersuites(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100273 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200274 char **err)
275{
276 char **target;
277
278 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphersuites : &global_ssl.connect_default_ciphersuites;
279
280 if (too_many_args(1, args, err, NULL))
281 return -1;
282
283 if (*(args[1]) == 0) {
284 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
285 return -1;
286 }
287
288 free(*target);
289 *target = strdup(args[1]);
290 return 0;
291}
292#endif
293
Ilya Shipitsin0aa8c292020-11-04 00:39:07 +0500294#if defined(SSL_CTX_set1_curves_list)
William Lallemanddad31052020-05-14 17:47:32 +0200295/*
296 * parse the "ssl-default-bind-curves" keyword in a global section.
297 * Returns <0 on alert, >0 on warning, 0 on success.
298 */
299static int ssl_parse_global_curves(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100300 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200301 char **err)
302{
303 char **target;
304 target = &global_ssl.listen_default_curves;
305
306 if (too_many_args(1, args, err, NULL))
307 return -1;
308
309 if (*(args[1]) == 0) {
310 memprintf(err, "global statement '%s' expects a curves suite as an arguments.", args[0]);
311 return -1;
312 }
313
314 free(*target);
315 *target = strdup(args[1]);
316 return 0;
317}
318#endif
William Lallemand1d3c8222023-05-04 15:33:55 +0200319
320#if defined(SSL_CTX_set1_sigalgs_list)
321/*
322 * parse the "ssl-default-bind-sigalgs" keyword in a global section.
323 * Returns <0 on alert, >0 on warning, 0 on success.
324 */
325static int ssl_parse_global_sigalgs(char **args, int section_type, struct proxy *curpx,
326 const struct proxy *defpx, const char *file, int line,
327 char **err)
328{
329 char **target;
330
331 target = &global_ssl.listen_default_sigalgs;
332
333 if (too_many_args(1, args, err, NULL))
334 return -1;
335
336 if (*(args[1]) == 0) {
337 memprintf(err, "global statement '%s' expects a curves suite as an arguments.", args[0]);
338 return -1;
339 }
340
341 free(*target);
342 *target = strdup(args[1]);
343 return 0;
344}
345#endif
346
William Lallemandb6ae2aa2023-05-05 00:05:46 +0200347#if defined(SSL_CTX_set1_client_sigalgs_list)
348/*
349 * parse the "ssl-default-bind-client-sigalgs" keyword in a global section.
350 * Returns <0 on alert, >0 on warning, 0 on success.
351 */
352static int ssl_parse_global_client_sigalgs(char **args, int section_type, struct proxy *curpx,
353 const struct proxy *defpx, const char *file, int line,
354 char **err)
355{
356 char **target;
357
358 target = &global_ssl.listen_default_client_sigalgs;
359
360 if (too_many_args(1, args, err, NULL))
361 return -1;
362
363 if (*(args[1]) == 0) {
364 memprintf(err, "global statement '%s' expects signature algorithms as an arguments.", args[0]);
365 return -1;
366 }
367
368 free(*target);
369 *target = strdup(args[1]);
370 return 0;
371}
372#endif
373
William Lallemanddad31052020-05-14 17:47:32 +0200374/* parse various global tune.ssl settings consisting in positive integers.
375 * Returns <0 on alert, >0 on warning, 0 on success.
376 */
377static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100378 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200379 char **err)
380{
381 int *target;
382
383 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
384 target = &global.tune.sslcachesize;
385 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
386 target = (int *)&global_ssl.max_record;
Thomas Prückl10243932022-04-27 13:04:54 +0200387 else if (strcmp(args[0], "tune.ssl.hard-maxrecord") == 0)
388 target = (int *)&global_ssl.hard_max_record;
William Lallemanddad31052020-05-14 17:47:32 +0200389 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
390 target = &global_ssl.ctx_cache;
391 else if (strcmp(args[0], "maxsslconn") == 0)
392 target = &global.maxsslconn;
Marcin Deranek310a2602021-07-13 19:04:24 +0200393 else if (strcmp(args[0], "tune.ssl.capture-buffer-size") == 0)
394 target = &global_ssl.capture_buffer_size;
395 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0) {
396 target = &global_ssl.capture_buffer_size;
397 ha_warning("parsing [%s:%d]: '%s' is deprecated and will be removed in version 2.7. Please use 'tune.ssl.capture-buffer-size' instead.\n",
398 file, line, args[0]);
399 }
William Lallemanddad31052020-05-14 17:47:32 +0200400 else {
401 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
402 return -1;
403 }
404
405 if (too_many_args(1, args, err, NULL))
406 return -1;
407
408 if (*(args[1]) == 0) {
409 memprintf(err, "'%s' expects an integer argument.", args[0]);
410 return -1;
411 }
412
413 *target = atoi(args[1]);
414 if (*target < 0) {
415 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
416 return -1;
417 }
418 return 0;
419}
420
Marcin Deranek310a2602021-07-13 19:04:24 +0200421static int ssl_parse_global_capture_buffer(char **args, int section_type, struct proxy *curpx,
422 const struct proxy *defpx, const char *file, int line,
423 char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200424{
425 int ret;
426
427 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
428 if (ret != 0)
429 return ret;
430
431 if (pool_head_ssl_capture) {
432 memprintf(err, "'%s' is already configured.", args[0]);
433 return -1;
434 }
435
Marcin Deranek310a2602021-07-13 19:04:24 +0200436 pool_head_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_buffer_size, MEM_F_SHARED);
William Lallemanddad31052020-05-14 17:47:32 +0200437 if (!pool_head_ssl_capture) {
438 memprintf(err, "Out of memory error.");
439 return -1;
440 }
441 return 0;
442}
443
William Lallemand7d42ef52020-07-06 11:41:30 +0200444/* init the SSLKEYLOGFILE pool */
William Lallemand722180a2021-06-09 16:46:12 +0200445#ifdef HAVE_SSL_KEYLOG
William Lallemand7d42ef52020-07-06 11:41:30 +0200446static int ssl_parse_global_keylog(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100447 const struct proxy *defpx, const char *file, int line,
William Lallemand7d42ef52020-07-06 11:41:30 +0200448 char **err)
449{
450
451 if (too_many_args(1, args, err, NULL))
452 return -1;
453
454 if (strcmp(args[1], "on") == 0)
455 global_ssl.keylog = 1;
456 else if (strcmp(args[1], "off") == 0)
457 global_ssl.keylog = 0;
458 else {
459 memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]);
460 return -1;
461 }
462
463 if (pool_head_ssl_keylog) /* already configured */
464 return 0;
465
466 pool_head_ssl_keylog = create_pool("ssl-keylogfile", sizeof(struct ssl_keylog), MEM_F_SHARED);
467 if (!pool_head_ssl_keylog) {
468 memprintf(err, "Out of memory error.");
469 return -1;
470 }
471
472 pool_head_ssl_keylog_str = create_pool("ssl-keylogfile-str", sizeof(char) * SSL_KEYLOG_MAX_SECRET_SIZE, MEM_F_SHARED);
473 if (!pool_head_ssl_keylog_str) {
474 memprintf(err, "Out of memory error.");
475 return -1;
476 }
477
478 return 0;
479}
William Lallemand722180a2021-06-09 16:46:12 +0200480#else
481static int ssl_parse_global_keylog(char **args, int section_type, struct proxy *curpx,
482 const struct proxy *defpx, const char *file, int line,
483 char **err)
484{
485 memprintf(err, "'%s' requires at least OpenSSL 1.1.1.", args[0]);
486 return -1;
487}
William Lallemand7d42ef52020-07-06 11:41:30 +0200488#endif
489
William Lallemanddad31052020-05-14 17:47:32 +0200490/* parse "ssl.force-private-cache".
491 * Returns <0 on alert, >0 on warning, 0 on success.
492 */
493static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100494 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200495 char **err)
496{
497 if (too_many_args(0, args, err, NULL))
498 return -1;
499
500 global_ssl.private_cache = 1;
501 return 0;
502}
503
504/* parse "ssl.lifetime".
505 * Returns <0 on alert, >0 on warning, 0 on success.
506 */
507static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100508 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200509 char **err)
510{
511 const char *res;
512
513 if (too_many_args(1, args, err, NULL))
514 return -1;
515
516 if (*(args[1]) == 0) {
517 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
518 return -1;
519 }
520
521 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
522 if (res == PARSE_TIME_OVER) {
523 memprintf(err, "timer overflow in argument '%s' to <%s> (maximum value is 2147483647 s or ~68 years).",
524 args[1], args[0]);
525 return -1;
526 }
527 else if (res == PARSE_TIME_UNDER) {
528 memprintf(err, "timer underflow in argument '%s' to <%s> (minimum non-null value is 1 s).",
529 args[1], args[0]);
530 return -1;
531 }
532 else if (res) {
533 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
534 return -1;
535 }
536 return 0;
537}
538
539#ifndef OPENSSL_NO_DH
540/* parse "ssl-dh-param-file".
541 * Returns <0 on alert, >0 on warning, 0 on success.
542 */
543static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100544 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200545 char **err)
546{
547 if (too_many_args(1, args, err, NULL))
548 return -1;
549
550 if (*(args[1]) == 0) {
551 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
552 return -1;
553 }
554
555 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
556 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
557 return -1;
558 }
559 return 0;
560}
561
562/* parse "ssl.default-dh-param".
563 * Returns <0 on alert, >0 on warning, 0 on success.
564 */
565static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100566 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200567 char **err)
568{
569 if (too_many_args(1, args, err, NULL))
570 return -1;
571
572 if (*(args[1]) == 0) {
573 memprintf(err, "'%s' expects an integer argument.", args[0]);
574 return -1;
575 }
576
577 global_ssl.default_dh_param = atoi(args[1]);
578 if (global_ssl.default_dh_param < 1024) {
579 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
580 return -1;
581 }
582 return 0;
583}
584#endif
585
586
587/*
588 * parse "ssl-load-extra-files".
589 * multiple arguments are allowed: "bundle", "sctl", "ocsp", "issuer", "all", "none"
590 */
591static int ssl_parse_global_extra_files(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100592 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +0200593 char **err)
594{
595 int i;
596 int gf = SSL_GF_NONE;
597
598 if (*(args[1]) == 0)
599 goto err_arg;
600
601 for (i = 1; *args[i]; i++) {
602
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100603 if (strcmp("bundle", args[i]) == 0) {
William Lallemanddad31052020-05-14 17:47:32 +0200604 gf |= SSL_GF_BUNDLE;
605
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100606 } else if (strcmp("sctl", args[i]) == 0) {
William Lallemanddad31052020-05-14 17:47:32 +0200607 gf |= SSL_GF_SCTL;
608
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100609 } else if (strcmp("ocsp", args[i]) == 0){
William Lallemanddad31052020-05-14 17:47:32 +0200610 gf |= SSL_GF_OCSP;
611
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100612 } else if (strcmp("issuer", args[i]) == 0){
William Lallemanddad31052020-05-14 17:47:32 +0200613 gf |= SSL_GF_OCSP_ISSUER;
614
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100615 } else if (strcmp("key", args[i]) == 0) {
William Lallemanddad31052020-05-14 17:47:32 +0200616 gf |= SSL_GF_KEY;
617
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100618 } else if (strcmp("none", args[i]) == 0) {
William Lallemanddad31052020-05-14 17:47:32 +0200619 if (gf != SSL_GF_NONE)
620 goto err_alone;
621 gf = SSL_GF_NONE;
622 i++;
623 break;
624
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100625 } else if (strcmp("all", args[i]) == 0) {
William Lallemanddad31052020-05-14 17:47:32 +0200626 if (gf != SSL_GF_NONE)
627 goto err_alone;
628 gf = SSL_GF_ALL;
629 i++;
630 break;
631 } else {
632 goto err_arg;
633 }
634 }
635 /* break from loop but there are still arguments */
636 if (*args[i])
637 goto err_alone;
638
639 global_ssl.extra_files = gf;
640
641 return 0;
642
643err_alone:
644 memprintf(err, "'%s' 'none' and 'all' can be only used alone", args[0]);
645 return -1;
646
647err_arg:
648 memprintf(err, "'%s' expects one or multiple arguments (none, all, bundle, sctl, ocsp, issuer).", args[0]);
649 return -1;
650}
651
652
William Lallemand8e8581e2020-10-20 17:36:46 +0200653/* parse 'ssl-load-extra-del-ext */
654static int ssl_parse_global_extra_noext(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +0100655 const struct proxy *defpx, const char *file, int line,
William Lallemand8e8581e2020-10-20 17:36:46 +0200656 char **err)
657{
658 global_ssl.extra_files_noext = 1;
659 return 0;
660}
661
Remi Tricot-Le Breton03c5fff2022-12-20 11:11:10 +0100662
William Lallemanddad31052020-05-14 17:47:32 +0200663/***************************** Bind keyword Parsing ********************************************/
664
665/* for ca-file and ca-verify-file */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100666static int ssl_bind_parse_ca_file_common(char **args, int cur_arg, char **ca_file_p, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200667{
668 if (!*args[cur_arg + 1]) {
669 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
670 return ERR_ALERT | ERR_FATAL;
671 }
672
William Lallemandf3e225d2023-10-23 21:54:23 +0200673 if ((*args[cur_arg + 1] != '/') && (*args[cur_arg + 1] != '@') && global_ssl.ca_base)
William Lallemanddad31052020-05-14 17:47:32 +0200674 memprintf(ca_file_p, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
675 else
676 memprintf(ca_file_p, "%s", args[cur_arg + 1]);
677
Remi Tricot-Le Breton0bb48242021-04-16 17:59:23 +0200678 if (!ssl_store_load_locations_file(*ca_file_p, !from_cli, CAFILE_CERT)) {
William Lallemanddad31052020-05-14 17:47:32 +0200679 memprintf(err, "'%s' : unable to load %s", args[cur_arg], *ca_file_p);
680 return ERR_ALERT | ERR_FATAL;
681 }
682 return 0;
683}
684
685/* parse the "ca-file" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100686static int ssl_bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200687{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100688 return ssl_bind_parse_ca_file_common(args, cur_arg, &conf->ca_file, from_cli, err);
William Lallemanddad31052020-05-14 17:47:32 +0200689}
690static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
691{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100692 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200693}
694
695/* parse the "ca-verify-file" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100696static int ssl_bind_parse_ca_verify_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200697{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100698 return ssl_bind_parse_ca_file_common(args, cur_arg, &conf->ca_verify_file, from_cli, err);
William Lallemanddad31052020-05-14 17:47:32 +0200699}
700static int bind_parse_ca_verify_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
701{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100702 return ssl_bind_parse_ca_verify_file(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200703}
704
705/* parse the "ca-sign-file" bind keyword */
706static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
707{
708 if (!*args[cur_arg + 1]) {
709 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
710 return ERR_ALERT | ERR_FATAL;
711 }
712
William Lallemandf3e225d2023-10-23 21:54:23 +0200713 if ((*args[cur_arg + 1] != '/') && (*args[cur_arg + 1] != '@') && global_ssl.ca_base)
William Lallemanddad31052020-05-14 17:47:32 +0200714 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
715 else
716 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
717
718 return 0;
719}
720
721/* parse the "ca-sign-pass" bind keyword */
722static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
723{
724 if (!*args[cur_arg + 1]) {
725 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
726 return ERR_ALERT | ERR_FATAL;
727 }
728 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
729 return 0;
730}
731
732/* parse the "ciphers" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100733static int ssl_bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200734{
735 if (!*args[cur_arg + 1]) {
736 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
737 return ERR_ALERT | ERR_FATAL;
738 }
739
740 free(conf->ciphers);
741 conf->ciphers = strdup(args[cur_arg + 1]);
742 return 0;
743}
744static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
745{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100746 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200747}
748
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +0500749#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +0200750/* parse the "ciphersuites" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100751static int ssl_bind_parse_ciphersuites(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200752{
753 if (!*args[cur_arg + 1]) {
754 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
755 return ERR_ALERT | ERR_FATAL;
756 }
757
758 free(conf->ciphersuites);
759 conf->ciphersuites = strdup(args[cur_arg + 1]);
760 return 0;
761}
762static int bind_parse_ciphersuites(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
763{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100764 return ssl_bind_parse_ciphersuites(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200765}
766#endif
767
768/* parse the "crt" bind keyword. Returns a set of ERR_* flags possibly with an error in <err>. */
769static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
770{
771 char path[MAXPATHLEN];
772
773 if (!*args[cur_arg + 1]) {
774 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
775 return ERR_ALERT | ERR_FATAL;
776 }
777
778 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
Willy Tarreau393e42a2022-05-09 10:31:28 +0200779 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > sizeof(path) ||
780 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]) > sizeof(path)) {
William Lallemanddad31052020-05-14 17:47:32 +0200781 memprintf(err, "'%s' : path too long", args[cur_arg]);
782 return ERR_ALERT | ERR_FATAL;
783 }
William Lallemanddad31052020-05-14 17:47:32 +0200784 return ssl_sock_load_cert(path, conf, err);
785 }
786
787 return ssl_sock_load_cert(args[cur_arg + 1], conf, err);
788}
789
790/* parse the "crt-list" bind keyword. Returns a set of ERR_* flags possibly with an error in <err>. */
791static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
792{
793 int err_code;
794
795 if (!*args[cur_arg + 1]) {
796 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
797 return ERR_ALERT | ERR_FATAL;
798 }
799
800 err_code = ssl_sock_load_cert_list_file(args[cur_arg + 1], 0, conf, px, err);
801 if (err_code)
802 memprintf(err, "'%s' : %s", args[cur_arg], *err);
803
804 return err_code;
805}
806
807/* parse the "crl-file" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100808static int ssl_bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200809{
810#ifndef X509_V_FLAG_CRL_CHECK
811 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
812 return ERR_ALERT | ERR_FATAL;
813#else
814 if (!*args[cur_arg + 1]) {
815 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
816 return ERR_ALERT | ERR_FATAL;
817 }
818
William Lallemandf3e225d2023-10-23 21:54:23 +0200819 if ((*args[cur_arg + 1] != '/') && (*args[cur_arg + 1] != '@') && global_ssl.ca_base)
William Lallemanddad31052020-05-14 17:47:32 +0200820 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
821 else
822 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
823
Remi Tricot-Le Breton0bb48242021-04-16 17:59:23 +0200824 if (!ssl_store_load_locations_file(conf->crl_file, !from_cli, CAFILE_CRL)) {
William Lallemanddad31052020-05-14 17:47:32 +0200825 memprintf(err, "'%s' : unable to load %s", args[cur_arg], conf->crl_file);
826 return ERR_ALERT | ERR_FATAL;
827 }
828 return 0;
829#endif
830}
831static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
832{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100833 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200834}
835
836/* parse the "curves" bind keyword keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100837static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200838{
Ilya Shipitsin0aa8c292020-11-04 00:39:07 +0500839#if defined(SSL_CTX_set1_curves_list)
William Lallemanddad31052020-05-14 17:47:32 +0200840 if (!*args[cur_arg + 1]) {
841 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
842 return ERR_ALERT | ERR_FATAL;
843 }
844 conf->curves = strdup(args[cur_arg + 1]);
845 return 0;
846#else
847 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
848 return ERR_ALERT | ERR_FATAL;
849#endif
850}
851static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
852{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100853 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200854}
855
William Lallemand1d3c8222023-05-04 15:33:55 +0200856/* parse the "sigalgs" bind keyword */
857static int ssl_bind_parse_sigalgs(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
858{
859#if defined(SSL_CTX_set1_sigalgs_list)
860 if (!*args[cur_arg + 1]) {
861 memprintf(err, "'%s' : missing signature algorithm list", args[cur_arg]);
862 return ERR_ALERT | ERR_FATAL;
863 }
864 conf->sigalgs = strdup(args[cur_arg + 1]);
865 return 0;
866#else
867 memprintf(err, "'%s' : library does not support setting signature algorithms", args[cur_arg]);
868 return ERR_ALERT | ERR_FATAL;
869#endif
870}
871static int bind_parse_sigalgs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
872{
873 return ssl_bind_parse_sigalgs(args, cur_arg, px, &conf->ssl_conf, 0, err);
874}
875
William Lallemandb6ae2aa2023-05-05 00:05:46 +0200876/* parse the "client-sigalgs" bind keyword */
877static int ssl_bind_parse_client_sigalgs(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
878{
879#if defined(SSL_CTX_set1_client_sigalgs_list)
880 if (!*args[cur_arg + 1]) {
881 memprintf(err, "'%s' : missing signature algorithm list", args[cur_arg]);
882 return ERR_ALERT | ERR_FATAL;
883 }
884 conf->client_sigalgs = strdup(args[cur_arg + 1]);
885 return 0;
886#else
887 memprintf(err, "'%s' : library does not support setting signature algorithms", args[cur_arg]);
888 return ERR_ALERT | ERR_FATAL;
889#endif
890}
891static int bind_parse_client_sigalgs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
892{
893 return ssl_bind_parse_client_sigalgs(args, cur_arg, px, &conf->ssl_conf, 0, err);
894}
895
William Lallemand1d3c8222023-05-04 15:33:55 +0200896
William Lallemanddad31052020-05-14 17:47:32 +0200897/* parse the "ecdhe" bind keyword keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100898static int ssl_bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +0200899{
Ilya Shipitsina0fd35b2021-03-21 12:50:47 +0500900#if !defined(SSL_CTX_set_tmp_ecdh)
William Lallemanddad31052020-05-14 17:47:32 +0200901 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
902 return ERR_ALERT | ERR_FATAL;
903#elif defined(OPENSSL_NO_ECDH)
904 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
905 return ERR_ALERT | ERR_FATAL;
906#else
907 if (!*args[cur_arg + 1]) {
908 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
909 return ERR_ALERT | ERR_FATAL;
910 }
911
912 conf->ecdhe = strdup(args[cur_arg + 1]);
913
914 return 0;
915#endif
916}
917static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
918{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +0100919 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +0200920}
921
922/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
923static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
924{
925 int code;
William Lallemand960fb742022-11-03 16:31:50 +0100926 char *s1 = NULL, *s2 = NULL;
927 char *token = NULL;
William Lallemanddad31052020-05-14 17:47:32 +0200928 char *p = args[cur_arg + 1];
William Lallemand960fb742022-11-03 16:31:50 +0100929 char *str;
Remi Tricot-Le Breton9b259822022-11-10 10:48:58 +0100930 unsigned long long *ignerr = conf->crt_ignerr_bitfield;
William Lallemanddad31052020-05-14 17:47:32 +0200931
932 if (!*p) {
933 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
934 return ERR_ALERT | ERR_FATAL;
935 }
936
937 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
Remi Tricot-Le Breton9b259822022-11-10 10:48:58 +0100938 ignerr = conf->ca_ignerr_bitfield;
William Lallemanddad31052020-05-14 17:47:32 +0200939
940 if (strcmp(p, "all") == 0) {
Remi Tricot-Le Breton9b259822022-11-10 10:48:58 +0100941 cert_ignerr_bitfield_set_all(ignerr);
William Lallemanddad31052020-05-14 17:47:32 +0200942 return 0;
943 }
944
William Lallemandf813dab2022-11-14 11:36:11 +0100945 /* copy the string to be able to dump the complete one in case of
946 * error, because strtok_r is writing \0 inside. */
947 str = strdup(p);
948 if (!str) {
949 memprintf(err, "'%s' : Could not allocate memory", args[cur_arg]);
950 return ERR_ALERT | ERR_FATAL;
951 }
952
William Lallemand960fb742022-11-03 16:31:50 +0100953 s1 = str;
954 while ((token = strtok_r(s1, ",", &s2))) {
955 s1 = NULL;
William Lallemand960fb742022-11-03 16:31:50 +0100956 if (isdigit((int)*token)) {
957 code = atoi(token);
958 if ((code <= 0) || (code > SSL_MAX_VFY_ERROR_CODE)) {
959 memprintf(err, "'%s' : ID '%d' out of range (1..%d) in error IDs list '%s'",
960 args[cur_arg], code, SSL_MAX_VFY_ERROR_CODE, args[cur_arg + 1]);
961 free(str);
962 return ERR_ALERT | ERR_FATAL;
963 }
964 } else {
965 code = x509_v_err_str_to_int(token);
966 if (code < 0) {
967 memprintf(err, "'%s' : error constant '%s' unknown in error IDs list '%s'",
968 args[cur_arg], token, args[cur_arg + 1]);
969 free(str);
970 return ERR_ALERT | ERR_FATAL;
971 }
William Lallemanddad31052020-05-14 17:47:32 +0200972 }
Remi Tricot-Le Breton9b259822022-11-10 10:48:58 +0100973 cert_ignerr_bitfield_set(ignerr, code);
William Lallemanddad31052020-05-14 17:47:32 +0200974 }
975
William Lallemand960fb742022-11-03 16:31:50 +0100976 free(str);
William Lallemanddad31052020-05-14 17:47:32 +0200977 return 0;
978}
979
980/* parse tls_method_options "no-xxx" and "force-xxx" */
981static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
982{
983 uint16_t v;
984 char *p;
985 p = strchr(arg, '-');
986 if (!p)
987 goto fail;
988 p++;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100989 if (strcmp(p, "sslv3") == 0)
William Lallemanddad31052020-05-14 17:47:32 +0200990 v = CONF_SSLV3;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100991 else if (strcmp(p, "tlsv10") == 0)
William Lallemanddad31052020-05-14 17:47:32 +0200992 v = CONF_TLSV10;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100993 else if (strcmp(p, "tlsv11") == 0)
William Lallemanddad31052020-05-14 17:47:32 +0200994 v = CONF_TLSV11;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100995 else if (strcmp(p, "tlsv12") == 0)
William Lallemanddad31052020-05-14 17:47:32 +0200996 v = CONF_TLSV12;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +0100997 else if (strcmp(p, "tlsv13") == 0)
William Lallemanddad31052020-05-14 17:47:32 +0200998 v = CONF_TLSV13;
999 else
1000 goto fail;
1001 if (!strncmp(arg, "no-", 3))
1002 methods->flags |= methodVersions[v].flag;
1003 else if (!strncmp(arg, "force-", 6))
1004 methods->min = methods->max = v;
1005 else
1006 goto fail;
1007 return 0;
1008 fail:
1009 memprintf(err, "'%s' : option not implemented", arg);
1010 return ERR_ALERT | ERR_FATAL;
1011}
1012
1013static int bind_parse_tls_method_options(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1014{
1015 return parse_tls_method_options(args[cur_arg], &conf->ssl_conf.ssl_methods, err);
1016}
1017
1018static int srv_parse_tls_method_options(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1019{
1020 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
1021}
1022
1023/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
1024static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
1025{
1026 uint16_t i, v = 0;
1027 char *argv = args[cur_arg + 1];
1028 if (!*argv) {
1029 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
1030 return ERR_ALERT | ERR_FATAL;
1031 }
1032 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001033 if (strcmp(argv, methodVersions[i].name) == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001034 v = i;
1035 if (!v) {
1036 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
1037 return ERR_ALERT | ERR_FATAL;
1038 }
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001039 if (strcmp("ssl-min-ver", args[cur_arg]) == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001040 methods->min = v;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001041 else if (strcmp("ssl-max-ver", args[cur_arg]) == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001042 methods->max = v;
1043 else {
1044 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
1045 return ERR_ALERT | ERR_FATAL;
1046 }
1047 return 0;
1048}
1049
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001050static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001051{
William Lallemand8177ad92020-05-20 16:49:02 +02001052 int ret;
1053
William Lallemanddad31052020-05-14 17:47:32 +02001054#if (HA_OPENSSL_VERSION_NUMBER < 0x10101000L) && !defined(OPENSSL_IS_BORINGSSL)
1055 ha_warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
1056#endif
William Lallemand8177ad92020-05-20 16:49:02 +02001057 ret = parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods_cfg, err);
1058 if (ret != ERR_NONE)
1059 return ret;
William Lallemanddad31052020-05-14 17:47:32 +02001060
William Lallemand8177ad92020-05-20 16:49:02 +02001061 conf->ssl_methods.min = conf->ssl_methods_cfg.min;
1062 conf->ssl_methods.max = conf->ssl_methods_cfg.max;
1063
1064 return ret;
1065}
William Lallemanddad31052020-05-14 17:47:32 +02001066static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1067{
1068 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_conf.ssl_methods, err);
1069}
1070
1071static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1072{
1073 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
1074}
1075
1076/* parse the "no-tls-tickets" bind keyword */
1077static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1078{
1079 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
1080 return 0;
1081}
1082
1083/* parse the "allow-0rtt" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001084static int ssl_bind_parse_allow_0rtt(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001085{
1086 conf->early_data = 1;
1087 return 0;
1088}
1089
1090static int bind_parse_allow_0rtt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1091{
1092 conf->ssl_conf.early_data = 1;
1093 return 0;
1094}
1095
1096/* parse the "npn" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001097static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001098{
1099#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
1100 char *p1, *p2;
1101
1102 if (!*args[cur_arg + 1]) {
1103 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
1104 return ERR_ALERT | ERR_FATAL;
1105 }
1106
1107 free(conf->npn_str);
1108
1109 /* the NPN string is built as a suite of (<len> <name>)*,
1110 * so we reuse each comma to store the next <len> and need
1111 * one more for the end of the string.
1112 */
1113 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
1114 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreauc57fb3b2022-12-29 11:11:02 +01001115 if (!conf->npn_str) {
1116 memprintf(err, "out of memory");
1117 return ERR_ALERT | ERR_FATAL;
1118 }
1119
William Lallemanddad31052020-05-14 17:47:32 +02001120 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
1121
1122 /* replace commas with the name length */
1123 p1 = conf->npn_str;
1124 p2 = p1 + 1;
1125 while (1) {
1126 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
1127 if (!p2)
1128 p2 = p1 + 1 + strlen(p1 + 1);
1129
1130 if (p2 - (p1 + 1) > 255) {
1131 *p2 = '\0';
1132 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
1133 return ERR_ALERT | ERR_FATAL;
1134 }
1135
1136 *p1 = p2 - (p1 + 1);
1137 p1 = p2;
1138
1139 if (!*p2)
1140 break;
1141
1142 *(p2++) = '\0';
1143 }
1144 return 0;
1145#else
1146 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
1147 return ERR_ALERT | ERR_FATAL;
1148#endif
1149}
1150
1151static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1152{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001153 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +02001154}
1155
1156
1157/* Parses a alpn string and converts it to the right format for the SSL api */
1158int ssl_sock_parse_alpn(char *arg, char **alpn_str, int *alpn_len, char **err)
1159{
1160 char *p1, *p2, *alpn = NULL;
1161 int len, ret = 0;
1162
1163 *alpn_str = NULL;
1164 *alpn_len = 0;
1165
1166 if (!*arg) {
1167 memprintf(err, "missing the comma-delimited ALPN protocol suite");
1168 goto error;
1169 }
1170
1171 /* the ALPN string is built as a suite of (<len> <name>)*,
1172 * so we reuse each comma to store the next <len> and need
1173 * one more for the end of the string.
1174 */
1175 len = strlen(arg) + 1;
1176 alpn = calloc(1, len+1);
1177 if (!alpn) {
1178 memprintf(err, "'%s' : out of memory", arg);
1179 goto error;
1180 }
1181 memcpy(alpn+1, arg, len);
1182
1183 /* replace commas with the name length */
1184 p1 = alpn;
1185 p2 = p1 + 1;
1186 while (1) {
1187 p2 = memchr(p1 + 1, ',', alpn + len - (p1 + 1));
1188 if (!p2)
1189 p2 = p1 + 1 + strlen(p1 + 1);
1190
1191 if (p2 - (p1 + 1) > 255) {
1192 *p2 = '\0';
1193 memprintf(err, "ALPN protocol name too long : '%s'", p1 + 1);
1194 goto error;
1195 }
1196
1197 *p1 = p2 - (p1 + 1);
1198 p1 = p2;
1199
1200 if (!*p2)
1201 break;
1202
1203 *(p2++) = '\0';
1204 }
1205
1206 *alpn_str = alpn;
1207 *alpn_len = len;
1208
1209 out:
1210 return ret;
1211
1212 error:
1213 free(alpn);
1214 ret = ERR_ALERT | ERR_FATAL;
1215 goto out;
1216}
1217
1218/* parse the "alpn" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001219static int ssl_bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001220{
1221#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1222 int ret;
1223
1224 free(conf->alpn_str);
1225
1226 ret = ssl_sock_parse_alpn(args[cur_arg + 1], &conf->alpn_str, &conf->alpn_len, err);
1227 if (ret)
1228 memprintf(err, "'%s' : %s", args[cur_arg], *err);
1229 return ret;
1230#else
1231 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
1232 return ERR_ALERT | ERR_FATAL;
1233#endif
1234}
1235
1236static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1237{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001238 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +02001239}
1240
1241/* parse the "ssl" bind keyword */
1242static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1243{
Willy Tarreau11ba4042022-05-20 15:56:32 +02001244 conf->options |= BC_O_USE_SSL;
William Lallemanddad31052020-05-14 17:47:32 +02001245
1246 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
1247 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Ilya Shipitsin0aa8c292020-11-04 00:39:07 +05001248#if defined(SSL_CTX_set1_curves_list)
William Lallemanddad31052020-05-14 17:47:32 +02001249 if (global_ssl.listen_default_curves && !conf->ssl_conf.curves)
1250 conf->ssl_conf.curves = strdup(global_ssl.listen_default_curves);
1251#endif
William Lallemand1d3c8222023-05-04 15:33:55 +02001252#if defined(SSL_CTX_set1_sigalgs_list)
1253 if (global_ssl.listen_default_sigalgs && !conf->ssl_conf.sigalgs)
1254 conf->ssl_conf.sigalgs = strdup(global_ssl.listen_default_sigalgs);
1255#endif
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05001256#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +02001257 if (global_ssl.listen_default_ciphersuites && !conf->ssl_conf.ciphersuites)
1258 conf->ssl_conf.ciphersuites = strdup(global_ssl.listen_default_ciphersuites);
1259#endif
1260 conf->ssl_options |= global_ssl.listen_default_ssloptions;
1261 conf->ssl_conf.ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
1262 if (!conf->ssl_conf.ssl_methods.min)
1263 conf->ssl_conf.ssl_methods.min = global_ssl.listen_default_sslmethods.min;
1264 if (!conf->ssl_conf.ssl_methods.max)
1265 conf->ssl_conf.ssl_methods.max = global_ssl.listen_default_sslmethods.max;
1266
1267 return 0;
1268}
1269
1270/* parse the "prefer-client-ciphers" bind keyword */
1271static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1272{
1273 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
1274 return 0;
1275}
1276
1277/* parse the "generate-certificates" bind keyword */
1278static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1279{
1280#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreau1ea6e6a2022-05-20 16:03:18 +02001281 conf->options |= BC_O_GENERATE_CERTS;
William Lallemanddad31052020-05-14 17:47:32 +02001282#else
1283 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
1284 err && *err ? *err : "");
1285#endif
1286 return 0;
1287}
1288
1289/* parse the "strict-sni" bind keyword */
1290static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1291{
1292 conf->strict_sni = 1;
1293 return 0;
1294}
1295
1296/* parse the "tls-ticket-keys" bind keyword */
1297static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1298{
1299#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
1300 FILE *f = NULL;
1301 int i = 0;
1302 char thisline[LINESIZE];
1303 struct tls_keys_ref *keys_ref = NULL;
1304
1305 if (!*args[cur_arg + 1]) {
1306 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
1307 goto fail;
1308 }
1309
1310 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
1311 if (keys_ref) {
1312 keys_ref->refcount++;
1313 conf->keys_ref = keys_ref;
1314 return 0;
1315 }
1316
1317 keys_ref = calloc(1, sizeof(*keys_ref));
1318 if (!keys_ref) {
1319 memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1320 goto fail;
1321 }
1322
1323 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(union tls_sess_key));
1324 if (!keys_ref->tlskeys) {
1325 memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1326 goto fail;
1327 }
1328
1329 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
1330 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
1331 goto fail;
1332 }
1333
1334 keys_ref->filename = strdup(args[cur_arg + 1]);
1335 if (!keys_ref->filename) {
1336 memprintf(err, "'%s' : allocation error", args[cur_arg+1]);
1337 goto fail;
1338 }
1339
1340 keys_ref->key_size_bits = 0;
1341 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1342 int len = strlen(thisline);
1343 int dec_size;
1344
1345 /* Strip newline characters from the end */
1346 if(thisline[len - 1] == '\n')
1347 thisline[--len] = 0;
1348
1349 if(thisline[len - 1] == '\r')
1350 thisline[--len] = 0;
1351
1352 dec_size = base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(union tls_sess_key));
1353 if (dec_size < 0) {
1354 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
1355 goto fail;
1356 }
1357 else if (!keys_ref->key_size_bits && (dec_size == sizeof(struct tls_sess_key_128))) {
1358 keys_ref->key_size_bits = 128;
1359 }
1360 else if (!keys_ref->key_size_bits && (dec_size == sizeof(struct tls_sess_key_256))) {
1361 keys_ref->key_size_bits = 256;
1362 }
1363 else if (((dec_size != sizeof(struct tls_sess_key_128)) && (dec_size != sizeof(struct tls_sess_key_256)))
1364 || ((dec_size == sizeof(struct tls_sess_key_128) && (keys_ref->key_size_bits != 128)))
1365 || ((dec_size == sizeof(struct tls_sess_key_256) && (keys_ref->key_size_bits != 256)))) {
1366 memprintf(err, "'%s' : wrong sized key on line %d", args[cur_arg+1], i + 1);
1367 goto fail;
1368 }
1369 i++;
1370 }
1371
1372 if (i < TLS_TICKETS_NO) {
1373 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
1374 goto fail;
1375 }
1376
1377 fclose(f);
1378
1379 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
1380 i -= 2;
1381 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
1382 keys_ref->unique_id = -1;
1383 keys_ref->refcount = 1;
1384 HA_RWLOCK_INIT(&keys_ref->lock);
1385 conf->keys_ref = keys_ref;
1386
Willy Tarreau2b718102021-04-21 07:32:39 +02001387 LIST_INSERT(&tlskeys_reference, &keys_ref->list);
William Lallemanddad31052020-05-14 17:47:32 +02001388
1389 return 0;
1390
1391 fail:
1392 if (f)
1393 fclose(f);
1394 if (keys_ref) {
1395 free(keys_ref->filename);
1396 free(keys_ref->tlskeys);
1397 free(keys_ref);
1398 }
1399 return ERR_ALERT | ERR_FATAL;
1400
1401#else
1402 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
1403 return ERR_ALERT | ERR_FATAL;
1404#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
1405}
1406
1407/* parse the "verify" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001408static int ssl_bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001409{
1410 if (!*args[cur_arg + 1]) {
1411 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
1412 return ERR_ALERT | ERR_FATAL;
1413 }
1414
1415 if (strcmp(args[cur_arg + 1], "none") == 0)
1416 conf->verify = SSL_SOCK_VERIFY_NONE;
1417 else if (strcmp(args[cur_arg + 1], "optional") == 0)
1418 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
1419 else if (strcmp(args[cur_arg + 1], "required") == 0)
1420 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
1421 else {
1422 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
1423 args[cur_arg], args[cur_arg + 1]);
1424 return ERR_ALERT | ERR_FATAL;
1425 }
1426
1427 return 0;
1428}
1429static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1430{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001431 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +02001432}
1433
Willy Tarreau158c18e2023-04-19 08:28:40 +02001434/* parse the "no-alpn" ssl-bind keyword, storing an empty ALPN string */
1435static int ssl_bind_parse_no_alpn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
1436{
1437 free(conf->alpn_str);
1438 conf->alpn_len = 0;
1439 conf->alpn_str = strdup("");
1440
1441 if (!conf->alpn_str) {
1442 memprintf(err, "'%s' : out of memory", *args);
1443 return ERR_ALERT | ERR_FATAL;
1444 }
1445 return 0;
1446}
1447
1448/* parse the "no-alpn" bind keyword, storing an empty ALPN string */
1449static int bind_parse_no_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1450{
1451 return ssl_bind_parse_no_alpn(args, cur_arg, px, &conf->ssl_conf, 0, err);
1452}
1453
1454
William Lallemanddad31052020-05-14 17:47:32 +02001455/* parse the "no-ca-names" bind keyword */
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001456static int ssl_bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
William Lallemanddad31052020-05-14 17:47:32 +02001457{
1458 conf->no_ca_names = 1;
1459 return 0;
1460}
Willy Tarreau158c18e2023-04-19 08:28:40 +02001461
William Lallemanddad31052020-05-14 17:47:32 +02001462static int bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1463{
Remi Tricot-Le Bretonfb00f312021-03-23 16:41:53 +01001464 return ssl_bind_parse_no_ca_names(args, cur_arg, px, &conf->ssl_conf, 0, err);
William Lallemanddad31052020-05-14 17:47:32 +02001465}
1466
Remi Tricot-Le Breton03c5fff2022-12-20 11:11:10 +01001467
1468static int ssl_bind_parse_ocsp_update(char **args, int cur_arg, struct proxy *px,
1469 struct ssl_bind_conf *ssl_conf, int from_cli, char **err)
1470{
1471 if (!*args[cur_arg + 1]) {
1472 memprintf(err, "'%s' : expecting <on|off>", args[cur_arg]);
1473 return ERR_ALERT | ERR_FATAL;
1474 }
1475
1476 if (strcmp(args[cur_arg + 1], "on") == 0)
1477 ssl_conf->ocsp_update = SSL_SOCK_OCSP_UPDATE_ON;
1478 else if (strcmp(args[cur_arg + 1], "off") == 0)
1479 ssl_conf->ocsp_update = SSL_SOCK_OCSP_UPDATE_OFF;
1480 else {
1481 memprintf(err, "'%s' : expecting <on|off>", args[cur_arg]);
1482 return ERR_ALERT | ERR_FATAL;
1483 }
1484
Remi Tricot-Le Bretonaff82772022-12-20 11:11:14 +01001485 if (ssl_conf->ocsp_update == SSL_SOCK_OCSP_UPDATE_ON) {
1486 /* We might need to create the main ocsp update task */
1487 int ret = ssl_create_ocsp_update_task(err);
1488 if (ret)
1489 return ret;
1490 }
1491
Remi Tricot-Le Breton03c5fff2022-12-20 11:11:10 +01001492 return 0;
1493}
1494
1495
William Lallemanddad31052020-05-14 17:47:32 +02001496/***************************** "server" keywords Parsing ********************************************/
1497
1498/* parse the "npn" bind keyword */
1499static int srv_parse_npn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1500{
1501#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
1502 char *p1, *p2;
1503
1504 if (!*args[*cur_arg + 1]) {
1505 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[*cur_arg]);
1506 return ERR_ALERT | ERR_FATAL;
1507 }
1508
1509 free(newsrv->ssl_ctx.npn_str);
1510
1511 /* the NPN string is built as a suite of (<len> <name>)*,
1512 * so we reuse each comma to store the next <len> and need
1513 * one more for the end of the string.
1514 */
1515 newsrv->ssl_ctx.npn_len = strlen(args[*cur_arg + 1]) + 1;
1516 newsrv->ssl_ctx.npn_str = calloc(1, newsrv->ssl_ctx.npn_len + 1);
Amaury Denoyelle1f9333b2021-06-01 11:54:23 +02001517 if (!newsrv->ssl_ctx.npn_str) {
1518 memprintf(err, "out of memory");
1519 return ERR_ALERT | ERR_FATAL;
1520 }
1521
William Lallemanddad31052020-05-14 17:47:32 +02001522 memcpy(newsrv->ssl_ctx.npn_str + 1, args[*cur_arg + 1],
1523 newsrv->ssl_ctx.npn_len);
1524
1525 /* replace commas with the name length */
1526 p1 = newsrv->ssl_ctx.npn_str;
1527 p2 = p1 + 1;
1528 while (1) {
1529 p2 = memchr(p1 + 1, ',', newsrv->ssl_ctx.npn_str +
1530 newsrv->ssl_ctx.npn_len - (p1 + 1));
1531 if (!p2)
1532 p2 = p1 + 1 + strlen(p1 + 1);
1533
1534 if (p2 - (p1 + 1) > 255) {
1535 *p2 = '\0';
1536 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[*cur_arg], p1 + 1);
1537 return ERR_ALERT | ERR_FATAL;
1538 }
1539
1540 *p1 = p2 - (p1 + 1);
1541 p1 = p2;
1542
1543 if (!*p2)
1544 break;
1545
1546 *(p2++) = '\0';
1547 }
1548 return 0;
1549#else
1550 memprintf(err, "'%s' : library does not support TLS NPN extension", args[*cur_arg]);
1551 return ERR_ALERT | ERR_FATAL;
1552#endif
1553}
1554
Amaury Denoyelle7addf562021-05-21 16:45:10 +02001555#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1556static int parse_alpn(char *alpn, char **out_alpn_str, int *out_alpn_len, char **err)
1557{
1558 free(*out_alpn_str);
1559 return ssl_sock_parse_alpn(alpn, out_alpn_str, out_alpn_len, err);
1560}
1561#endif
1562
1563/* parse the "alpn" server keyword */
William Lallemanddad31052020-05-14 17:47:32 +02001564static int srv_parse_alpn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1565{
1566#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Amaury Denoyelle7addf562021-05-21 16:45:10 +02001567 int ret = parse_alpn(args[*cur_arg + 1],
1568 &newsrv->ssl_ctx.alpn_str,
1569 &newsrv->ssl_ctx.alpn_len, err);
1570 if (ret)
1571 memprintf(err, "'%s' : %s", args[*cur_arg], *err);
1572 return ret;
1573#else
1574 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[*cur_arg]);
1575 return ERR_ALERT | ERR_FATAL;
1576#endif
1577}
William Lallemanddad31052020-05-14 17:47:32 +02001578
Amaury Denoyelle7addf562021-05-21 16:45:10 +02001579/* parse the "check-alpn" server keyword */
1580static int srv_parse_check_alpn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1581{
1582#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1583 int ret = parse_alpn(args[*cur_arg + 1],
1584 &newsrv->check.alpn_str,
1585 &newsrv->check.alpn_len, err);
William Lallemanddad31052020-05-14 17:47:32 +02001586 if (ret)
1587 memprintf(err, "'%s' : %s", args[*cur_arg], *err);
1588 return ret;
1589#else
1590 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[*cur_arg]);
1591 return ERR_ALERT | ERR_FATAL;
1592#endif
1593}
1594
1595/* parse the "ca-file" server keyword */
1596static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1597{
Amaury Denoyelle48255022021-05-19 09:46:59 +02001598 const int create_if_none = newsrv->flags & SRV_F_DYNAMIC ? 0 : 1;
1599
William Lallemanddad31052020-05-14 17:47:32 +02001600 if (!*args[*cur_arg + 1]) {
1601 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
1602 return ERR_ALERT | ERR_FATAL;
1603 }
1604
William Lallemandf3e225d2023-10-23 21:54:23 +02001605 if ((*args[*cur_arg + 1] != '/') && (*args[*cur_arg + 1] != '@') && global_ssl.ca_base)
William Lallemanddad31052020-05-14 17:47:32 +02001606 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
1607 else
1608 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
1609
Amaury Denoyelle48255022021-05-19 09:46:59 +02001610 if (!ssl_store_load_locations_file(newsrv->ssl_ctx.ca_file, create_if_none, CAFILE_CERT)) {
William Lallemanddad31052020-05-14 17:47:32 +02001611 memprintf(err, "'%s' : unable to load %s", args[*cur_arg], newsrv->ssl_ctx.ca_file);
1612 return ERR_ALERT | ERR_FATAL;
1613 }
Amaury Denoyelle48255022021-05-19 09:46:59 +02001614
William Lallemanddad31052020-05-14 17:47:32 +02001615 return 0;
1616}
1617
1618/* parse the "check-sni" server keyword */
1619static int srv_parse_check_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1620{
1621 if (!*args[*cur_arg + 1]) {
1622 memprintf(err, "'%s' : missing SNI", args[*cur_arg]);
1623 return ERR_ALERT | ERR_FATAL;
1624 }
1625
1626 newsrv->check.sni = strdup(args[*cur_arg + 1]);
1627 if (!newsrv->check.sni) {
1628 memprintf(err, "'%s' : failed to allocate memory", args[*cur_arg]);
1629 return ERR_ALERT | ERR_FATAL;
1630 }
1631 return 0;
1632
1633}
1634
William Dauchyfc52f522020-11-14 19:25:32 +01001635/* common function to init ssl_ctx */
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001636static int ssl_sock_init_srv(struct server *s)
William Lallemanddad31052020-05-14 17:47:32 +02001637{
William Dauchyfc52f522020-11-14 19:25:32 +01001638 if (global_ssl.connect_default_ciphers && !s->ssl_ctx.ciphers)
1639 s->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05001640#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001641 if (global_ssl.connect_default_ciphersuites && !s->ssl_ctx.ciphersuites) {
William Dauchyfc52f522020-11-14 19:25:32 +01001642 s->ssl_ctx.ciphersuites = strdup(global_ssl.connect_default_ciphersuites);
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001643 if (!s->ssl_ctx.ciphersuites)
1644 return 1;
1645 }
William Lallemanddad31052020-05-14 17:47:32 +02001646#endif
William Dauchyfc52f522020-11-14 19:25:32 +01001647 s->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
1648 s->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
1649
1650 if (!s->ssl_ctx.methods.min)
1651 s->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
William Lallemanddad31052020-05-14 17:47:32 +02001652
William Dauchyfc52f522020-11-14 19:25:32 +01001653 if (!s->ssl_ctx.methods.max)
1654 s->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001655
1656 return 0;
William Dauchyfc52f522020-11-14 19:25:32 +01001657}
1658
1659/* parse the "check-ssl" server keyword */
1660static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1661{
1662 newsrv->check.use_ssl = 1;
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001663 if (ssl_sock_init_srv(newsrv)) {
1664 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1665 return ERR_ALERT | ERR_FATAL;
1666 }
1667
William Lallemanddad31052020-05-14 17:47:32 +02001668 return 0;
1669}
1670
1671/* parse the "ciphers" server keyword */
1672static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1673{
1674 if (!*args[*cur_arg + 1]) {
1675 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
1676 return ERR_ALERT | ERR_FATAL;
1677 }
1678
1679 free(newsrv->ssl_ctx.ciphers);
1680 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
Amaury Denoyellecbbf87f2021-05-19 14:57:04 +02001681
1682 if (!newsrv->ssl_ctx.ciphers) {
1683 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1684 return ERR_ALERT | ERR_FATAL;
1685 }
1686
William Lallemanddad31052020-05-14 17:47:32 +02001687 return 0;
1688}
1689
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05001690#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +02001691/* parse the "ciphersuites" server keyword */
1692static int srv_parse_ciphersuites(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1693{
1694 if (!*args[*cur_arg + 1]) {
1695 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
1696 return ERR_ALERT | ERR_FATAL;
1697 }
1698
1699 free(newsrv->ssl_ctx.ciphersuites);
1700 newsrv->ssl_ctx.ciphersuites = strdup(args[*cur_arg + 1]);
Amaury Denoyellecbbf87f2021-05-19 14:57:04 +02001701
1702 if (!newsrv->ssl_ctx.ciphersuites) {
1703 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1704 return ERR_ALERT | ERR_FATAL;
1705 }
1706
William Lallemanddad31052020-05-14 17:47:32 +02001707 return 0;
1708}
1709#endif
1710
1711/* parse the "crl-file" server keyword */
1712static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1713{
1714#ifndef X509_V_FLAG_CRL_CHECK
1715 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
1716 return ERR_ALERT | ERR_FATAL;
1717#else
Amaury Denoyellefde82602021-06-14 10:10:32 +02001718 const int create_if_none = newsrv->flags & SRV_F_DYNAMIC ? 0 : 1;
1719
William Lallemanddad31052020-05-14 17:47:32 +02001720 if (!*args[*cur_arg + 1]) {
1721 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
1722 return ERR_ALERT | ERR_FATAL;
1723 }
1724
William Lallemandf3e225d2023-10-23 21:54:23 +02001725 if ((*args[*cur_arg + 1] != '/') && (*args[*cur_arg + 1] != '@') && global_ssl.ca_base)
William Lallemanddad31052020-05-14 17:47:32 +02001726 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
1727 else
1728 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
1729
Amaury Denoyellefde82602021-06-14 10:10:32 +02001730 if (!ssl_store_load_locations_file(newsrv->ssl_ctx.crl_file, create_if_none, CAFILE_CRL)) {
William Lallemanddad31052020-05-14 17:47:32 +02001731 memprintf(err, "'%s' : unable to load %s", args[*cur_arg], newsrv->ssl_ctx.crl_file);
1732 return ERR_ALERT | ERR_FATAL;
1733 }
1734 return 0;
1735#endif
1736}
1737
1738/* parse the "crt" server keyword */
1739static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1740{
Remi Tricot-Le Bretonbb470aa2021-01-25 17:19:45 +01001741
William Lallemanddad31052020-05-14 17:47:32 +02001742 if (!*args[*cur_arg + 1]) {
1743 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
1744 return ERR_ALERT | ERR_FATAL;
1745 }
1746
1747 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
William Lallemand2c776f12021-12-28 18:47:17 +01001748 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.crt_base, args[*cur_arg + 1]);
William Lallemanddad31052020-05-14 17:47:32 +02001749 else
William Lallemand2c776f12021-12-28 18:47:17 +01001750 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
William Lallemanddad31052020-05-14 17:47:32 +02001751
William Lallemand2c776f12021-12-28 18:47:17 +01001752 return 0;
William Lallemanddad31052020-05-14 17:47:32 +02001753}
1754
1755/* parse the "no-check-ssl" server keyword */
1756static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1757{
1758 newsrv->check.use_ssl = -1;
Willy Tarreau61cfdf42021-02-20 10:46:51 +01001759 ha_free(&newsrv->ssl_ctx.ciphers);
William Lallemanddad31052020-05-14 17:47:32 +02001760 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
1761 return 0;
1762}
1763
1764/* parse the "no-send-proxy-v2-ssl" server keyword */
1765static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1766{
1767 newsrv->pp_opts &= ~SRV_PP_V2;
1768 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
1769 return 0;
1770}
1771
1772/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
1773static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1774{
1775 newsrv->pp_opts &= ~SRV_PP_V2;
1776 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
1777 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
1778 return 0;
1779}
1780
1781/* parse the "no-ssl" server keyword */
1782static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1783{
William Dauchyf6370442020-11-14 19:25:33 +01001784 /* if default-server have use_ssl, prepare ssl settings */
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001785 if (newsrv->use_ssl == 1) {
1786 if (ssl_sock_init_srv(newsrv)) {
1787 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1788 return ERR_ALERT | ERR_FATAL;
1789 }
1790 }
William Dauchyf6370442020-11-14 19:25:33 +01001791 else {
Willy Tarreau61cfdf42021-02-20 10:46:51 +01001792 ha_free(&newsrv->ssl_ctx.ciphers);
William Dauchyf6370442020-11-14 19:25:33 +01001793 }
William Lallemanddad31052020-05-14 17:47:32 +02001794 newsrv->use_ssl = -1;
William Lallemanddad31052020-05-14 17:47:32 +02001795 return 0;
1796}
1797
1798/* parse the "allow-0rtt" server keyword */
1799static int srv_parse_allow_0rtt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1800{
1801 newsrv->ssl_ctx.options |= SRV_SSL_O_EARLY_DATA;
1802 return 0;
1803}
1804
1805/* parse the "no-ssl-reuse" server keyword */
1806static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1807{
1808 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
1809 return 0;
1810}
1811
1812/* parse the "no-tls-tickets" server keyword */
1813static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1814{
1815 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
1816 return 0;
1817}
1818/* parse the "send-proxy-v2-ssl" server keyword */
1819static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1820{
1821 newsrv->pp_opts |= SRV_PP_V2;
1822 newsrv->pp_opts |= SRV_PP_V2_SSL;
1823 return 0;
1824}
1825
1826/* parse the "send-proxy-v2-ssl-cn" server keyword */
1827static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1828{
1829 newsrv->pp_opts |= SRV_PP_V2;
1830 newsrv->pp_opts |= SRV_PP_V2_SSL;
1831 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
1832 return 0;
1833}
1834
1835/* parse the "sni" server keyword */
1836static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1837{
1838#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
1839 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
1840 return ERR_ALERT | ERR_FATAL;
1841#else
1842 char *arg;
1843
1844 arg = args[*cur_arg + 1];
1845 if (!*arg) {
1846 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
1847 return ERR_ALERT | ERR_FATAL;
1848 }
1849
1850 free(newsrv->sni_expr);
1851 newsrv->sni_expr = strdup(arg);
Amaury Denoyelle1f9333b2021-06-01 11:54:23 +02001852 if (!newsrv->sni_expr) {
1853 memprintf(err, "out of memory");
1854 return ERR_ALERT | ERR_FATAL;
1855 }
William Lallemanddad31052020-05-14 17:47:32 +02001856
1857 return 0;
1858#endif
1859}
1860
1861/* parse the "ssl" server keyword */
1862static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1863{
1864 newsrv->use_ssl = 1;
Amaury Denoyelle949c94e2021-05-19 11:52:50 +02001865 if (ssl_sock_init_srv(newsrv)) {
1866 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1867 return ERR_ALERT | ERR_FATAL;
1868 }
1869
William Lallemanddad31052020-05-14 17:47:32 +02001870 return 0;
1871}
1872
1873/* parse the "ssl-reuse" server keyword */
1874static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1875{
1876 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
1877 return 0;
1878}
1879
1880/* parse the "tls-tickets" server keyword */
1881static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1882{
1883 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
1884 return 0;
1885}
1886
1887/* parse the "verify" server keyword */
1888static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1889{
1890 if (!*args[*cur_arg + 1]) {
1891 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
1892 return ERR_ALERT | ERR_FATAL;
1893 }
1894
1895 if (strcmp(args[*cur_arg + 1], "none") == 0)
1896 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
1897 else if (strcmp(args[*cur_arg + 1], "required") == 0)
1898 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
1899 else {
1900 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
1901 args[*cur_arg], args[*cur_arg + 1]);
1902 return ERR_ALERT | ERR_FATAL;
1903 }
1904
1905 return 0;
1906}
1907
1908/* parse the "verifyhost" server keyword */
1909static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1910{
1911 if (!*args[*cur_arg + 1]) {
1912 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
1913 return ERR_ALERT | ERR_FATAL;
1914 }
1915
1916 free(newsrv->ssl_ctx.verify_host);
1917 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
1918
Amaury Denoyellecbbf87f2021-05-19 14:57:04 +02001919 if (!newsrv->ssl_ctx.verify_host) {
1920 memprintf(err, "'%s' : not enough memory", args[*cur_arg]);
1921 return ERR_ALERT | ERR_FATAL;
1922 }
1923
William Lallemanddad31052020-05-14 17:47:32 +02001924 return 0;
1925}
1926
1927/* parse the "ssl-default-bind-options" keyword in global section */
1928static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +01001929 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +02001930 char **err) {
1931 int i = 1;
1932
1933 if (*(args[i]) == 0) {
1934 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
1935 return -1;
1936 }
1937 while (*(args[i])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001938 if (strcmp(args[i], "no-tls-tickets") == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001939 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001940 else if (strcmp(args[i], "prefer-client-ciphers") == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001941 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001942 else if (strcmp(args[i], "ssl-min-ver") == 0 || strcmp(args[i], "ssl-max-ver") == 0) {
William Lallemanddad31052020-05-14 17:47:32 +02001943 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
1944 i++;
1945 else {
1946 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
1947 return -1;
1948 }
1949 }
1950 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
1951 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
1952 return -1;
1953 }
1954 i++;
1955 }
1956 return 0;
1957}
1958
1959/* parse the "ssl-default-server-options" keyword in global section */
1960static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +01001961 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +02001962 char **err) {
1963 int i = 1;
1964
1965 if (*(args[i]) == 0) {
1966 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
1967 return -1;
1968 }
1969 while (*(args[i])) {
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001970 if (strcmp(args[i], "no-tls-tickets") == 0)
William Lallemanddad31052020-05-14 17:47:32 +02001971 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Tim Duesterhuse5ff1412021-01-02 22:31:53 +01001972 else if (strcmp(args[i], "ssl-min-ver") == 0 || strcmp(args[i], "ssl-max-ver") == 0) {
William Lallemanddad31052020-05-14 17:47:32 +02001973 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
1974 i++;
1975 else {
1976 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
1977 return -1;
1978 }
1979 }
1980 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
1981 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
1982 return -1;
1983 }
1984 i++;
1985 }
1986 return 0;
1987}
1988
1989/* parse the "ca-base" / "crt-base" keywords in global section.
1990 * Returns <0 on alert, >0 on warning, 0 on success.
1991 */
1992static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +01001993 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +02001994 char **err)
1995{
1996 char **target;
1997
1998 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
1999
2000 if (too_many_args(1, args, err, NULL))
2001 return -1;
2002
2003 if (*target) {
2004 memprintf(err, "'%s' already specified.", args[0]);
2005 return -1;
2006 }
2007
2008 if (*(args[1]) == 0) {
2009 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
2010 return -1;
2011 }
2012 *target = strdup(args[1]);
2013 return 0;
2014}
2015
2016/* parse the "ssl-skip-self-issued-ca" keyword in global section. */
2017static int ssl_parse_skip_self_issued_ca(char **args, int section_type, struct proxy *curpx,
Willy Tarreau01825162021-03-09 09:53:46 +01002018 const struct proxy *defpx, const char *file, int line,
William Lallemanddad31052020-05-14 17:47:32 +02002019 char **err)
2020{
William Lallemand9a1d8392020-08-10 17:28:23 +02002021#ifdef SSL_CTX_build_cert_chain
William Lallemanddad31052020-05-14 17:47:32 +02002022 global_ssl.skip_self_issued_ca = 1;
2023 return 0;
William Lallemand9a1d8392020-08-10 17:28:23 +02002024#else
2025 memprintf(err, "global statement '%s' requires at least OpenSSL 1.0.2.", args[0]);
2026 return -1;
2027#endif
William Lallemanddad31052020-05-14 17:47:32 +02002028}
2029
2030
Remi Tricot-Le Breton58432372023-02-28 17:46:29 +01002031static int ssl_parse_global_ocsp_maxdelay(char **args, int section_type, struct proxy *curpx,
2032 const struct proxy *defpx, const char *file, int line,
2033 char **err)
2034{
2035 int value = 0;
William Lallemanddad31052020-05-14 17:47:32 +02002036
Remi Tricot-Le Breton58432372023-02-28 17:46:29 +01002037 if (*(args[1]) == 0) {
2038 memprintf(err, "'%s' expects an integer argument.", args[0]);
2039 return -1;
2040 }
William Lallemanddad31052020-05-14 17:47:32 +02002041
Remi Tricot-Le Breton58432372023-02-28 17:46:29 +01002042 value = atoi(args[1]);
2043 if (value < 0) {
2044 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
2045 return -1;
2046 }
2047
2048 if (global_ssl.ocsp_update.delay_min > value) {
2049 memprintf(err, "'%s' can not be lower than tune.ssl.ocsp-update.mindelay.", args[0]);
2050 return -1;
2051 }
2052
2053 global_ssl.ocsp_update.delay_max = value;
2054
2055 return 0;
2056}
2057
2058static int ssl_parse_global_ocsp_mindelay(char **args, int section_type, struct proxy *curpx,
2059 const struct proxy *defpx, const char *file, int line,
2060 char **err)
2061{
2062 int value = 0;
2063
2064 if (*(args[1]) == 0) {
2065 memprintf(err, "'%s' expects an integer argument.", args[0]);
2066 return -1;
2067 }
2068
2069 value = atoi(args[1]);
2070 if (value < 0) {
2071 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
2072 return -1;
2073 }
2074
2075 if (value > global_ssl.ocsp_update.delay_max) {
2076 memprintf(err, "'%s' can not be higher than tune.ssl.ocsp-update.maxdelay.", args[0]);
2077 return -1;
2078 }
2079
2080 global_ssl.ocsp_update.delay_min = value;
2081
2082 return 0;
2083}
2084
2085
William Lallemanddad31052020-05-14 17:47:32 +02002086
2087/* Note: must not be declared <const> as its list will be overwritten.
2088 * Please take care of keeping this list alphabetically sorted, doing so helps
2089 * all code contributors.
2090 * Optional keywords are also declared with a NULL ->parse() function so that
2091 * the config parser can report an appropriate error when a known keyword was
2092 * not enabled.
2093 */
2094
William Lallemandaf678062023-02-13 10:58:13 +01002095/* the <ssl_crtlist_kws> keywords are used for crt-list parsing, they *MUST* be safe
William Lallemandb5a3d582024-05-21 17:49:58 +02002096 * with their proxy argument NULL and must only fill the ssl_bind_conf
2097 *
2098 * /!\ Please update configuration.txt at the crt-list option of the Bind options
2099 * section when adding a keyword in ssl_crtlist_kws. /!\
2100 *
2101 */
William Lallemandaf678062023-02-13 10:58:13 +01002102struct ssl_crtlist_kw ssl_crtlist_kws[] = {
William Lallemanddad31052020-05-14 17:47:32 +02002103 { "allow-0rtt", ssl_bind_parse_allow_0rtt, 0 }, /* allow 0-RTT */
2104 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
2105 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process ca-names and verify on client cert */
2106 { "ca-verify-file", ssl_bind_parse_ca_verify_file, 1 }, /* set CAverify file to process verify on client cert */
2107 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05002108#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +02002109 { "ciphersuites", ssl_bind_parse_ciphersuites, 1 }, /* set TLS 1.3 cipher suite */
2110#endif
William Lallemandb6ae2aa2023-05-05 00:05:46 +02002111 { "client-sigalgs", ssl_bind_parse_client_sigalgs, 1 }, /* set SSL client signature algorithms */
William Lallemanddad31052020-05-14 17:47:32 +02002112 { "crl-file", ssl_bind_parse_crl_file, 1 }, /* set certificate revocation list file use on client cert verify */
2113 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
2114 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Willy Tarreau158c18e2023-04-19 08:28:40 +02002115 { "no-alpn", ssl_bind_parse_no_alpn, 0 }, /* disable sending ALPN */
William Lallemanddad31052020-05-14 17:47:32 +02002116 { "no-ca-names", ssl_bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
2117 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
William Lallemand1d3c8222023-05-04 15:33:55 +02002118 { "sigalgs", ssl_bind_parse_sigalgs, 1 }, /* set SSL signature algorithms */
William Lallemanddad31052020-05-14 17:47:32 +02002119 { "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
2120 { "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
2121 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
Remi Tricot-Le Breton03c5fff2022-12-20 11:11:10 +01002122 { "ocsp-update", ssl_bind_parse_ocsp_update, 1 }, /* ocsp update mode (on or off) */
William Lallemanddad31052020-05-14 17:47:32 +02002123 { NULL, NULL, 0 },
2124};
2125
2126/* no initcall for ssl_bind_kws, these ones are parsed in the parser loop */
2127
2128static struct bind_kw_list bind_kws = { "SSL", { }, {
2129 { "allow-0rtt", bind_parse_allow_0rtt, 0 }, /* Allow 0RTT */
2130 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
2131 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process ca-names and verify on client cert */
2132 { "ca-verify-file", bind_parse_ca_verify_file, 1 }, /* set CAverify file to process verify on client cert */
2133 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
2134 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
2135 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
2136 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05002137#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +02002138 { "ciphersuites", bind_parse_ciphersuites, 1 }, /* set TLS 1.3 cipher suite */
2139#endif
William Lallemandb6ae2aa2023-05-05 00:05:46 +02002140 { "client-sigalgs", bind_parse_client_sigalgs, 1 }, /* set SSL client signature algorithms */
William Lallemanddad31052020-05-14 17:47:32 +02002141 { "crl-file", bind_parse_crl_file, 1 }, /* set certificate revocation list file use on client cert verify */
2142 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
2143 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth == 0 */
2144 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
2145 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
2146 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
2147 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
2148 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
2149 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
2150 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
2151 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
2152 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Willy Tarreau158c18e2023-04-19 08:28:40 +02002153 { "no-alpn", bind_parse_no_alpn, 0 }, /* disable sending ALPN */
William Lallemanddad31052020-05-14 17:47:32 +02002154 { "no-ca-names", bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
2155 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
2156 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
2157 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
2158 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
2159 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
2160 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
William Lallemand1d3c8222023-05-04 15:33:55 +02002161 { "sigalgs", bind_parse_sigalgs, 1 }, /* set SSL signature algorithms */
William Lallemanddad31052020-05-14 17:47:32 +02002162 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
2163 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
2164 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
2165 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
2166 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
2167 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
2168 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
2169 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
2170 { NULL, NULL, 0 },
2171}};
2172
2173INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
2174
2175/* Note: must not be declared <const> as its list will be overwritten.
2176 * Please take care of keeping this list alphabetically sorted, doing so helps
2177 * all code contributors.
2178 * Optional keywords are also declared with a NULL ->parse() function so that
2179 * the config parser can report an appropriate error when a known keyword was
2180 * not enabled.
2181 */
2182static struct srv_kw_list srv_kws = { "SSL", { }, {
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002183 { "allow-0rtt", srv_parse_allow_0rtt, 0, 1, 1 }, /* Allow using early data on this server */
2184 { "alpn", srv_parse_alpn, 1, 1, 1 }, /* Set ALPN supported protocols */
Amaury Denoyelle48255022021-05-19 09:46:59 +02002185 { "ca-file", srv_parse_ca_file, 1, 1, 1 }, /* set CAfile to process verify server cert */
Amaury Denoyelle79b90e82021-09-20 15:15:19 +02002186 { "check-alpn", srv_parse_check_alpn, 1, 1, 1 }, /* Set ALPN used for checks */
2187 { "check-sni", srv_parse_check_sni, 1, 1, 1 }, /* set SNI */
2188 { "check-ssl", srv_parse_check_ssl, 0, 1, 1 }, /* enable SSL for health checks */
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002189 { "ciphers", srv_parse_ciphers, 1, 1, 1 }, /* select the cipher suite */
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05002190#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002191 { "ciphersuites", srv_parse_ciphersuites, 1, 1, 1 }, /* select the cipher suite */
William Lallemanddad31052020-05-14 17:47:32 +02002192#endif
Amaury Denoyellefde82602021-06-14 10:10:32 +02002193 { "crl-file", srv_parse_crl_file, 1, 1, 1 }, /* set certificate revocation list file use on server cert verify */
Amaury Denoyelle93be21e2021-05-21 16:22:53 +02002194 { "crt", srv_parse_crt, 1, 1, 1 }, /* set client certificate */
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002195 { "force-sslv3", srv_parse_tls_method_options, 0, 1, 1 }, /* force SSLv3 */
2196 { "force-tlsv10", srv_parse_tls_method_options, 0, 1, 1 }, /* force TLSv10 */
2197 { "force-tlsv11", srv_parse_tls_method_options, 0, 1, 1 }, /* force TLSv11 */
2198 { "force-tlsv12", srv_parse_tls_method_options, 0, 1, 1 }, /* force TLSv12 */
2199 { "force-tlsv13", srv_parse_tls_method_options, 0, 1, 1 }, /* force TLSv13 */
Amaury Denoyelle76e10e72021-03-08 17:08:01 +01002200 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1, 0 }, /* disable SSL for health checks */
2201 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1, 0 }, /* do not send PROXY protocol header v2 with SSL info */
2202 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1, 0 }, /* do not send PROXY protocol header v2 with CN */
2203 { "no-ssl", srv_parse_no_ssl, 0, 1, 0 }, /* disable SSL processing */
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002204 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1, 1 }, /* disable session reuse */
2205 { "no-sslv3", srv_parse_tls_method_options, 0, 0, 1 }, /* disable SSLv3 */
2206 { "no-tlsv10", srv_parse_tls_method_options, 0, 0, 1 }, /* disable TLSv10 */
2207 { "no-tlsv11", srv_parse_tls_method_options, 0, 0, 1 }, /* disable TLSv11 */
2208 { "no-tlsv12", srv_parse_tls_method_options, 0, 0, 1 }, /* disable TLSv12 */
2209 { "no-tlsv13", srv_parse_tls_method_options, 0, 0, 1 }, /* disable TLSv13 */
2210 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1, 1 }, /* disable session resumption tickets */
2211 { "npn", srv_parse_npn, 1, 1, 1 }, /* Set NPN supported protocols */
2212 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1, 1 }, /* send PROXY protocol header v2 with SSL info */
2213 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1, 1 }, /* send PROXY protocol header v2 with CN */
2214 { "sni", srv_parse_sni, 1, 1, 1 }, /* send SNI extension */
Amaury Denoyelle34897d22021-05-19 09:49:41 +02002215 { "ssl", srv_parse_ssl, 0, 1, 1 }, /* enable SSL processing */
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002216 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1, 1 }, /* minimum version */
2217 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1, 1 }, /* maximum version */
Amaury Denoyelle76e10e72021-03-08 17:08:01 +01002218 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1, 0 }, /* enable session reuse */
Amaury Denoyelle71f9a062021-05-20 15:10:55 +02002219 { "tls-tickets", srv_parse_tls_tickets, 0, 1, 1 }, /* enable session resumption tickets */
2220 { "verify", srv_parse_verify, 1, 1, 1 }, /* set SSL verify method */
2221 { "verifyhost", srv_parse_verifyhost, 1, 1, 1 }, /* require that SSL cert verifies for hostname */
William Lallemanddad31052020-05-14 17:47:32 +02002222 { NULL, NULL, 0, 0 },
2223}};
2224
2225INITCALL1(STG_REGISTER, srv_register_keywords, &srv_kws);
2226
2227static struct cfg_kw_list cfg_kws = {ILH, {
2228 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
2229 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
2230 { CFG_GLOBAL, "issuers-chain-path", ssl_load_global_issuers_from_path },
2231 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
2232 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
2233 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
2234#ifndef OPENSSL_NO_DH
2235 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
2236#endif
2237 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
William Lallemandd7bfbe22022-04-11 18:41:24 +02002238#if defined(USE_ENGINE) && !defined(OPENSSL_NO_ENGINE)
William Lallemanddad31052020-05-14 17:47:32 +02002239 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
2240#endif
Remi Tricot-Le Bretone8097652022-05-16 16:24:32 +02002241#ifdef HAVE_SSL_PROVIDERS
2242 { CFG_GLOBAL, "ssl-propquery", ssl_parse_global_ssl_propquery },
Remi Tricot-Le Breton1746a382022-05-16 16:24:33 +02002243 { CFG_GLOBAL, "ssl-provider", ssl_parse_global_ssl_provider },
Remi Tricot-Le Bretonccc03552022-05-17 15:18:37 +02002244 { CFG_GLOBAL, "ssl-provider-path", ssl_parse_global_ssl_provider_path },
Remi Tricot-Le Bretone8097652022-05-16 16:24:32 +02002245#endif
William Lallemanddad31052020-05-14 17:47:32 +02002246 { CFG_GLOBAL, "ssl-skip-self-issued-ca", ssl_parse_skip_self_issued_ca },
2247 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
2248#ifndef OPENSSL_NO_DH
2249 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
2250#endif
2251 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
2252 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
2253 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
Thomas Prückl10243932022-04-27 13:04:54 +02002254 { CFG_GLOBAL, "tune.ssl.hard-maxrecord", ssl_parse_global_int },
William Lallemanddad31052020-05-14 17:47:32 +02002255 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Marcin Deranek310a2602021-07-13 19:04:24 +02002256 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_buffer },
2257 { CFG_GLOBAL, "tune.ssl.capture-buffer-size", ssl_parse_global_capture_buffer },
William Lallemand7d42ef52020-07-06 11:41:30 +02002258 { CFG_GLOBAL, "tune.ssl.keylog", ssl_parse_global_keylog },
William Lallemanddad31052020-05-14 17:47:32 +02002259 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
2260 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Ilya Shipitsin0aa8c292020-11-04 00:39:07 +05002261#if defined(SSL_CTX_set1_curves_list)
William Lallemanddad31052020-05-14 17:47:32 +02002262 { CFG_GLOBAL, "ssl-default-bind-curves", ssl_parse_global_curves },
2263#endif
William Lallemand1d3c8222023-05-04 15:33:55 +02002264#if defined(SSL_CTX_set1_sigalgs_list)
2265 { CFG_GLOBAL, "ssl-default-bind-sigalgs", ssl_parse_global_sigalgs },
2266#endif
William Lallemandb6ae2aa2023-05-05 00:05:46 +02002267#if defined(SSL_CTX_set1_client_sigalgs_list)
2268 { CFG_GLOBAL, "ssl-default-bind-client-sigalgs", ssl_parse_global_client_sigalgs },
2269#endif
Ilya Shipitsinf34ed0b2020-11-21 14:37:34 +05002270#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
William Lallemanddad31052020-05-14 17:47:32 +02002271 { CFG_GLOBAL, "ssl-default-bind-ciphersuites", ssl_parse_global_ciphersuites },
2272 { CFG_GLOBAL, "ssl-default-server-ciphersuites", ssl_parse_global_ciphersuites },
2273#endif
2274 { CFG_GLOBAL, "ssl-load-extra-files", ssl_parse_global_extra_files },
William Lallemand8e8581e2020-10-20 17:36:46 +02002275 { CFG_GLOBAL, "ssl-load-extra-del-ext", ssl_parse_global_extra_noext },
Remi Tricot-Le Breton58432372023-02-28 17:46:29 +01002276#ifndef OPENSSL_NO_OCSP
2277 { CFG_GLOBAL, "tune.ssl.ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay },
2278 { CFG_GLOBAL, "tune.ssl.ocsp-update.mindelay", ssl_parse_global_ocsp_mindelay },
2279#endif
William Lallemanddad31052020-05-14 17:47:32 +02002280 { 0, NULL, NULL },
2281}};
2282
2283INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);