Commit 5bb70664 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

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.
parent 3e3ff7ac
...@@ -336,7 +336,6 @@ void fill_default_config() ...@@ -336,7 +336,6 @@ void fill_default_config()
mod_config()->verbose = false; mod_config()->verbose = false;
mod_config()->daemon = false; mod_config()->daemon = false;
mod_config()->verify_client = false;
mod_config()->server_name = "nghttpx nghttp2/" NGHTTP2_VERSION; mod_config()->server_name = "nghttpx nghttp2/" NGHTTP2_VERSION;
set_config_str(&mod_config()->host, "0.0.0.0"); set_config_str(&mod_config()->host, "0.0.0.0");
...@@ -418,6 +417,7 @@ void fill_default_config() ...@@ -418,6 +417,7 @@ void fill_default_config()
mod_config()->write_burst = 0; mod_config()->write_burst = 0;
mod_config()->npn_list = nullptr; mod_config()->npn_list = nullptr;
mod_config()->verify_client = false; mod_config()->verify_client = false;
mod_config()->verify_client_cacert = nullptr;
} }
} // namespace } // namespace
...@@ -595,6 +595,11 @@ void print_help(std::ostream& out) ...@@ -595,6 +595,11 @@ void print_help(std::ostream& out)
<< " as a part of protocol string.\n" << " as a part of protocol string.\n"
<< " Default: " << DEFAULT_NPN_LIST << "\n" << " Default: " << DEFAULT_NPN_LIST << "\n"
<< " --verify-client Require and verify client certificate.\n" << " --verify-client Require and verify client certificate.\n"
<< " --verify-client-cacert=<PATH>\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" << "\n"
<< " HTTP/2.0 and SPDY:\n" << " HTTP/2.0 and SPDY:\n"
<< " -c, --spdy-max-concurrent-streams=<NUM>\n" << " -c, --spdy-max-concurrent-streams=<NUM>\n"
...@@ -733,6 +738,7 @@ int main(int argc, char **argv) ...@@ -733,6 +738,7 @@ int main(int argc, char **argv)
{"write-burst", required_argument, &flag, 37}, {"write-burst", required_argument, &flag, 37},
{"npn-list", required_argument, &flag, 38}, {"npn-list", required_argument, &flag, 38},
{"verify-client", no_argument, &flag, 39}, {"verify-client", no_argument, &flag, 39},
{"verify-client-cacert", required_argument, &flag, 40},
{nullptr, 0, nullptr, 0 } {nullptr, 0, nullptr, 0 }
}; };
int option_index = 0; int option_index = 0;
...@@ -940,6 +946,11 @@ int main(int argc, char **argv) ...@@ -940,6 +946,11 @@ int main(int argc, char **argv)
// --verify-client // --verify-client
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_VERIFY_CLIENT, "yes")); cmdcfgs.push_back(std::make_pair(SHRPX_OPT_VERIFY_CLIENT, "yes"));
break; break;
case 40:
// --verify-client-cacert
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_VERIFY_CLIENT_CACERT,
optarg));
break;
default: default:
break; break;
} }
......
...@@ -101,6 +101,7 @@ const char SHRPX_OPT_WRITE_RATE[] = "write-rate"; ...@@ -101,6 +101,7 @@ const char SHRPX_OPT_WRITE_RATE[] = "write-rate";
const char SHRPX_OPT_WRITE_BURST[] = "write-burst"; const char SHRPX_OPT_WRITE_BURST[] = "write-burst";
const char SHRPX_OPT_NPN_LIST[] = "npn-list"; const char SHRPX_OPT_NPN_LIST[] = "npn-list";
const char SHRPX_OPT_VERIFY_CLIENT[] = "verify-client"; const char SHRPX_OPT_VERIFY_CLIENT[] = "verify-client";
const char SHRPX_OPT_VERIFY_CLIENT_CACERT[] = "verify-client-cacert";
namespace { namespace {
Config *config = nullptr; Config *config = nullptr;
...@@ -409,6 +410,8 @@ int parse_config(const char *opt, const char *optarg) ...@@ -409,6 +410,8 @@ int parse_config(const char *opt, const char *optarg)
parse_config_npn_list(optarg); parse_config_npn_list(optarg);
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) { } else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) {
mod_config()->verify_client = util::strieq(optarg, "yes"); 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")) { } else if(util::strieq(opt, "conf")) {
LOG(WARNING) << "conf is ignored"; LOG(WARNING) << "conf is ignored";
} else { } else {
......
...@@ -92,6 +92,7 @@ extern const char SHRPX_OPT_WRITE_RATE[]; ...@@ -92,6 +92,7 @@ extern const char SHRPX_OPT_WRITE_RATE[];
extern const char SHRPX_OPT_WRITE_BURST[]; extern const char SHRPX_OPT_WRITE_BURST[];
extern const char SHRPX_OPT_NPN_LIST[]; extern const char SHRPX_OPT_NPN_LIST[];
extern const char SHRPX_OPT_VERIFY_CLIENT[]; extern const char SHRPX_OPT_VERIFY_CLIENT[];
extern const char SHRPX_OPT_VERIFY_CLIENT_CACERT[];
union sockaddr_union { union sockaddr_union {
sockaddr sa; sockaddr sa;
...@@ -187,6 +188,9 @@ struct Config { ...@@ -187,6 +188,9 @@ struct Config {
size_t npn_list_len; size_t npn_list_len;
// The list of (private key file, certificate file) pair // The list of (private key file, certificate file) pair
std::vector<std::pair<std::string, std::string>> subcerts; std::vector<std::pair<std::string, std::string>> subcerts;
// Path to file containing CA certificate solely used for client
// certificate validation
char *verify_client_cacert;
}; };
const Config* get_config(); const Config* get_config();
......
...@@ -218,15 +218,12 @@ SSL_CTX* create_ssl_context(const char *private_key_file, ...@@ -218,15 +218,12 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
DIE(); DIE();
} }
if(get_config()->verify_client) { if(get_config()->verify_client) {
if(SSL_CTX_set_default_verify_paths(ssl_ctx) != 1) { if(get_config()->verify_client_cacert) {
LOG(WARNING) << "Could not load system trusted ca certificates: " if(SSL_CTX_load_verify_locations(ssl_ctx,
<< ERR_error_string(ERR_get_error(), nullptr); get_config()->verify_client_cacert,
} nullptr) != 1) {
if(get_config()->cacert) {
if(SSL_CTX_load_verify_locations(ssl_ctx, get_config()->cacert, nullptr)
!= 1) {
LOG(FATAL) << "Could not load trusted ca certificates from " LOG(FATAL) << "Could not load trusted ca certificates from "
<< get_config()->cacert << ": " << get_config()->verify_client_cacert << ": "
<< ERR_error_string(ERR_get_error(), nullptr); << ERR_error_string(ERR_get_error(), nullptr);
DIE(); DIE();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment