Resolve tls_ca_{file,path} relative to config dir

This commit is contained in:
Přemysl Eric Janouch 2016-02-19 23:46:44 +01:00
parent 798ed73a8c
commit 056e0a4765
2 changed files with 109 additions and 63 deletions

View File

@ -4470,6 +4470,51 @@ transport_tls_verify_callback (int preverify_ok, X509_STORE_CTX *ctx)
return preverify_ok;
}
static bool
transport_tls_init_ca_set (SSL_CTX *ssl_ctx, const char *file, const char *path,
struct error **e)
{
ERR_clear_error ();
if (file || path)
{
if (SSL_CTX_load_verify_locations (ssl_ctx, file, path))
return true;
FAIL ("%s: %s", "Failed to set locations for the CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
}
if (!SSL_CTX_set_default_verify_paths (ssl_ctx))
FAIL ("%s: %s", "Couldn't load the default CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
return true;
}
static bool
transport_tls_init_ca (struct server *s, SSL_CTX *ssl_ctx, struct error **e)
{
const char *ca_file = get_config_string (s->config, "tls_ca_file");
const char *ca_path = get_config_string (s->config, "tls_ca_path");
char *full_ca_file = ca_file
? resolve_filename (ca_file, resolve_relative_config_filename) : NULL;
char *full_ca_path = ca_path
? resolve_filename (ca_path, resolve_relative_config_filename) : NULL;
bool ok = false;
if (ca_file && !full_ca_file)
error_set (e, "Couldn't find the CA bundle file");
else if (ca_path && !full_ca_path)
error_set (e, "Couldn't find the CA bundle path");
else
ok = transport_tls_init_ca_set (ssl_ctx, full_ca_file, full_ca_path, e);
free (full_ca_file);
free (full_ca_path);
return ok;
}
static bool
transport_tls_init_ctx (struct server *s, SSL_CTX *ssl_ctx, struct error **e)
{
@ -4499,33 +4544,9 @@ transport_tls_init_ctx (struct server *s, SSL_CTX *ssl_ctx, struct error **e)
SSL_CTX_set_options (ssl_ctx, SSL_OP_NO_COMPRESSION);
#endif // SSL_OP_NO_COMPRESSION
const char *ca_file = get_config_string (s->config, "tls_ca_file");
const char *ca_path = get_config_string (s->config, "tls_ca_path");
ERR_clear_error ();
struct error *error = NULL;
if (ca_file || ca_path)
if (!transport_tls_init_ca (s, ssl_ctx, &error))
{
if (SSL_CTX_load_verify_locations (ssl_ctx, ca_file, ca_path))
return true;
error_set (&error, "%s: %s",
"Failed to set locations for the CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
goto ca_error;
}
if (!SSL_CTX_set_default_verify_paths (ssl_ctx))
{
error_set (&error, "%s: %s",
"Couldn't load the default CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
goto ca_error;
}
return true;
ca_error:
if (verify)
{
error_propagate (e, error);
@ -4535,6 +4556,7 @@ ca_error:
// Only inform the user if we're not actually verifying
log_server_error (s, s->buffer, "#s", error->message);
error_free (error);
}
return true;
}

View File

@ -1,7 +1,7 @@
/*
* zyklonb.c: the experimental IRC bot
*
* Copyright (c) 2014 - 2015, Přemysl Janouch <p.janouch@gmail.com>
* Copyright (c) 2014 - 2016, Přemysl Janouch <p.janouch@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -314,6 +314,51 @@ irc_get_boolean_from_config
return false;
}
static bool
irc_initialize_ca_set (SSL_CTX *ssl_ctx, const char *file, const char *path,
struct error **e)
{
ERR_clear_error ();
if (file || path)
{
if (SSL_CTX_load_verify_locations (ssl_ctx, file, path))
return true;
FAIL ("%s: %s", "failed to set locations for the CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
}
if (!SSL_CTX_set_default_verify_paths (ssl_ctx))
FAIL ("%s: %s", "couldn't load the default CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
return true;
}
static bool
irc_initialize_ca (struct bot_context *ctx, struct error **e)
{
const char *ca_file = str_map_find (&ctx->config, "tls_ca_file");
const char *ca_path = str_map_find (&ctx->config, "tls_ca_path");
char *full_file = ca_file
? resolve_filename (ca_file, resolve_relative_config_filename) : NULL;
char *full_path = ca_path
? resolve_filename (ca_path, resolve_relative_config_filename) : NULL;
bool ok = false;
if (ca_file && !full_file)
error_set (e, "couldn't find the CA bundle file");
else if (ca_path && !full_path)
error_set (e, "couldn't find the CA bundle path");
else
ok = irc_initialize_ca_set (ctx->ssl_ctx, full_file, full_path, e);
free (full_file);
free (full_path);
return ok;
}
static bool
irc_initialize_ssl_ctx (struct bot_context *ctx, struct error **e)
{
@ -326,31 +371,9 @@ irc_initialize_ssl_ctx (struct bot_context *ctx, struct error **e)
SSL_CTX_set_verify (ctx->ssl_ctx,
verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
const char *ca_file = str_map_find (&ctx->config, "tls_ca_file");
const char *ca_path = str_map_find (&ctx->config, "tls_ca_path");
struct error *error = NULL;
if (ca_file || ca_path)
if (!irc_initialize_ca (ctx, &error))
{
if (SSL_CTX_load_verify_locations (ctx->ssl_ctx, ca_file, ca_path))
return true;
error_set (&error, "%s: %s",
"failed to set locations for the CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
goto ca_error;
}
if (!SSL_CTX_set_default_verify_paths (ctx->ssl_ctx))
{
error_set (&error, "%s: %s",
"couldn't load the default CA certificate bundle",
ERR_reason_error_string (ERR_get_error ()));
goto ca_error;
}
return true;
ca_error:
if (verify)
{
error_propagate (e, error);
@ -360,6 +383,7 @@ ca_error:
// Only inform the user if we're not actually verifying
print_warning ("%s", error->message);
error_free (error);
}
return true;
}