Merge pull request #1045 from nghttp2/nghttpx-sha1-fingerprint
Nghttpx sha1 fingerprint
This commit is contained in:
commit
e29b9c1261
|
@ -368,10 +368,14 @@ respectively.
|
||||||
|
|
||||||
Return the TLS SNI value which client sent in this connection.
|
Return the TLS SNI value which client sent in this connection.
|
||||||
|
|
||||||
.. rb:attr_reader:: tls_client_fingerprint
|
.. rb:attr_reader:: tls_client_fingerprint_sha256
|
||||||
|
|
||||||
Return the SHA-256 fingerprint of a client certificate.
|
Return the SHA-256 fingerprint of a client certificate.
|
||||||
|
|
||||||
|
.. rb:attr_reader:: tls_client_fingerprint_sha1
|
||||||
|
|
||||||
|
Return the SHA-1 fingerprint of a client certificate.
|
||||||
|
|
||||||
.. rb:attr_reader:: tls_client_subject_name
|
.. rb:attr_reader:: tls_client_subject_name
|
||||||
|
|
||||||
Return the subject name of a client certificate.
|
Return the subject name of a client certificate.
|
||||||
|
|
|
@ -191,7 +191,8 @@ LOGVARS = [
|
||||||
"tls_session_id",
|
"tls_session_id",
|
||||||
"tls_session_reused",
|
"tls_session_reused",
|
||||||
"tls_sni",
|
"tls_sni",
|
||||||
"tls_client_fingerprint",
|
"tls_client_fingerprint_sha256",
|
||||||
|
"tls_client_fingerprint_sha1",
|
||||||
"tls_client_subject_name",
|
"tls_client_subject_name",
|
||||||
"backend_host",
|
"backend_host",
|
||||||
"backend_port",
|
"backend_port",
|
||||||
|
|
|
@ -2482,8 +2482,10 @@ Logging:
|
||||||
the response. For HTTP/1, ALPN is always http/1.1,
|
the response. For HTTP/1, ALPN is always http/1.1,
|
||||||
regardless of minor version.
|
regardless of minor version.
|
||||||
* $tls_cipher: cipher used for SSL/TLS connection.
|
* $tls_cipher: cipher used for SSL/TLS connection.
|
||||||
* $tls_client_fingerprint: SHA-256 fingerprint of client
|
* $tls_client_fingerprint_sha256: SHA-256 fingerprint of
|
||||||
certificate.
|
client certificate.
|
||||||
|
* $tls_client_fingerprint_sha1: SHA-1 fingerprint of
|
||||||
|
client certificate.
|
||||||
* $tls_client_subject_name: subject name in client
|
* $tls_client_subject_name: subject name in client
|
||||||
certificate.
|
certificate.
|
||||||
* $tls_protocol: protocol for SSL/TLS connection.
|
* $tls_protocol: protocol for SSL/TLS connection.
|
||||||
|
|
|
@ -510,15 +510,6 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 22:
|
|
||||||
switch (name[21]) {
|
|
||||||
case 't':
|
|
||||||
if (util::strieq_l("tls_client_fingerprin", name, 21)) {
|
|
||||||
return SHRPX_LOGF_TLS_CLIENT_FINGERPRINT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 23:
|
case 23:
|
||||||
switch (name[22]) {
|
switch (name[22]) {
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -528,6 +519,24 @@ LogFragmentType log_var_lookup_token(const char *name, size_t namelen) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 27:
|
||||||
|
switch (name[26]) {
|
||||||
|
case '1':
|
||||||
|
if (util::strieq_l("tls_client_fingerprint_sha", name, 26)) {
|
||||||
|
return SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
switch (name[28]) {
|
||||||
|
case '6':
|
||||||
|
if (util::strieq_l("tls_client_fingerprint_sha25", name, 28)) {
|
||||||
|
return SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA256;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return SHRPX_LOGF_NONE;
|
return SHRPX_LOGF_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,7 +533,8 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
}
|
}
|
||||||
std::tie(p, last) = copy_escape(lgsp.sni, p, last);
|
std::tie(p, last) = copy_escape(lgsp.sni, p, last);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_TLS_CLIENT_FINGERPRINT: {
|
case SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA1:
|
||||||
|
case SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA256: {
|
||||||
if (!lgsp.ssl) {
|
if (!lgsp.ssl) {
|
||||||
std::tie(p, last) = copy('-', p, last);
|
std::tie(p, last) = copy('-', p, last);
|
||||||
break;
|
break;
|
||||||
|
@ -544,7 +545,10 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::array<uint8_t, 32> buf;
|
std::array<uint8_t, 32> buf;
|
||||||
auto len = tls::get_x509_fingerprint(buf.data(), buf.size(), x);
|
auto len = tls::get_x509_fingerprint(
|
||||||
|
buf.data(), buf.size(), x,
|
||||||
|
lf.type == SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA256 ? EVP_sha256()
|
||||||
|
: EVP_sha1());
|
||||||
X509_free(x);
|
X509_free(x);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
std::tie(p, last) = copy('-', p, last);
|
std::tie(p, last) = copy('-', p, last);
|
||||||
|
|
|
@ -138,7 +138,8 @@ enum LogFragmentType {
|
||||||
SHRPX_LOGF_TLS_SESSION_REUSED,
|
SHRPX_LOGF_TLS_SESSION_REUSED,
|
||||||
SHRPX_LOGF_SSL_SESSION_REUSED = SHRPX_LOGF_TLS_SESSION_REUSED,
|
SHRPX_LOGF_SSL_SESSION_REUSED = SHRPX_LOGF_TLS_SESSION_REUSED,
|
||||||
SHRPX_LOGF_TLS_SNI,
|
SHRPX_LOGF_TLS_SNI,
|
||||||
SHRPX_LOGF_TLS_CLIENT_FINGERPRINT,
|
SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA1,
|
||||||
|
SHRPX_LOGF_TLS_CLIENT_FINGERPRINT_SHA256,
|
||||||
SHRPX_LOGF_TLS_CLIENT_SUBJECT_NAME,
|
SHRPX_LOGF_TLS_CLIENT_SUBJECT_NAME,
|
||||||
SHRPX_LOGF_BACKEND_HOST,
|
SHRPX_LOGF_BACKEND_HOST,
|
||||||
SHRPX_LOGF_BACKEND_PORT,
|
SHRPX_LOGF_BACKEND_PORT,
|
||||||
|
|
|
@ -142,7 +142,7 @@ mrb_value env_get_tls_sni(mrb_state *mrb, mrb_value self) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
mrb_value env_get_tls_client_fingerprint(mrb_state *mrb, mrb_value self) {
|
mrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) {
|
||||||
auto data = static_cast<MRubyAssocData *>(mrb->ud);
|
auto data = static_cast<MRubyAssocData *>(mrb->ud);
|
||||||
auto downstream = data->downstream;
|
auto downstream = data->downstream;
|
||||||
auto upstream = downstream->get_upstream();
|
auto upstream = downstream->get_upstream();
|
||||||
|
@ -158,9 +158,9 @@ mrb_value env_get_tls_client_fingerprint(mrb_state *mrb, mrb_value self) {
|
||||||
return mrb_str_new_static(mrb, "", 0);
|
return mrb_str_new_static(mrb, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fingerprint is SHA-256, so we need 32 bytes buffer.
|
// Currently the largest hash value is SHA-256, which is 32 bytes.
|
||||||
std::array<uint8_t, 32> buf;
|
std::array<uint8_t, 32> buf;
|
||||||
auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x);
|
auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md);
|
||||||
X509_free(x);
|
X509_free(x);
|
||||||
if (slen == -1) {
|
if (slen == -1) {
|
||||||
mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint");
|
mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint");
|
||||||
|
@ -174,6 +174,19 @@ mrb_value env_get_tls_client_fingerprint(mrb_state *mrb, mrb_value self) {
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
mrb_value env_get_tls_client_fingerprint_sha256(mrb_state *mrb,
|
||||||
|
mrb_value self) {
|
||||||
|
return env_get_tls_client_fingerprint_md(mrb, EVP_sha256());
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
mrb_value env_get_tls_client_fingerprint_sha1(mrb_state *mrb, mrb_value self) {
|
||||||
|
return env_get_tls_client_fingerprint_md(mrb, EVP_sha1());
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
mrb_value env_get_tls_client_subject_name(mrb_state *mrb, mrb_value self) {
|
mrb_value env_get_tls_client_subject_name(mrb_state *mrb, mrb_value self) {
|
||||||
auto data = static_cast<MRubyAssocData *>(mrb->ud);
|
auto data = static_cast<MRubyAssocData *>(mrb->ud);
|
||||||
|
@ -303,8 +316,10 @@ void init_env_class(mrb_state *mrb, RClass *module) {
|
||||||
MRB_ARGS_NONE());
|
MRB_ARGS_NONE());
|
||||||
mrb_define_method(mrb, env_class, "tls_sni", env_get_tls_sni,
|
mrb_define_method(mrb, env_class, "tls_sni", env_get_tls_sni,
|
||||||
MRB_ARGS_NONE());
|
MRB_ARGS_NONE());
|
||||||
mrb_define_method(mrb, env_class, "tls_client_fingerprint",
|
mrb_define_method(mrb, env_class, "tls_client_fingerprint_sha256",
|
||||||
env_get_tls_client_fingerprint, MRB_ARGS_NONE());
|
env_get_tls_client_fingerprint_sha256, MRB_ARGS_NONE());
|
||||||
|
mrb_define_method(mrb, env_class, "tls_client_fingerprint_sha1",
|
||||||
|
env_get_tls_client_fingerprint_sha1, MRB_ARGS_NONE());
|
||||||
mrb_define_method(mrb, env_class, "tls_client_subject_name",
|
mrb_define_method(mrb, env_class, "tls_client_subject_name",
|
||||||
env_get_tls_client_subject_name, MRB_ARGS_NONE());
|
env_get_tls_client_subject_name, MRB_ARGS_NONE());
|
||||||
mrb_define_method(mrb, env_class, "tls_cipher", env_get_tls_cipher,
|
mrb_define_method(mrb, env_class, "tls_cipher", env_get_tls_cipher,
|
||||||
|
|
|
@ -1920,10 +1920,10 @@ int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, X509 *x) {
|
ssize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, const X509 *x,
|
||||||
assert(dstlen >= 32);
|
const EVP_MD *md) {
|
||||||
unsigned int len = dstlen;
|
unsigned int len = dstlen;
|
||||||
if (X509_digest(x, EVP_sha256(), dst, &len) != 1) {
|
if (X509_digest(x, md, dst, &len) != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
|
|
|
@ -269,10 +269,12 @@ int proto_version_from_string(const StringRef &v);
|
||||||
int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
|
int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
|
||||||
size_t ocsp_resplen);
|
size_t ocsp_resplen);
|
||||||
|
|
||||||
// Stores SHA-256 fingerprint of |x| in |dst| of length |dstlen|.
|
// Stores fingerprint of |x| in |dst| of length |dstlen|. |md|
|
||||||
// |dstlen| must be larger than 32 bytes. This function returns the
|
// specifies hash function to use, and |dstlen| must be large enough
|
||||||
// number of bytes written in |dst|, or -1.
|
// to include hash value (e.g., 32 bytes for SHA-256). This function
|
||||||
ssize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, X509 *x);
|
// returns the number of bytes written in |dst|, or -1.
|
||||||
|
ssize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, const X509 *x,
|
||||||
|
const EVP_MD *md);
|
||||||
|
|
||||||
// Returns subject name of |x|. If this function fails to get subject
|
// Returns subject name of |x|. If this function fails to get subject
|
||||||
// name, it returns an empty string.
|
// name, it returns an empty string.
|
||||||
|
|
Loading…
Reference in New Issue