aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2017-04-04 13:52:36 -0400
committerCQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>2017-04-05 00:33:57 +0000
commitc8ff30cbe716c72279a6f6a9d7d7d0d4091220fa (patch)
tree793307005f660bd286e991146c83502dc03ece70
parent0686c09eeaed24f778fe0a86561ae7200751be13 (diff)
downloadboringssl-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.h11
-rw-r--r--ssl/ssl_lib.c3
-rw-r--r--ssl/t1_lib.c46
-rw-r--r--ssl/test/bssl_shim.cc4
-rw-r--r--ssl/test/runner/runner.go16
-rw-r--r--ssl/test/test_config.cc1
-rw-r--r--ssl/test/test_config.h1
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);