From: Graham Leggett Date: Sun, 23 Sep 2018 21:39:15 +0000 (+0000) Subject: ab: Add client certificate support. X-Git-Tag: 2.5.0-alpha2-ci-test-only~2327 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95d673ea402cc8308fed3ff192fbc2371287d575;p=thirdparty%2Fapache%2Fhttpd.git ab: Add client certificate support. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1841784 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index d5080a61020..5eafac77bdc 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) ab: Add client certificate support. [Graham Leggett] + *) mod_proxy_hcheck: Fix issues with TCP health checks. PR 61499 [Dominik Stillhard ] diff --git a/docs/manual/programs/ab.xml b/docs/manual/programs/ab.xml index 3ddebe039e9..abdb26016d2 100644 --- a/docs/manual/programs/ab.xml +++ b/docs/manual/programs/ab.xml @@ -43,6 +43,7 @@ [ -C cookie-name=value ] [ -d ] [ -e csv-file ] + [ -E client-certificate file ] [ -f protocol ] [ -g gnuplot-file ] [ -h ] @@ -105,6 +106,12 @@ that percentage of the requests. This is usually more useful than the 'gnuplot' file; as the results are already 'binned'. +
-E client-certificate-file
+
When connecting to an SSL website, use the provided client certificate + in PEM format to authenticate with the server. The file is expected to + contain the client certificate, followed by intermediate certificates, + followed by the private key. Available in 2.4.36 and later.
+
-f protocol
Specify SSL/TLS protocol (SSL2, SSL3, TLS1, TLS1.1, TLS1.2, or ALL).
TLS1.1 and TLS1.2 support available in 2.4.4 and later.
diff --git a/support/ab.c b/support/ab.c index 224bd69f99a..410d58e56e5 100644 --- a/support/ab.c +++ b/support/ab.c @@ -353,6 +353,7 @@ int is_ssl; SSL_CTX *ssl_ctx; char *ssl_cipher = NULL; char *ssl_info = NULL; +char *ssl_cert = NULL; #if OPENSSL_VERSION_NUMBER >= 0x10002000L char *ssl_tmp_key = NULL; #endif @@ -2170,6 +2171,7 @@ static void usage(const char *progname) fprintf(stderr, " -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)\n"); fprintf(stderr, " -f protocol Specify SSL/TLS protocol\n"); fprintf(stderr, " (" SSL2_HELP_MSG SSL3_HELP_MSG "TLS1" TLS1_X_HELP_MSG " or ALL)\n"); + fprintf(stderr, " -E certfile Specify optional client certificate chain and private key\n"); #endif exit(EINVAL); } @@ -2340,7 +2342,7 @@ int main(int argc, const char * const argv[]) apr_getopt_init(&opt, cntxt, argc, argv); while ((status = apr_getopt(opt, "n:c:t:s:b:T:p:u:v:lrkVhwiIx:y:z:C:H:P:A:g:X:de:SqB:m:" #ifdef USE_SSL - "Z:f:" + "Z:f:E:" #endif ,&c, &opt_arg)) == APR_SUCCESS) { switch (c) { @@ -2524,6 +2526,9 @@ int main(int argc, const char * const argv[]) case 'Z': ssl_cipher = strdup(opt_arg); break; + case 'E': + ssl_cert = strdup(opt_arg); + break; case 'f': #if OPENSSL_VERSION_NUMBER < 0x10100000L if (strncasecmp(opt_arg, "ALL", 3) == 0) { @@ -2658,6 +2663,26 @@ int main(int argc, const char * const argv[]) if (verbosity >= 3) { SSL_CTX_set_info_callback(ssl_ctx, ssl_state_cb); } + if (ssl_cert != NULL) { + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, ssl_cert) <= 0) { + BIO_printf(bio_err, "unable to get certificate from '%s'\n", + ssl_cert); + ERR_print_errors(bio_err); + exit(1); + } + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, ssl_cert, SSL_FILETYPE_PEM) <= 0) { + BIO_printf(bio_err, "unable to get private key from '%s'\n", + ssl_cert); + ERR_print_errors(bio_err); + exit(1); + } + if (!SSL_CTX_check_private_key(ssl_ctx)) { + BIO_printf(bio_err, + "private key does not match the certificate public key in %s\n", ssl_cert); + exit(1); + } + } + #endif #ifdef SIGPIPE apr_signal(SIGPIPE, SIG_IGN); /* Ignore writes to connections that