diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-11 22:28:44 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-11-11 22:43:33 +0300 |
commit | 175ec788d14db88a2fafb920c8b5117209c12d5b (patch) | |
tree | 5ff4a7d314ce3887c5df8f051d83866edd585ac1 /contrib/libs/curl/lib/vtls/rustls.c | |
parent | b6c20a8a26d0be34045f2604b4da1ee189920ed2 (diff) | |
download | ydb-175ec788d14db88a2fafb920c8b5117209c12d5b.tar.gz |
Update contrib/libs/curl to 8.2.1
Diffstat (limited to 'contrib/libs/curl/lib/vtls/rustls.c')
-rw-r--r-- | contrib/libs/curl/lib/vtls/rustls.c | 377 |
1 files changed, 221 insertions, 156 deletions
diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c index 77a49f1ab4..76d3e24d23 100644 --- a/contrib/libs/curl/lib/vtls/rustls.c +++ b/contrib/libs/curl/lib/vtls/rustls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2020 - 2022, Jacob Hoffman-Andrews, + * Copyright (C) Jacob Hoffman-Andrews, * <github@hoffman-andrews.com> * * This software is licensed as described in the file COPYING, which @@ -35,11 +35,12 @@ #include "urldata.h" #include "sendf.h" #include "vtls.h" +#include "vtls_int.h" #include "select.h" #include "strerror.h" #include "multiif.h" -struct ssl_backend_data +struct rustls_ssl_backend_data { const struct rustls_client_config *config; struct rustls_connection *conn; @@ -63,43 +64,117 @@ static CURLcode map_error(rustls_result r) } static bool -cr_data_pending(const struct connectdata *conn, int sockindex) +cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data) { - const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - DEBUGASSERT(backend); + struct ssl_connect_data *ctx = cf->ctx; + struct rustls_ssl_backend_data *backend; + + (void)data; + DEBUGASSERT(ctx && ctx->backend); + backend = (struct rustls_ssl_backend_data *)ctx->backend; return backend->data_pending; } static CURLcode -cr_connect(struct Curl_easy *data UNUSED_PARAM, - struct connectdata *conn UNUSED_PARAM, - int sockindex UNUSED_PARAM) +cr_connect(struct Curl_cfilter *cf UNUSED_PARAM, + struct Curl_easy *data UNUSED_PARAM) { infof(data, "rustls_connect: unimplemented"); return CURLE_SSL_CONNECT_ERROR; } +struct io_ctx { + struct Curl_cfilter *cf; + struct Curl_easy *data; +}; + static int read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) { - ssize_t n = sread(*(int *)userdata, buf, len); - if(n < 0) { - return SOCKERRNO; + struct io_ctx *io_ctx = userdata; + CURLcode result; + int ret = 0; + ssize_t nread = Curl_conn_cf_recv(io_ctx->cf->next, io_ctx->data, + (char *)buf, len, &result); + if(nread < 0) { + nread = 0; + if(CURLE_AGAIN == result) + ret = EAGAIN; + else + ret = EINVAL; } - *out_n = n; - return 0; + *out_n = (int)nread; + /* + DEBUGF(LOG_CF(io_ctx->data, io_ctx->cf, "cf->next recv(len=%zu) -> %zd, %d", + len, nread, result)); + */ + return ret; } static int write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) { - ssize_t n = swrite(*(int *)userdata, buf, len); - if(n < 0) { - return SOCKERRNO; + struct io_ctx *io_ctx = userdata; + CURLcode result; + int ret = 0; + ssize_t nwritten = Curl_conn_cf_send(io_ctx->cf->next, io_ctx->data, + (const char *)buf, len, &result); + if(nwritten < 0) { + nwritten = 0; + if(CURLE_AGAIN == result) + ret = EAGAIN; + else + ret = EINVAL; } - *out_n = n; - return 0; + *out_n = (int)nwritten; + /* + DEBUGF(LOG_CF(io_ctx->data, io_ctx->cf, "cf->next send(len=%zu) -> %zd, %d", + len, nwritten, result)); + */ + return ret; +} + +static ssize_t tls_recv_more(struct Curl_cfilter *cf, + struct Curl_easy *data, CURLcode *err) +{ + struct ssl_connect_data *const connssl = cf->ctx; + struct rustls_ssl_backend_data *const backend = + (struct rustls_ssl_backend_data *)connssl->backend; + struct io_ctx io_ctx; + size_t tls_bytes_read = 0; + rustls_io_result io_error; + rustls_result rresult = 0; + + io_ctx.cf = cf; + io_ctx.data = data; + io_error = rustls_connection_read_tls(backend->conn, read_cb, &io_ctx, + &tls_bytes_read); + if(io_error == EAGAIN || io_error == EWOULDBLOCK) { + *err = CURLE_AGAIN; + return -1; + } + else if(io_error) { + char buffer[STRERROR_LEN]; + failf(data, "reading from socket: %s", + Curl_strerror(io_error, buffer, sizeof(buffer))); + *err = CURLE_READ_ERROR; + return -1; + } + + rresult = rustls_connection_process_new_packets(backend->conn); + if(rresult != RUSTLS_RESULT_OK) { + char errorbuf[255]; + size_t errorlen; + rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); + failf(data, "rustls_connection_process_new_packets: %.*s", + errorlen, errorbuf); + *err = map_error(rresult); + return -1; + } + + backend->data_pending = TRUE; + *err = CURLE_OK; + return (ssize_t)tls_bytes_read; } /* @@ -115,94 +190,86 @@ write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) * output buffer. */ static ssize_t -cr_recv(struct Curl_easy *data, int sockindex, +cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data, char *plainbuf, size_t plainlen, CURLcode *err) { - struct connectdata *conn = data->conn; - struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *const backend = connssl->backend; + struct ssl_connect_data *const connssl = cf->ctx; + struct rustls_ssl_backend_data *const backend = + (struct rustls_ssl_backend_data *)connssl->backend; struct rustls_connection *rconn = NULL; - size_t n = 0; - size_t tls_bytes_read = 0; size_t plain_bytes_copied = 0; rustls_result rresult = 0; - char errorbuf[255]; - rustls_io_result io_error; + ssize_t nread; + bool eof = FALSE; DEBUGASSERT(backend); rconn = backend->conn; - io_error = rustls_connection_read_tls(rconn, read_cb, - &conn->sock[sockindex], &tls_bytes_read); - if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - infof(data, "sread: EAGAIN or EWOULDBLOCK"); - } - else if(io_error) { - char buffer[STRERROR_LEN]; - failf(data, "reading from socket: %s", - Curl_strerror(io_error, buffer, sizeof(buffer))); - *err = CURLE_READ_ERROR; - return -1; - } - - infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read); - - rresult = rustls_connection_process_new_packets(rconn); - if(rresult != RUSTLS_RESULT_OK) { - rustls_error(rresult, errorbuf, sizeof(errorbuf), &n); - failf(data, "%.*s", n, errorbuf); - *err = map_error(rresult); - return -1; - } - - backend->data_pending = TRUE; - while(plain_bytes_copied < plainlen) { + if(!backend->data_pending) { + if(tls_recv_more(cf, data, err) < 0) { + if(*err != CURLE_AGAIN) { + nread = -1; + goto out; + } + break; + } + } + rresult = rustls_connection_read(rconn, (uint8_t *)plainbuf + plain_bytes_copied, plainlen - plain_bytes_copied, &n); if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) { - infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later."); backend->data_pending = FALSE; - break; + } + else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) { + failf(data, "rustls: peer closed TCP connection " + "without first closing TLS connection"); + *err = CURLE_READ_ERROR; + nread = -1; + goto out; } else if(rresult != RUSTLS_RESULT_OK) { /* n always equals 0 in this case, don't need to check it */ - failf(data, "error in rustls_connection_read: %d", rresult); + char errorbuf[255]; + size_t errorlen; + rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); + failf(data, "rustls_connection_read: %.*s", errorlen, errorbuf); *err = CURLE_READ_ERROR; - return -1; + nread = -1; + goto out; } else if(n == 0) { /* n == 0 indicates clean EOF, but we may have read some other plaintext bytes before we reached this. Break out of the loop so we can figure out whether to return success or EOF. */ + eof = TRUE; break; } else { - infof(data, "cr_recv copied out %ld bytes of plaintext", n); plain_bytes_copied += n; } } if(plain_bytes_copied) { *err = CURLE_OK; - return plain_bytes_copied; + nread = (ssize_t)plain_bytes_copied; } - - /* If we wrote out 0 plaintext bytes, that means either we hit a clean EOF, - OR we got a RUSTLS_RESULT_PLAINTEXT_EMPTY. - If the latter, return CURLE_AGAIN so curl doesn't treat this as EOF. */ - if(!backend->data_pending) { + else if(eof) { + *err = CURLE_OK; + nread = 0; + } + else { *err = CURLE_AGAIN; - return -1; + nread = -1; } - /* Zero bytes read, and no RUSTLS_RESULT_PLAINTEXT_EMPTY, means the TCP - connection was cleanly closed (with a close_notify alert). */ - *err = CURLE_OK; - return 0; +out: + DEBUGF(LOG_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", + plainlen, nread, *err)); + return nread; } /* @@ -216,44 +283,52 @@ cr_recv(struct Curl_easy *data, int sockindex, * It will only drain rustls' plaintext output buffer into the socket. */ static ssize_t -cr_send(struct Curl_easy *data, int sockindex, +cr_send(struct Curl_cfilter *cf, struct Curl_easy *data, const void *plainbuf, size_t plainlen, CURLcode *err) { - struct connectdata *conn = data->conn; - struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *const backend = connssl->backend; + struct ssl_connect_data *const connssl = cf->ctx; + struct rustls_ssl_backend_data *const backend = + (struct rustls_ssl_backend_data *)connssl->backend; struct rustls_connection *rconn = NULL; + struct io_ctx io_ctx; size_t plainwritten = 0; size_t tlswritten = 0; size_t tlswritten_total = 0; rustls_result rresult; rustls_io_result io_error; + char errorbuf[256]; + size_t errorlen; DEBUGASSERT(backend); rconn = backend->conn; - infof(data, "cr_send %ld bytes of plaintext", plainlen); + DEBUGF(LOG_CF(data, cf, "cf_send: %ld plain bytes", plainlen)); + + io_ctx.cf = cf; + io_ctx.data = data; if(plainlen > 0) { rresult = rustls_connection_write(rconn, plainbuf, plainlen, &plainwritten); if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_connection_write"); + rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); + failf(data, "rustls_connection_write: %.*s", errorlen, errorbuf); *err = CURLE_WRITE_ERROR; return -1; } else if(plainwritten == 0) { - failf(data, "EOF in rustls_connection_write"); + failf(data, "rustls_connection_write: EOF"); *err = CURLE_WRITE_ERROR; return -1; } } while(rustls_connection_wants_write(rconn)) { - io_error = rustls_connection_write_tls(rconn, write_cb, - &conn->sock[sockindex], &tlswritten); + io_error = rustls_connection_write_tls(rconn, write_cb, &io_ctx, + &tlswritten); if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - infof(data, "swrite: EAGAIN after %ld bytes", tlswritten_total); + DEBUGF(LOG_CF(data, cf, "cf_send: EAGAIN after %zu bytes", + tlswritten_total)); *err = CURLE_AGAIN; return -1; } @@ -269,7 +344,7 @@ cr_send(struct Curl_easy *data, int sockindex, *err = CURLE_WRITE_ERROR; return -1; } - infof(data, "cr_send wrote %ld bytes to network", tlswritten); + DEBUGF(LOG_CF(data, cf, "cf_send: wrote %zu TLS bytes", tlswritten)); tlswritten_total += tlswritten; } @@ -302,37 +377,42 @@ cr_hostname_is_ip(const char *hostname) } static CURLcode -cr_init_backend(struct Curl_easy *data, struct connectdata *conn, - struct ssl_backend_data *const backend) +cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data, + struct rustls_ssl_backend_data *const backend) { + struct ssl_connect_data *connssl = cf->ctx; + struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct rustls_connection *rconn = NULL; struct rustls_client_config_builder *config_builder = NULL; struct rustls_root_cert_store *roots = NULL; - const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob); + const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; const char * const ssl_cafile = /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ - (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile)); - const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - const char *hostname = conn->host.name; + (ca_info_blob ? NULL : conn_config->CAfile); + const bool verifypeer = conn_config->verifypeer; + const char *hostname = connssl->hostname; 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 }, - }; DEBUGASSERT(backend); rconn = backend->conn; config_builder = rustls_client_config_builder_new(); -#ifdef USE_HTTP2 - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2); - rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2); -#else - rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1); -#endif - infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1); + if(connssl->alpn) { + struct alpn_proto_buf proto; + rustls_slice_bytes alpn[ALPN_ENTRIES_MAX]; + size_t i; + + for(i = 0; i < connssl->alpn->count; ++i) { + alpn[i].data = (const uint8_t *)connssl->alpn->entries[i]; + alpn[i].len = strlen(connssl->alpn->entries[i]); + } + rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, + connssl->alpn->count); + Curl_alpn_to_proto_str(&proto, connssl->alpn); + infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); + } if(!verifypeer) { rustls_client_config_builder_dangerous_set_certificate_verifier( config_builder, cr_verify_none); @@ -352,7 +432,7 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, result = rustls_root_cert_store_add_pem(roots, ca_info_blob->data, ca_info_blob->len, verifypeer); if(result != RUSTLS_RESULT_OK) { - failf(data, "failed to parse trusted certificates from blob"); + failf(data, "rustls: failed to parse trusted certificates from blob"); rustls_root_cert_store_free(roots); rustls_client_config_free( rustls_client_config_builder_build(config_builder)); @@ -362,7 +442,7 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, result = rustls_client_config_builder_use_roots(config_builder, roots); rustls_root_cert_store_free(roots); if(result != RUSTLS_RESULT_OK) { - failf(data, "failed to load trusted certificates"); + failf(data, "rustls: failed to load trusted certificates"); rustls_client_config_free( rustls_client_config_builder_build(config_builder)); return CURLE_SSL_CACERT_BADFILE; @@ -372,7 +452,7 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, result = rustls_client_config_builder_load_roots_from_file( config_builder, ssl_cafile); if(result != RUSTLS_RESULT_OK) { - failf(data, "failed to load trusted certificates"); + failf(data, "rustls: failed to load trusted certificates"); rustls_client_config_free( rustls_client_config_builder_build(config_builder)); return CURLE_SSL_CACERT_BADFILE; @@ -384,7 +464,7 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, { char *snihost = Curl_ssl_snihost(data, hostname, NULL); if(!snihost) { - failf(data, "Failed to set SNI"); + failf(data, "rustls: failed to get SNI"); return CURLE_SSL_CONNECT_ERROR; } result = rustls_client_connection_new(backend->config, snihost, &rconn); @@ -400,45 +480,24 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, } static void -cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn, +cr_set_negotiated_alpn(struct Curl_cfilter *cf, struct Curl_easy *data, const struct rustls_connection *rconn) { const uint8_t *protocol = NULL; size_t len = 0; rustls_connection_get_alpn_protocol(rconn, &protocol, &len); - if(!protocol) { - infof(data, VTLS_INFOF_NO_ALPN); - return; - } - -#ifdef USE_HTTP2 - if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) { - infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_H2); - conn->alpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(len == ALPN_HTTP_1_1_LENGTH && - 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) { - infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_HTTP_1_1); - conn->alpn = CURL_HTTP_VERSION_1_1; - } - else { - infof(data, "ALPN, negotiated an unrecognized protocol"); - } - - Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + Curl_alpn_set_negotiated(cf, data, protocol, len); } static CURLcode -cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, - int sockindex, bool *done) +cr_connect_nonblocking(struct Curl_cfilter *cf, + struct Curl_easy *data, bool *done) { - struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_backend_data *const backend = connssl->backend; + struct ssl_connect_data *const connssl = cf->ctx; + curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); + struct rustls_ssl_backend_data *const backend = + (struct rustls_ssl_backend_data *)connssl->backend; struct rustls_connection *rconn = NULL; CURLcode tmperr = CURLE_OK; int result; @@ -451,7 +510,8 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, DEBUGASSERT(backend); if(ssl_connection_none == connssl->state) { - result = cr_init_backend(data, conn, connssl->backend); + result = cr_init_backend(cf, data, + (struct rustls_ssl_backend_data *)connssl->backend); if(result != CURLE_OK) { return result; } @@ -471,10 +531,8 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* Done with the handshake. Set up callbacks to send/receive data. */ connssl->state = ssl_connection_complete; - cr_set_negotiated_alpn(data, conn, rconn); + cr_set_negotiated_alpn(cf, data, rconn); - conn->recv[sockindex] = cr_recv; - conn->send[sockindex] = cr_send; *done = TRUE; return CURLE_OK; } @@ -502,7 +560,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, if(wants_write) { infof(data, "rustls_connection wants us to write_tls."); - cr_send(data, sockindex, NULL, 0, &tmperr); + cr_send(cf, data, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { infof(data, "writing would block"); /* fall through */ @@ -515,13 +573,12 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, if(wants_read) { infof(data, "rustls_connection wants us to read_tls."); - cr_recv(data, sockindex, NULL, 0, &tmperr); - if(tmperr == CURLE_AGAIN) { - infof(data, "reading would block"); - /* fall through */ - } - else if(tmperr != CURLE_OK) { - if(tmperr == CURLE_READ_ERROR) { + if(tls_recv_more(cf, data, &tmperr) < 0) { + if(tmperr == CURLE_AGAIN) { + infof(data, "reading would block"); + /* fall through */ + } + else if(tmperr == CURLE_READ_ERROR) { return CURLE_SSL_CONNECT_ERROR; } else { @@ -539,13 +596,16 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* returns a bitmap of flags for this connection's first socket indicating whether we want to read or write */ static int -cr_getsock(struct connectdata *conn, curl_socket_t *socks) +cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data, + curl_socket_t *socks) { - struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET]; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - struct ssl_backend_data *const backend = connssl->backend; + struct ssl_connect_data *const connssl = cf->ctx; + curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data); + struct rustls_ssl_backend_data *const backend = + (struct rustls_ssl_backend_data *)connssl->backend; struct rustls_connection *rconn = NULL; + (void)data; DEBUGASSERT(backend); rconn = backend->conn; @@ -565,17 +625,18 @@ static void * cr_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct rustls_ssl_backend_data *backend = + (struct rustls_ssl_backend_data *)connssl->backend; DEBUGASSERT(backend); return &backend->conn; } static void -cr_close(struct Curl_easy *data, struct connectdata *conn, - int sockindex) +cr_close(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_connect_data *connssl = cf->ctx; + struct rustls_ssl_backend_data *backend = + (struct rustls_ssl_backend_data *)connssl->backend; CURLcode tmperr = CURLE_OK; ssize_t n = 0; @@ -583,9 +644,9 @@ cr_close(struct Curl_easy *data, struct connectdata *conn, if(backend->conn) { rustls_connection_send_close_notify(backend->conn); - n = cr_send(data, sockindex, NULL, 0, &tmperr); + n = cr_send(cf, data, NULL, 0, &tmperr); if(n < 0) { - failf(data, "error sending close notify: %d", tmperr); + failf(data, "rustls: error sending close_notify: %d", tmperr); } rustls_connection_free(backend->conn); @@ -606,8 +667,9 @@ static size_t cr_version(char *buffer, size_t size) const struct Curl_ssl Curl_ssl_rustls = { { CURLSSLBACKEND_RUSTLS, "rustls" }, SSLSUPP_CAINFO_BLOB | /* supports */ - SSLSUPP_TLS13_CIPHERSUITES, - sizeof(struct ssl_backend_data), + SSLSUPP_TLS13_CIPHERSUITES | + SSLSUPP_HTTPS_PROXY, + sizeof(struct rustls_ssl_backend_data), Curl_none_init, /* init */ Curl_none_cleanup, /* cleanup */ @@ -619,7 +681,7 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_cert_status_request, /* cert_status_request */ cr_connect, /* connect */ cr_connect_nonblocking, /* connect_nonblocking */ - cr_getsock, /* cr_getsock */ + cr_get_select_socks, /* get_select_socks */ cr_get_internals, /* get_internals */ cr_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -630,7 +692,10 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_false_start, /* false_start */ NULL, /* sha256sum */ NULL, /* associate_connection */ - NULL /* disassociate_connection */ + NULL, /* disassociate_connection */ + NULL, /* free_multi_ssl_backend_data */ + cr_recv, /* recv decrypted data */ + cr_send, /* send data to encrypt */ }; #endif /* USE_RUSTLS */ |