Browse Source

Add an option to allow unknown ALPN protocols.

We received an external request to add an option to undo the check added
in 3e51757de2.

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>
kris/onging/CECPQ3_patch15
David Benjamin 7 years ago
committed by CQ bot account: commit-bot@chromium.org
parent
commit
c8ff30cbe7
7 changed files with 59 additions and 23 deletions
  1. +11
    -0
      include/openssl/ssl.h
  2. +3
    -0
      ssl/ssl_lib.c
  3. +24
    -22
      ssl/t1_lib.c
  4. +4
    -0
      ssl/test/bssl_shim.cc
  5. +15
    -1
      ssl/test/runner/runner.go
  6. +1
    -0
      ssl/test/test_config.cc
  7. +1
    -0
      ssl/test/test_config.h

+ 11
- 0
include/openssl/ssl.h View File

@@ -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;
};




+ 3
- 0
ssl/ssl_lib.c View File

@@ -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;


+ 24
- 22
ssl/t1_lib.c View File

@@ -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,


+ 4
- 0
ssl/test/bssl_shim.cc View File

@@ -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;
}



+ 15
- 1
ssl/test/runner/runner.go View File

@@ -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{
@@ -4903,6 +4903,20 @@ func addExtensionTests() {
expectedError: ":INVALID_ALPN_PROTOCOL:",
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,


+ 1
- 0
ssl/test/test_config.cc View File

@@ -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[] = {


+ 1
- 0
ssl/test/test_config.h View File

@@ -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);


Loading…
Cancel
Save