* Copyright (C) Jacob Hoffman-Andrews,
* <github@hoffman-andrews.com>
* Copyright (C) kpcyrd, <kpcyrd@archlinux.org>
+ * Copyright (C) Daniel McCarney, <daniel@binaryparadox.net>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "vtls.h"
#include "vtls_int.h"
#include "rustls.h"
-#include "select.h"
#include "strerror.h"
-#include "multiif.h"
-#include "connect.h" /* for the connect timeout */
#include "cipher_suite.h"
-#include "rand.h"
#include "x509asn1.h"
struct rustls_ssl_backend_data
};
/* For a given rustls_result error code, return the best-matching CURLcode. */
-static CURLcode map_error(rustls_result r)
+static CURLcode map_error(const rustls_result r)
{
if(rustls_result_is_cert_error(r)) {
return CURLE_PEER_FAILED_VERIFICATION;
}
}
+static void
+rustls_failf(struct Curl_easy *data, const rustls_result rr, const char *msg)
+{
+ char errorbuf[STRERROR_LEN];
+ size_t errorlen;
+ rustls_error(rr, errorbuf, sizeof(errorbuf), &errorlen);
+ failf(data, "%s: %.*s", msg, (int)errorlen, errorbuf);
+}
+
static bool
cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
{
- struct ssl_connect_data *ctx = cf->ctx;
+ const struct ssl_connect_data *ctx = cf->ctx;
struct rustls_ssl_backend_data *backend;
(void)data;
static int
read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n)
{
- struct io_ctx *io_ctx = userdata;
+ const struct io_ctx *io_ctx = userdata;
struct ssl_connect_data *const connssl = io_ctx->cf->ctx;
CURLcode result;
int ret = 0;
static int
write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n)
{
- struct io_ctx *io_ctx = userdata;
+ const 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,
static ssize_t tls_recv_more(struct Curl_cfilter *cf,
struct Curl_easy *data, CURLcode *err)
{
- struct ssl_connect_data *const connssl = cf->ctx;
+ const 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;
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",
- (int)errorlen, errorbuf);
+ rustls_failf(data, rresult, "rustls_connection_process_new_packets");
*err = map_error(rresult);
return -1;
}
cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *plainbuf, size_t plainlen, CURLcode *err)
{
- struct ssl_connect_data *const connssl = cf->ctx;
+ const 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;
}
else if(rresult != RUSTLS_RESULT_OK) {
/* n always equals 0 in this case, do not need to check it */
- char errorbuf[255];
- size_t errorlen;
- rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen);
- failf(data, "rustls_connection_read: %.*s", (int)errorlen, errorbuf);
+ rustls_failf(data, rresult, "rustls_connection_read");
*err = CURLE_RECV_ERROR;
nread = -1;
goto out;
rustls_io_result io_error;
size_t tlswritten = 0;
size_t tlswritten_total = 0;
- CURLcode result = CURLE_OK;
io_ctx.cf = cf;
io_ctx.data = data;
CURL_TRC_CF(data, cf, "cf_send: wrote %zu TLS bytes", tlswritten);
tlswritten_total += tlswritten;
}
- return result;
+ return CURLE_OK;
}
/*
cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *plainbuf, size_t plainlen, CURLcode *err)
{
- struct ssl_connect_data *const connssl = cf->ctx;
+ const 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 plainwritten = 0;
- rustls_result rresult;
- char errorbuf[256];
- size_t errorlen;
const unsigned char *buf = plainbuf;
size_t blen = plainlen;
ssize_t nwritten = 0;
}
if(blen > 0) {
+ rustls_result rresult;
CURL_TRC_CF(data, cf, "cf_send: adding %zu plain bytes to Rustls", blen);
rresult = rustls_connection_write(rconn, buf, blen, &plainwritten);
if(rresult != RUSTLS_RESULT_OK) {
- rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen);
- failf(data, "rustls_connection_write: %.*s", (int)errorlen, errorbuf);
+ rustls_failf(data, rresult, "rustls_connection_write");
*err = CURLE_WRITE_ERROR;
return -1;
}
while(!feof(f)) {
uint8_t buf[256];
- size_t rr = fread(buf, 1, sizeof(buf), f);
+ const size_t rr = fread(buf, 1, sizeof(buf), f);
if(rr == 0 ||
CURLE_OK != Curl_dyn_addn(out, buf, rr)) {
fclose(f);
const struct rustls_supported_ciphersuite **selected,
size_t *selected_size)
{
- size_t supported_len = *selected_size;
- size_t default_len = rustls_default_crypto_provider_ciphersuites_len();
+ const size_t supported_len = *selected_size;
+ const size_t default_len = rustls_default_crypto_provider_ciphersuites_len();
const struct rustls_supported_ciphersuite *entry;
const char *ciphers = ciphers12;
size_t count = 0, default13_count = 0, i, j;
}
static CURLcode
-cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
- struct rustls_ssl_backend_data *const backend)
+init_config_builder(struct Curl_easy *data,
+ const struct ssl_primary_config *conn_config,
+ struct rustls_client_config_builder **config_builder)
{
- struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ const struct rustls_supported_ciphersuite **cipher_suites = NULL;
struct rustls_crypto_provider_builder *custom_provider_builder = NULL;
const struct rustls_crypto_provider *custom_provider = NULL;
- struct rustls_connection *rconn = NULL;
- struct rustls_client_config_builder *config_builder = NULL;
- const struct rustls_root_cert_store *roots = NULL;
- struct rustls_root_cert_store_builder *roots_builder = NULL;
- struct rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL;
- struct rustls_server_cert_verifier *server_cert_verifier = NULL;
- 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 : conn_config->CAfile);
- const bool verifypeer = conn_config->verifypeer;
- char errorbuf[256];
- size_t errorlen;
- rustls_result result;
- DEBUGASSERT(backend);
- rconn = backend->conn;
+ uint16_t tls_versions[2] = {
+ RUSTLS_TLS_VERSION_TLSV1_2,
+ RUSTLS_TLS_VERSION_TLSV1_3,
+ };
+ size_t tls_versions_len = 2;
+ size_t cipher_suites_len =
+ rustls_default_crypto_provider_ciphersuites_len();
- {
- uint16_t tls_versions[2] = {
- RUSTLS_TLS_VERSION_TLSV1_2,
- RUSTLS_TLS_VERSION_TLSV1_3,
- };
- size_t tls_versions_len = 2;
- const struct rustls_supported_ciphersuite **cipher_suites;
- size_t cipher_suites_len =
- rustls_default_crypto_provider_ciphersuites_len();
-
- switch(conn_config->version) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- case CURL_SSLVERSION_TLSv1_0:
- case CURL_SSLVERSION_TLSv1_1:
- case CURL_SSLVERSION_TLSv1_2:
- break;
- case CURL_SSLVERSION_TLSv1_3:
- tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3;
+ CURLcode result = CURLE_OK;
+ rustls_result rr;
+
+ switch(conn_config->version) {
+ case CURL_SSLVERSION_DEFAULT:
+ case CURL_SSLVERSION_TLSv1:
+ case CURL_SSLVERSION_TLSv1_0:
+ case CURL_SSLVERSION_TLSv1_1:
+ case CURL_SSLVERSION_TLSv1_2:
+ break;
+ case CURL_SSLVERSION_TLSv1_3:
+ tls_versions[0] = RUSTLS_TLS_VERSION_TLSV1_3;
+ tls_versions_len = 1;
+ break;
+ default:
+ failf(data, "rustls: unsupported minimum TLS version value");
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ goto cleanup;
+ }
+
+ switch(conn_config->version_max) {
+ case CURL_SSLVERSION_MAX_DEFAULT:
+ case CURL_SSLVERSION_MAX_NONE:
+ case CURL_SSLVERSION_MAX_TLSv1_3:
+ break;
+ case CURL_SSLVERSION_MAX_TLSv1_2:
+ if(tls_versions[0] == RUSTLS_TLS_VERSION_TLSV1_2) {
tls_versions_len = 1;
break;
- default:
- failf(data, "rustls: unsupported minimum TLS version value");
- return CURLE_BAD_FUNCTION_ARGUMENT;
}
+ FALLTHROUGH();
+ case CURL_SSLVERSION_MAX_TLSv1_1:
+ case CURL_SSLVERSION_MAX_TLSv1_0:
+ default:
+ failf(data, "rustls: unsupported maximum TLS version value");
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ goto cleanup;
+ }
- switch(conn_config->version_max) {
- case CURL_SSLVERSION_MAX_DEFAULT:
- case CURL_SSLVERSION_MAX_NONE:
- case CURL_SSLVERSION_MAX_TLSv1_3:
- break;
- case CURL_SSLVERSION_MAX_TLSv1_2:
- if(tls_versions[0] == RUSTLS_TLS_VERSION_TLSV1_2) {
- tls_versions_len = 1;
- break;
- }
- FALLTHROUGH();
- case CURL_SSLVERSION_MAX_TLSv1_1:
- case CURL_SSLVERSION_MAX_TLSv1_0:
- default:
- failf(data, "rustls: unsupported maximum TLS version value");
- return CURLE_BAD_FUNCTION_ARGUMENT;
- }
+ cipher_suites = malloc(sizeof(cipher_suites) * (cipher_suites_len));
+ if(!cipher_suites) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto cleanup;
+ }
- cipher_suites = malloc(sizeof(cipher_suites) * (cipher_suites_len));
- if(!cipher_suites)
- return CURLE_OUT_OF_MEMORY;
-
- cr_get_selected_ciphers(data,
- conn_config->cipher_list,
- conn_config->cipher_list13,
- cipher_suites, &cipher_suites_len);
- if(cipher_suites_len == 0) {
- failf(data, "rustls: no supported cipher in list");
- free(cipher_suites);
- return CURLE_SSL_CIPHER;
- }
+ cr_get_selected_ciphers(data,
+ conn_config->cipher_list,
+ conn_config->cipher_list13,
+ cipher_suites, &cipher_suites_len);
+ if(cipher_suites_len == 0) {
+ failf(data, "rustls: no supported cipher in list");
+ result = CURLE_SSL_CIPHER;
+ goto cleanup;
+ }
- result = rustls_crypto_provider_builder_new_from_default(
- &custom_provider_builder);
- if(result != RUSTLS_RESULT_OK) {
- failf(data,
- "rustls: failed to create crypto provider builder from default");
- return CURLE_SSL_CIPHER;
- }
+ rr = rustls_crypto_provider_builder_new_from_default(
+ &custom_provider_builder);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr,
+ "failed to create crypto provider builder from default");
+ result = CURLE_SSL_CIPHER;
+ goto cleanup;
+ }
- result =
- rustls_crypto_provider_builder_set_cipher_suites(
- custom_provider_builder,
- cipher_suites,
- cipher_suites_len);
- if(result != RUSTLS_RESULT_OK) {
- failf(data,
- "rustls: failed to set ciphersuites for crypto provider builder");
- rustls_crypto_provider_builder_free(custom_provider_builder);
- return CURLE_SSL_CIPHER;
- }
+ rr =
+ rustls_crypto_provider_builder_set_cipher_suites(
+ custom_provider_builder,
+ cipher_suites,
+ cipher_suites_len);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr,
+ "failed to set ciphersuites for crypto provider builder");
+ result = CURLE_SSL_CIPHER;
+ goto cleanup;
+ }
- result = rustls_crypto_provider_builder_build(
- custom_provider_builder, &custom_provider);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to build custom crypto provider");
- rustls_crypto_provider_builder_free(custom_provider_builder);
- return CURLE_SSL_CIPHER;
- }
+ rr = rustls_crypto_provider_builder_build(
+ custom_provider_builder, &custom_provider);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to build custom crypto provider");
+ result = CURLE_SSL_CIPHER;
+ goto cleanup;
+ }
- result = rustls_client_config_builder_new_custom(custom_provider,
+ rr = rustls_client_config_builder_new_custom(custom_provider,
tls_versions,
tls_versions_len,
- &config_builder);
+ config_builder);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to create client config builder");
+ result = CURLE_SSL_CIPHER;
+ goto cleanup;
+ }
+
+cleanup:
+ if(cipher_suites) {
free(cipher_suites);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to create client config");
- return CURLE_SSL_CIPHER;
- }
}
+ if(custom_provider_builder) {
+ rustls_crypto_provider_builder_free(custom_provider_builder);
+ }
+ if(custom_provider) {
+ rustls_crypto_provider_free(custom_provider);
+ }
+ return result;
+}
- rustls_crypto_provider_builder_free(custom_provider_builder);
- rustls_crypto_provider_free(custom_provider);
+static void
+init_config_builder_alpn(struct Curl_easy *data,
+ const struct ssl_connect_data *connssl,
+ struct rustls_client_config_builder *config_builder) {
+ struct alpn_proto_buf proto;
+ rustls_slice_bytes alpn[ALPN_ENTRIES_MAX];
+ size_t i;
- 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);
+}
- 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);
+static CURLcode
+init_config_builder_verifier_crl(
+ struct Curl_easy *data,
+ const struct ssl_primary_config *conn_config,
+ struct rustls_web_pki_server_cert_verifier_builder *builder)
+{
+ CURLcode result = CURLE_OK;
+ struct dynbuf crl_contents;
+ rustls_result rr;
+
+ Curl_dyn_init(&crl_contents, DYN_CRLFILE_SIZE);
+ if(!read_file_into(conn_config->CRLfile, &crl_contents)) {
+ failf(data, "rustls: failed to read revocation list file");
+ result = CURLE_SSL_CRL_BADFILE;
+ goto cleanup;
}
- if(!verifypeer) {
- rustls_client_config_builder_dangerous_set_certificate_verifier(
- config_builder, cr_verify_none);
+
+ rr = rustls_web_pki_server_cert_verifier_builder_add_crl(
+ builder,
+ Curl_dyn_uptr(&crl_contents),
+ Curl_dyn_len(&crl_contents));
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to parse revocation list");
+ result = CURLE_SSL_CRL_BADFILE;
+ goto cleanup;
}
- else if(ca_info_blob || ssl_cafile) {
- roots_builder = rustls_root_cert_store_builder_new();
-
- if(ca_info_blob) {
- /* Enable strict parsing only if verification is not disabled. */
- result = rustls_root_cert_store_builder_add_pem(roots_builder,
- ca_info_blob->data,
- ca_info_blob->len,
- verifypeer);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to parse trusted certificates from blob");
- rustls_root_cert_store_builder_free(roots_builder);
- rustls_client_config_builder_free(config_builder);
- return CURLE_SSL_CACERT_BADFILE;
- }
+
+cleanup:
+ Curl_dyn_free(&crl_contents);
+ return result;
+}
+
+static CURLcode
+init_config_builder_verifier(struct Curl_easy *data,
+ struct rustls_client_config_builder *builder,
+ const struct ssl_primary_config *conn_config,
+ const struct curl_blob *ca_info_blob,
+ const char * const ssl_cafile) {
+ const struct rustls_root_cert_store *roots = NULL;
+ struct rustls_root_cert_store_builder *roots_builder = NULL;
+ struct rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL;
+ struct rustls_server_cert_verifier *server_cert_verifier = NULL;
+ rustls_result rr = RUSTLS_RESULT_OK;
+ CURLcode result = CURLE_OK;
+
+ roots_builder = rustls_root_cert_store_builder_new();
+ if(ca_info_blob) {
+ rr = rustls_root_cert_store_builder_add_pem(roots_builder,
+ ca_info_blob->data,
+ ca_info_blob->len,
+ 1);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to parse trusted certificates from blob");
+
+ result = CURLE_SSL_CACERT_BADFILE;
+ goto cleanup;
}
- else if(ssl_cafile) {
- /* Enable strict parsing only if verification is not disabled. */
- result = rustls_root_cert_store_builder_load_roots_from_file(
- roots_builder, ssl_cafile, verifypeer);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to load trusted certificates");
- rustls_root_cert_store_builder_free(roots_builder);
- rustls_client_config_builder_free(config_builder);
- return CURLE_SSL_CACERT_BADFILE;
- }
+ }
+ else if(ssl_cafile) {
+ rr = rustls_root_cert_store_builder_load_roots_from_file(roots_builder,
+ ssl_cafile,
+ 1);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to load trusted certificates");
+
+ result = CURLE_SSL_CACERT_BADFILE;
+ goto cleanup;
}
+ }
- result = rustls_root_cert_store_builder_build(roots_builder, &roots);
- rustls_root_cert_store_builder_free(roots_builder);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to build trusted root certificate store");
- rustls_client_config_builder_free(config_builder);
- return CURLE_SSL_CACERT_BADFILE;
+ rr = rustls_root_cert_store_builder_build(roots_builder, &roots);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to build trusted root certificate store");
+ result = CURLE_SSL_CACERT_BADFILE;
+ }
+
+ verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots);
+
+ if(conn_config->CRLfile) {
+ result = init_config_builder_verifier_crl(data,
+ conn_config,
+ verifier_builder);
+ if(result != CURLE_OK) {
+ goto cleanup;
}
+ }
+
+ rr = rustls_web_pki_server_cert_verifier_builder_build(
+ verifier_builder, &server_cert_verifier);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to build certificate verifier");
+ result = CURLE_SSL_CACERT_BADFILE;
+ goto cleanup;
+ }
- verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(roots);
+ rustls_client_config_builder_set_server_verifier(builder,
+ server_cert_verifier);
+cleanup:
+ if(roots_builder) {
+ rustls_root_cert_store_builder_free(roots_builder);
+ }
+ if(roots) {
rustls_root_cert_store_free(roots);
+ }
+ if(verifier_builder) {
+ rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
+ }
+ if(server_cert_verifier) {
+ rustls_server_cert_verifier_free(server_cert_verifier);
+ }
- if(conn_config->CRLfile) {
- struct dynbuf crl_contents;
- Curl_dyn_init(&crl_contents, DYN_CRLFILE_SIZE);
- if(!read_file_into(conn_config->CRLfile, &crl_contents)) {
- failf(data, "rustls: failed to read revocation list file");
- Curl_dyn_free(&crl_contents);
- rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
- return CURLE_SSL_CRL_BADFILE;
- }
+ return result;
+}
- result = rustls_web_pki_server_cert_verifier_builder_add_crl(
- verifier_builder,
- Curl_dyn_uptr(&crl_contents),
- Curl_dyn_len(&crl_contents));
- Curl_dyn_free(&crl_contents);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to parse revocation list");
- rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
- return CURLE_SSL_CRL_BADFILE;
- }
- }
+static CURLcode
+cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
+ struct rustls_ssl_backend_data *const backend)
+{
+ const struct ssl_connect_data *connssl = cf->ctx;
+ const 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;
- result = rustls_web_pki_server_cert_verifier_builder_build(
- verifier_builder, &server_cert_verifier);
- rustls_web_pki_server_cert_verifier_builder_free(verifier_builder);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to build certificate verifier");
- rustls_server_cert_verifier_free(server_cert_verifier);
+ 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 : conn_config->CAfile);
+ CURLcode result = CURLE_OK;
+ rustls_result rr;
+
+ DEBUGASSERT(backend);
+ rconn = backend->conn;
+
+ result = init_config_builder(data, conn_config, &config_builder);
+ if(result != CURLE_OK) {
+ return result;
+ }
+
+ if(connssl->alpn) {
+ init_config_builder_alpn(data, connssl, config_builder);
+ }
+
+ if(!conn_config->verifypeer) {
+ rustls_client_config_builder_dangerous_set_certificate_verifier(
+ config_builder, cr_verify_none);
+ }
+ else if(ca_info_blob || ssl_cafile) {
+ result = init_config_builder_verifier(data,
+ config_builder,
+ conn_config,
+ ca_info_blob,
+ ssl_cafile);
+ if(result != CURLE_OK) {
rustls_client_config_builder_free(config_builder);
- return CURLE_SSL_CACERT_BADFILE;
+ return result;
}
-
- rustls_client_config_builder_set_server_verifier(config_builder,
- server_cert_verifier);
- rustls_server_cert_verifier_free(server_cert_verifier);
}
- result = rustls_client_config_builder_build(
+ rr = rustls_client_config_builder_build(
config_builder,
&backend->config);
- if(result != RUSTLS_RESULT_OK) {
- failf(data, "rustls: failed to build client config");
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, rr, "failed to build client config");
+ rustls_client_config_builder_free(config_builder);
rustls_client_config_free(backend->config);
return CURLE_SSL_CONNECT_ERROR;
}
DEBUGASSERT(rconn == NULL);
- result = rustls_client_connection_new(backend->config,
- connssl->peer.hostname, &rconn);
- if(result != RUSTLS_RESULT_OK) {
- rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen);
- failf(data, "rustls_client_connection_new: %.*s", (int)errorlen, errorbuf);
+ rr = rustls_client_connection_new(backend->config,
+ connssl->peer.hostname,
+ &rconn);
+ if(rr != RUSTLS_RESULT_OK) {
+ rustls_failf(data, result, "rustls_client_connection_new");
return CURLE_COULDNT_CONNECT;
}
DEBUGASSERT(rconn);
rustls_connection_set_userdata(rconn, backend);
backend->conn = rconn;
- return CURLE_OK;
+
+ return result;
}
static void
struct Curl_easy *data, bool *done)
{
struct ssl_connect_data *const connssl = cf->ctx;
- struct rustls_ssl_backend_data *const backend =
+ const struct rustls_ssl_backend_data *const backend =
(struct rustls_ssl_backend_data *)connssl->backend;
- struct rustls_connection *rconn = NULL;
+ const struct rustls_connection *rconn = NULL;
CURLcode tmperr = CURLE_OK;
int result;
bool wants_read;
}
/* REALLY Done with the handshake. */
{
- uint16_t proto = rustls_connection_get_protocol_version(rconn);
- uint16_t cipher = rustls_connection_get_negotiated_ciphersuite(rconn);
+ const uint16_t proto =
+ rustls_connection_get_protocol_version(rconn);
+ const uint16_t cipher =
+ rustls_connection_get_negotiated_ciphersuite(rconn);
char buf[64] = "";
const char *ver = "TLS version unknown";
if(proto == RUSTLS_TLS_VERSION_TLSV1_3)
static CURLcode
cr_shutdown(struct Curl_cfilter *cf,
struct Curl_easy *data,
- bool send_shutdown, bool *done)
+ const bool send_shutdown, bool *done)
{
struct ssl_connect_data *connssl = cf->ctx;
struct rustls_ssl_backend_data *backend =
(struct rustls_ssl_backend_data *)connssl->backend;
CURLcode result = CURLE_OK;
ssize_t nwritten, nread;
- char buf[1024];
size_t i;
DEBUGASSERT(backend);
}
for(i = 0; i < 10; ++i) {
+ char buf[1024];
nread = cr_recv(cf, data, buf, (int)sizeof(buf), &result);
if(nread <= 0)
break;
static void
cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = cf->ctx;
+ const struct ssl_connect_data *connssl = cf->ctx;
struct rustls_ssl_backend_data *backend =
(struct rustls_ssl_backend_data *)connssl->backend;
static size_t cr_version(char *buffer, size_t size)
{
- struct rustls_str ver = rustls_version();
+ const struct rustls_str ver = rustls_version();
return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data);
}