Skip to content

Commit

Permalink
tls: added ca_path config option
Browse files Browse the repository at this point in the history
- used to provide path to directory with CA files in pem format, to be
given as parameter to SSL_CTX_load_verify_locations()
- GH kamailio#2682
  • Loading branch information
miconda authored and piotr-gregor committed Mar 26, 2021
1 parent b4cb257 commit eb45409
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 15 deletions.
9 changes: 7 additions & 2 deletions src/modules/tls/tls_cfg.c
Expand Up @@ -44,6 +44,7 @@ struct cfg_group_tls default_tls_cfg = {
STR_STATIC_INIT("off"), /* verify_client */
STR_NULL, /* private_key (default value set in fix_tls_cfg) */
STR_NULL, /* ca_list (default value set in fix_tls_cfg) */
STR_NULL, /* ca_path (default value set in fix_tls_cfg) */
STR_NULL, /* crl (default value set in fix_tls_cfg) */
STR_NULL, /* certificate (default value set in fix_tls_cfg) */
STR_NULL, /* cipher_list (default value set in fix_tls_cfg) */
Expand Down Expand Up @@ -163,6 +164,8 @@ cfg_def_t tls_cfg_def[] = {
" contained in the certificate file" },
{"ca_list", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
"name of the file containing the trusted CA list (pem format)" },
{"ca_path", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
"name of the directory containing the trusted CA files (pem format)" },
{"crl", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
"name of the file containing the CRL (certificare revocation list"
" in pem format)" },
Expand Down Expand Up @@ -266,7 +269,7 @@ static int fix_initial_pathname(str* path, char* def)
int fix_tls_cfg(struct cfg_group_tls* cfg)
{
cfg->con_lifetime = S_TO_TICKS(cfg->con_lifetime);
fix_timeout("tls_connection_timeout", &cfg->con_lifetime,
fix_timeout("tls_connection_timeout", &cfg->con_lifetime,
MAX_TLS_CON_LIFETIME, MAX_TLS_CON_LIFETIME);
/* Update relative paths of files configured through modparams, relative
* pathnames will be converted to absolute and the directory of the main
Expand All @@ -278,11 +281,13 @@ int fix_tls_cfg(struct cfg_group_tls* cfg)
return -1;
if (fix_initial_pathname(&cfg->ca_list, TLS_CA_FILE) < 0 )
return -1;
if (fix_initial_pathname(&cfg->ca_path, TLS_CA_PATH) < 0 )
return -1;
if (fix_initial_pathname(&cfg->crl, TLS_CRL_FILE) < 0 )
return -1;
if (fix_initial_pathname(&cfg->certificate, TLS_CERT_FILE) < 0)
return -1;

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions src/modules/tls/tls_cfg.h
Expand Up @@ -49,6 +49,7 @@ struct cfg_group_tls {
str verify_client;
str private_key;
str ca_list;
str ca_path;
str crl;
str certificate;
str cipher_list;
Expand Down
2 changes: 2 additions & 0 deletions src/modules/tls/tls_config.c
Expand Up @@ -183,6 +183,7 @@ static cfg_option_t options[] = {
{"server_name_mode", .f = cfg_parse_int_opt},
{"server_id", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM},
{"verify_client", .param = verify_client_params, .f = cfg_parse_enum_opt},
{"ca_path", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM},
{0}
};

Expand Down Expand Up @@ -212,6 +213,7 @@ static void update_opt_variables(void)
for(i = 0; verify_client_params[i].name; i++) {
verify_client_params[i].param = &_ksr_tls_domain->verify_client;
}
options[19].param = &_ksr_tls_domain->ca_path;
}


Expand Down
38 changes: 26 additions & 12 deletions src/modules/tls/tls_domain.c
Expand Up @@ -192,7 +192,7 @@ void tls_free_domain(tls_domain_t* d)
{
int i;
int procs_no;

if (!d) return;
if (d->ctx) {
procs_no=get_max_procs();
Expand All @@ -204,6 +204,7 @@ void tls_free_domain(tls_domain_t* d)

if (d->cipher_list.s) shm_free(d->cipher_list.s);
if (d->ca_file.s) shm_free(d->ca_file.s);
if (d->ca_path.s) shm_free(d->ca_path.s);
if (d->crl_file.s) shm_free(d->crl_file.s);
if (d->pkey_file.s) shm_free(d->pkey_file.s);
if (d->cert_file.s) shm_free(d->cert_file.s);
Expand Down Expand Up @@ -327,6 +328,13 @@ static int ksr_tls_fill_missing(tls_domain_t* d, tls_domain_t* parent)
}
LOG(L_INFO, "%s: ca_list='%s'\n", tls_domain_str(d), d->ca_file.s);

if (!d->ca_path.s){
if (shm_asciiz_dup(&d->ca_path.s, parent->ca_path.s) < 0)
return -1;
d->ca_path.len = parent->ca_path.len;
}
LOG(L_INFO, "%s: ca_path='%s'\n", tls_domain_str(d), d->ca_path.s);

if (!d->crl_file.s) {
if (shm_asciiz_dup(&d->crl_file.s, parent->crl_file.s) < 0)
return -1;
Expand Down Expand Up @@ -568,26 +576,32 @@ static int load_ca_list(tls_domain_t* d)
int i;
int procs_no;

if (!d->ca_file.s || !d->ca_file.len) {
if ((!d->ca_file.s || !d->ca_file.len) && (!d->ca_path.s || !d->ca_path.len)) {
DBG("%s: No CA list configured\n", tls_domain_str(d));
return 0;
}
if (fix_shm_pathname(&d->ca_file) < 0)
if (d->ca_file.len>0 && fix_shm_pathname(&d->ca_file) < 0)
return -1;
if (d->ca_path.len>0 && fix_shm_pathname(&d->ca_path) < 0)
return -1;
procs_no=get_max_procs();
for(i = 0; i < procs_no; i++) {
if (SSL_CTX_load_verify_locations(d->ctx[i], d->ca_file.s, 0) != 1) {
ERR("%s: Unable to load CA list '%s'\n", tls_domain_str(d),
d->ca_file.s);
if (SSL_CTX_load_verify_locations(d->ctx[i], d->ca_file.s,
d->ca_path.s) != 1) {
ERR("%s: Unable to load CA list file '%s' dir '%s'\n",
tls_domain_str(d), (d->ca_file.s)?d->ca_file.s:"",
(d->ca_path.s)?d->ca_path.s:"");
TLS_ERR("load_ca_list:");
return -1;
}
SSL_CTX_set_client_CA_list(d->ctx[i],
SSL_load_client_CA_file(d->ca_file.s));
if (SSL_CTX_get_client_CA_list(d->ctx[i]) == 0) {
ERR("%s: Error while setting client CA list\n", tls_domain_str(d));
TLS_ERR("load_ca_list:");
return -1;
if(d->ca_file.len>0) {
SSL_CTX_set_client_CA_list(d->ctx[i],
SSL_load_client_CA_file(d->ca_file.s));
if (SSL_CTX_get_client_CA_list(d->ctx[i]) == 0) {
ERR("%s: Error while setting client CA list\n", tls_domain_str(d));
TLS_ERR("load_ca_list:");
return -1;
}
}
}
return 0;
Expand Down
1 change: 1 addition & 0 deletions src/modules/tls/tls_domain.h
Expand Up @@ -117,6 +117,7 @@ typedef struct tls_domain {
int verify_cert;
int verify_depth;
str ca_file;
str ca_path;
int require_cert;
str cipher_list;
enum tls_method method;
Expand Down
6 changes: 5 additions & 1 deletion src/modules/tls/tls_mod.c
Expand Up @@ -101,8 +101,9 @@ static tls_domain_t mod_params = {
0, /* Verify certificate */
9, /* Verify depth */
STR_STATIC_INIT(TLS_CA_FILE), /* CA file */
STR_STATIC_INIT(TLS_CA_PATH), /* CA path */
0, /* Require certificate */
{0, }, /* Cipher list */
{0, 0}, /* Cipher list */
TLS_USE_TLSv1_PLUS, /* TLS method */
STR_STATIC_INIT(TLS_CRL_FILE), /* Certificate revocation list */
{0, 0}, /* Server name (SNI) */
Expand All @@ -126,6 +127,7 @@ tls_domain_t srv_defaults = {
0, /* Verify certificate */
9, /* Verify depth */
STR_STATIC_INIT(TLS_CA_FILE), /* CA file */
STR_STATIC_INIT(TLS_CA_PATH), /* CA path */
0, /* Require certificate */
{0, 0}, /* Cipher list */
TLS_USE_TLSv1_PLUS, /* TLS method */
Expand Down Expand Up @@ -168,6 +170,7 @@ tls_domain_t cli_defaults = {
0, /* Verify certificate */
9, /* Verify depth */
STR_STATIC_INIT(TLS_CA_FILE), /* CA file */
STR_STATIC_INIT(TLS_CA_PATH), /* CA path */
0, /* Require certificate */
{0, 0}, /* Cipher list */
TLS_USE_TLSv1_PLUS, /* TLS method */
Expand Down Expand Up @@ -212,6 +215,7 @@ static param_export_t params[] = {
{"verify_client", PARAM_STR, &default_tls_cfg.verify_client},
{"private_key", PARAM_STR, &default_tls_cfg.private_key },
{"ca_list", PARAM_STR, &default_tls_cfg.ca_list },
{"ca_path", PARAM_STR, &default_tls_cfg.ca_path },
{"certificate", PARAM_STR, &default_tls_cfg.certificate },
{"crl", PARAM_STR, &default_tls_cfg.crl },
{"cipher_list", PARAM_STR, &default_tls_cfg.cipher_list },
Expand Down

0 comments on commit eb45409

Please sign in to comment.