ECH: cleanups
No binary (build failed)
—
(log yok)
| @@ -1858,6 +1858,45 @@ static CURLcode setopt_copypostfields(const char *ptr, struct UserDefined *s) | |
| } | |
| #endif | |
| + | #ifdef USE_ECH |
| + | static CURLcode setopt_ech(struct Curl_easy *data, const char *ptr) |
| + | { |
| + | struct UserDefined *s = &data->set; |
| + | CURLcode result = CURLE_OK; |
| + | |
| + | if(!ptr || !strcmp(ptr, "false")) |
| + | s->tls_ech = CURLECH_DISABLE; |
| + | else { |
| + | size_t plen = strlen(ptr); |
| + | if(plen > CURL_MAX_INPUT_LENGTH) |
| + | result = CURLE_BAD_FUNCTION_ARGUMENT; |
| + | else { |
| + | if(!strcmp(ptr, "grease")) |
| + | s->tls_ech = CURLECH_GREASE; |
| + | else if(!strcmp(ptr, "true")) |
| + | s->tls_ech = CURLECH_ENABLE; |
| + | else if(!strcmp(ptr, "hard")) |
| + | s->tls_ech = CURLECH_HARD; |
| + | else if(plen > 4 && !strncmp(ptr, "ecl:", 4)) { |
| + | if(!s->tls_ech) |
| + | s->tls_ech = CURLECH_HARD; |
| + | result = Curl_setstropt(&s->str[STRING_ECH_CONFIG], ptr + 4); |
| + | } |
| + | else if(plen > 3 && !strncmp(ptr, "pn:", 3)) { |
| + | if(!s->tls_ech) |
| + | s->tls_ech = CURLECH_HARD; |
| + | result = Curl_setstropt(&s->str[STRING_ECH_PUBLIC], ptr + 3); |
| + | } |
| + | else |
| + | result = CURLE_BAD_FUNCTION_ARGUMENT; |
| + | } |
| + | } |
| + | return result; |
| + | } |
| + | #else |
| + | #define setopt_ech(x,y) CURLE_NOT_BUILT_IN |
| + | #endif |
| + | |
| static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, | |
| char *ptr) | |
| { | |
| @@ -2495,38 +2534,8 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, | |
| return Curl_altsvc_load(data->asi, ptr); | |
| break; | |
| #endif /* !CURL_DISABLE_ALTSVC */ | |
| - | #ifdef USE_ECH |
| - | case CURLOPT_ECH: { |
| - | size_t plen = 0; |
| - | |
| - | if(!ptr) { |
| - | s->tls_ech = CURLECH_DISABLE; |
| - | break; |
| - | } |
| - | plen = strlen(ptr); |
| - | if(plen > CURL_MAX_INPUT_LENGTH) { |
| - | s->tls_ech = CURLECH_DISABLE; |
| - | return CURLE_BAD_FUNCTION_ARGUMENT; |
| - | } |
| - | /* set tls_ech flag value, preserving CLA_CFG bit */ |
| - | if(!strcmp(ptr, "false")) |
| - | s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_DISABLE; |
| - | else if(!strcmp(ptr, "grease")) |
| - | s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_GREASE; |
| - | else if(!strcmp(ptr, "true")) |
| - | s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_ENABLE; |
| - | else if(!strcmp(ptr, "hard")) |
| - | s->tls_ech = (s->tls_ech & CURLECH_CLA_CFG) | CURLECH_HARD; |
| - | else if(plen > 5 && !strncmp(ptr, "ecl:", 4)) { |
| - | result = Curl_setstropt(&s->str[STRING_ECH_CONFIG], ptr + 4); |
| - | if(!result) |
| - | s->tls_ech |= CURLECH_CLA_CFG; |
| - | } |
| - | else if(plen > 4 && !strncmp(ptr, "pn:", 3)) |
| - | result = Curl_setstropt(&s->str[STRING_ECH_PUBLIC], ptr + 3); |
| - | break; |
| - | } |
| - | #endif |
| + | case CURLOPT_ECH: |
| + | return setopt_ech(data, ptr); |
| default: | |
| return CURLE_UNKNOWN_OPTION; | |
| } | |
| @@ -1157,9 +1157,6 @@ struct UserDefined { | |
| struct curl_slist *mail_rcpt; /* linked list of mail recipients */ | |
| #endif | |
| uint32_t maxconnects; /* Max idle connections in the connection cache */ | |
| - | #ifdef USE_ECH |
| - | int tls_ech; /* TLS ECH configuration */ |
| - | #endif |
| short maxredirs; /* maximum no. of http(s) redirects to follow, | |
| set to -1 for infinity */ | |
| uint16_t expect_100_timeout; /* in milliseconds */ | |
| @@ -1174,6 +1171,9 @@ struct UserDefined { | |
| #ifndef CURL_DISABLE_TFTP | |
| uint16_t tftp_blksize; /* in bytes, 0 means use default */ | |
| #endif | |
| + | #ifdef USE_ECH |
| + | uint8_t tls_ech; /* TLS ECH configuration */ |
| + | #endif |
| #ifndef CURL_DISABLE_NETRC | |
| uint8_t use_netrc; /* enum CURL_NETRC_OPTION values */ | |
| #endif | |
| @@ -3430,9 +3430,9 @@ bool Curl_ossl_need_httpsrr(struct Curl_easy *data) | |
| { | |
| if(!CURLECH_ENABLED(data)) | |
| return FALSE; | |
| - | if((data->set.tls_ech & CURLECH_GREASE) || |
| - | (data->set.tls_ech & CURLECH_CLA_CFG)) |
| - | return FALSE; |
| + | if((data->set.tls_ech == CURLECH_GREASE) || |
| + | data->set.str[STRING_ECH_CONFIG]) |
| + | return FALSE; |
| return TRUE; | |
| } | |
| @@ -3450,7 +3450,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| if(!CURLECH_ENABLED(data)) | |
| return CURLE_OK; | |
| - | if(data->set.tls_ech & CURLECH_GREASE) { |
| + | if(data->set.tls_ech == CURLECH_GREASE) { |
| infof(data, "ECH: will GREASE ClientHello"); | |
| #ifdef HAVE_BORINGSSL_LIKE | |
| SSL_set_enable_ech_grease(octx->ssl, 1); | |
| @@ -3458,7 +3458,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| SSL_set_options(octx->ssl, SSL_OP_ECH_GREASE); | |
| #endif | |
| } | |
| - | else if(data->set.tls_ech & CURLECH_CLA_CFG) { |
| + | else if(data->set.tls_ech && data->set.str[STRING_ECH_CONFIG]) { |
| #ifdef HAVE_BORINGSSL_LIKE | |
| /* have to do base64 decode here for BoringSSL */ | |
| const char *b64 = data->set.str[STRING_ECH_CONFIG]; | |
| @@ -3471,12 +3471,12 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| result = curlx_base64_decode(b64, &ech_config, &ech_config_len); | |
| if(result || !ech_config) { | |
| infof(data, "ECH: cannot base64 decode ECHConfig from command line"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) |
| + | if(data->set.tls_ech == CURLECH_HARD) |
| return result; | |
| } | |
| if(SSL_set1_ech_config_list(octx->ssl, ech_config, ech_config_len) != 1) { | |
| infof(data, "ECH: SSL_ECH_set1_ech_config_list failed"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| + | if(data->set.tls_ech == CURLECH_HARD) { |
| curlx_free(ech_config); | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| @@ -3492,7 +3492,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| ech_config_len = strlen(data->set.str[STRING_ECH_CONFIG]); | |
| if(SSL_set1_ech_config_list(octx->ssl, ech_config, ech_config_len) != 1) { | |
| infof(data, "ECH: SSL_ECH_set1_ech_config_list failed"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) |
| + | if(data->set.tls_ech == CURLECH_HARD) |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| else | |
| @@ -3511,7 +3511,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| infof(data, "ECH: ECHConfig from HTTPS RR"); | |
| if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) { | |
| infof(data, "ECH: SSL_set1_ech_config_list failed"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) |
| + | if(data->set.tls_ech == CURLECH_HARD) |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| else { | |
| @@ -3521,7 +3521,7 @@ static CURLcode ossl_init_ech(struct ossl_ctx *octx, | |
| } | |
| else { | |
| infof(data, "ECH: requested but no ECHConfig available"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) |
| + | if(data->set.tls_ech == CURLECH_HARD) |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| } | |
| @@ -4335,7 +4335,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, | |
| /* trace retry_configs if we got some */ | |
| ossl_trace_ech_retry_configs(data, octx->ssl, 0); | |
| } | |
| - | if(rv != SSL_ECH_STATUS_SUCCESS && (data->set.tls_ech & CURLECH_HARD)) { |
| + | if(rv != SSL_ECH_STATUS_SUCCESS && (data->set.tls_ech == CURLECH_HARD)) { |
| infof(data, "ECH: ech-hard failed"); | |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| @@ -915,9 +915,9 @@ static bool cr_ech_need_httpsrr(struct Curl_easy *data) | |
| { | |
| if(!CURLECH_ENABLED(data)) | |
| return FALSE; | |
| - | if((data->set.tls_ech & CURLECH_GREASE) || |
| - | (data->set.tls_ech & CURLECH_CLA_CFG)) |
| - | return FALSE; |
| + | if((data->set.tls_ech == CURLECH_GREASE) || |
| + | data->set.str[STRING_ECH_CONFIG]) |
| + | return FALSE; |
| return TRUE; | |
| } | |
| @@ -957,7 +957,7 @@ init_config_builder_ech(struct Curl_easy *data, | |
| return CURLE_OK; | |
| } | |
| - | if(data->set.tls_ech & CURLECH_CLA_CFG && data->set.str[STRING_ECH_CONFIG]) { |
| + | if(data->set.tls_ech && data->set.str[STRING_ECH_CONFIG]) { |
| const char *b64 = data->set.str[STRING_ECH_CONFIG]; | |
| size_t decode_result; | |
| if(!b64) { | |
| @@ -997,7 +997,7 @@ init_config_builder_ech(struct Curl_easy *data, | |
| } | |
| cleanup: | |
| /* if we base64 decoded, we can free now */ | |
| - | if(data->set.tls_ech & CURLECH_CLA_CFG && data->set.str[STRING_ECH_CONFIG]) { |
| + | if(data->set.tls_ech && data->set.str[STRING_ECH_CONFIG]) { |
| curlx_free(ech_config); | |
| } | |
| if(dns) { | |
| @@ -1074,7 +1074,7 @@ static CURLcode cr_init_backend(struct Curl_cfilter *cf, | |
| #ifdef USE_ECH | |
| if(CURLECH_ENABLED(data)) { | |
| result = init_config_builder_ech(data, cf, config_builder); | |
| - | if(result != CURLE_OK && data->set.tls_ech & CURLECH_HARD) { |
| + | if((result != CURLE_OK) && (data->set.tls_ech == CURLECH_HARD)) { |
| rustls_client_config_builder_free(config_builder); | |
| return result; | |
| } | |
| @@ -49,15 +49,13 @@ struct dynbuf; | |
| #define SSLSUPP_ISSUERCERT_BLOB (1 << 14) /* CURLOPT_ISSUERCERT_BLOB */ | |
| #ifdef USE_ECH | |
| - | /* CURLECH_ bits for the tls_ech option */ |
| - | #define CURLECH_DISABLE (1 << 0) |
| - | #define CURLECH_GREASE (1 << 1) |
| - | #define CURLECH_ENABLE (1 << 2) |
| - | #define CURLECH_HARD (1 << 3) |
| - | #define CURLECH_CLA_CFG (1 << 4) |
| - | |
| - | #define CURLECH_ENABLED(data) \ |
| - | ((data)->set.tls_ech && !((data)->set.tls_ech & CURLECH_DISABLE)) |
| + | /* CURLECH_ values for the tls_ech option */ |
| + | #define CURLECH_DISABLE 0 |
| + | #define CURLECH_GREASE 1 |
| + | #define CURLECH_ENABLE 2 |
| + | #define CURLECH_HARD 3 |
| + | |
| + | #define CURLECH_ENABLED(data) ((data)->set.tls_ech) |
| #endif /* USE_ECH */ | |
| #define ALPN_ACCEPTED "ALPN: server accepted " | |
| @@ -1273,15 +1273,14 @@ static CURLcode wssl_init_ech(struct wssl_ctx *wctx, | |
| infof(data, "ECH: GREASE is done by default by" | |
| " wolfSSL: no need to ask"); | |
| } | |
| - | if(data->set.tls_ech & CURLECH_CLA_CFG && |
| - | data->set.str[STRING_ECH_CONFIG]) { |
| + | if(data->set.tls_ech && data->set.str[STRING_ECH_CONFIG]) { |
| char *b64val = data->set.str[STRING_ECH_CONFIG]; | |
| word32 b64len = 0; | |
| b64len = (word32)strlen(b64val); | |
| if(b64len && wolfSSL_SetEchConfigsBase64(wctx->ssl, b64val, | |
| b64len) != WOLFSSL_SUCCESS) { | |
| - | if(data->set.tls_ech & CURLECH_HARD) |
| + | if(data->set.tls_ech == CURLECH_HARD) |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| else { | |
| @@ -1301,7 +1300,7 @@ static CURLcode wssl_init_ech(struct wssl_ctx *wctx, | |
| if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) != | |
| WOLFSSL_SUCCESS) { | |
| infof(data, "ECH: wolfSSL_SetEchConfigs failed"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| + | if(data->set.tls_ech == CURLECH_HARD) { |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| } | |
| @@ -1312,7 +1311,7 @@ static CURLcode wssl_init_ech(struct wssl_ctx *wctx, | |
| } | |
| else { | |
| infof(data, "ECH: requested but no ECHConfig available"); | |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| + | if(data->set.tls_ech == CURLECH_HARD) { |
| return CURLE_SSL_CONNECT_ERROR; | |
| } | |
| } | |
| @@ -1492,9 +1491,9 @@ bool Curl_wssl_need_httpsrr(struct Curl_easy *data) | |
| #ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG | |
| if(!CURLECH_ENABLED(data)) | |
| return FALSE; | |
| - | if((data->set.tls_ech & CURLECH_GREASE) || |
| - | (data->set.tls_ech & CURLECH_CLA_CFG)) |
| - | return FALSE; |
| + | if((data->set.tls_ech == CURLECH_GREASE) || |
| + | data->set.str[STRING_ECH_CONFIG]) |
| + | return FALSE; |
| return TRUE; | |
| #else | |
| (void)data; | |
| @@ -42,6 +42,7 @@ my @bad_function_argument = ( | |
| 'CURLOPT_DNS_LOCAL_IP4', | |
| 'CURLOPT_DNS_LOCAL_IP6', | |
| 'CURLOPT_DNS_SERVERS', | |
| + | 'CURLOPT_ECH', |
| 'CURLOPT_PROXY_TLSAUTH_TYPE', | |
| 'CURLOPT_SSLENGINE', | |
| 'CURLOPT_TLSAUTH_TYPE', | |