diff options
author | Maxim Yurchuk <maxim-yurchuk@ydb.tech> | 2024-10-18 20:31:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-18 20:31:38 +0300 |
commit | 2a74bac2d2d3bccb4e10120f1ead805640ec9dd0 (patch) | |
tree | 047e4818ced5aaf73f58517629e5260b5291f9f0 /contrib/libs/curl/lib/vtls/bearssl.c | |
parent | 2d9656823e9521d8c29ea4c9a1d0eab78391abfc (diff) | |
parent | 3d834a1923bbf9403cd4a448e7f32b670aa4124f (diff) | |
download | ydb-2a74bac2d2d3bccb4e10120f1ead805640ec9dd0.tar.gz |
Merge pull request #10502 from ydb-platform/mergelibs-241016-1210
Library import 241016-1210
Diffstat (limited to 'contrib/libs/curl/lib/vtls/bearssl.c')
-rw-r--r-- | contrib/libs/curl/lib/vtls/bearssl.c | 496 |
1 files changed, 270 insertions, 226 deletions
diff --git a/contrib/libs/curl/lib/vtls/bearssl.c b/contrib/libs/curl/lib/vtls/bearssl.c index 224913bd1e..b52fc14262 100644 --- a/contrib/libs/curl/lib/vtls/bearssl.c +++ b/contrib/libs/curl/lib/vtls/bearssl.c @@ -28,7 +28,6 @@ #error #include <bearssl.h> #include "bearssl.h" -#error #include "cipher_suite.h" #include "urldata.h" #include "sendf.h" #include "inet_pton.h" @@ -38,6 +37,7 @@ #include "select.h" #include "multiif.h" #include "curl_printf.h" +#include "strcase.h" /* The last #include files should be: */ #include "curl_memory.h" @@ -63,7 +63,6 @@ struct bearssl_ssl_backend_data { bool active; /* size of pending write, yet to be flushed */ size_t pending_write; - BIT(sent_shutdown); }; struct cafile_parser { @@ -121,9 +120,9 @@ static CURLcode load_cafile(struct cafile_source *source, br_x509_pkey *pkey; FILE *fp = 0; unsigned char buf[BUFSIZ]; - const unsigned char *p = NULL; + const unsigned char *p; const char *name; - size_t n = 0, i, pushed; + size_t n, i, pushed; DEBUGASSERT(source->type == CAFILE_SOURCE_PATH || source->type == CAFILE_SOURCE_BLOB); @@ -328,7 +327,7 @@ static unsigned x509_end_chain(const br_x509_class **ctx) struct x509_context *x509 = (struct x509_context *)ctx; if(!x509->verifypeer) { - return (unsigned)br_x509_decoder_last_error(&x509->decoder); + return br_x509_decoder_last_error(&x509->decoder); } return x509->minimal.vtable->end_chain(&x509->minimal.vtable); @@ -361,171 +360,213 @@ static const br_x509_class x509_vtable = { x509_get_pkey }; -static CURLcode -bearssl_set_ssl_version_min_max(struct Curl_easy *data, - br_ssl_engine_context *ssl_eng, - struct ssl_primary_config *conn_config) -{ - unsigned version_min, version_max; - - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - version_min = BR_TLS10; - break; - case CURL_SSLVERSION_TLSv1_1: - version_min = BR_TLS11; - break; - case CURL_SSLVERSION_TLSv1_2: - version_min = BR_TLS12; - break; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "BearSSL: does not support TLS 1.3"); - return CURLE_SSL_CONNECT_ERROR; - default: - failf(data, "BearSSL: unsupported minimum TLS version value"); - return CURLE_SSL_CONNECT_ERROR; - } - - switch(conn_config->version_max) { - case CURL_SSLVERSION_MAX_DEFAULT: - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_TLSv1_3: - case CURL_SSLVERSION_MAX_TLSv1_2: - version_max = BR_TLS12; - break; - case CURL_SSLVERSION_MAX_TLSv1_1: - version_max = BR_TLS11; - break; - case CURL_SSLVERSION_MAX_TLSv1_0: - version_max = BR_TLS10; - break; - default: - failf(data, "BearSSL: unsupported maximum TLS version value"); - return CURLE_SSL_CONNECT_ERROR; - } - - br_ssl_engine_set_versions(ssl_eng, version_min, version_max); +struct st_cipher { + const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */ + const char *alias_name; /* Alias name is the same as OpenSSL cipher name */ + uint16_t num; /* BearSSL cipher suite */ +}; - return CURLE_OK; -} +/* Macro to initialize st_cipher data structure */ +#define CIPHER_DEF(num, alias) { #num, alias, BR_##num } -static const uint16_t ciphertable[] = { +static const struct st_cipher ciphertable[] = { /* RFC 2246 TLS 1.0 */ - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */ + CIPHER_DEF(TLS_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */ + "DES-CBC3-SHA"), /* RFC 3268 TLS 1.0 AES */ - BR_TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */ - BR_TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */ + "AES128-SHA"), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */ + "AES256-SHA"), /* RFC 5246 TLS 1.2 */ - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */ - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */ + "AES128-SHA256"), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */ + "AES256-SHA256"), /* RFC 5288 TLS 1.2 AES GCM */ - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */ - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */ + "AES128-GCM-SHA256"), + CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */ + "AES256-GCM-SHA384"), /* RFC 4492 TLS 1.0 ECC */ - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */ - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */ - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */ - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */ - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */ - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */ - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */ - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */ - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */ - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */ - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */ - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */ + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */ + "ECDH-ECDSA-DES-CBC3-SHA"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */ + "ECDH-ECDSA-AES128-SHA"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */ + "ECDH-ECDSA-AES256-SHA"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */ + "ECDHE-ECDSA-DES-CBC3-SHA"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */ + "ECDHE-ECDSA-AES128-SHA"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */ + "ECDHE-ECDSA-AES256-SHA"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */ + "ECDH-RSA-DES-CBC3-SHA"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */ + "ECDH-RSA-AES128-SHA"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */ + "ECDH-RSA-AES256-SHA"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */ + "ECDHE-RSA-DES-CBC3-SHA"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */ + "ECDHE-RSA-AES128-SHA"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */ + "ECDHE-RSA-AES256-SHA"), /* RFC 5289 TLS 1.2 ECC HMAC SHA256/384 */ - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */ - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */ - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */ - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */ - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */ - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */ - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */ - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */ + "ECDHE-ECDSA-AES128-SHA256"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */ + "ECDHE-ECDSA-AES256-SHA384"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */ + "ECDH-ECDSA-AES128-SHA256"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */ + "ECDH-ECDSA-AES256-SHA384"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */ + "ECDHE-RSA-AES128-SHA256"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */ + "ECDHE-RSA-AES256-SHA384"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */ + "ECDH-RSA-AES128-SHA256"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */ + "ECDH-RSA-AES256-SHA384"), /* RFC 5289 TLS 1.2 GCM */ - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */ - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */ - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */ - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */ - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */ - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */ - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */ - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */ - + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */ + "ECDHE-ECDSA-AES128-GCM-SHA256"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */ + "ECDHE-ECDSA-AES256-GCM-SHA384"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */ + "ECDH-ECDSA-AES128-GCM-SHA256"), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */ + "ECDH-ECDSA-AES256-GCM-SHA384"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */ + "ECDHE-RSA-AES128-GCM-SHA256"), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */ + "ECDHE-RSA-AES256-GCM-SHA384"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */ + "ECDH-RSA-AES128-GCM-SHA256"), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */ + "ECDH-RSA-AES256-GCM-SHA384"), #ifdef BR_TLS_RSA_WITH_AES_128_CCM + /* RFC 6655 TLS 1.2 CCM Supported since BearSSL 0.6 */ - BR_TLS_RSA_WITH_AES_128_CCM, /* 0xC09C */ - BR_TLS_RSA_WITH_AES_256_CCM, /* 0xC09D */ - BR_TLS_RSA_WITH_AES_128_CCM_8, /* 0xC0A0 */ - BR_TLS_RSA_WITH_AES_256_CCM_8, /* 0xC0A1 */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_CCM, /* 0xC09C */ + "AES128-CCM"), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CCM, /* 0xC09D */ + "AES256-CCM"), + CIPHER_DEF(TLS_RSA_WITH_AES_128_CCM_8, /* 0xC0A0 */ + "AES128-CCM8"), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CCM_8, /* 0xC0A1 */ + "AES256-CCM8"), /* RFC 7251 TLS 1.2 ECC CCM Supported since BearSSL 0.6 */ - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, /* 0xC0AC */ - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, /* 0xC0AD */ - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, /* 0xC0AE */ - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, /* 0xC0AF */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CCM, /* 0xC0AC */ + "ECDHE-ECDSA-AES128-CCM"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CCM, /* 0xC0AD */ + "ECDHE-ECDSA-AES256-CCM"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, /* 0xC0AE */ + "ECDHE-ECDSA-AES128-CCM8"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, /* 0xC0AF */ + "ECDHE-ECDSA-AES256-CCM8"), #endif /* RFC 7905 TLS 1.2 ChaCha20-Poly1305 Supported since BearSSL 0.2 */ - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */ - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */ + CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */ + "ECDHE-RSA-CHACHA20-POLY1305"), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */ + "ECDHE-ECDSA-CHACHA20-POLY1305"), }; #define NUM_OF_CIPHERS (sizeof(ciphertable) / sizeof(ciphertable[0])) +#define CIPHER_NAME_BUF_LEN 64 + +static bool is_separator(char c) +{ + /* Return whether character is a cipher list separator. */ + switch(c) { + case ' ': + case '\t': + case ':': + case ',': + case ';': + return true; + } + return false; +} static CURLcode bearssl_set_selected_ciphers(struct Curl_easy *data, br_ssl_engine_context *ssl_eng, const char *ciphers) { - uint16_t selected[NUM_OF_CIPHERS]; - size_t count = 0, i; - const char *ptr, *end; - - for(ptr = ciphers; ptr[0] != '\0' && count < NUM_OF_CIPHERS; ptr = end) { - uint16_t id = Curl_cipher_suite_walk_str(&ptr, &end); - - /* Check if cipher is supported */ - if(id) { - for(i = 0; i < NUM_OF_CIPHERS && ciphertable[i] != id; i++); - if(i == NUM_OF_CIPHERS) - id = 0; + uint16_t selected_ciphers[NUM_OF_CIPHERS]; + size_t selected_count = 0; + char cipher_name[CIPHER_NAME_BUF_LEN]; + const char *cipher_start = ciphers; + const char *cipher_end; + size_t i, j; + + if(!cipher_start) + return CURLE_SSL_CIPHER; + + while(true) { + /* Extract the next cipher name from the ciphers string */ + while(is_separator(*cipher_start)) + ++cipher_start; + if(*cipher_start == '\0') + break; + cipher_end = cipher_start; + while(*cipher_end != '\0' && !is_separator(*cipher_end)) + ++cipher_end; + j = cipher_end - cipher_start < CIPHER_NAME_BUF_LEN - 1 ? + cipher_end - cipher_start : CIPHER_NAME_BUF_LEN - 1; + strncpy(cipher_name, cipher_start, j); + cipher_name[j] = '\0'; + cipher_start = cipher_end; + + /* Lookup the cipher name in the table of available ciphers. If the cipher + name starts with "TLS_" we do the lookup by IANA name. Otherwise, we try + to match cipher name by an (OpenSSL) alias. */ + if(strncasecompare(cipher_name, "TLS_", 4)) { + for(i = 0; i < NUM_OF_CIPHERS && + !strcasecompare(cipher_name, ciphertable[i].name); ++i); } - if(!id) { - if(ptr[0] != '\0') - infof(data, "BearSSL: unknown cipher in list: \"%.*s\"", - (int) (end - ptr), ptr); + else { + for(i = 0; i < NUM_OF_CIPHERS && + !strcasecompare(cipher_name, ciphertable[i].alias_name); ++i); + } + if(i == NUM_OF_CIPHERS) { + infof(data, "BearSSL: unknown cipher in list: %s", cipher_name); continue; } /* No duplicates allowed */ - for(i = 0; i < count && selected[i] != id; i++); - if(i < count) { - infof(data, "BearSSL: duplicate cipher in list: \"%.*s\"", - (int) (end - ptr), ptr); + for(j = 0; j < selected_count && + selected_ciphers[j] != ciphertable[i].num; j++); + if(j < selected_count) { + infof(data, "BearSSL: duplicate cipher in list: %s", cipher_name); continue; } - selected[count++] = id; + DEBUGASSERT(selected_count < NUM_OF_CIPHERS); + selected_ciphers[selected_count] = ciphertable[i].num; + ++selected_count; } - if(count == 0) { + if(selected_count == 0) { failf(data, "BearSSL: no supported cipher in list"); return CURLE_SSL_CIPHER; } - br_ssl_engine_set_suites(ssl_eng, selected, count); + br_ssl_engine_set_suites(ssl_eng, selected_ciphers, selected_count); return CURLE_OK; } @@ -545,11 +586,41 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, const bool verifypeer = conn_config->verifypeer; const bool verifyhost = conn_config->verifyhost; CURLcode ret; + unsigned version_min, version_max; int session_set = 0; DEBUGASSERT(backend); CURL_TRC_CF(data, cf, "connect_step1"); + switch(conn_config->version) { + case CURL_SSLVERSION_SSLv2: + failf(data, "BearSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: + failf(data, "BearSSL does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_0: + version_min = BR_TLS10; + version_max = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + version_min = BR_TLS11; + version_max = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + version_min = BR_TLS12; + version_max = BR_TLS12; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + version_min = BR_TLS10; + version_max = BR_TLS12; + break; + default: + failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + if(verifypeer) { if(ca_info_blob) { struct cafile_source source; @@ -584,11 +655,7 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, /* initialize SSL context */ br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal, backend->anchors, backend->anchors_len); - - ret = bearssl_set_ssl_version_min_max(data, &backend->ctx.eng, conn_config); - if(ret != CURLE_OK) - return ret; - + br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max); br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf, sizeof(backend->buf), 1); @@ -608,12 +675,12 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, backend->x509.verifyhost = verifyhost; br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable); - if(ssl_config->primary.cache_session) { + if(ssl_config->primary.sessionid) { void *session; CURL_TRC_CF(data, cf, "connect_step1, check session cache"); Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(cf, data, &connssl->peer, &session, NULL)) { + if(!Curl_ssl_getsessionid(cf, data, &session, NULL)) { br_ssl_engine_set_session_parameters(&backend->ctx.eng, session); session_set = 1; infof(data, "BearSSL: reusing session ID"); @@ -634,7 +701,7 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); } - if(connssl->peer.type != CURL_SSL_PEER_DNS) { + if(connssl->peer.is_ip_address) { if(verifyhost) { failf(data, "BearSSL: " "host verification of IP address is not supported"); @@ -672,6 +739,28 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf, return CURLE_OK; } +static void bearssl_adjust_pollset(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct easy_pollset *ps) +{ + if(!cf->connected) { + curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data); + if(sock != CURL_SOCKET_BAD) { + struct ssl_connect_data *connssl = cf->ctx; + struct bearssl_ssl_backend_data *backend = + (struct bearssl_ssl_backend_data *)connssl->backend; + unsigned state = br_ssl_engine_current_state(&backend->ctx.eng); + + if(state & BR_SSL_SENDREC) { + Curl_pollset_set_out_only(data, ps, sock); + } + else { + Curl_pollset_set_in_only(data, ps, sock); + } + } + } +} + static CURLcode bearssl_run_until(struct Curl_cfilter *cf, struct Curl_easy *data, unsigned target) @@ -688,7 +777,6 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, DEBUGASSERT(backend); - connssl->io_need = CURL_SSL_IO_NEED_NONE; for(;;) { state = br_ssl_engine_current_state(&backend->ctx.eng); if(state & BR_SSL_CLOSED) { @@ -713,9 +801,7 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, failf(data, "SSL: X.509 verification: " "chain could not be linked to a trust anchor"); return CURLE_PEER_FAILED_VERIFICATION; - default:; } - failf(data, "BearSSL: connection error 0x%04x", err); /* X.509 errors are documented to have the range 32..63 */ if(err >= 32 && err < 64) return CURLE_PEER_FAILED_VERIFICATION; @@ -725,12 +811,9 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, return CURLE_OK; if(state & BR_SSL_SENDREC) { buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len); - ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, FALSE, - &result); + ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, &result); CURL_TRC_CF(data, cf, "ssl_send(len=%zu) -> %zd, %d", len, ret, result); if(ret <= 0) { - if(result == CURLE_AGAIN) - connssl->io_need |= CURL_SSL_IO_NEED_SEND; return result; } br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret); @@ -741,11 +824,9 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf, CURL_TRC_CF(data, cf, "ssl_recv(len=%zu) -> %zd, %d", len, ret, result); if(ret == 0) { failf(data, "SSL: EOF without close notify"); - return CURLE_RECV_ERROR; + return CURLE_READ_ERROR; } if(ret <= 0) { - if(result == CURLE_AGAIN) - connssl->io_need |= CURL_SSL_IO_NEED_RECV; return result; } br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret); @@ -759,9 +840,6 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf, struct ssl_connect_data *connssl = cf->ctx; struct bearssl_ssl_backend_data *backend = (struct bearssl_ssl_backend_data *)connssl->backend; - br_ssl_session_parameters session; - char cipher_str[64]; - char ver_str[16]; CURLcode ret; DEBUGASSERT(backend); @@ -772,7 +850,6 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf, return CURLE_OK; if(ret == CURLE_OK) { unsigned int tver; - if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) { failf(data, "SSL: connection closed during handshake"); return CURLE_SSL_CONNECT_ERROR; @@ -780,29 +857,16 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf, connssl->connecting_state = ssl_connect_3; /* Informational message */ tver = br_ssl_engine_get_version(&backend->ctx.eng); - if(tver == BR_TLS12) - strcpy(ver_str, "TLSv1.2"); - else if(tver == BR_TLS11) - strcpy(ver_str, "TLSv1.1"); - else if(tver == BR_TLS10) - strcpy(ver_str, "TLSv1.0"); - else { - msnprintf(ver_str, sizeof(ver_str), "TLS 0x%04x", tver); - } - br_ssl_engine_get_session_parameters(&backend->ctx.eng, &session); - Curl_cipher_suite_get_str(session.cipher_suite, cipher_str, - sizeof(cipher_str), true); - infof(data, "BearSSL: %s connection using %s", ver_str, cipher_str); + if(tver == 0x0303) + infof(data, "SSL connection using TLSv1.2"); + else if(tver == 0x0304) + infof(data, "SSL connection using TLSv1.3"); + else + infof(data, "SSL connection using TLS 0x%x", tver); } return ret; } -static void bearssl_session_free(void *sessionid, size_t idsize) -{ - (void)idsize; - free(sessionid); -} - static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -824,7 +888,10 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf, proto? strlen(proto) : 0); } - if(ssl_config->primary.cache_session) { + if(ssl_config->primary.sessionid) { + bool incache; + bool added = FALSE; + void *oldsession; br_ssl_session_parameters *session; session = malloc(sizeof(*session)); @@ -832,11 +899,16 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf, return CURLE_OUT_OF_MEMORY; br_ssl_engine_get_session_parameters(&backend->ctx.eng, session); Curl_ssl_sessionid_lock(data); - ret = Curl_ssl_set_sessionid(cf, data, &connssl->peer, session, 0, - bearssl_session_free); + incache = !(Curl_ssl_getsessionid(cf, data, &oldsession, NULL)); + if(incache) + Curl_ssl_delsessionid(data, oldsession); + ret = Curl_ssl_addsessionid(cf, data, session, 0, &added); Curl_ssl_sessionid_unlock(data); - if(ret) - return ret; + if(!added) + free(session); + if(ret) { + return CURLE_OUT_OF_MEMORY; + } } connssl->connecting_state = ssl_connect_done; @@ -929,7 +1001,9 @@ static CURLcode bearssl_connect_common(struct Curl_cfilter *cf, return ret; } - while(ssl_connect_2 == connssl->connecting_state) { + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { /* check allowed time left */ timeout_ms = Curl_timeleft(data, NULL, TRUE); @@ -939,13 +1013,14 @@ static CURLcode bearssl_connect_common(struct Curl_cfilter *cf, return CURLE_OPERATION_TIMEDOUT; } - /* if ssl is expecting something, check if it is available. */ - if(connssl->io_need) { + /* if ssl is expecting something, check if it's available. */ + if(ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { - curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND)? - sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV)? - sockfd:CURL_SOCKET_BAD; + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; CURL_TRC_CF(data, cf, "connect_common, check socket"); what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, @@ -976,9 +1051,11 @@ static CURLcode bearssl_connect_common(struct Curl_cfilter *cf, * before step2 has completed while ensuring that a client using select() * or epoll() will always have a valid fdset to wait on. */ - connssl->io_need = CURL_SSL_IO_NEED_NONE; ret = bearssl_connect_step2(cf, data); - if(ret || (nonblocking && (ssl_connect_2 == connssl->connecting_state))) + if(ret || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) return ret; } @@ -1069,43 +1146,6 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl, return &backend->ctx; } -static CURLcode bearssl_shutdown(struct Curl_cfilter *cf, - struct Curl_easy *data, - bool send_shutdown, bool *done) -{ - struct ssl_connect_data *connssl = cf->ctx; - struct bearssl_ssl_backend_data *backend = - (struct bearssl_ssl_backend_data *)connssl->backend; - CURLcode result; - - DEBUGASSERT(backend); - if(!backend->active || cf->shutdown) { - *done = TRUE; - return CURLE_OK; - } - - *done = FALSE; - if(!backend->sent_shutdown) { - (void)send_shutdown; /* unknown how to suppress our close notify */ - br_ssl_engine_close(&backend->ctx.eng); - backend->sent_shutdown = TRUE; - } - - result = bearssl_run_until(cf, data, BR_SSL_CLOSED); - if(result == CURLE_OK) { - *done = TRUE; - } - else if(result == CURLE_AGAIN) { - CURL_TRC_CF(data, cf, "shutdown EAGAIN, io_need=%x", connssl->io_need); - result = CURLE_OK; - } - else - CURL_TRC_CF(data, cf, "shutdown error: %d", result); - - cf->shutdown = (result || *done); - return result; -} - static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) { struct ssl_connect_data *connssl = cf->ctx; @@ -1113,10 +1153,13 @@ static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) (struct bearssl_ssl_backend_data *)connssl->backend; size_t i; - (void)data; DEBUGASSERT(backend); - backend->active = FALSE; + if(backend->active) { + backend->active = FALSE; + br_ssl_engine_close(&backend->ctx.eng); + (void)bearssl_run_until(cf, data, BR_SSL_CLOSED); + } if(backend->anchors) { for(i = 0; i < backend->anchors_len; ++i) free(backend->anchors[i].dn.data); @@ -1124,6 +1167,11 @@ static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data) } } +static void bearssl_session_free(void *ptr) +{ + free(ptr); +} + static CURLcode bearssl_sha256sum(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, @@ -1139,28 +1187,24 @@ static CURLcode bearssl_sha256sum(const unsigned char *input, const struct Curl_ssl Curl_ssl_bearssl = { { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ - - SSLSUPP_CAINFO_BLOB | - SSLSUPP_SSL_CTX | - SSLSUPP_HTTPS_PROXY | - SSLSUPP_CIPHER_LIST, - + SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY, sizeof(struct bearssl_ssl_backend_data), Curl_none_init, /* init */ Curl_none_cleanup, /* cleanup */ bearssl_version, /* version */ Curl_none_check_cxn, /* check_cxn */ - bearssl_shutdown, /* shutdown */ + Curl_none_shutdown, /* shutdown */ bearssl_data_pending, /* data_pending */ bearssl_random, /* random */ Curl_none_cert_status_request, /* cert_status_request */ bearssl_connect, /* connect */ bearssl_connect_nonblocking, /* connect_nonblocking */ - Curl_ssl_adjust_pollset, /* adjust_pollset */ + bearssl_adjust_pollset, /* adjust_pollset */ bearssl_get_internals, /* get_internals */ bearssl_close, /* close_one */ Curl_none_close_all, /* close_all */ + bearssl_session_free, /* session_free */ Curl_none_set_engine, /* set_engine */ Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ @@ -1168,9 +1212,9 @@ const struct Curl_ssl Curl_ssl_bearssl = { bearssl_sha256sum, /* sha256sum */ NULL, /* associate_connection */ NULL, /* disassociate_connection */ + NULL, /* free_multi_ssl_backend_data */ bearssl_recv, /* recv decrypted data */ bearssl_send, /* send data to encrypt */ - NULL, /* get_channel_binding */ }; #endif /* USE_BEARSSL */ |