ECH: enable support for the AWS-LC backend

Extend existing ECH support for BoringSSL to its AWS-LC fork.

Also enable ECH in AWS-LC CI jobs.

```
curl 8.11.0-DEV (x86_64-pc-linux-gnu) libcurl/8.11.0-DEV AWS-LC/1.37.0 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libpsl/0.21.2
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli ECH HSTS HTTPS-proxy IPv6 Largefile libz NTLM PSL SSL threadsafe UnixSockets zstd
```

Closes #15499
This commit is contained in:
Viktor Szakats 2024-11-06 16:37:07 +01:00
parent cbafcec50b
commit 1cd745a581
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
4 changed files with 33 additions and 33 deletions

View file

@ -140,12 +140,12 @@ jobs:
- name: awslc
install_packages: zlib1g-dev
install_steps: awslc
configure: LDFLAGS="-Wl,-rpath,$HOME/awslc/lib" --with-openssl=$HOME/awslc
configure: LDFLAGS="-Wl,-rpath,$HOME/awslc/lib" --with-openssl=$HOME/awslc --enable-httpsrr --enable-ech
- name: awslc
install_packages: zlib1g-dev
install_steps: awslc
generate: -DOPENSSL_ROOT_DIR=$HOME/awslc -DCMAKE_UNITY_BUILD=OFF
generate: -DOPENSSL_ROOT_DIR=$HOME/awslc -DUSE_HTTPSRR=ON -DUSE_ECH=ON -DCMAKE_UNITY_BUILD=OFF
- name: openssl default
install_steps: pytest

View file

@ -834,7 +834,7 @@ if(USE_ECH)
if(USE_OPENSSL OR USE_WOLFSSL)
# Be sure that the TLS library actually supports ECH.
if(NOT DEFINED HAVE_ECH)
if(USE_OPENSSL AND HAVE_BORINGSSL)
if(USE_OPENSSL AND (HAVE_BORINGSSL OR HAVE_AWSLC))
openssl_check_symbol_exists("SSL_set1_ech_config_list" "openssl/ssl.h" HAVE_ECH "")
elseif(USE_OPENSSL)
openssl_check_symbol_exists("SSL_ech_set1_echconfig" "openssl/ech.h" HAVE_ECH "")
@ -843,12 +843,12 @@ if(USE_ECH)
endif()
endif()
if(NOT HAVE_ECH)
message(FATAL_ERROR "ECH support missing in OpenSSL/BoringSSL/wolfSSL")
message(FATAL_ERROR "ECH support missing in OpenSSL/BoringSSL/AWS-LC/wolfSSL")
else()
message(STATUS "ECH enabled.")
endif()
else()
message(FATAL_ERROR "ECH requires ECH-enablded OpenSSL, BoringSSL or wolfSSL")
message(FATAL_ERROR "ECH requires ECH-enablded OpenSSL, BoringSSL, AWS-LC or wolfSSL")
endif()
endif()

View file

@ -8,8 +8,8 @@ SPDX-License-Identifier: curl
We have added support for ECH to curl. It can use HTTPS RRs published in the
DNS if curl uses DoH, or else can accept the relevant ECHConfigList values
from the command line. This works with OpenSSL, wolfSSL or BoringSSL as the
TLS provider.
from the command line. This works with OpenSSL, wolfSSL, BoringSSL or AWS-LC as
the TLS provider.
This feature is EXPERIMENTAL. DO NOT USE IN PRODUCTION.
@ -149,7 +149,7 @@ the verbose output, e.g.:
```
At that point, you could copy the base64 encoded value above and try again.
For now, this only works for the OpenSSL and BoringSSL builds.
For now, this only works for the OpenSSL and BoringSSL/AWS-LC builds.
## Default settings
@ -334,12 +334,12 @@ Then:
make
```
The BoringSSL APIs are fairly similar to those in our ECH-enabled OpenSSL
fork, so code changes are also in ``lib/vtls/openssl.c``, protected
The BoringSSL/AWS-LC APIs are fairly similar to those in our ECH-enabled
OpenSSL fork, so code changes are also in ``lib/vtls/openssl.c``, protected
via ``#ifdef OPENSSL_IS_BORINGSSL`` and are mostly obvious API variations.
The BoringSSL APIs however do not support the ``--ech pn:`` command line
variant as of now.
The BoringSSL/AWS-LC APIs however do not support the ``--ech pn:`` command
line variant as of now.
## wolfSSL build
@ -401,7 +401,7 @@ Then there are some functional code changes:
The lack of support for ``--ech false`` is because wolfSSL has decided to
always at least GREASE if built to support ECH. In other words, GREASE is
a compile time choice for wolfSSL, but a runtime choice for OpenSSL or
BoringSSL. (Both are reasonable.)
BoringSSL/AWS-LC. (Both are reasonable.)
## Additional notes
@ -474,5 +474,5 @@ to get the HTTPS RR and pass the ECHConfigList from that on the command line,
if needed, or one can access the value from command line output in verbose more
and then reuse that in another invocation.
Both our OpenSSL fork and BoringSSL have APIs for both controlling GREASE and
accessing and logging ``retry_configs``, it seems wolfSSL has neither.
Both our OpenSSL fork and BoringSSL/AWS-LC have APIs for both controlling GREASE
and accessing and logging ``retry_configs``, it seems wolfSSL has neither.

