Browse code

tls: added ca_path config option

- used to provide path to directory with CA files in pem format, to be
given as parameter to SSL_CTX_load_verify_locations()
- GH #2682

Daniel-Constantin Mierla authored on 23/03/2021 07:54:20
Showing 6 changed files
... ...
@@ -44,6 +44,7 @@ struct cfg_group_tls default_tls_cfg = {
44 44
 	STR_STATIC_INIT("off"), /* verify_client */
45 45
 	STR_NULL, /* private_key (default value set in fix_tls_cfg) */
46 46
 	STR_NULL, /* ca_list (default value set in fix_tls_cfg) */
47
+	STR_NULL, /* ca_path (default value set in fix_tls_cfg) */
47 48
 	STR_NULL, /* crl (default value set in fix_tls_cfg) */
48 49
 	STR_NULL, /* certificate (default value set in fix_tls_cfg) */
49 50
 	STR_NULL, /* cipher_list (default value set in fix_tls_cfg) */
... ...
@@ -163,6 +164,8 @@ cfg_def_t	tls_cfg_def[] = {
163 164
 		" contained in the certificate file" },
164 165
 	{"ca_list", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
165 166
 		"name of the file containing the trusted CA list (pem format)" },
167
+	{"ca_path", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
168
+		"name of the directory containing the trusted CA files (pem format)" },
166 169
 	{"crl", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
167 170
 		"name of the file containing the CRL  (certificare revocation list"
168 171
 			" in pem format)" },
... ...
@@ -266,7 +269,7 @@ static int fix_initial_pathname(str* path, char* def)
266 269
 int fix_tls_cfg(struct cfg_group_tls* cfg)
267 270
 {
268 271
 	cfg->con_lifetime = S_TO_TICKS(cfg->con_lifetime);
269
-	fix_timeout("tls_connection_timeout", &cfg->con_lifetime, 
272
+	fix_timeout("tls_connection_timeout", &cfg->con_lifetime,
270 273
 						MAX_TLS_CON_LIFETIME, MAX_TLS_CON_LIFETIME);
271 274
 	/* Update relative paths of files configured through modparams, relative
272 275
 	 * pathnames will be converted to absolute and the directory of the main
... ...
@@ -278,11 +281,13 @@ int fix_tls_cfg(struct cfg_group_tls* cfg)
278 281
 		return -1;
279 282
 	if (fix_initial_pathname(&cfg->ca_list, TLS_CA_FILE) < 0 )
280 283
 		return -1;
284
+	if (fix_initial_pathname(&cfg->ca_path, TLS_CA_PATH) < 0 )
285
+		return -1;
281 286
 	if (fix_initial_pathname(&cfg->crl, TLS_CRL_FILE) < 0 )
282 287
 		return -1;
283 288
 	if (fix_initial_pathname(&cfg->certificate, TLS_CERT_FILE) < 0)
284 289
 		return -1;
285
-	
290
+
286 291
 	return 0;
287 292
 }
288 293
 
... ...
@@ -49,6 +49,7 @@ struct cfg_group_tls {
49 49
 	str verify_client;
50 50
 	str private_key;
51 51
 	str ca_list;
52
+	str ca_path;
52 53
 	str crl;
53 54
 	str certificate;
54 55
 	str cipher_list;
... ...
@@ -183,6 +183,7 @@ static cfg_option_t options[] = {
183 183
 	{"server_name_mode",    .f = cfg_parse_int_opt},
184 184
 	{"server_id",           .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM},
185 185
 	{"verify_client",       .param = verify_client_params, .f = cfg_parse_enum_opt},
186
+	{"ca_path",             .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM},
186 187
 	{0}
187 188
 };
188 189
 
... ...
@@ -212,6 +213,7 @@ static void update_opt_variables(void)
212 213
 	for(i = 0; verify_client_params[i].name; i++) {
213 214
 		verify_client_params[i].param = &_ksr_tls_domain->verify_client;
214 215
 	}
216
+	options[19].param = &_ksr_tls_domain->ca_path;
215 217
 }
216 218
 
217 219
 
... ...
@@ -192,7 +192,7 @@ void tls_free_domain(tls_domain_t* d)
192 192
 {
193 193
 	int i;
194 194
 	int procs_no;
195
-	
195
+
196 196
 	if (!d) return;
197 197
 	if (d->ctx) {
198 198
 		procs_no=get_max_procs();
... ...
@@ -204,6 +204,7 @@ void tls_free_domain(tls_domain_t* d)
204 204
 
205 205
 	if (d->cipher_list.s) shm_free(d->cipher_list.s);
206 206
 	if (d->ca_file.s) shm_free(d->ca_file.s);
207
+	if (d->ca_path.s) shm_free(d->ca_path.s);
207 208
 	if (d->crl_file.s) shm_free(d->crl_file.s);
208 209
 	if (d->pkey_file.s) shm_free(d->pkey_file.s);
209 210
 	if (d->cert_file.s) shm_free(d->cert_file.s);
... ...
@@ -327,6 +328,13 @@ static int ksr_tls_fill_missing(tls_domain_t* d, tls_domain_t* parent)
327 328
 	}
328 329
 	LOG(L_INFO, "%s: ca_list='%s'\n", tls_domain_str(d), d->ca_file.s);
329 330
 
331
+	if (!d->ca_path.s){
332
+		if (shm_asciiz_dup(&d->ca_path.s, parent->ca_path.s) < 0)
333
+			return -1;
334
+		d->ca_path.len = parent->ca_path.len;
335
+	}
336
+	LOG(L_INFO, "%s: ca_path='%s'\n", tls_domain_str(d), d->ca_path.s);
337
+
330 338
 	if (!d->crl_file.s) {
331 339
 		if (shm_asciiz_dup(&d->crl_file.s, parent->crl_file.s) < 0)
332 340
 			return -1;
... ...
@@ -568,26 +576,32 @@ static int load_ca_list(tls_domain_t* d)
568 576
 	int i;
569 577
 	int procs_no;
570 578
 
571
-	if (!d->ca_file.s || !d->ca_file.len) {
579
+	if ((!d->ca_file.s || !d->ca_file.len) && (!d->ca_path.s || !d->ca_path.len)) {
572 580
 		DBG("%s: No CA list configured\n", tls_domain_str(d));
573 581
 		return 0;
574 582
 	}
575
-	if (fix_shm_pathname(&d->ca_file) < 0)
583
+	if (d->ca_file.len>0 && fix_shm_pathname(&d->ca_file) < 0)
584
+		return -1;
585
+	if (d->ca_path.len>0 && fix_shm_pathname(&d->ca_path) < 0)
576 586
 		return -1;
577 587
 	procs_no=get_max_procs();
578 588
 	for(i = 0; i < procs_no; i++) {
579
-		if (SSL_CTX_load_verify_locations(d->ctx[i], d->ca_file.s, 0) != 1) {
580
-			ERR("%s: Unable to load CA list '%s'\n", tls_domain_str(d),
581
-					d->ca_file.s);
589
+		if (SSL_CTX_load_verify_locations(d->ctx[i], d->ca_file.s,
590
+					d->ca_path.s) != 1) {
591
+			ERR("%s: Unable to load CA list file '%s' dir '%s'\n",
592
+					tls_domain_str(d), (d->ca_file.s)?d->ca_file.s:"",
593
+					(d->ca_path.s)?d->ca_path.s:"");
582 594
 			TLS_ERR("load_ca_list:");
583 595
 			return -1;
584 596
 		}
585
-		SSL_CTX_set_client_CA_list(d->ctx[i],
586
-				SSL_load_client_CA_file(d->ca_file.s));
587
-		if (SSL_CTX_get_client_CA_list(d->ctx[i]) == 0) {
588
-			ERR("%s: Error while setting client CA list\n", tls_domain_str(d));
589
-			TLS_ERR("load_ca_list:");
590
-			return -1;
597
+		if(d->ca_file.len>0) {
598
+			SSL_CTX_set_client_CA_list(d->ctx[i],
599
+					SSL_load_client_CA_file(d->ca_file.s));
600
+			if (SSL_CTX_get_client_CA_list(d->ctx[i]) == 0) {
601
+				ERR("%s: Error while setting client CA list\n", tls_domain_str(d));
602
+				TLS_ERR("load_ca_list:");
603
+				return -1;
604
+			}
591 605
 		}
592 606
 	}
593 607
 	return 0;
... ...
@@ -117,6 +117,7 @@ typedef struct tls_domain {
117 117
 	int verify_cert;
118 118
 	int verify_depth;
119 119
 	str ca_file;
120
+	str ca_path;
120 121
 	int require_cert;
121 122
 	str cipher_list;
122 123
 	enum tls_method method;
... ...
@@ -101,8 +101,9 @@ static tls_domain_t mod_params = {
101 101
 	0,                /* Verify certificate */
102 102
 	9,                /* Verify depth */
103 103
 	STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
104
+	STR_STATIC_INIT(TLS_CA_PATH),      /* CA path */
104 105
 	0,                /* Require certificate */
105
-	{0, },                /* Cipher list */
106
+	{0, 0},                /* Cipher list */
106 107
 	TLS_USE_TLSv1_PLUS,   /* TLS method */
107 108
 	STR_STATIC_INIT(TLS_CRL_FILE), /* Certificate revocation list */
108 109
 	{0, 0},           /* Server name (SNI) */
... ...
@@ -126,6 +127,7 @@ tls_domain_t srv_defaults = {
126 127
 	0,                /* Verify certificate */
127 128
 	9,                /* Verify depth */
128 129
 	STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
130
+	STR_STATIC_INIT(TLS_CA_PATH),      /* CA path */
129 131
 	0,                /* Require certificate */
130 132
 	{0, 0},                /* Cipher list */
131 133
 	TLS_USE_TLSv1_PLUS,    /* TLS method */
... ...
@@ -168,6 +170,7 @@ tls_domain_t cli_defaults = {
168 170
 	0,                /* Verify certificate */
169 171
 	9,                /* Verify depth */
170 172
 	STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
173
+	STR_STATIC_INIT(TLS_CA_PATH),      /* CA path */
171 174
 	0,                /* Require certificate */
172 175
 	{0, 0},                /* Cipher list */
173 176
 	TLS_USE_TLSv1_PLUS,    /* TLS method */
... ...
@@ -212,6 +215,7 @@ static param_export_t params[] = {
212 215
 	{"verify_client",       PARAM_STR,    &default_tls_cfg.verify_client},
213 216
 	{"private_key",         PARAM_STR,    &default_tls_cfg.private_key  },
214 217
 	{"ca_list",             PARAM_STR,    &default_tls_cfg.ca_list      },
218
+	{"ca_path",             PARAM_STR,    &default_tls_cfg.ca_path      },
215 219
 	{"certificate",         PARAM_STR,    &default_tls_cfg.certificate  },
216 220
 	{"crl",                 PARAM_STR,    &default_tls_cfg.crl          },
217 221
 	{"cipher_list",         PARAM_STR,    &default_tls_cfg.cipher_list  },