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.
This commit is contained in:
Tatsuhiro Tsujikawa 2013-11-02 21:30:32 +09:00
parent 3e3ff7acd6
commit 5bb7066474
4 changed files with 24 additions and 9 deletions

View File

@ -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=<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"
<< " HTTP/2.0 and SPDY:\n"
<< " -c, --spdy-max-concurrent-streams=<NUM>\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;
}

View File

@ -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 {

View File

@ -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<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();

View File

@ -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();
}