diff options
author | David Benjamin <davidben@google.com> | 2017-04-04 13:52:36 -0400 |
---|---|---|
committer | CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> | 2017-04-05 00:33:57 +0000 |
commit | c8ff30cbe716c72279a6f6a9d7d7d0d4091220fa (patch) | |
tree | 793307005f660bd286e991146c83502dc03ece70 | |
parent | 0686c09eeaed24f778fe0a86561ae7200751be13 (diff) | |
download | boringssl-chromium-3071.zip boringssl-chromium-3071.tar.gz boringssl-chromium-3071.tar.bz2 |
Add an option to allow unknown ALPN protocols.chromium-3071
We received an external request to add an option to undo the check added
in 3e51757de2bf9beef7d249f22d255e4dd9ddb012.
Change-Id: Ifdd4b07705f2fa3d781d775d5cd139ea72d36734
Reviewed-on: https://boringssl-review.googlesource.com/14644
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
-rw-r--r-- | include/openssl/ssl.h | 11 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 3 | ||||
-rw-r--r-- | ssl/t1_lib.c | 46 | ||||
-rw-r--r-- | ssl/test/bssl_shim.cc | 4 | ||||
-rw-r--r-- | ssl/test/runner/runner.go | 16 | ||||
-rw-r--r-- | ssl/test/test_config.cc | 1 | ||||
-rw-r--r-- | ssl/test/test_config.h | 1 |
7 files changed, 59 insertions, 23 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 75862fc..6a6cd85 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2586,6 +2586,13 @@ OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, unsigned *out_len); +/* SSL_CTX_set_allow_unknown_alpn_protos configures client connections on |ctx| + * to allow unknown ALPN protocols from the server. Otherwise, by default, the + * client will require that the protocol be advertised in + * |SSL_CTX_set_alpn_protos|. */ +OPENSSL_EXPORT void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, + int enabled); + /* Next protocol negotiation. * @@ -4280,6 +4287,10 @@ struct ssl_ctx_st { * that this currently requires post-handshake verification of * certificates. */ unsigned i_promise_to_verify_certs_after_the_handshake:1; + + /* allow_unknown_alpn_protos is one if the client allows unsolicited ALPN + * protocols from the peer. */ + unsigned allow_unknown_alpn_protos:1; }; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 17e6521..7adf103 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1753,6 +1753,9 @@ void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, } } +void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { + ctx->allow_unknown_alpn_protos = !!enabled; +} void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, int enabled) { ctx->tlsext_channel_id_enabled = !!enabled; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 45a04c1..793e2d7 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1432,31 +1432,33 @@ static int ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, return 0; } - /* Check that the protcol name is one of the ones we advertised. */ - int protocol_ok = 0; - CBS client_protocol_name_list, client_protocol_name; - CBS_init(&client_protocol_name_list, ssl->alpn_client_proto_list, - ssl->alpn_client_proto_list_len); - while (CBS_len(&client_protocol_name_list) > 0) { - if (!CBS_get_u8_length_prefixed(&client_protocol_name_list, - &client_protocol_name)) { - *out_alert = SSL_AD_INTERNAL_ERROR; - return 0; - } + if (!ssl->ctx->allow_unknown_alpn_protos) { + /* Check that the protocol name is one of the ones we advertised. */ + int protocol_ok = 0; + CBS client_protocol_name_list, client_protocol_name; + CBS_init(&client_protocol_name_list, ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len); + while (CBS_len(&client_protocol_name_list) > 0) { + if (!CBS_get_u8_length_prefixed(&client_protocol_name_list, + &client_protocol_name)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return 0; + } - if (CBS_len(&client_protocol_name) == CBS_len(&protocol_name) && - OPENSSL_memcmp(CBS_data(&client_protocol_name), - CBS_data(&protocol_name), - CBS_len(&protocol_name)) == 0) { - protocol_ok = 1; - break; + if (CBS_len(&client_protocol_name) == CBS_len(&protocol_name) && + OPENSSL_memcmp(CBS_data(&client_protocol_name), + CBS_data(&protocol_name), + CBS_len(&protocol_name)) == 0) { + protocol_ok = 1; + break; + } } - } - if (!protocol_ok) { - OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); - *out_alert = SSL_AD_ILLEGAL_PARAMETER; - return 0; + if (!protocol_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } } if (!CBS_stow(&protocol_name, &ssl->s3->alpn_selected, diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 70ea664..b60c809 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -1187,6 +1187,10 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(const TestConfig *config) { SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1); } + if (config->allow_unknown_alpn_protos) { + SSL_CTX_set_allow_unknown_alpn_protos(ssl_ctx.get(), 1); + } + return ssl_ctx; } diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 8444c21..ed328b6 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -4889,7 +4889,7 @@ func addExtensionTests() { }) testCases = append(testCases, testCase{ testType: clientTest, - name: "ALPNClient-Mismatch-" + ver.name, + name: "ALPNClient-RejectUnknown-" + ver.name, config: Config{ MaxVersion: ver.version, Bugs: ProtocolBugs{ @@ -4904,6 +4904,20 @@ func addExtensionTests() { expectedLocalError: "remote error: illegal parameter", }) testCases = append(testCases, testCase{ + testType: clientTest, + name: "ALPNClient-AllowUnknown-" + ver.name, + config: Config{ + MaxVersion: ver.version, + Bugs: ProtocolBugs{ + SendALPN: "baz", + }, + }, + flags: []string{ + "-advertise-alpn", "\x03foo\x03bar", + "-allow-unknown-alpn-protos", + }, + }) + testCases = append(testCases, testCase{ testType: serverTest, name: "ALPNServer-" + ver.name, config: Config{ diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index a8cf755..1b23b02 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc @@ -130,6 +130,7 @@ const Flag<bool> kBoolFlags[] = { { "-expect-no-resume-alpn", &TestConfig::expect_no_resume_alpn }, { "-no-op-extra-handshake", &TestConfig::no_op_extra_handshake }, { "-handshake-twice", &TestConfig::handshake_twice }, + { "-allow-unknown-alpn-protos", &TestConfig::allow_unknown_alpn_protos }, }; const Flag<std::string> kStringFlags[] = { diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index ef14f15..839c0fc 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h @@ -143,6 +143,7 @@ struct TestConfig { int expect_ticket_age_skew = 0; bool no_op_extra_handshake = false; bool handshake_twice = false; + bool allow_unknown_alpn_protos = false; }; bool ParseConfig(int argc, char **argv, TestConfig *out_config); |