View file

@ -83,7 +83,7 @@
#include <openssl/evp.h>
#ifdef USE_ECH
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
# include <openssl/ech.h>
# endif
# include "curl_base64.h"
@ -3849,15 +3849,15 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
if(data->set.tls_ech & CURLECH_GREASE) {
infof(data, "ECH: will GREASE ClientHello");
# ifdef OPENSSL_IS_BORINGSSL
# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
SSL_set_enable_ech_grease(octx->ssl, 1);
# else
SSL_set_options(octx->ssl, SSL_OP_ECH_GREASE);
# endif
}
else if(data->set.tls_ech & CURLECH_CLA_CFG) {
# ifdef OPENSSL_IS_BORINGSSL
/* have to do base64 decode here for boring */
# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
/* have to do base64 decode here for BoringSSL */
const char *b64 = data->set.str[STRING_ECH_CONFIG];
if(!b64) {
@ -3917,7 +3917,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
size_t elen = rinfo->echconfiglist_len;
infof(data, "ECH: ECHConfig from DoH HTTPS RR");
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
if(SSL_ech_set1_echconfig(octx->ssl, ecl, elen) != 1) {
infof(data, "ECH: SSL_ECH_set1_echconfig failed");
if(data->set.tls_ech & CURLECH_HARD)
@ -3925,7 +3925,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
}
# else
if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) {
infof(data, "ECH: SSL_set1_ech_config_list failed (boring)");
infof(data, "ECH: SSL_set1_ech_config_list failed (BoringSSL)");
if(data->set.tls_ech & CURLECH_HARD)
return CURLE_SSL_CONNECT_ERROR;
}
@ -3943,7 +3943,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
Curl_resolv_unlink(data, &dns);
}
}
# ifdef OPENSSL_IS_BORINGSSL
# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
if(trying_ech_now && outername) {
infof(data, "ECH: setting public_name not supported with BoringSSL");
return CURLE_SSL_CONNECT_ERROR;
@ -3960,7 +3960,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
return CURLE_SSL_CONNECT_ERROR;
}
}
# endif /* not BORING */
# endif /* OPENSSL_IS_BORINGSSL || OPENSSL_IS_AWSLC */
if(trying_ech_now
&& SSL_set_min_proto_version(octx->ssl, TLS1_3_VERSION) != 1) {
infof(data, "ECH: cannot force TLSv1.3 [ERROR]");
@ -4071,7 +4071,7 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
CURLcode result = CURLE_OK;
size_t rcl = 0;
int rv = 1;
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
char *inner = NULL;
unsigned char *rcs = NULL;
char *outer = NULL;
@ -4086,7 +4086,7 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
/* nothing to trace if not doing ECH */
if(!ECH_ENABLED(data))
return;
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
rv = SSL_ech_get_retry_config(ssl, &rcs, &rcl);
# else
SSL_get0_ech_retry_configs(ssl, &rcs, &rcl);
@ -4103,23 +4103,23 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
if(!result && b64str)
infof(data, "ECH: retry_configs %s", b64str);
free(b64str);
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
rv = SSL_ech_get_status(ssl, &inner, &outer);
infof(data, "ECH: retry_configs for %s from %s, %d %d",
inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
#else
# else
rv = SSL_ech_accepted(ssl);
servername_type = SSL_get_servername_type(ssl);
inner = SSL_get_servername(ssl, servername_type);
SSL_get0_ech_name_override(ssl, &outer, &out_name_len);
/* TODO: get the inner from boring */
/* TODO: get the inner from BoringSSL */
infof(data, "ECH: retry_configs for %s from %s, %d %d",
inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
#endif
# endif
}
else
infof(data, "ECH: no retry_configs (rv = %d)", rv);
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
OPENSSL_free((void *)rcs);
# endif
return;
@ -4243,7 +4243,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
#endif
#ifdef USE_ECH
else if((lib == ERR_LIB_SSL) &&
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
(reason == SSL_R_ECH_REQUIRED)) {
# else
(reason == SSL_R_ECH_REJECTED)) {
@ -4309,7 +4309,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
OBJ_nid2sn(psigtype_nid));
#ifdef USE_ECH
# ifndef OPENSSL_IS_BORINGSSL
# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
if(ECH_ENABLED(data)) {
char *inner = NULL, *outer = NULL;
const char *status = NULL;
@ -4367,7 +4367,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
else {
infof(data, "ECH: result: status is not attempted");
}
# endif /* BORING */
# endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */
#endif /* USE_ECH */
#ifdef HAS_ALPN