rustls: use ALPN

Update required rustls to 0.5.0

Closes #6960
This commit is contained in:
Jacob Hoffman-Andrews 2021-04-24 18:02:24 -07:00 committed by Daniel Stenberg
parent ea17a022b3
commit 8228002cd1
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 50 additions and 3 deletions

View File

@ -125,7 +125,7 @@ jobs:
- libbrotli-dev
- libzstd-dev
- env:
- T=debug-rustls RUSTLS_VERSION="v0.4.0" C="--with-rustls=$HOME/crust"
- T=debug-rustls RUSTLS_VERSION="v0.5.0" C="--with-rustls=$HOME/crust"
addons:
apt:
<<: *common_apt

View File

@ -3,7 +3,7 @@
[Rustls is a TLS backend written in Rust.](https://docs.rs/rustls/). Curl can
be built to use it as an alternative to OpenSSL or other TLS backends. We use
the [crustls C bindings](https://github.com/abetterinternet/crustls/). This
version of curl depends on version v0.4.0 of crustls.
version of curl depends on version v0.5.0 of crustls.
# Building with rustls
@ -12,7 +12,7 @@ First, [install Rust](https://rustup.rs/).
Next, check out, build, and install the appropriate version of crustls:
% cargo install cbindgen
% git clone https://github.com/abetterinternet/crustls/ -b v0.4.0
% git clone https://github.com/abetterinternet/crustls/ -b v0.5.0
% cd crustls
% make
% make DESTDIR=${HOME}/crustls-built/ install

View File

@ -321,6 +321,10 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
char errorbuf[256];
size_t errorlen;
int result;
rustls_slice_bytes alpn[2] = {
{ (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH },
{ (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH },
};
backend->tlsbuf = calloc(TLSBUF_SIZE, 1);
if(!backend->tlsbuf) {
@ -328,6 +332,13 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
}
config_builder = rustls_client_config_builder_new();
#ifdef USE_HTTP2
infof(data, "offering ALPN for HTTP/1.1 and HTTP/2\n");
rustls_client_config_builder_set_protocols(config_builder, alpn, 2);
#else
infof(data, "offering ALPN for HTTP/1.1 only\n");
rustls_client_config_builder_set_protocols(config_builder, alpn, 1);
#endif
if(!verifypeer) {
rustls_client_config_builder_dangerous_set_certificate_verifier(
config_builder, cr_verify_none, NULL);
@ -372,6 +383,39 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
static void
cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
const struct rustls_client_session *session)
{
const uint8_t *protocol = NULL;
size_t len = 0;
rustls_client_session_get_alpn_protocol(session, &protocol, &len);
if(NULL == protocol) {
infof(data, "ALPN, server did not agree to a protocol\n");
return;
}
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) {
infof(data, "ALPN, negotiated h2\n");
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
0 == memcmp(ALPN_HTTP_1_1, protocol, len)) {
infof(data, "ALPN, negotiated http/1.1\n");
conn->negnpn = CURL_HTTP_VERSION_1_1;
}
else {
infof(data, "ALPN, negotiated an unrecognized protocol\n");
}
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
static CURLcode
cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
int sockindex, bool *done)
@ -411,6 +455,9 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
infof(data, "Done handshaking\n");
/* Done with the handshake. Set up callbacks to send/receive data. */
connssl->state = ssl_connection_complete;
cr_set_negotiated_alpn(data, conn, session);
conn->recv[sockindex] = cr_recv;
conn->send[sockindex] = cr_send;
*done = TRUE;