summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/vtls/rustls.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/rustls.c')
-rw-r--r--Utilities/cmcurl/lib/vtls/rustls.c105
1 files changed, 49 insertions, 56 deletions
diff --git a/Utilities/cmcurl/lib/vtls/rustls.c b/Utilities/cmcurl/lib/vtls/rustls.c
index 27f4ec8d8c..003533dbb9 100644
--- a/Utilities/cmcurl/lib/vtls/rustls.c
+++ b/Utilities/cmcurl/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
@@ -150,6 +150,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
size_t plain_bytes_copied = 0;
rustls_result rresult = 0;
char errorbuf[255];
+ size_t errorlen;
rustls_io_result io_error;
DEBUGASSERT(backend);
@@ -161,7 +162,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
io_error = rustls_connection_read_tls(rconn, read_cb, &io_ctx,
&tls_bytes_read);
if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
- infof(data, CFMSG(cf, "cr_recv: EAGAIN or EWOULDBLOCK"));
+ DEBUGF(LOG_CF(data, cf, "cr_recv: EAGAIN or EWOULDBLOCK"));
}
else if(io_error) {
char buffer[STRERROR_LEN];
@@ -171,12 +172,13 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
return -1;
}
- infof(data, CFMSG(cf, "cr_recv: read %ld TLS bytes"), tls_bytes_read);
+ DEBUGF(LOG_CF(data, cf, "cr_recv: read %ld TLS bytes", 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);
+ rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen);
+ failf(data, "rustls_connection_process_new_packets: %.*s",
+ errorlen, errorbuf);
*err = map_error(rresult);
return -1;
}
@@ -189,14 +191,21 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
plainlen - plain_bytes_copied,
&n);
if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
- infof(data, CFMSG(cf, "cr_recv: got PLAINTEXT_EMPTY. "
- "will try again later."));
+ DEBUGF(LOG_CF(data, cf, "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;
+ return -1;
+ }
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);
+ rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen);
+ failf(data, "rustls_connection_read: %.*s", errorlen, errorbuf);
*err = CURLE_READ_ERROR;
return -1;
}
@@ -207,7 +216,7 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
break;
}
else {
- infof(data, CFMSG(cf, "cr_recv: got %ld plain bytes"), n);
+ DEBUGF(LOG_CF(data, cf, "cr_recv: got %ld plain bytes", n));
plain_bytes_copied += n;
}
}
@@ -254,22 +263,25 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
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, CFMSG(cf, "cr_send: %ld plain bytes"), plainlen);
+ DEBUGF(LOG_CF(data, cf, "cr_send: %ld plain bytes", plainlen));
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;
}
@@ -282,8 +294,8 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
io_error = rustls_connection_write_tls(rconn, write_cb, &io_ctx,
&tlswritten);
if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
- infof(data, CFMSG(cf, "cr_send: EAGAIN after %ld bytes"),
- tlswritten_total);
+ DEBUGF(LOG_CF(data, cf, "cr_send: EAGAIN after %zu bytes",
+ tlswritten_total));
*err = CURLE_AGAIN;
return -1;
}
@@ -299,7 +311,7 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
*err = CURLE_WRITE_ERROR;
return -1;
}
- infof(data, CFMSG(cf, "cr_send: wrote %ld TLS bytes"), tlswritten);
+ DEBUGF(LOG_CF(data, cf, "cr_send: wrote %zu TLS bytes", tlswritten));
tlswritten_total += tlswritten;
}
@@ -349,22 +361,25 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
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);
@@ -384,7 +399,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
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));
@@ -394,7 +409,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
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;
@@ -404,7 +419,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
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;
@@ -416,7 +431,7 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
{
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);
@@ -439,29 +454,7 @@ cr_set_negotiated_alpn(struct Curl_cfilter *cf, struct Curl_easy *data,
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);
- cf->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);
- cf->conn->alpn = CURL_HTTP_VERSION_1_1;
- }
- else {
- infof(data, "ALPN, negotiated an unrecognized protocol");
- }
-
- Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
- BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+ Curl_alpn_set_negotiated(cf, data, protocol, len);
}
static CURLcode
@@ -469,7 +462,7 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
struct Curl_easy *data, bool *done)
{
struct ssl_connect_data *const connssl = cf->ctx;
- curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
+ curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
@@ -573,7 +566,7 @@ cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
curl_socket_t *socks)
{
struct ssl_connect_data *const connssl = cf->ctx;
- curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
+ curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = NULL;
@@ -616,7 +609,7 @@ cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
rustls_connection_send_close_notify(backend->conn);
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);