Add an option to disable NPN on a per-SSL basis.
Right whether NPN is advertised can only be configured globally on the SSL_CTX.
Rather than adding two pointers to each SSL*, add an options bit to disable it
so we may plumb in a field trial to disable NPN.
Chromium wants to be able to route a bit in to disable NPN, but it uses SSL_CTX
incorrectly and has a global one, so it can't disconnect the callback. (That
really needs to get fixed. Although it's not clear this necessarily wants to be
lifted up to SSL_CTX as far as Chromium's SSLClientSocket is concerned since
NPN doesn't interact with the session cache.)
BUG=526713
Change-Id: I49c86828b963eb341c6ea6a442557b7dfa190ed3
Reviewed-on: https://boringssl-review.googlesource.com/6351
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index a133d09..17a91ad 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1124,6 +1124,9 @@
if (!config->check_close_notify) {
SSL_set_quiet_shutdown(ssl.get(), 1);
}
+ if (config->disable_npn) {
+ SSL_set_options(ssl.get(), SSL_OP_DISABLE_NPN);
+ }
int sock = Connect(config->port);
if (sock == -1) {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 01813f9..fb1e46f 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -3366,6 +3366,18 @@
shouldFail: true,
expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
})
+ // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
+ testCases = append(testCases, testCase{
+ name: "DisableNPN",
+ config: Config{
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-select-next-proto", "foo",
+ "-disable-npn",
+ },
+ expectNoNextProto: true,
+ })
// Resume with a corrupt ticket.
testCases = append(testCases, testCase{
testType: serverTest,
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 4e19be6..54492df 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -97,6 +97,7 @@
{ "-expect-verify-result", &TestConfig::expect_verify_result },
{ "-renegotiate-once", &TestConfig::renegotiate_once },
{ "-renegotiate-freely", &TestConfig::renegotiate_freely },
+ { "-disable-npn", &TestConfig::disable_npn },
};
const Flag<std::string> kStringFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 4601851..af1dd80 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -99,6 +99,7 @@
int expect_total_renegotiations = 0;
bool renegotiate_once = false;
bool renegotiate_freely = false;
+ bool disable_npn = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);