From 5bb70664748e3a8e6b0ab50da070ecae615f20bd Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 2 Nov 2013 21:30:32 +0900 Subject: [PATCH] nghttpx: Add --verify-client-cacert option Using --cacert to load certificate for client certificate authentication is problematic since, --cacert is also used for client mode. This commit adds --verify-client-cacert option which specify the CA certficate file used only for client certificate validation. This change also removes the default certficate load function for client certificate validation. --- src/shrpx.cc | 13 ++++++++++++- src/shrpx_config.cc | 3 +++ src/shrpx_config.h | 4 ++++ src/shrpx_ssl.cc | 13 +++++-------- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/shrpx.cc b/src/shrpx.cc index 50f7907c..c6f85e7f 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -336,7 +336,6 @@ void fill_default_config() mod_config()->verbose = false; mod_config()->daemon = false; - mod_config()->verify_client = false; mod_config()->server_name = "nghttpx nghttp2/" NGHTTP2_VERSION; set_config_str(&mod_config()->host, "0.0.0.0"); @@ -418,6 +417,7 @@ void fill_default_config() mod_config()->write_burst = 0; mod_config()->npn_list = nullptr; mod_config()->verify_client = false; + mod_config()->verify_client_cacert = nullptr; } } // namespace @@ -595,6 +595,11 @@ void print_help(std::ostream& out) << " as a part of protocol string.\n" << " Default: " << DEFAULT_NPN_LIST << "\n" << " --verify-client Require and verify client certificate.\n" + << " --verify-client-cacert=\n" + << " Path to file that contains CA certificates\n" + << " to verify client certificate.\n" + << " The file must be in PEM format. It can\n" + << " contain multiple certificates.\n" << "\n" << " HTTP/2.0 and SPDY:\n" << " -c, --spdy-max-concurrent-streams=\n" @@ -733,6 +738,7 @@ int main(int argc, char **argv) {"write-burst", required_argument, &flag, 37}, {"npn-list", required_argument, &flag, 38}, {"verify-client", no_argument, &flag, 39}, + {"verify-client-cacert", required_argument, &flag, 40}, {nullptr, 0, nullptr, 0 } }; int option_index = 0; @@ -940,6 +946,11 @@ int main(int argc, char **argv) // --verify-client cmdcfgs.push_back(std::make_pair(SHRPX_OPT_VERIFY_CLIENT, "yes")); break; + case 40: + // --verify-client-cacert + cmdcfgs.push_back(std::make_pair(SHRPX_OPT_VERIFY_CLIENT_CACERT, + optarg)); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index 8f9c6f51..beccb16f 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -101,6 +101,7 @@ const char SHRPX_OPT_WRITE_RATE[] = "write-rate"; const char SHRPX_OPT_WRITE_BURST[] = "write-burst"; const char SHRPX_OPT_NPN_LIST[] = "npn-list"; const char SHRPX_OPT_VERIFY_CLIENT[] = "verify-client"; +const char SHRPX_OPT_VERIFY_CLIENT_CACERT[] = "verify-client-cacert"; namespace { Config *config = nullptr; @@ -409,6 +410,8 @@ int parse_config(const char *opt, const char *optarg) parse_config_npn_list(optarg); } else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) { mod_config()->verify_client = util::strieq(optarg, "yes"); + } else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT_CACERT)) { + set_config_str(&mod_config()->verify_client_cacert, optarg); } else if(util::strieq(opt, "conf")) { LOG(WARNING) << "conf is ignored"; } else { diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 5cf704ba..a38b8a35 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -92,6 +92,7 @@ extern const char SHRPX_OPT_WRITE_RATE[]; extern const char SHRPX_OPT_WRITE_BURST[]; extern const char SHRPX_OPT_NPN_LIST[]; extern const char SHRPX_OPT_VERIFY_CLIENT[]; +extern const char SHRPX_OPT_VERIFY_CLIENT_CACERT[]; union sockaddr_union { sockaddr sa; @@ -187,6 +188,9 @@ struct Config { size_t npn_list_len; // The list of (private key file, certificate file) pair std::vector> subcerts; + // Path to file containing CA certificate solely used for client + // certificate validation + char *verify_client_cacert; }; const Config* get_config(); diff --git a/src/shrpx_ssl.cc b/src/shrpx_ssl.cc index c226dad8..867dc97c 100644 --- a/src/shrpx_ssl.cc +++ b/src/shrpx_ssl.cc @@ -218,15 +218,12 @@ SSL_CTX* create_ssl_context(const char *private_key_file, DIE(); } if(get_config()->verify_client) { - if(SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) { - LOG(WARNING) << "Could not load system trusted ca certificates: " - << ERR_error_string(ERR_get_error(), nullptr); - } - if(get_config()->cacert) { - if(SSL_CTX_load_verify_locations(ssl_ctx, get_config()->cacert, nullptr) - != 1) { + if(get_config()->verify_client_cacert) { + if(SSL_CTX_load_verify_locations(ssl_ctx, + get_config()->verify_client_cacert, + nullptr) != 1) { LOG(FATAL) << "Could not load trusted ca certificates from " - << get_config()->cacert << ": " + << get_config()->verify_client_cacert << ": " << ERR_error_string(ERR_get_error(), nullptr); DIE(); }