diff options
Diffstat (limited to 'modules/ssl/ssl_engine_vars.c')
-rw-r--r-- | modules/ssl/ssl_engine_vars.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c index 7d09846c27..45a5a5bab6 100644 --- a/modules/ssl/ssl_engine_vars.c +++ b/modules/ssl/ssl_engine_vars.c @@ -52,6 +52,7 @@ static const char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, const SSLConnRe static const char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, const SSLConnRec *sslconn, const char *var); static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); static const char *ssl_var_lookup_ssl_handshake_rtt(apr_pool_t *p, SSL *ssl); +static const char *ssl_var_lookup_ssl_clienthello(apr_pool_t *p, const SSLConnRec *sslconn, const char *var); static const char *ssl_var_lookup_ssl_version(const char *var); static const char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); @@ -476,6 +477,9 @@ static const char *ssl_var_lookup_ssl(apr_pool_t *p, const SSLConnRec *sslconn, else if (ssl != NULL && strcEQ(var, "HANDSHAKE_RTT")) { result = ssl_var_lookup_ssl_handshake_rtt(p, ssl); } + else if (ssl != NULL && strlen(var) >= 12 && strcEQn(var, "CLIENTHELLO_", 12)) { + result = ssl_var_lookup_ssl_clienthello(p, sslconn, var+12); + } else if (ssl != NULL && strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) { sk = SSL_get_peer_cert_chain(ssl); result = ssl_var_lookup_ssl_cert_chain(p, sk, var+18, 1); @@ -975,6 +979,62 @@ static const char *ssl_var_lookup_ssl_handshake_rtt(apr_pool_t *p, SSL *ssl) return NULL; } +static const char *ssl_var_lookup_ssl_clienthello(apr_pool_t *p, const SSLConnRec *sslconn, const char *var) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) + char *value; + modssl_clienthello_vars *clienthello_vars; + apr_size_t i; + + clienthello_vars = sslconn->clienthello_vars; + + if (!clienthello_vars) + return NULL; + + if (strEQ(var, "VERSION")) { + return apr_psprintf(p, "%04x", (uint16_t) clienthello_vars->version); + } + else if (strEQ(var, "CIPHERS") && (clienthello_vars->ciphers_len > 0)) { + value = apr_palloc(p, clienthello_vars->ciphers_len * 2 + 1); + ap_bin2hex(clienthello_vars->ciphers_data, clienthello_vars->ciphers_len, value); + return value; + } + else if (strEQ(var, "EXTENSIONS") && (clienthello_vars->extids_len > 0)) { + value = apr_palloc(p, clienthello_vars->extids_len * 4 + 1); + for (i = 0; i < clienthello_vars->extids_len; i++) { + apr_snprintf(value + i * 4, 5, "%04x", (uint16_t) clienthello_vars->extids_data[i]); + } + return value; + } + else if (strEQ(var, "GROUPS") && (clienthello_vars->ecgroups_len > 2)) { + value = apr_palloc(p, clienthello_vars->ecgroups_len * 2 + 1 - 2); + ap_bin2hex(clienthello_vars->ecgroups_data + 2, clienthello_vars->ecgroups_len - 2, value); + return value; + } + else if (strEQ(var, "EC_FORMATS") && (clienthello_vars->ecformats_len > 1)) { + value = apr_palloc(p, clienthello_vars->ecformats_len * 2 + 1 - 1); + ap_bin2hex(clienthello_vars->ecformats_data + 1, clienthello_vars->ecformats_len - 1, value); + return value; + } + else if (strEQ(var, "SIG_ALGOS") && (clienthello_vars->sigalgos_len > 2)) { + value = apr_palloc(p, clienthello_vars->sigalgos_len * 2 + 1 - 2); + ap_bin2hex(clienthello_vars->sigalgos_data + 2, clienthello_vars->sigalgos_len - 2, value); + return value; + } + else if (strEQ(var, "ALPN") && (clienthello_vars->alpn_len > 2)) { + value = apr_palloc(p, clienthello_vars->alpn_len * 2 + 1 - 2); + ap_bin2hex(clienthello_vars->alpn_data + 2, clienthello_vars->alpn_len - 2, value); + return value; + } + else if (strEQ(var, "VERSIONS") && (clienthello_vars->versions_len > 1)) { + value = apr_palloc(p, clienthello_vars->versions_len * 2 + 1 - 1); + ap_bin2hex(clienthello_vars->versions_data + 1, clienthello_vars->versions_len - 1, value); + return value; + } +#endif + return NULL; +} + static const char *ssl_var_lookup_ssl_version(const char *var) { if (strEQ(var, "INTERFACE")) { |