From 38a4072d76e8dd733f8865d23aa8e10b1844724c Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Thu, 6 Jun 2024 13:43:29 +0000 Subject: [PATCH] Merge of /httpd/httpd/trunk:r1917270 * mod_tls: update version of rustls-ffi to v0.13.0. [Daniel McCarney (@cpu}] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1918194 13f79535-47bb-0310-9956-ffa450edef68 --- .github/workflows/linux.yml | 2 +- changes-entries/mod_tls_v0.9.0.txt | 2 + modules/tls/tls_cert.c | 91 ++++++++++++++++----------- modules/tls/tls_cert.h | 8 +-- modules/tls/tls_core.c | 14 +++-- modules/tls/tls_version.h | 4 +- test/modules/tls/test_08_vars.py | 2 +- test/modules/tls/test_14_proxy_ssl.py | 2 +- 8 files changed, 76 insertions(+), 49 deletions(-) create mode 100644 changes-entries/mod_tls_v0.9.0.txt diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ddacd4af193..ff5f5ec269f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -215,7 +215,7 @@ jobs: APR_VERSION=1.7.4 APU_VERSION=1.6.3 APU_CONFIG="--with-crypto" - RUSTLS_VERSION="v0.10.0" + RUSTLS_VERSION="v0.13.0" NO_TEST_FRAMEWORK=1 TEST_INSTALL=1 TEST_MOD_TLS=1 diff --git a/changes-entries/mod_tls_v0.9.0.txt b/changes-entries/mod_tls_v0.9.0.txt new file mode 100644 index 00000000000..b57bf0b7c4d --- /dev/null +++ b/changes-entries/mod_tls_v0.9.0.txt @@ -0,0 +1,2 @@ + * mod_tls: update version of rustls-ffi to v0.13.0. + [Daniel McCarney (@cpu}] diff --git a/modules/tls/tls_cert.c b/modules/tls/tls_cert.c index 624535aa444..ffb941cae40 100644 --- a/modules/tls/tls_cert.c +++ b/modules/tls/tls_cert.c @@ -331,11 +331,12 @@ const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key } apr_status_t tls_cert_load_root_store( - apr_pool_t *p, const char *store_file, rustls_root_cert_store **pstore) + apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore) { const char *fpath; tls_data_t pem; - rustls_root_cert_store *store = NULL; + rustls_root_cert_store_builder *store_builder = NULL; + const rustls_root_cert_store *store = NULL; rustls_result rr = RUSTLS_RESULT_OK; apr_pool_t *ptemp = NULL; apr_status_t rv; @@ -353,11 +354,17 @@ apr_status_t tls_cert_load_root_store( rv = tls_util_file_load(ptemp, fpath, 0, 1024*1024, &pem); if (APR_SUCCESS != rv) goto cleanup; - store = rustls_root_cert_store_new(); - rr = rustls_root_cert_store_add_pem(store, pem.data, pem.len, 1); + store_builder = rustls_root_cert_store_builder_new(); + rr = rustls_root_cert_store_builder_add_pem(store_builder, pem.data, pem.len, 1); + if (RUSTLS_RESULT_OK != rr) goto cleanup; + + rr = rustls_root_cert_store_builder_build(store_builder, &store); if (RUSTLS_RESULT_OK != rr) goto cleanup; cleanup: + if (store_builder != NULL) { + rustls_root_cert_store_builder_free(store_builder); + } if (RUSTLS_RESULT_OK != rr) { const char *err_descr; rv = tls_util_rustls_error(p, rr, &err_descr); @@ -378,7 +385,7 @@ cleanup: typedef struct { const char *id; - rustls_root_cert_store *store; + const rustls_root_cert_store *store; } tls_cert_root_stores_entry_t; static int stores_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val) @@ -421,14 +428,14 @@ void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores) apr_status_t tls_cert_root_stores_get( tls_cert_root_stores_t *stores, const char *store_file, - rustls_root_cert_store **pstore) + const rustls_root_cert_store **pstore) { apr_status_t rv = APR_SUCCESS; tls_cert_root_stores_entry_t *entry; entry = apr_hash_get(stores->file2store, store_file, APR_HASH_KEY_STRING); if (!entry) { - rustls_root_cert_store *store; + const rustls_root_cert_store *store; rv = tls_cert_load_root_store(stores->pool, store_file, &store); if (APR_SUCCESS != rv) goto cleanup; entry = apr_pcalloc(stores->pool, sizeof(*entry)); @@ -449,8 +456,8 @@ cleanup: typedef struct { const char *id; - const rustls_client_cert_verifier *client_verifier; - const rustls_client_cert_verifier_optional *client_verifier_opt; + rustls_client_cert_verifier *client_verifier; + rustls_client_cert_verifier *client_verifier_opt; } tls_cert_verifiers_entry_t; static int verifiers_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val) @@ -462,7 +469,7 @@ static int verifiers_entry_cleanup(void *ctx, const void *key, apr_ssize_t klen, entry->client_verifier = NULL; } if (entry->client_verifier_opt) { - rustls_client_cert_verifier_optional_free(entry->client_verifier_opt); + rustls_client_cert_verifier_free(entry->client_verifier_opt); entry->client_verifier_opt = NULL; } return 1; @@ -511,23 +518,44 @@ static tls_cert_verifiers_entry_t * verifiers_get_or_make_entry( return entry; } -apr_status_t tls_cert_client_verifiers_get( - tls_cert_verifiers_t *verifiers, - const char *store_file, - const rustls_client_cert_verifier **pverifier) +static apr_status_t tls_cert_client_verifiers_get_internal( + tls_cert_verifiers_t *verifiers, + const char *store_file, + const rustls_client_cert_verifier **pverifier, + bool allow_unauthenticated) { apr_status_t rv = APR_SUCCESS; tls_cert_verifiers_entry_t *entry; + rustls_result rr = RUSTLS_RESULT_OK; + struct rustls_web_pki_client_cert_verifier_builder *verifier_builder = NULL; entry = verifiers_get_or_make_entry(verifiers, store_file); if (!entry->client_verifier) { - rustls_root_cert_store *store; + const rustls_root_cert_store *store; rv = tls_cert_root_stores_get(verifiers->stores, store_file, &store); if (APR_SUCCESS != rv) goto cleanup; - entry->client_verifier = rustls_client_cert_verifier_new(store); + verifier_builder = rustls_web_pki_client_cert_verifier_builder_new(store); + + if (allow_unauthenticated) { + rr = rustls_web_pki_client_cert_verifier_builder_allow_unauthenticated(verifier_builder); + if (rr != RUSTLS_RESULT_OK) { + goto cleanup; + } + } + + rr = rustls_web_pki_client_cert_verifier_builder_build(verifier_builder, &entry->client_verifier); + if (rr != RUSTLS_RESULT_OK) { + goto cleanup; + } } cleanup: + if (verifier_builder != NULL) { + rustls_web_pki_client_cert_verifier_builder_free(verifier_builder); + } + if (rr != RUSTLS_RESULT_OK) { + rv = tls_util_rustls_error(verifiers->pool, rr, NULL); + } if (APR_SUCCESS == rv) { *pverifier = entry->client_verifier; } @@ -537,28 +565,19 @@ cleanup: return rv; } -apr_status_t tls_cert_client_verifiers_get_optional( + +apr_status_t tls_cert_client_verifiers_get( tls_cert_verifiers_t *verifiers, const char *store_file, - const rustls_client_cert_verifier_optional **pverifier) + const rustls_client_cert_verifier **pverifier) { - apr_status_t rv = APR_SUCCESS; - tls_cert_verifiers_entry_t *entry; - - entry = verifiers_get_or_make_entry(verifiers, store_file); - if (!entry->client_verifier_opt) { - rustls_root_cert_store *store; - rv = tls_cert_root_stores_get(verifiers->stores, store_file, &store); - if (APR_SUCCESS != rv) goto cleanup; - entry->client_verifier_opt = rustls_client_cert_verifier_optional_new(store); - } + return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, false); +} -cleanup: - if (APR_SUCCESS == rv) { - *pverifier = entry->client_verifier_opt; - } - else { - *pverifier = NULL; - } - return rv; +apr_status_t tls_cert_client_verifiers_get_optional( + tls_cert_verifiers_t *verifiers, + const char *store_file, + const rustls_client_cert_verifier **pverifier) +{ + return tls_cert_client_verifiers_get_internal(verifiers, store_file, pverifier, true); } diff --git a/modules/tls/tls_cert.h b/modules/tls/tls_cert.h index 6ab3f48ae13..3326f0eb3e7 100644 --- a/modules/tls/tls_cert.h +++ b/modules/tls/tls_cert.h @@ -128,7 +128,7 @@ const char *tls_cert_reg_get_id(tls_cert_reg_t *reg, const rustls_certified_key * @param pstore the loaded root store on success */ apr_status_t tls_cert_load_root_store( - apr_pool_t *p, const char *store_file, rustls_root_cert_store **pstore); + apr_pool_t *p, const char *store_file, const rustls_root_cert_store **pstore); typedef struct tls_cert_root_stores_t tls_cert_root_stores_t; struct tls_cert_root_stores_t { @@ -157,7 +157,7 @@ void tls_cert_root_stores_clear(tls_cert_root_stores_t *stores); apr_status_t tls_cert_root_stores_get( tls_cert_root_stores_t *stores, const char *store_file, - rustls_root_cert_store **pstore); + const rustls_root_cert_store **pstore); typedef struct tls_cert_verifiers_t tls_cert_verifiers_t; struct tls_cert_verifiers_t { @@ -206,6 +206,6 @@ apr_status_t tls_cert_client_verifiers_get( apr_status_t tls_cert_client_verifiers_get_optional( tls_cert_verifiers_t *verifiers, const char *store_file, - const rustls_client_cert_verifier_optional **pverifier); + const rustls_client_cert_verifier **pverifier); -#endif /* tls_cert_h */ \ No newline at end of file +#endif /* tls_cert_h */ diff --git a/modules/tls/tls_core.c b/modules/tls/tls_core.c index 25479392f1a..1cef254f103 100644 --- a/modules/tls/tls_core.c +++ b/modules/tls/tls_core.c @@ -764,8 +764,10 @@ static apr_status_t init_outgoing_connection(conn_rec *c) tls_conf_proxy_t *pc; const apr_array_header_t *ciphersuites = NULL; apr_array_header_t *tls_versions = NULL; + rustls_web_pki_server_cert_verifier_builder *verifier_builder = NULL; + struct rustls_server_cert_verifier *verifier = NULL; rustls_client_config_builder *builder = NULL; - rustls_root_cert_store *ca_store = NULL; + const rustls_root_cert_store *ca_store = NULL; const char *hostname = NULL, *alpn_note = NULL; rustls_result rr = RUSTLS_RESULT_OK; apr_status_t rv = APR_SUCCESS; @@ -809,7 +811,10 @@ static apr_status_t init_outgoing_connection(conn_rec *c) if (pc->proxy_ca && strcasecmp(pc->proxy_ca, "default")) { rv = tls_cert_root_stores_get(pc->global->stores, pc->proxy_ca, &ca_store); if (APR_SUCCESS != rv) goto cleanup; - rustls_client_config_builder_use_roots(builder, ca_store); + verifier_builder = rustls_web_pki_server_cert_verifier_builder_new(ca_store); + rr = rustls_web_pki_server_cert_verifier_builder_build(verifier_builder, &verifier); + if (RUSTLS_RESULT_OK != rr) goto cleanup; + rustls_client_config_builder_set_server_verifier(builder, verifier); } #if TLS_MACHINE_CERTS @@ -881,6 +886,7 @@ static apr_status_t init_outgoing_connection(conn_rec *c) rustls_connection_set_userdata(cc->rustls_connection, c); cleanup: + if (verifier_builder != NULL) rustls_web_pki_server_cert_verifier_builder_free(verifier_builder); if (builder != NULL) rustls_client_config_builder_free(builder); if (RUSTLS_RESULT_OK != rr) { const char *err_descr = NULL; @@ -1125,10 +1131,10 @@ static apr_status_t build_server_connection(rustls_connection **pconnection, rustls_server_config_builder_set_client_verifier(builder, verifier); } else { - const rustls_client_cert_verifier_optional *verifier; + const rustls_client_cert_verifier *verifier; rv = tls_cert_client_verifiers_get_optional(sc->global->verifiers, sc->client_ca, &verifier); if (APR_SUCCESS != rv) goto cleanup; - rustls_server_config_builder_set_client_verifier_optional(builder, verifier); + rustls_server_config_builder_set_client_verifier(builder, verifier); } } diff --git a/modules/tls/tls_version.h b/modules/tls/tls_version.h index 811d6f11ef5..bc9fb0bbb78 100644 --- a/modules/tls/tls_version.h +++ b/modules/tls/tls_version.h @@ -26,7 +26,7 @@ * @macro * Version number of the md module as c string */ -#define MOD_TLS_VERSION "0.8.3" +#define MOD_TLS_VERSION "0.9.0" /** * @macro @@ -34,6 +34,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define MOD_TLS_VERSION_NUM 0x000802 +#define MOD_TLS_VERSION_NUM 0x000900 #endif /* mod_md_md_version_h */ diff --git a/test/modules/tls/test_08_vars.py b/test/modules/tls/test_08_vars.py index f1bd9b418a2..a8df99af2aa 100644 --- a/test/modules/tls/test_08_vars.py +++ b/test/modules/tls/test_08_vars.py @@ -51,7 +51,7 @@ class TestVars: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_08_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/vars.py?name={name}") diff --git a/test/modules/tls/test_14_proxy_ssl.py b/test/modules/tls/test_14_proxy_ssl.py index 79b2fb4b041..cefcbf60011 100644 --- a/test/modules/tls/test_14_proxy_ssl.py +++ b/test/modules/tls/test_14_proxy_ssl.py @@ -69,7 +69,7 @@ class TestProxySSL: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}") -- 2.47.2