diff --git a/gennghttpxfun.py b/gennghttpxfun.py
index 4d4fb7e4..cac3a548 100755
--- a/gennghttpxfun.py
+++ b/gennghttpxfun.py
@@ -155,6 +155,7 @@ OPTIONS = [
"frontend-keep-alive-timeout",
"psk-secrets",
"client-psk-secrets",
+ "client-no-http2-cipher-black-list",
]
LOGVARS = [
diff --git a/src/shrpx.cc b/src/shrpx.cc
index c31ae514..4dc79b70 100644
--- a/src/shrpx.cc
+++ b/src/shrpx.cc
@@ -2091,9 +2091,15 @@ SSL/TLS:
Default: )"
<< util::duration_str(config->tls.dyn_rec.idle_timeout) << R"(
--no-http2-cipher-black-list
- Allow black listed cipher suite on HTTP/2 connection.
- See https://tools.ietf.org/html/rfc7540#appendix-A for
- the complete HTTP/2 cipher suites black list.
+ Allow black listed cipher suite on frontend HTTP/2
+ connection. See
+ https://tools.ietf.org/html/rfc7540#appendix-A for the
+ complete HTTP/2 cipher suites black list.
+ --client-no-http2-cipher-black-list
+ Allow black listed cipher suite on backend HTTP/2
+ connection. See
+ https://tools.ietf.org/html/rfc7540#appendix-A for the
+ complete HTTP/2 cipher suites black list.
--tls-sct-dir=
Specifies the directory where *.sct files exist. All
*.sct files in are read, and sent as
@@ -3096,6 +3102,8 @@ int main(int argc, char **argv) {
&flag, 146},
{SHRPX_OPT_PSK_SECRETS.c_str(), required_argument, &flag, 147},
{SHRPX_OPT_CLIENT_PSK_SECRETS.c_str(), required_argument, &flag, 148},
+ {SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST.c_str(), no_argument,
+ &flag, 149},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
@@ -3794,6 +3802,11 @@ int main(int argc, char **argv) {
// --client-psk-secrets
cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_PSK_SECRETS, StringRef{optarg});
break;
+ case 149:
+ // --client-no-http2-cipher-black-list
+ cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST,
+ StringRef::from_lit("yes"));
+ break;
default:
break;
}
diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc
index 4bd4efdf..4fc3f841 100644
--- a/src/shrpx_config.cc
+++ b/src/shrpx_config.cc
@@ -2004,6 +2004,11 @@ int option_lookup_token(const char *name, size_t namelen) {
return SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL;
}
break;
+ case 't':
+ if (util::strieq_l("client-no-http2-cipher-black-lis", name, 32)) {
+ return SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST;
+ }
+ break;
}
break;
case 34:
@@ -3274,6 +3279,11 @@ int parse_config(Config *config, int optid, const StringRef &opt,
return parse_psk_secrets(config, optarg);
case SHRPX_OPTID_CLIENT_PSK_SECRETS:
return parse_client_psk_secrets(config, optarg);
+ case SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST:
+ config->tls.client.no_http2_cipher_black_list =
+ util::strieq_l("yes", optarg);
+
+ return 0;
case SHRPX_OPTID_CONF:
LOG(WARN) << "conf: ignored";
diff --git a/src/shrpx_config.h b/src/shrpx_config.h
index 118ecc1a..0d9c8c81 100644
--- a/src/shrpx_config.h
+++ b/src/shrpx_config.h
@@ -322,6 +322,8 @@ constexpr auto SHRPX_OPT_FRONTEND_KEEP_ALIVE_TIMEOUT =
constexpr auto SHRPX_OPT_PSK_SECRETS = StringRef::from_lit("psk-secrets");
constexpr auto SHRPX_OPT_CLIENT_PSK_SECRETS =
StringRef::from_lit("client-psk-secrets");
+constexpr auto SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST =
+ StringRef::from_lit("client-no-http2-cipher-black-list");
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
@@ -556,6 +558,7 @@ struct TLSConfig {
} psk;
StringRef private_key_file;
StringRef cert_file;
+ bool no_http2_cipher_black_list;
} client;
// PSK secrets. The key is identity, and the associated value is
@@ -924,6 +927,7 @@ enum {
SHRPX_OPTID_CIPHERS,
SHRPX_OPTID_CLIENT,
SHRPX_OPTID_CLIENT_CERT_FILE,
+ SHRPX_OPTID_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST,
SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE,
SHRPX_OPTID_CLIENT_PROXY,
SHRPX_OPTID_CLIENT_PSK_SECRETS,
diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc
index a10f4358..914c7ccb 100644
--- a/src/shrpx_connection.cc
+++ b/src/shrpx_connection.cc
@@ -141,7 +141,10 @@ void Connection::disconnect() {
void Connection::prepare_client_handshake() { SSL_set_connect_state(tls.ssl); }
-void Connection::prepare_server_handshake() { SSL_set_accept_state(tls.ssl); }
+void Connection::prepare_server_handshake() {
+ SSL_set_accept_state(tls.ssl);
+ tls.server_handshake = true;
+}
// BIO implementation is inspired by openldap implementation:
// http://www.openldap.org/devel/cvsweb.cgi/~checkout~/libraries/libldap/tls_o.c
@@ -530,7 +533,15 @@ int Connection::check_http2_requirement() {
}
return -1;
}
- if (!get_config()->tls.no_http2_cipher_black_list &&
+
+ auto check_black_list = false;
+ if (tls.server_handshake) {
+ check_black_list = !get_config()->tls.no_http2_cipher_black_list;
+ } else {
+ check_black_list = !get_config()->tls.client.no_http2_cipher_black_list;
+ }
+
+ if (check_black_list &&
nghttp2::ssl::check_http2_cipher_black_list(tls.ssl)) {
if (LOG_ENABLED(INFO)) {
LOG(INFO) << "The negotiated cipher suite is in HTTP/2 cipher suite "
diff --git a/src/shrpx_connection.h b/src/shrpx_connection.h
index 5dc1c37e..990a85ed 100644
--- a/src/shrpx_connection.h
+++ b/src/shrpx_connection.h
@@ -64,6 +64,8 @@ struct TLSConnection {
int handshake_state;
bool initial_handshake_done;
bool reneg_started;
+ // true if ssl is prepared to do handshake as server.
+ bool server_handshake;
};
struct TCPHint {