diff --git a/.gitignore b/.gitignore index 7d5abd7..df2c92a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ SOURCES/gmp-6.2.1.tar.xz -SOURCES/gnutls-3.8.3.tar.xz -SOURCES/gnutls-3.8.3.tar.xz.sig +SOURCES/gnutls-3.8.10.tar.xz +SOURCES/gnutls-3.8.10.tar.xz.sig +SOURCES/leancrypto-1.5.0.tar.gz diff --git a/.gnutls.metadata b/.gnutls.metadata index ac90e14..711b0ac 100644 --- a/.gnutls.metadata +++ b/.gnutls.metadata @@ -1,3 +1,4 @@ 0578d48607ec0e272177d175fd1807c30b00fdf2 SOURCES/gmp-6.2.1.tar.xz -806156ac9563caab642d6274496b9cc5b2117612 SOURCES/gnutls-3.8.3.tar.xz -dd7822b360953108a86dc3dbc7d07214563cc678 SOURCES/gnutls-3.8.3.tar.xz.sig +cdd236faa328ac3ad9c80a1c745461a75dcbc41b SOURCES/gnutls-3.8.10.tar.xz +adfe4a10d0a148ac7bd4b183d2d33ce23c428901 SOURCES/gnutls-3.8.10.tar.xz.sig +749aad01194f16924737d354711a9978471bdad8 SOURCES/leancrypto-1.5.0.tar.gz diff --git a/SOURCES/gnutls-3.7.3-fips-dsa-post.patch b/SOURCES/gnutls-3.7.3-fips-dsa-post.patch deleted file mode 100644 index 7d1aea2..0000000 --- a/SOURCES/gnutls-3.7.3-fips-dsa-post.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0a29639ad24072afbd79b2ceede9976e51b9e2af Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Fri, 1 Jul 2022 16:46:07 +0900 -Subject: [PATCH] fips: don't run POST for DSA - -Signed-off-by: rpm-build <> ---- - lib/fips.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/lib/fips.c b/lib/fips.c -index 656d43e..c776690 100644 ---- a/lib/fips.c -+++ b/lib/fips.c -@@ -523,11 +523,6 @@ int _gnutls_fips_perform_self_checks2(void) - return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); - } - -- ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA); -- if (ret < 0) { -- return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); -- } -- - ret = gnutls_pk_self_test(0, GNUTLS_PK_EC); - if (ret < 0) { - return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); --- -2.36.1 - diff --git a/SOURCES/gnutls-3.7.6-fips-sha1-sigver.patch b/SOURCES/gnutls-3.7.6-fips-sha1-sigver.patch deleted file mode 100644 index e71b739..0000000 --- a/SOURCES/gnutls-3.7.6-fips-sha1-sigver.patch +++ /dev/null @@ -1,109 +0,0 @@ -From cc7473a9ea185e072ab1bae0903c77bd7d7cf5bc Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Mon, 20 Nov 2023 07:45:42 +0900 -Subject: [PATCH] gnutls-3.7.6-fips-sha1-sigver.patch - -Signed-off-by: rpm-build ---- - lib/nettle/pk.c | 13 +++++-------- - lib/pubkey.c | 3 --- - tests/fips-test.c | 8 ++++---- - 3 files changed, 9 insertions(+), 15 deletions(-) - -diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c -index 4ddfcff..36a7c24 100644 ---- a/lib/nettle/pk.c -+++ b/lib/nettle/pk.c -@@ -1609,10 +1609,7 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, - if (hash_len > vdata->size) - hash_len = vdata->size; - -- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy -- * mode */ - switch (DIG_TO_MAC(sign_params->dsa_dig)) { -- case GNUTLS_MAC_SHA1: - case GNUTLS_MAC_SHA256: - case GNUTLS_MAC_SHA384: - case GNUTLS_MAC_SHA512: -@@ -1683,8 +1680,8 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, - * 2048-bit or one of the known lengths (1024, 1280, - * 1536, 1792; i.e., multiple of 256-bits). - * -- * In addition to this, only SHA-1 and SHA-2 are allowed -- * for SigVer; it is checked in _pkcs1_rsa_verify_sig in -+ * In addition to this, only SHA-2 is allowed for -+ * SigVer; it is checked in _pkcs1_rsa_verify_sig in - * lib/pubkey.c. - */ - if (unlikely(bits < 2048 && bits != 1024 && bits != 1280 && -@@ -1730,9 +1727,9 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, - } - - /* RSA modulus size should be 2048-bit or larger in FIPS -- * 140-3. In addition to this, only SHA-1 and SHA-2 are -- * allowed for SigVer, while Nettle only supports -- * SHA256, SHA384, and SHA512 for RSA-PSS (see -+ * 140-3. In addition to this, only SHA-2 is allowed -+ * for SigVer, while Nettle only supports SHA256, -+ * SHA384, and SHA512 for RSA-PSS (see - * _rsa_pss_verify_digest in this file for the details). - */ - if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) { -diff --git a/lib/pubkey.c b/lib/pubkey.c -index 1139ad9..714806a 100644 ---- a/lib/pubkey.c -+++ b/lib/pubkey.c -@@ -2452,10 +2452,7 @@ static int _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk, - d.size = digest_size; - - if (pk == GNUTLS_PK_RSA) { -- /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy -- * mode */ - switch (me->id) { -- case GNUTLS_MAC_SHA1: - case GNUTLS_MAC_SHA256: - case GNUTLS_MAC_SHA384: - case GNUTLS_MAC_SHA512: -diff --git a/tests/fips-test.c b/tests/fips-test.c -index 180da05..09120c1 100644 ---- a/tests/fips-test.c -+++ b/tests/fips-test.c -@@ -596,7 +596,7 @@ void doit(void) - } - FIPS_POP_CONTEXT(NOT_APPROVED); - -- /* Verify a signature created with 2432-bit RSA and SHA-1; approved */ -+ /* Verify a signature created with 2432-bit RSA and SHA-1; not approved */ - FIPS_PUSH_CONTEXT(); - ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, - GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, -@@ -604,7 +604,7 @@ void doit(void) - if (ret < 0) { - fail("gnutls_pubkey_verify_data2 failed\n"); - } -- FIPS_POP_CONTEXT(APPROVED); -+ FIPS_POP_CONTEXT(NOT_APPROVED); - gnutls_free(signature.data); - gnutls_pubkey_deinit(pubkey); - gnutls_privkey_deinit(privkey); -@@ -708,7 +708,7 @@ void doit(void) - } - FIPS_POP_CONTEXT(NOT_APPROVED); - -- /* Verify a signature created with ECDSA and SHA-1; approved */ -+ /* Verify a signature created with ECDSA and SHA-1; not approved */ - FIPS_PUSH_CONTEXT(); - ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1, - GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, -@@ -716,7 +716,7 @@ void doit(void) - if (ret < 0) { - fail("gnutls_pubkey_verify_data2 failed\n"); - } -- FIPS_POP_CONTEXT(APPROVED); -+ FIPS_POP_CONTEXT(NOT_APPROVED); - gnutls_free(signature.data); - - /* Create a signature with ECDSA and SHA-1 (old API); not approved */ --- -2.41.0 - diff --git a/SOURCES/gnutls-3.7.6-gmp-static.patch b/SOURCES/gnutls-3.7.6-gmp-static.patch deleted file mode 100644 index 0b94c8d..0000000 --- a/SOURCES/gnutls-3.7.6-gmp-static.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 3c931abeb7e9bbf744cde83fbaaf3bb011107834 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Fri, 19 Aug 2022 12:32:27 +0900 -Subject: [PATCH] build: allow GMP to be statically linked - -Even though we set the custom allocator[1] to zeroize sensitive data, -it can be easily invalidated if the application sets its own custom -allocator. An approach to prevent that is to link against a static -library of GMP, so the use of GMP is privatized and the custom -allocator configuration is not shared with other applications. - -This patch allows libgnutls to be linked with the static library of -GMP. Note that, to this work libgmp.a needs to be compiled with -fPIC -and libhogweed in Nettle is also linked to the static library of GMP. - -1. https://gitlab.com/gnutls/gnutls/-/merge_requests/1554 - -Signed-off-by: Daiki Ueno ---- - configure.ac | 14 +++++++++++++- - lib/fips.c | 18 +++++++++++++++++- - lib/fipshmac.c | 2 ++ - lib/global.c | 2 ++ - 4 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/configure.ac b/configure.ac -index f81d93edc0..b38583c554 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -786,6 +786,8 @@ LIBS=$save_LIBS - AM_CONDITIONAL([NEED_SIV_GCM], [test "$ac_cv_func_nettle_siv_gcm_encrypt_message" != yes]) - - # Check sonames of the linked libraries needed for FIPS selftests. -+save_CFLAGS=$CFLAGS -+CFLAGS="$CFLAGS $GMP_CFLAGS" - save_LIBS=$LIBS - LIBS="$LIBS $GMP_LIBS" - AC_MSG_CHECKING([gmp soname]) -@@ -799,9 +801,14 @@ if test -z "$gmp_so"; then - gmp_so=none - fi - AC_MSG_RESULT($gmp_so) --AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library]) -+if test "$gmp_so" != none; then -+ AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library]) -+fi - LIBS=$save_LIBS -+CFLAGS=$save_CFLAGS - -+save_CFLAGS=$CFLAGS -+CFLAGS="$CFLAGS $NETTLE_CFLAGS" - save_LIBS=$LIBS - LIBS="$LIBS $NETTLE_LIBS" - AC_MSG_CHECKING([nettle soname]) -@@ -817,7 +824,11 @@ fi - AC_MSG_RESULT($nettle_so) - AC_DEFINE_UNQUOTED([NETTLE_LIBRARY_SONAME], ["$nettle_so"], [The soname of nettle library]) - LIBS=$save_LIBS -+CFLAGS=$save_CFLAGS - -+save_CFLAGS=$CFLAGS -+# includes -+CFLAGS="$CFLAGS $HOGWEED_CFLAGS $GMP_CFLAGS" - save_LIBS=$LIBS - LIBS="$LIBS $HOGWEED_LIBS" - AC_MSG_CHECKING([hogweed soname]) -@@ -833,6 +844,7 @@ fi - AC_MSG_RESULT($hogweed_so) - AC_DEFINE_UNQUOTED([HOGWEED_LIBRARY_SONAME], ["$hogweed_so"], [The soname of hogweed library]) - LIBS=$save_LIBS -+CFLAGS=$save_CFLAGS - - gnutls_so=libgnutls.so.`expr "$LT_CURRENT" - "$LT_AGE"` - AC_DEFINE_UNQUOTED([GNUTLS_LIBRARY_SONAME], ["$gnutls_so"], [The soname of gnutls library]) -diff --git a/lib/fips.c b/lib/fips.c -index e337221267..c1859709da 100644 ---- a/lib/fips.c -+++ b/lib/fips.c -@@ -157,7 +157,11 @@ void _gnutls_fips_mode_reset_zombie(void) - #define GNUTLS_LIBRARY_NAME GNUTLS_LIBRARY_SONAME - #define NETTLE_LIBRARY_NAME NETTLE_LIBRARY_SONAME - #define HOGWEED_LIBRARY_NAME HOGWEED_LIBRARY_SONAME -+ -+/* GMP can be statically linked. */ -+#ifdef GMP_LIBRARY_SONAME - #define GMP_LIBRARY_NAME GMP_LIBRARY_SONAME -+#endif - - #define HMAC_SIZE 32 - #define HMAC_ALGO GNUTLS_MAC_SHA256 -@@ -173,14 +177,18 @@ struct hmac_file { - struct hmac_entry gnutls; - struct hmac_entry nettle; - struct hmac_entry hogweed; -+#ifdef GMP_LIBRARY_SONAME - struct hmac_entry gmp; -+#endif - }; - - struct lib_paths { - char gnutls[GNUTLS_PATH_MAX]; - char nettle[GNUTLS_PATH_MAX]; - char hogweed[GNUTLS_PATH_MAX]; -+#ifdef GMP_LIBRARY_SONAME - char gmp[GNUTLS_PATH_MAX]; -+#endif - }; - - /* -@@ -244,8 +252,10 @@ static int handler(void *user, const char *section, const char *name, - return lib_handler(&p->nettle, section, name, value); - } else if (!strcmp(section, HOGWEED_LIBRARY_NAME)) { - return lib_handler(&p->hogweed, section, name, value); -+#ifdef GMP_LIBRARY_SONAME - } else if (!strcmp(section, GMP_LIBRARY_NAME)) { - return lib_handler(&p->gmp, section, name, value); -+#endif - } else { - return 0; - } -@@ -393,8 +403,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data) - _gnutls_str_cpy(paths->nettle, GNUTLS_PATH_MAX, path); - else if (!strcmp(soname, HOGWEED_LIBRARY_SONAME)) - _gnutls_str_cpy(paths->hogweed, GNUTLS_PATH_MAX, path); -+#ifdef GMP_LIBRARY_SONAME - else if (!strcmp(soname, GMP_LIBRARY_SONAME)) - _gnutls_str_cpy(paths->gmp, GNUTLS_PATH_MAX, path); -+#endif - return 0; - } - -@@ -415,10 +427,12 @@ static int load_lib_paths(struct lib_paths *paths) - _gnutls_debug_log("Hogweed library path was not found\n"); - return gnutls_assert_val(GNUTLS_E_FILE_ERROR); - } -+#ifdef GMP_LIBRARY_SONAME - if (paths->gmp[0] == '\0') { - _gnutls_debug_log("Gmp library path was not found\n"); - return gnutls_assert_val(GNUTLS_E_FILE_ERROR); - } -+#endif - - return GNUTLS_E_SUCCESS; - } -@@ -471,9 +485,11 @@ static int check_binary_integrity(void) - ret = check_lib_hmac(&hmac.hogweed, paths.hogweed); - if (ret < 0) - return ret; -- ret = check_lib_hmac(&hmac.gmp, paths.gmp); -+#ifdef GMP_LIBRARY_SONAME -+ ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init"); - if (ret < 0) - return ret; -+#endif - - return 0; - } -diff --git a/lib/fipshmac.c b/lib/fipshmac.c -index 51f38f18e5..6a4883a131 100644 ---- a/lib/fipshmac.c -+++ b/lib/fipshmac.c -@@ -107,8 +107,10 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data) - return print_lib(path, soname); - if (!strcmp(soname, HOGWEED_LIBRARY_SONAME)) - return print_lib(path, soname); -+#ifdef GMP_LIBRARY_SONAME - if (!strcmp(soname, GMP_LIBRARY_SONAME)) - return print_lib(path, soname); -+#endif - return 0; - } - -diff --git a/lib/global.c b/lib/global.c -index 924ec945de..c197fd0e5f 100644 ---- a/lib/global.c -+++ b/lib/global.c -@@ -564,7 +564,9 @@ static const struct gnutls_library_config_st _gnutls_library_config[] = { - { "libgnutls-soname", GNUTLS_LIBRARY_SONAME }, - { "libnettle-soname", NETTLE_LIBRARY_SONAME }, - { "libhogweed-soname", HOGWEED_LIBRARY_SONAME }, -+#ifdef GMP_LIBRARY_SONAME - { "libgmp-soname", GMP_LIBRARY_SONAME }, -+#endif - { "hardware-features", HW_FEATURES }, - { "tls-features", TLS_FEATURES }, - { "default-system-config", SYSTEM_PRIORITY_FILE }, --- -2.41.0 - diff --git a/SOURCES/gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch b/SOURCES/gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch deleted file mode 100644 index 301f211..0000000 --- a/SOURCES/gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 7d98e7768f3e4e1f981f76e27338ae7118ee2c39 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Mon, 22 Jan 2024 15:17:04 +0900 -Subject: [PATCH] gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch - ---- - tests/gnutls_ktls.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c -index ccbe566..8b8992d 100644 ---- a/tests/gnutls_ktls.c -+++ b/tests/gnutls_ktls.c -@@ -347,10 +347,8 @@ void doit(void) - { - run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-GCM"); - run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-256-GCM"); -- run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+CHACHA20-POLY1305"); - run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM"); - run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM"); -- run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305"); - #if defined(__linux__) - run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-CCM"); - run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-CCM"); --- -2.43.0 - diff --git a/SOURCES/gnutls-3.8.10-CVE-2025-14831.patch b/SOURCES/gnutls-3.8.10-CVE-2025-14831.patch new file mode 100644 index 0000000..e89b2c9 --- /dev/null +++ b/SOURCES/gnutls-3.8.10-CVE-2025-14831.patch @@ -0,0 +1,1630 @@ +From 98fa09e31884c44fe663bbee8719c215c827a9c8 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Mon, 26 Jan 2026 19:02:27 +0100 +Subject: [PATCH 1/9] x509/name_constraints: use actual zeroes in universal + exclude IP NC + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index 3c6e30630..e88461211 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -61,7 +61,7 @@ struct gnutls_name_constraints_st { + + static struct name_constraints_node_st * + name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, +- unsigned char *data, unsigned int size); ++ const unsigned char *data, unsigned int size); + + static int + name_constraints_node_list_add(struct name_constraints_node_list_st *list, +@@ -285,7 +285,7 @@ static void name_constraints_node_free(struct name_constraints_node_st *node) + -*/ + static struct name_constraints_node_st * + name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, +- unsigned char *data, unsigned int size) ++ const unsigned char *data, unsigned int size) + { + struct name_constraints_node_st *tmp; + int ret; +@@ -339,6 +339,7 @@ static int name_constraints_node_list_intersect( + struct name_constraints_node_list_st removed = { .data = NULL, + .size = 0, + .capacity = 0 }; ++ static const unsigned char universal_ip[32] = { 0 }; + + /* temporary array to see, if we need to add universal excluded constraints + * (see phase 3 for details) +@@ -471,7 +472,7 @@ static int name_constraints_node_list_intersect( + case GNUTLS_SAN_IPADDRESS: + // add universal restricted range for IPv4 + tmp = name_constraints_node_new( +- nc, GNUTLS_SAN_IPADDRESS, NULL, 8); ++ nc, GNUTLS_SAN_IPADDRESS, universal_ip, 8); + if (tmp == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; +@@ -484,7 +485,7 @@ static int name_constraints_node_list_intersect( + } + // add universal restricted range for IPv6 + tmp = name_constraints_node_new( +- nc, GNUTLS_SAN_IPADDRESS, NULL, 32); ++ nc, GNUTLS_SAN_IPADDRESS, universal_ip, 32); + if (tmp == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; +-- +2.52.0 + + +From 6f204d1b913db76c1425d993a4986bd99aac0c4c Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Mon, 26 Jan 2026 19:10:58 +0100 +Subject: [PATCH 2/9] tests/name-constraints-ip: stop swallowing errors... + +... now when it started to pass + +Signed-off-by: Alexander Sosedkin +--- + tests/name-constraints-ip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/name-constraints-ip.c b/tests/name-constraints-ip.c +index 7a196088d..a0cf172b7 100644 +--- a/tests/name-constraints-ip.c ++++ b/tests/name-constraints-ip.c +@@ -772,5 +772,5 @@ int main(int argc, char **argv) + cmocka_unit_test_setup_teardown( + check_ipv4v6_single_constraint_each, setup, teardown) + }; +- cmocka_run_group_tests(tests, NULL, NULL); ++ return cmocka_run_group_tests(tests, NULL, NULL); + } +-- +2.52.0 + + +From acc30a22329ad2c8f577c14c05c4321849991905 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Mon, 26 Jan 2026 20:14:33 +0100 +Subject: [PATCH 3/9] x509/name_constraints: reject some malformed domain names + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index e88461211..c62609ba5 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -159,6 +159,23 @@ static int validate_name_constraints_node(gnutls_x509_subject_alt_name_t type, + return gnutls_assert_val(GNUTLS_E_MALFORMED_CIDR); + } + ++ /* Validate DNS names and email addresses for malformed input */ ++ if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME) { ++ unsigned int i; ++ if (name->size == 0) ++ return GNUTLS_E_SUCCESS; ++ ++ /* reject names with consecutive dots... */ ++ for (i = 0; i + 1 < name->size; i++) { ++ if (name->data[i] == '.' && name->data[i + 1] == '.') ++ return gnutls_assert_val( ++ GNUTLS_E_ILLEGAL_PARAMETER); ++ } ++ /* ... or names consisting exclusively of dots */ ++ if (name->size == 1 && name->data[0] == '.') ++ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); ++ } ++ + return GNUTLS_E_SUCCESS; + } + +-- +2.52.0 + + +From 614f2f95b5ceba00fbe05bffbcc23c0574b03ea0 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Thu, 5 Feb 2026 13:22:10 +0100 +Subject: [PATCH 4/9] x509/name_constraints: + name_constraints_node_add_{new,copy} + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 112 ++++++++++++++++-------------------- + 1 file changed, 51 insertions(+), 61 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index c62609ba5..f0c8191c3 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -86,6 +86,38 @@ name_constraints_node_list_add(struct name_constraints_node_list_st *list, + return 0; + } + ++static int ++name_constraints_node_add_new(gnutls_x509_name_constraints_t nc, ++ struct name_constraints_node_list_st *list, ++ unsigned type, const unsigned char *data, ++ unsigned int size) ++{ ++ struct name_constraints_node_st *node; ++ int ret; ++ node = name_constraints_node_new(nc, type, data, size); ++ if (node == NULL) { ++ gnutls_assert(); ++ return GNUTLS_E_MEMORY_ERROR; ++ } ++ ret = name_constraints_node_list_add(list, node); ++ if (ret < 0) { ++ gnutls_assert(); ++ return ret; ++ } ++ return GNUTLS_E_SUCCESS; ++} ++ ++static int ++name_constraints_node_add_copy(gnutls_x509_name_constraints_t nc, ++ struct name_constraints_node_list_st *dest, ++ const struct name_constraints_node_st *src) ++{ ++ if (!src) ++ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ++ return name_constraints_node_add_new(nc, dest, src->type, ++ src->name.data, src->name.size); ++} ++ + // for documentation see the implementation + static int name_constraints_intersect_nodes( + gnutls_x509_name_constraints_t nc, +@@ -188,7 +220,6 @@ static int extract_name_constraints(gnutls_x509_name_constraints_t nc, + unsigned indx; + gnutls_datum_t tmp = { NULL, 0 }; + unsigned int type; +- struct name_constraints_node_st *node; + + for (indx = 1;; indx++) { + snprintf(tmpstr, sizeof(tmpstr), "%s.?%u.base", vstr, indx); +@@ -231,15 +262,9 @@ static int extract_name_constraints(gnutls_x509_name_constraints_t nc, + goto cleanup; + } + +- node = name_constraints_node_new(nc, type, tmp.data, tmp.size); ++ ret = name_constraints_node_add_new(nc, nodes, type, tmp.data, ++ tmp.size); + _gnutls_free_datum(&tmp); +- if (node == NULL) { +- gnutls_assert(); +- ret = GNUTLS_E_MEMORY_ERROR; +- goto cleanup; +- } +- +- ret = name_constraints_node_list_add(nodes, node); + if (ret < 0) { + gnutls_assert(); + goto cleanup; +@@ -459,14 +484,7 @@ static int name_constraints_node_list_intersect( + // Beware: also copies nodes other than DNS, email, IP, + // since their counterpart may have been moved in phase 1. + if (!used) { +- tmp = name_constraints_node_new( +- nc, t2->type, t2->name.data, t2->name.size); +- if (tmp == NULL) { +- gnutls_assert(); +- ret = GNUTLS_E_MEMORY_ERROR; +- goto cleanup; +- } +- ret = name_constraints_node_list_add(permitted, tmp); ++ ret = name_constraints_node_add_copy(nc, permitted, t2); + if (ret < 0) { + gnutls_assert(); + goto cleanup; +@@ -488,27 +506,17 @@ static int name_constraints_node_list_intersect( + switch (type) { + case GNUTLS_SAN_IPADDRESS: + // add universal restricted range for IPv4 +- tmp = name_constraints_node_new( +- nc, GNUTLS_SAN_IPADDRESS, universal_ip, 8); +- if (tmp == NULL) { +- gnutls_assert(); +- ret = GNUTLS_E_MEMORY_ERROR; +- goto cleanup; +- } +- ret = name_constraints_node_list_add(excluded, tmp); ++ ret = name_constraints_node_add_new( ++ nc, excluded, GNUTLS_SAN_IPADDRESS, ++ universal_ip, 8); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + // add universal restricted range for IPv6 +- tmp = name_constraints_node_new( +- nc, GNUTLS_SAN_IPADDRESS, universal_ip, 32); +- if (tmp == NULL) { +- gnutls_assert(); +- ret = GNUTLS_E_MEMORY_ERROR; +- goto cleanup; +- } +- ret = name_constraints_node_list_add(excluded, tmp); ++ ret = name_constraints_node_add_new( ++ nc, excluded, GNUTLS_SAN_IPADDRESS, ++ universal_ip, 32); + if (ret < 0) { + gnutls_assert(); + goto cleanup; +@@ -516,13 +524,8 @@ static int name_constraints_node_list_intersect( + break; + case GNUTLS_SAN_DNSNAME: + case GNUTLS_SAN_RFC822NAME: +- tmp = name_constraints_node_new(nc, type, NULL, 0); +- if (tmp == NULL) { +- gnutls_assert(); +- ret = GNUTLS_E_MEMORY_ERROR; +- goto cleanup; +- } +- ret = name_constraints_node_list_add(excluded, tmp); ++ ret = name_constraints_node_add_new(nc, excluded, type, ++ NULL, 0); + if (ret < 0) { + gnutls_assert(); + goto cleanup; +@@ -544,20 +547,13 @@ static int name_constraints_node_list_concat( + struct name_constraints_node_list_st *nodes, + const struct name_constraints_node_list_st *nodes2) + { ++ int ret; ++ + for (size_t i = 0; i < nodes2->size; i++) { +- const struct name_constraints_node_st *node = nodes2->data[i]; +- struct name_constraints_node_st *tmp; +- int ret; +- +- tmp = name_constraints_node_new(nc, node->type, node->name.data, +- node->name.size); +- if (tmp == NULL) { +- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); +- } +- ret = name_constraints_node_list_add(nodes, tmp); ++ ret = name_constraints_node_add_copy(nc, nodes, ++ nodes2->data[i]); + if (ret < 0) { +- name_constraints_node_free(tmp); +- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ++ return gnutls_assert_val(ret); + } + } + +@@ -687,7 +683,6 @@ static int name_constraints_add(gnutls_x509_name_constraints_t nc, + gnutls_x509_subject_alt_name_t type, + const gnutls_datum_t *name, unsigned permitted) + { +- struct name_constraints_node_st *tmp; + struct name_constraints_node_list_st *nodes; + int ret; + +@@ -697,15 +692,10 @@ static int name_constraints_add(gnutls_x509_name_constraints_t nc, + + nodes = permitted ? &nc->permitted : &nc->excluded; + +- tmp = name_constraints_node_new(nc, type, name->data, name->size); +- if (tmp == NULL) +- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); +- +- ret = name_constraints_node_list_add(nodes, tmp); +- if (ret < 0) { +- name_constraints_node_free(tmp); ++ ret = name_constraints_node_add_new(nc, nodes, type, name->data, ++ name->size); ++ if (ret < 0) + return gnutls_assert_val(ret); +- } + + return 0; + } +-- +2.52.0 + + +From 4a39cd884e33fd7d4845046166b4b32b492cffc5 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Mon, 26 Jan 2026 20:16:36 +0100 +Subject: [PATCH 5/9] x509/name_constraints: introduce a rich comparator + +These are preparatory changes before implementing N * log N intersection +over sorted lists of constraints. + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 411 ++++++++++++++++++++++++++++-------- + 1 file changed, 320 insertions(+), 91 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index f0c8191c3..b4f1fc00c 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -39,6 +39,9 @@ + #include "ip.h" + #include "ip-in-cidr.h" + #include "intprops.h" ++#include "minmax.h" ++ ++#include + + #define MAX_NC_CHECKS (1 << 20) + +@@ -63,6 +66,282 @@ static struct name_constraints_node_st * + name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, + const unsigned char *data, unsigned int size); + ++/* An enum for "rich" comparisons that not only let us sort name constraints, ++ * children-before-parent, but also subsume them during intersection. */ ++enum name_constraint_relation { ++ NC_SORTS_BEFORE = -2, /* unrelated constraints */ ++ NC_INCLUDED_BY = -1, /* nc1 is included by nc2 / children sort first */ ++ NC_EQUAL = 0, /* exact match */ ++ NC_INCLUDES = 1, /* nc1 includes nc2 / parents sort last */ ++ NC_SORTS_AFTER = 2 /* unrelated constraints */ ++}; ++ ++/* A helper to compare just a pair of strings with this rich comparison */ ++static enum name_constraint_relation ++compare_strings(const void *n1, size_t n1_len, const void *n2, size_t n2_len) ++{ ++ int r = memcmp(n1, n2, MIN(n1_len, n2_len)); ++ if (r < 0) ++ return NC_SORTS_BEFORE; ++ if (r > 0) ++ return NC_SORTS_AFTER; ++ if (n1_len < n2_len) ++ return NC_SORTS_BEFORE; ++ if (n1_len > n2_len) ++ return NC_SORTS_AFTER; ++ return NC_EQUAL; ++} ++ ++/* Rich-compare DNS names. Example order/relationships: ++ * z.x.a INCLUDED_BY x.a BEFORE y.a INCLUDED_BY a BEFORE x.b BEFORE y.b */ ++static enum name_constraint_relation compare_dns_names(const gnutls_datum_t *n1, ++ const gnutls_datum_t *n2) ++{ ++ enum name_constraint_relation rel; ++ unsigned int i, j, i_end, j_end; ++ ++ /* start from the end of each name */ ++ i = i_end = n1->size; ++ j = j_end = n2->size; ++ ++ /* skip the trailing dots for the comparison */ ++ while (i && n1->data[i - 1] == '.') ++ i_end = i = i - 1; ++ while (j && n2->data[j - 1] == '.') ++ j_end = j = j - 1; ++ ++ while (1) { ++ // rewind back to beginning or an after-dot position ++ while (i && n1->data[i - 1] != '.') ++ i--; ++ while (j && n2->data[j - 1] != '.') ++ j--; ++ ++ rel = compare_strings(&n1->data[i], i_end - i, &n2->data[j], ++ j_end - j); ++ if (rel == NC_SORTS_BEFORE) /* x.a BEFORE y.a */ ++ return NC_SORTS_BEFORE; ++ if (rel == NC_SORTS_AFTER) /* y.a AFTER x.a */ ++ return NC_SORTS_AFTER; ++ if (!i && j) /* x.a INCLUDES z.x.a */ ++ return NC_INCLUDES; ++ if (i && !j) /* z.x.a INCLUDED_BY x.a */ ++ return NC_INCLUDED_BY; ++ ++ if (!i && !j) /* r == 0, we ran out of components to compare */ ++ return NC_EQUAL; ++ /* r == 0, i && j: step back past a dot and keep comparing */ ++ i_end = i = i - 1; ++ j_end = j = j - 1; ++ ++ /* support for non-standard ".gr INCLUDES example.gr" [1] */ ++ if (!i && j) /* .a INCLUDES x.a */ ++ return NC_INCLUDES; ++ if (i && !j) /* x.a INCLUDED_BY .a */ ++ return NC_INCLUDED_BY; ++ } ++} ++/* [1] https://mailarchive.ietf.org/arch/msg/saag/Bw6PtreW0G7aEG7SikfzKHES4VA */ ++ ++/* Rich-compare email name constraints. Example order/relationships: ++ * z@x.a INCLUDED_BY x.a BEFORE y.a INCLUDED_BY a BEFORE x@b BEFORE y@b */ ++static enum name_constraint_relation compare_emails(const gnutls_datum_t *n1, ++ const gnutls_datum_t *n2) ++{ ++ enum name_constraint_relation domains_rel; ++ unsigned int i, j, i_end, j_end; ++ gnutls_datum_t d1, d2; /* borrow from n1 and n2 */ ++ ++ /* start from the end of each name */ ++ i = i_end = n1->size; ++ j = j_end = n2->size; ++ ++ /* rewind to @s to look for domains */ ++ while (i && n1->data[i - 1] != '@') ++ i--; ++ d1.size = i_end - i; ++ d1.data = &n1->data[i]; ++ while (j && n2->data[j - 1] != '@') ++ j--; ++ d2.size = j_end - j; ++ d2.data = &n2->data[j]; ++ ++ domains_rel = compare_dns_names(&d1, &d2); ++ ++ /* email constraint semantics differ from DNS ++ * DNS: x.a INCLUDED_BY a ++ * Email: x.a INCLUDED_BY .a BEFORE a */ ++ if (domains_rel == NC_INCLUDED_BY || domains_rel == NC_INCLUDES) { ++ bool d1_has_dot = (d1.size > 0 && d1.data[0] == '.'); ++ bool d2_has_dot = (d2.size > 0 && d2.data[0] == '.'); ++ /* a constraint without a dot is exact, excluding subdomains */ ++ if (!d2_has_dot && domains_rel == NC_INCLUDED_BY) ++ domains_rel = NC_SORTS_BEFORE; /* x.a BEFORE a */ ++ if (!d1_has_dot && domains_rel == NC_INCLUDES) ++ domains_rel = NC_SORTS_AFTER; /* a AFTER x.a */ ++ } ++ ++ if (!i && !j) { /* both are domains-only */ ++ return domains_rel; ++ } else if (i && !j) { /* n1 is email, n2 is domain */ ++ switch (domains_rel) { ++ case NC_SORTS_AFTER: ++ return NC_SORTS_AFTER; ++ case NC_SORTS_BEFORE: ++ return NC_SORTS_BEFORE; ++ case NC_INCLUDES: /* n2 is more specific, a@x.a AFTER z.x.a */ ++ return NC_SORTS_AFTER; ++ case NC_EQUAL: /* subdomains match, z@x.a INCLUDED_BY x.a */ ++ case NC_INCLUDED_BY: /* n1 is more specific */ ++ return NC_INCLUDED_BY; ++ } ++ } else if (!i && j) { /* n1 is domain, n2 is email */ ++ switch (domains_rel) { ++ case NC_SORTS_AFTER: ++ return NC_SORTS_AFTER; ++ case NC_SORTS_BEFORE: ++ return NC_SORTS_BEFORE; ++ case NC_INCLUDES: /* n2 is more specific, a AFTER z@x.a */ ++ return NC_SORTS_AFTER; ++ case NC_EQUAL: /* subdomains match, x.a INCLUDES z@x.a */ ++ return NC_INCLUDES; ++ case NC_INCLUDED_BY: /* n1 is more specific, x.a BEFORE z@a */ ++ return NC_SORTS_BEFORE; ++ } ++ } else if (i && j) { /* both are emails */ ++ switch (domains_rel) { ++ case NC_SORTS_AFTER: ++ return NC_SORTS_AFTER; ++ case NC_SORTS_BEFORE: ++ return NC_SORTS_BEFORE; ++ case NC_INCLUDES: // n2 is more specific ++ return NC_SORTS_AFTER; ++ case NC_INCLUDED_BY: // n1 is more specific ++ return NC_SORTS_BEFORE; ++ case NC_EQUAL: // only case when we need to look before the @ ++ break; // see below for readability ++ } ++ } ++ ++ /* i && j, both are emails, domain names match, compare up to @ */ ++ return compare_strings(n1->data, i - 1, n2->data, j - 1); ++} ++ ++/* Rich-compare IP address constraints. Example order/relationships: ++ * 10.0.0.0/24 INCLUDED_BY 10.0.0.0/16 BEFORE 1::1/128 INCLUDED_BY 1::1/127 */ ++static enum name_constraint_relation compare_ip_ncs(const gnutls_datum_t *n1, ++ const gnutls_datum_t *n2) ++{ ++ unsigned int len, i; ++ int r; ++ const unsigned char *ip1, *ip2, *mask1, *mask2; ++ unsigned char masked11[16], masked22[16], masked12[16], masked21[16]; ++ ++ if (n1->size < n2->size) ++ return NC_SORTS_BEFORE; ++ if (n1->size > n2->size) ++ return NC_SORTS_AFTER; ++ len = n1->size / 2; /* 4 for IPv4, 16 for IPv6 */ ++ ++ /* data is a concatenation of prefix and mask */ ++ ip1 = n1->data; ++ ip2 = n2->data; ++ mask1 = n1->data + len; ++ mask2 = n2->data + len; ++ for (i = 0; i < len; i++) { ++ masked11[i] = ip1[i] & mask1[i]; ++ masked22[i] = ip2[i] & mask2[i]; ++ masked12[i] = ip1[i] & mask2[i]; ++ masked21[i] = ip2[i] & mask1[i]; ++ } ++ ++ r = memcmp(mask1, mask2, len); ++ if (r < 0 && !memcmp(masked11, masked21, len)) /* prefix1 < prefix2 */ ++ return NC_INCLUDES; /* ip1 & mask1 == ip2 & mask1 */ ++ if (r > 0 && !memcmp(masked12, masked22, len)) /* prefix1 > prefix2 */ ++ return NC_INCLUDED_BY; /* ip1 & mask2 == ip2 & mask2 */ ++ ++ r = memcmp(masked11, masked22, len); ++ if (r < 0) ++ return NC_SORTS_BEFORE; ++ else if (r > 0) ++ return NC_SORTS_AFTER; ++ return NC_EQUAL; ++} ++ ++static inline bool is_supported_type(unsigned type) ++{ ++ return type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME || ++ type == GNUTLS_SAN_IPADDRESS; ++} ++ ++/* Universal comparison for name constraint nodes. ++ * Unsupported types sort before supported types to allow early handling. ++ * NULL represents end-of-list and sorts after everything else. */ ++static enum name_constraint_relation ++compare_name_constraint_nodes(const struct name_constraints_node_st *n1, ++ const struct name_constraints_node_st *n2) ++{ ++ bool n1_supported, n2_supported; ++ ++ if (!n1 && !n2) ++ return NC_EQUAL; ++ if (!n1) ++ return NC_SORTS_AFTER; ++ if (!n2) ++ return NC_SORTS_BEFORE; ++ ++ n1_supported = is_supported_type(n1->type); ++ n2_supported = is_supported_type(n2->type); ++ ++ /* unsupported types bubble up (sort first). intersect relies on this */ ++ if (!n1_supported && n2_supported) ++ return NC_SORTS_BEFORE; ++ if (n1_supported && !n2_supported) ++ return NC_SORTS_AFTER; ++ ++ /* next, sort by type */ ++ if (n1->type < n2->type) ++ return NC_SORTS_BEFORE; ++ if (n1->type > n2->type) ++ return NC_SORTS_AFTER; ++ ++ /* now look deeper */ ++ switch (n1->type) { ++ case GNUTLS_SAN_DNSNAME: ++ return compare_dns_names(&n1->name, &n2->name); ++ case GNUTLS_SAN_RFC822NAME: ++ return compare_emails(&n1->name, &n2->name); ++ case GNUTLS_SAN_IPADDRESS: ++ return compare_ip_ncs(&n1->name, &n2->name); ++ default: ++ /* unsupported types: stable lexicographic order */ ++ return compare_strings(n1->name.data, n1->name.size, ++ n2->name.data, n2->name.size); ++ } ++} ++ ++/* qsort-compatible wrapper */ ++static int compare_name_constraint_nodes_qsort(const void *a, const void *b) ++{ ++ const struct name_constraints_node_st *const *n1 = a; ++ const struct name_constraints_node_st *const *n2 = b; ++ enum name_constraint_relation rel; ++ ++ rel = compare_name_constraint_nodes(*n1, *n2); ++ switch (rel) { ++ case NC_SORTS_BEFORE: ++ case NC_INCLUDED_BY: ++ return -1; ++ case NC_SORTS_AFTER: ++ case NC_INCLUDES: ++ return 1; ++ case NC_EQUAL: ++ default: ++ return 0; ++ } ++} ++ + static int + name_constraints_node_list_add(struct name_constraints_node_list_st *list, + struct name_constraints_node_st *node) +@@ -420,9 +699,7 @@ static int name_constraints_node_list_intersect( + } + } + +- if (found != NULL && (t->type == GNUTLS_SAN_DNSNAME || +- t->type == GNUTLS_SAN_RFC822NAME || +- t->type == GNUTLS_SAN_IPADDRESS)) { ++ if (found != NULL && is_supported_type(t->type)) { + /* move node from PERMITTED to REMOVED */ + ret = name_constraints_node_list_add(&removed, t); + if (ret < 0) { +@@ -824,61 +1101,14 @@ cleanup: + return ret; + } + +-static unsigned ends_with(const gnutls_datum_t *str, +- const gnutls_datum_t *suffix) +-{ +- unsigned char *tree; +- unsigned int treelen; +- +- if (suffix->size >= str->size) +- return 0; +- +- tree = suffix->data; +- treelen = suffix->size; +- if ((treelen > 0) && (tree[0] == '.')) { +- tree++; +- treelen--; +- } +- +- if (memcmp(str->data + str->size - treelen, tree, treelen) == 0 && +- str->data[str->size - treelen - 1] == '.') +- return 1; /* match */ +- +- return 0; +-} +- +-static unsigned email_ends_with(const gnutls_datum_t *str, +- const gnutls_datum_t *suffix) +-{ +- if (suffix->size >= str->size) { +- return 0; +- } +- +- if (suffix->size > 0 && memcmp(str->data + str->size - suffix->size, +- suffix->data, suffix->size) != 0) { +- return 0; +- } +- +- if (suffix->size > 1 && suffix->data[0] == '.') { /* .domain.com */ +- return 1; /* match */ +- } else if (str->data[str->size - suffix->size - 1] == '@') { +- return 1; /* match */ +- } +- +- return 0; +-} +- + static unsigned dnsname_matches(const gnutls_datum_t *name, + const gnutls_datum_t *suffix) + { + _gnutls_hard_log("matching %.*s with DNS constraint %.*s\n", name->size, + name->data, suffix->size, suffix->data); + +- if (suffix->size == name->size && +- memcmp(suffix->data, name->data, suffix->size) == 0) +- return 1; /* match */ +- +- return ends_with(name, suffix); ++ enum name_constraint_relation rel = compare_dns_names(name, suffix); ++ return rel == NC_EQUAL || rel == NC_INCLUDED_BY; + } + + static unsigned email_matches(const gnutls_datum_t *name, +@@ -887,11 +1117,8 @@ static unsigned email_matches(const gnutls_datum_t *name, + _gnutls_hard_log("matching %.*s with e-mail constraint %.*s\n", + name->size, name->data, suffix->size, suffix->data); + +- if (suffix->size == name->size && +- memcmp(suffix->data, name->data, suffix->size) == 0) +- return 1; /* match */ +- +- return email_ends_with(name, suffix); ++ enum name_constraint_relation rel = compare_emails(name, suffix); ++ return rel == NC_EQUAL || rel == NC_INCLUDED_BY; + } + + /*- +@@ -915,8 +1142,7 @@ static int name_constraints_intersect_nodes( + // presume empty intersection + struct name_constraints_node_st *intersection = NULL; + const struct name_constraints_node_st *to_copy = NULL; +- unsigned iplength = 0; +- unsigned byte; ++ enum name_constraint_relation rel; + + *_intersection = NULL; + +@@ -925,32 +1151,49 @@ static int name_constraints_intersect_nodes( + } + switch (node1->type) { + case GNUTLS_SAN_DNSNAME: +- if (!dnsname_matches(&node2->name, &node1->name)) ++ rel = compare_dns_names(&node1->name, &node2->name); ++ switch (rel) { ++ case NC_EQUAL: // equal means doesn't matter which one ++ case NC_INCLUDES: // node2 is more specific ++ to_copy = node2; ++ break; ++ case NC_INCLUDED_BY: // node1 is more specific ++ to_copy = node1; ++ break; ++ case NC_SORTS_BEFORE: // no intersection ++ case NC_SORTS_AFTER: // no intersection + return GNUTLS_E_SUCCESS; +- to_copy = node2; ++ } + break; + case GNUTLS_SAN_RFC822NAME: +- if (!email_matches(&node2->name, &node1->name)) ++ rel = compare_emails(&node1->name, &node2->name); ++ switch (rel) { ++ case NC_EQUAL: // equal means doesn't matter which one ++ case NC_INCLUDES: // node2 is more specific ++ to_copy = node2; ++ break; ++ case NC_INCLUDED_BY: // node1 is more specific ++ to_copy = node1; ++ break; ++ case NC_SORTS_BEFORE: // no intersection ++ case NC_SORTS_AFTER: // no intersection + return GNUTLS_E_SUCCESS; +- to_copy = node2; ++ } + break; + case GNUTLS_SAN_IPADDRESS: +- if (node1->name.size != node2->name.size) ++ rel = compare_ip_ncs(&node1->name, &node2->name); ++ switch (rel) { ++ case NC_EQUAL: // equal means doesn't matter which one ++ case NC_INCLUDES: // node2 is more specific ++ to_copy = node2; ++ break; ++ case NC_INCLUDED_BY: // node1 is more specific ++ to_copy = node1; ++ break; ++ case NC_SORTS_BEFORE: // no intersection ++ case NC_SORTS_AFTER: // no intersection + return GNUTLS_E_SUCCESS; +- iplength = node1->name.size / 2; +- for (byte = 0; byte < iplength; byte++) { +- if (((node1->name.data[byte] ^ +- node2->name.data[byte]) // XOR of addresses +- & node1->name.data[byte + +- iplength] // AND mask from nc1 +- & node2->name.data[byte + +- iplength]) // AND mask from nc2 +- != 0) { +- // CIDRS do not intersect +- return GNUTLS_E_SUCCESS; +- } + } +- to_copy = node2; + break; + default: + // for other types, we don't know how to do the intersection, assume empty +@@ -967,20 +1210,6 @@ static int name_constraints_intersect_nodes( + intersection = *_intersection; + + assert(intersection->name.data != NULL); +- +- if (intersection->type == GNUTLS_SAN_IPADDRESS) { +- // make sure both IP addresses are correctly masked +- _gnutls_mask_ip(intersection->name.data, +- intersection->name.data + iplength, +- iplength); +- _gnutls_mask_ip(node1->name.data, +- node1->name.data + iplength, iplength); +- // update intersection, if necessary (we already know one is subset of other) +- for (byte = 0; byte < 2 * iplength; byte++) { +- intersection->name.data[byte] |= +- node1->name.data[byte]; +- } +- } + } + + return GNUTLS_E_SUCCESS; +-- +2.52.0 + + +From 8f5bf94225156ac09f8928b2d0da9d6c40f0aba8 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Wed, 4 Feb 2026 09:09:46 +0100 +Subject: [PATCH 6/9] x509/name_constraints: add sorted_view in preparation... + +... for actually using it later for performance gains. + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 62 ++++++++++++++++++++++++++++++------- + 1 file changed, 51 insertions(+), 11 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index b4f1fc00c..f2c279946 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -54,6 +54,9 @@ struct name_constraints_node_list_st { + struct name_constraints_node_st **data; + size_t size; + size_t capacity; ++ /* sorted-on-demand view, valid only when dirty == false */ ++ bool dirty; ++ struct name_constraints_node_st **sorted_view; + }; + + struct gnutls_name_constraints_st { +@@ -342,6 +345,37 @@ static int compare_name_constraint_nodes_qsort(const void *a, const void *b) + } + } + ++/* Bring the sorted view up to date with the list data; clear the dirty flag. */ ++static int ensure_sorted(struct name_constraints_node_list_st *list) ++{ ++ struct name_constraints_node_st **new_data; ++ ++ if (!list->dirty) ++ return GNUTLS_E_SUCCESS; ++ if (!list->size) { ++ list->dirty = false; ++ return GNUTLS_E_SUCCESS; ++ } ++ ++ /* reallocate sorted view to match current size */ ++ new_data = ++ _gnutls_reallocarray(list->sorted_view, list->size, ++ sizeof(struct name_constraints_node_st *)); ++ if (!new_data) ++ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ++ list->sorted_view = new_data; ++ ++ /* copy pointers and sort in-place */ ++ memcpy(list->sorted_view, list->data, ++ list->size * sizeof(struct name_constraints_node_st *)); ++ qsort(list->sorted_view, list->size, ++ sizeof(struct name_constraints_node_st *), ++ compare_name_constraint_nodes_qsort); ++ ++ list->dirty = false; ++ return GNUTLS_E_SUCCESS; ++} ++ + static int + name_constraints_node_list_add(struct name_constraints_node_list_st *list, + struct name_constraints_node_st *node) +@@ -361,10 +395,23 @@ name_constraints_node_list_add(struct name_constraints_node_list_st *list, + list->capacity = new_capacity; + list->data = new_data; + } ++ list->dirty = true; + list->data[list->size++] = node; + return 0; + } + ++static void ++name_constraints_node_list_clear(struct name_constraints_node_list_st *list) ++{ ++ gnutls_free(list->data); ++ gnutls_free(list->sorted_view); ++ list->data = NULL; ++ list->sorted_view = NULL; ++ list->capacity = 0; ++ list->size = 0; ++ list->dirty = false; ++} ++ + static int + name_constraints_node_add_new(gnutls_x509_name_constraints_t nc, + struct name_constraints_node_list_st *list, +@@ -711,6 +758,7 @@ static int name_constraints_node_list_intersect( + permitted->data[i] = + permitted->data[permitted->size - 1]; + permitted->size--; ++ permitted->dirty = true; + continue; + } + i++; +@@ -905,17 +953,9 @@ void _gnutls_x509_name_constraints_clear(gnutls_x509_name_constraints_t nc) + struct name_constraints_node_st *node = nc->nodes.data[i]; + name_constraints_node_free(node); + } +- gnutls_free(nc->nodes.data); +- nc->nodes.capacity = 0; +- nc->nodes.size = 0; +- +- gnutls_free(nc->permitted.data); +- nc->permitted.capacity = 0; +- nc->permitted.size = 0; +- +- gnutls_free(nc->excluded.data); +- nc->excluded.capacity = 0; +- nc->excluded.size = 0; ++ name_constraints_node_list_clear(&nc->nodes); ++ name_constraints_node_list_clear(&nc->permitted); ++ name_constraints_node_list_clear(&nc->excluded); + } + + /** +-- +2.52.0 + + +From 998bc5d6761d29f7e3c0f07feff318e4a7e9b933 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Wed, 4 Feb 2026 13:30:08 +0100 +Subject: [PATCH 7/9] x509/name_constraints: implement + name_constraints_node_list_union + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 98 ++++++++++++++++++++++++++++++++----- + 1 file changed, 86 insertions(+), 12 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index f2c279946..230bd0079 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -41,6 +41,7 @@ + #include "intprops.h" + #include "minmax.h" + ++#include + #include + + #define MAX_NC_CHECKS (1 << 20) +@@ -867,22 +868,95 @@ cleanup: + return ret; + } + +-static int name_constraints_node_list_concat( +- gnutls_x509_name_constraints_t nc, +- struct name_constraints_node_list_st *nodes, +- const struct name_constraints_node_list_st *nodes2) ++static int ++name_constraints_node_list_union(gnutls_x509_name_constraints_t nc, ++ struct name_constraints_node_list_st *nodes, ++ struct name_constraints_node_list_st *nodes2) + { + int ret; ++ size_t i = 0, j = 0; ++ struct name_constraints_node_st *nc1; ++ const struct name_constraints_node_st *nc2; ++ enum name_constraint_relation rel; ++ struct name_constraints_node_list_st result = { 0 }; + +- for (size_t i = 0; i < nodes2->size; i++) { +- ret = name_constraints_node_add_copy(nc, nodes, +- nodes2->data[i]); ++ if (nodes2->size == 0) /* nothing to do */ ++ return GNUTLS_E_SUCCESS; ++ ++ ret = ensure_sorted(nodes); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; ++ } ++ ret = ensure_sorted(nodes2); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; ++ } ++ ++ /* traverse both lists in a single pass and merge them w/o duplicates */ ++ while (i < nodes->size || j < nodes2->size) { ++ nc1 = (i < nodes->size) ? nodes->sorted_view[i] : NULL; ++ nc2 = (j < nodes2->size) ? nodes2->sorted_view[j] : NULL; ++ ++ rel = compare_name_constraint_nodes(nc1, nc2); ++ switch (rel) { ++ case NC_SORTS_BEFORE: ++ assert(nc1 != NULL); /* comparator-guaranteed */ ++ ret = name_constraints_node_list_add(&result, nc1); ++ i++; ++ break; ++ case NC_SORTS_AFTER: ++ assert(nc2 != NULL); /* comparator-guaranteed */ ++ ret = name_constraints_node_add_copy(nc, &result, nc2); ++ j++; ++ break; ++ case NC_INCLUDES: /* nc1 is broader, shallow-copy it */ ++ assert(nc1 != NULL && nc2 != NULL); /* comparator */ ++ ret = name_constraints_node_list_add(&result, nc1); ++ i++; ++ j++; ++ break; ++ case NC_INCLUDED_BY: /* nc2 is broader, deep-copy it */ ++ assert(nc1 != NULL && nc2 != NULL); /* comparator */ ++ ret = name_constraints_node_add_copy(nc, &result, nc2); ++ i++; ++ j++; ++ break; ++ case NC_EQUAL: ++ assert(nc1 != NULL && nc2 != NULL); /* loop condition */ ++ ret = name_constraints_node_list_add(&result, nc1); ++ i++; ++ j++; ++ break; ++ } + if (ret < 0) { +- return gnutls_assert_val(ret); ++ gnutls_assert(); ++ goto cleanup; + } + } + +- return 0; ++ gnutls_free(nodes->data); ++ gnutls_free(nodes->sorted_view); ++ nodes->data = result.data; ++ nodes->sorted_view = NULL; ++ nodes->size = result.size; ++ nodes->capacity = result.capacity; ++ nodes->dirty = true; ++ /* since we know it's sorted, populate sorted_view almost for free */ ++ nodes->sorted_view = gnutls_calloc( ++ nodes->size, sizeof(struct name_constraints_node_st *)); ++ if (!nodes->sorted_view) ++ return GNUTLS_E_SUCCESS; /* we tried, no harm done */ ++ memcpy(nodes->sorted_view, nodes->data, ++ nodes->size * sizeof(struct name_constraints_node_st *)); ++ nodes->dirty = false; ++ ++ result.data = NULL; ++ return GNUTLS_E_SUCCESS; ++cleanup: ++ name_constraints_node_list_clear(&result); ++ return gnutls_assert_val(ret); + } + + /** +@@ -1023,7 +1097,7 @@ static int name_constraints_add(gnutls_x509_name_constraints_t nc, + * @nc2: The name constraints to be merged with + * + * This function will merge the provided name constraints structures +- * as per RFC5280 p6.1.4. That is, the excluded constraints will be appended, ++ * as per RFC5280 p6.1.4. That is, the excluded constraints will be unioned, + * and permitted will be intersected. The intersection assumes that @nc + * is the root CA constraints. + * +@@ -1045,8 +1119,8 @@ int _gnutls_x509_name_constraints_merge(gnutls_x509_name_constraints_t nc, + return ret; + } + +- ret = name_constraints_node_list_concat(nc, &nc->excluded, +- &nc2->excluded); ++ ret = name_constraints_node_list_union(nc, &nc->excluded, ++ &nc2->excluded); + if (ret < 0) { + gnutls_assert(); + return ret; +-- +2.52.0 + + +From dce5fded86d227ba492b37cc91822c8aabff0337 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Wed, 4 Feb 2026 18:31:37 +0100 +Subject: [PATCH 8/9] x509/name_constraints: make types_with_empty_intersection + a bitmask + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 39 +++++++++++++++++++++++++++---------- + 1 file changed, 29 insertions(+), 10 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index 230bd0079..d1006eb8d 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -275,6 +275,7 @@ static enum name_constraint_relation compare_ip_ncs(const gnutls_datum_t *n1, + + static inline bool is_supported_type(unsigned type) + { ++ /* all of these should be under GNUTLS_SAN_MAX (intersect bitmasks) */ + return type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME || + type == GNUTLS_SAN_IPADDRESS; + } +@@ -683,6 +684,21 @@ name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, + return tmp; + } + ++static int ++name_constraints_node_list_union(gnutls_x509_name_constraints_t nc, ++ struct name_constraints_node_list_st *nodes, ++ struct name_constraints_node_list_st *nodes2); ++ ++#define type_bitmask_t uint8_t /* increase if GNUTLS_SAN_MAX grows */ ++#define type_bitmask_set(mask, t) ((mask) |= (1u << (t))) ++#define type_bitmask_clr(mask, t) ((mask) &= ~(1u << (t))) ++#define type_bitmask_in(mask, t) ((mask) & (1u << (t))) ++/* C99-compatible compile-time assertions; gnutls_int.h undefines verify */ ++typedef char assert_san_max[(GNUTLS_SAN_MAX < 8) ? 1 : -1]; ++typedef char assert_dnsname[(GNUTLS_SAN_DNSNAME <= GNUTLS_SAN_MAX) ? 1 : -1]; ++typedef char assert_rfc822[(GNUTLS_SAN_RFC822NAME <= GNUTLS_SAN_MAX) ? 1 : -1]; ++typedef char assert_ipaddr[(GNUTLS_SAN_IPADDRESS <= GNUTLS_SAN_MAX) ? 1 : -1]; ++ + /*- + * @brief name_constraints_node_list_intersect: + * @nc: %gnutls_x509_name_constraints_t +@@ -710,12 +726,9 @@ static int name_constraints_node_list_intersect( + .capacity = 0 }; + static const unsigned char universal_ip[32] = { 0 }; + +- /* temporary array to see, if we need to add universal excluded constraints +- * (see phase 3 for details) +- * indexed directly by (gnutls_x509_subject_alt_name_t enum - 1) */ +- unsigned char types_with_empty_intersection[GNUTLS_SAN_MAX]; +- memset(types_with_empty_intersection, 0, +- sizeof(types_with_empty_intersection)); ++ /* bitmask to see if we need to add universal excluded constraints ++ * (see phase 3 for details) */ ++ type_bitmask_t types_with_empty_intersection = 0; + + if (permitted->size == 0 || permitted2->size == 0) + return 0; +@@ -741,7 +754,8 @@ static int name_constraints_node_list_intersect( + // note the possibility of empty intersection for this type + // if we add something to the intersection in phase 2, + // we will reset this flag back to 0 then +- types_with_empty_intersection[t->type - 1] = 1; ++ type_bitmask_set(types_with_empty_intersection, ++ t->type); + found = t2; + break; + } +@@ -795,8 +809,8 @@ static int name_constraints_node_list_intersect( + GNUTLS_E_INTERNAL_ERROR); + } + // we will not add universal excluded constraint for this type +- types_with_empty_intersection[tmp->type - 1] = +- 0; ++ type_bitmask_clr(types_with_empty_intersection, ++ tmp->type); + // add intersection node to PERMITTED + ret = name_constraints_node_list_add(permitted, + tmp); +@@ -824,7 +838,7 @@ static int name_constraints_node_list_intersect( + * excluded constraint with universal wildcard + * (since the intersection of permitted is now empty). */ + for (type = 1; type <= GNUTLS_SAN_MAX; type++) { +- if (types_with_empty_intersection[type - 1] == 0) ++ if (!type_bitmask_in(types_with_empty_intersection, type)) + continue; + _gnutls_hard_log( + "Adding universal excluded name constraint for type %d.\n", +@@ -868,6 +882,11 @@ cleanup: + return ret; + } + ++#undef type_bitmask_t ++#undef type_bitmask_set ++#undef type_bitmask_clr ++#undef type_bitmask_in ++ + static int + name_constraints_node_list_union(gnutls_x509_name_constraints_t nc, + struct name_constraints_node_list_st *nodes, +-- +2.52.0 + + +From 5f54d43c5523347a56adf4c3b46ec38b11feaa79 Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Wed, 4 Feb 2026 20:03:49 +0100 +Subject: [PATCH 9/9] x509/name_constraints: + name_constraints_node_list_intersect over sorted + +Fixes: CVE-2025-14831 + +Signed-off-by: Alexander Sosedkin +--- + lib/x509/name_constraints.c | 343 ++++++++++++++---------------------- + 1 file changed, 133 insertions(+), 210 deletions(-) + +diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c +index d1006eb8d..04722bdf4 100644 +--- a/lib/x509/name_constraints.c ++++ b/lib/x509/name_constraints.c +@@ -446,13 +446,6 @@ name_constraints_node_add_copy(gnutls_x509_name_constraints_t nc, + src->name.data, src->name.size); + } + +-// for documentation see the implementation +-static int name_constraints_intersect_nodes( +- gnutls_x509_name_constraints_t nc, +- const struct name_constraints_node_st *node1, +- const struct name_constraints_node_st *node2, +- struct name_constraints_node_st **intersection); +- + /*- + * _gnutls_x509_name_constraints_is_empty: + * @nc: name constraints structure +@@ -716,129 +709,143 @@ typedef char assert_ipaddr[(GNUTLS_SAN_IPADDRESS <= GNUTLS_SAN_MAX) ? 1 : -1]; + static int name_constraints_node_list_intersect( + gnutls_x509_name_constraints_t nc, + struct name_constraints_node_list_st *permitted, +- const struct name_constraints_node_list_st *permitted2, ++ struct name_constraints_node_list_st *permitted2, + struct name_constraints_node_list_st *excluded) + { +- struct name_constraints_node_st *tmp; +- int ret, type, used; +- struct name_constraints_node_list_st removed = { .data = NULL, +- .size = 0, +- .capacity = 0 }; ++ struct name_constraints_node_st *nc1, *nc2; ++ struct name_constraints_node_list_st result = { 0 }; ++ struct name_constraints_node_list_st unsupp2 = { 0 }; ++ enum name_constraint_relation rel; ++ unsigned type; ++ int ret = GNUTLS_E_SUCCESS; ++ size_t i, j, p1_unsupp = 0, p2_unsupp = 0; ++ type_bitmask_t universal_exclude_needed = 0; ++ type_bitmask_t types_in_p1 = 0, types_in_p2 = 0; + static const unsigned char universal_ip[32] = { 0 }; + +- /* bitmask to see if we need to add universal excluded constraints +- * (see phase 3 for details) */ +- type_bitmask_t types_with_empty_intersection = 0; +- + if (permitted->size == 0 || permitted2->size == 0) +- return 0; ++ return GNUTLS_E_SUCCESS; + +- /* Phase 1 +- * For each name in PERMITTED, if a PERMITTED2 does not contain a name +- * with the same type, move the original name to REMOVED. +- * Do this also for node of unknown type (not DNS, email, IP) */ +- for (size_t i = 0; i < permitted->size;) { +- struct name_constraints_node_st *t = permitted->data[i]; +- const struct name_constraints_node_st *found = NULL; ++ /* make sorted views of the arrays */ ++ ret = ensure_sorted(permitted); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; ++ } ++ ret = ensure_sorted(permitted2); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; ++ } + +- for (size_t j = 0; j < permitted2->size; j++) { +- const struct name_constraints_node_st *t2 = +- permitted2->data[j]; +- if (t->type == t2->type) { +- // check bounds (we will use 't->type' as index) +- if (t->type > GNUTLS_SAN_MAX || t->type == 0) { +- gnutls_assert(); +- ret = GNUTLS_E_INTERNAL_ERROR; +- goto cleanup; +- } +- // note the possibility of empty intersection for this type +- // if we add something to the intersection in phase 2, +- // we will reset this flag back to 0 then +- type_bitmask_set(types_with_empty_intersection, +- t->type); +- found = t2; +- break; +- } ++ /* deal with the leading unsupported types first: count, then union */ ++ while (p1_unsupp < permitted->size && ++ !is_supported_type(permitted->sorted_view[p1_unsupp]->type)) ++ p1_unsupp++; ++ while (p2_unsupp < permitted2->size && ++ !is_supported_type(permitted2->sorted_view[p2_unsupp]->type)) ++ p2_unsupp++; ++ if (p1_unsupp) { /* copy p1 unsupported type pointers into result */ ++ result.data = gnutls_calloc( ++ p1_unsupp, sizeof(struct name_constraints_node_st *)); ++ if (!result.data) { ++ ret = GNUTLS_E_MEMORY_ERROR; ++ gnutls_assert(); ++ goto cleanup; ++ } ++ memcpy(result.data, permitted->sorted_view, ++ p1_unsupp * sizeof(struct name_constraints_node_st *)); ++ result.size = result.capacity = p1_unsupp; ++ result.dirty = true; ++ } ++ if (p2_unsupp) { /* union will make deep copies from p2 */ ++ unsupp2.data = permitted2->sorted_view; /* so, just alias */ ++ unsupp2.size = unsupp2.capacity = p2_unsupp; ++ unsupp2.dirty = false; /* we know it's sorted */ ++ unsupp2.sorted_view = permitted2->sorted_view; ++ ret = name_constraints_node_list_union(nc, &result, &unsupp2); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; + } ++ } + +- if (found != NULL && is_supported_type(t->type)) { +- /* move node from PERMITTED to REMOVED */ +- ret = name_constraints_node_list_add(&removed, t); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } +- /* remove node by swapping */ +- if (i < permitted->size - 1) +- permitted->data[i] = +- permitted->data[permitted->size - 1]; +- permitted->size--; +- permitted->dirty = true; +- continue; ++ /* with that out of the way, pre-compute the supported types we have */ ++ for (i = p1_unsupp; i < permitted->size; i++) { ++ type = permitted->sorted_view[i]->type; ++ if (type < 1 || type > GNUTLS_SAN_MAX) { ++ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ++ goto cleanup; ++ } ++ type_bitmask_set(types_in_p1, type); ++ } ++ for (j = p2_unsupp; j < permitted2->size; j++) { ++ type = permitted2->sorted_view[j]->type; ++ if (type < 1 || type > GNUTLS_SAN_MAX) { ++ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ++ goto cleanup; + } +- i++; ++ type_bitmask_set(types_in_p2, type); + } ++ /* universal excludes might be needed for types intersecting to empty */ ++ universal_exclude_needed = types_in_p1 & types_in_p2; + +- /* Phase 2 +- * iterate through all combinations from PERMITTED2 and PERMITTED +- * and create intersections of nodes with same type */ +- for (size_t i = 0; i < permitted2->size; i++) { +- const struct name_constraints_node_st *t2 = permitted2->data[i]; ++ /* go through supported type NCs and intersect in a single pass */ ++ i = p1_unsupp; ++ j = p2_unsupp; ++ while (i < permitted->size || j < permitted2->size) { ++ nc1 = (i < permitted->size) ? permitted->sorted_view[i] : NULL; ++ nc2 = (j < permitted2->size) ? permitted2->sorted_view[j] : ++ NULL; ++ rel = compare_name_constraint_nodes(nc1, nc2); + +- // current PERMITTED2 node has not yet been used for any intersection +- // (and is not in REMOVED either) +- used = 0; +- for (size_t j = 0; j < removed.size; j++) { +- const struct name_constraints_node_st *t = +- removed.data[j]; +- // save intersection of name constraints into tmp +- ret = name_constraints_intersect_nodes(nc, t, t2, &tmp); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } +- used = 1; +- // if intersection is not empty +- if (tmp != +- NULL) { // intersection for this type is not empty +- // check bounds +- if (tmp->type > GNUTLS_SAN_MAX || +- tmp->type == 0) { +- gnutls_free(tmp); +- return gnutls_assert_val( +- GNUTLS_E_INTERNAL_ERROR); +- } +- // we will not add universal excluded constraint for this type +- type_bitmask_clr(types_with_empty_intersection, +- tmp->type); +- // add intersection node to PERMITTED +- ret = name_constraints_node_list_add(permitted, +- tmp); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } +- } ++ switch (rel) { ++ case NC_SORTS_BEFORE: ++ assert(nc1 != NULL); /* comparator-guaranteed */ ++ /* if nothing to intersect with, shallow-copy nc1 */ ++ if (!type_bitmask_in(types_in_p2, nc1->type)) ++ ret = name_constraints_node_list_add(&result, ++ nc1); ++ i++; /* otherwise skip nc1 */ ++ break; ++ case NC_SORTS_AFTER: ++ assert(nc2 != NULL); /* comparator-guaranteed */ ++ /* if nothing to intersect with, deep-copy nc2 */ ++ if (!type_bitmask_in(types_in_p1, nc2->type)) ++ ret = name_constraints_node_add_copy( ++ nc, &result, nc2); ++ j++; /* otherwise skip nc2 */ ++ break; ++ case NC_INCLUDED_BY: /* add nc1, shallow-copy */ ++ assert(nc1 != NULL && nc2 != NULL); /* comparator */ ++ type_bitmask_clr(universal_exclude_needed, nc1->type); ++ ret = name_constraints_node_list_add(&result, nc1); ++ i++; ++ break; ++ case NC_INCLUDES: /* pick nc2, deep-copy */ ++ assert(nc1 != NULL && nc2 != NULL); /* comparator */ ++ type_bitmask_clr(universal_exclude_needed, nc2->type); ++ ret = name_constraints_node_add_copy(nc, &result, nc2); ++ j++; ++ break; ++ case NC_EQUAL: /* pick whichever: nc1, shallow-copy */ ++ assert(nc1 != NULL && nc2 != NULL); /* loop condition */ ++ type_bitmask_clr(universal_exclude_needed, nc1->type); ++ ret = name_constraints_node_list_add(&result, nc1); ++ i++; ++ j++; ++ break; + } +- // if the node from PERMITTED2 was not used for intersection, copy it to DEST +- // Beware: also copies nodes other than DNS, email, IP, +- // since their counterpart may have been moved in phase 1. +- if (!used) { +- ret = name_constraints_node_add_copy(nc, permitted, t2); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; + } + } + +- /* Phase 3 +- * For each type: If we have empty permitted name constraints now +- * and we didn't have at the beginning, we have to add a new +- * excluded constraint with universal wildcard +- * (since the intersection of permitted is now empty). */ ++ /* finishing touch: add universal excluded constraints for types where ++ * both lists had constraints, but all intersections ended up empty */ + for (type = 1; type <= GNUTLS_SAN_MAX; type++) { +- if (!type_bitmask_in(types_with_empty_intersection, type)) ++ if (!type_bitmask_in(universal_exclude_needed, type)) + continue; + _gnutls_hard_log( + "Adding universal excluded name constraint for type %d.\n", +@@ -871,14 +878,24 @@ static int name_constraints_node_list_intersect( + goto cleanup; + } + break; +- default: // do nothing, at least one node was already moved in phase 1 +- break; ++ default: /* unsupported type; should be unreacheable */ ++ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); ++ goto cleanup; + } + } ++ ++ gnutls_free(permitted->data); ++ gnutls_free(permitted->sorted_view); ++ permitted->data = result.data; ++ permitted->sorted_view = NULL; ++ permitted->size = result.size; ++ permitted->capacity = result.capacity; ++ permitted->dirty = true; ++ ++ result.data = NULL; + ret = GNUTLS_E_SUCCESS; +- + cleanup: +- gnutls_free(removed.data); ++ name_constraints_node_list_clear(&result); + return ret; + } + +@@ -1254,100 +1271,6 @@ static unsigned email_matches(const gnutls_datum_t *name, + return rel == NC_EQUAL || rel == NC_INCLUDED_BY; + } + +-/*- +- * name_constraints_intersect_nodes: +- * @nc1: name constraints node 1 +- * @nc2: name constraints node 2 +- * @_intersection: newly allocated node with intersected constraints, +- * NULL if the intersection is empty +- * +- * Inspect 2 name constraints nodes (of possibly different types) and allocate +- * a new node with intersection of given constraints. +- * +- * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value. +- -*/ +-static int name_constraints_intersect_nodes( +- gnutls_x509_name_constraints_t nc, +- const struct name_constraints_node_st *node1, +- const struct name_constraints_node_st *node2, +- struct name_constraints_node_st **_intersection) +-{ +- // presume empty intersection +- struct name_constraints_node_st *intersection = NULL; +- const struct name_constraints_node_st *to_copy = NULL; +- enum name_constraint_relation rel; +- +- *_intersection = NULL; +- +- if (node1->type != node2->type) { +- return GNUTLS_E_SUCCESS; +- } +- switch (node1->type) { +- case GNUTLS_SAN_DNSNAME: +- rel = compare_dns_names(&node1->name, &node2->name); +- switch (rel) { +- case NC_EQUAL: // equal means doesn't matter which one +- case NC_INCLUDES: // node2 is more specific +- to_copy = node2; +- break; +- case NC_INCLUDED_BY: // node1 is more specific +- to_copy = node1; +- break; +- case NC_SORTS_BEFORE: // no intersection +- case NC_SORTS_AFTER: // no intersection +- return GNUTLS_E_SUCCESS; +- } +- break; +- case GNUTLS_SAN_RFC822NAME: +- rel = compare_emails(&node1->name, &node2->name); +- switch (rel) { +- case NC_EQUAL: // equal means doesn't matter which one +- case NC_INCLUDES: // node2 is more specific +- to_copy = node2; +- break; +- case NC_INCLUDED_BY: // node1 is more specific +- to_copy = node1; +- break; +- case NC_SORTS_BEFORE: // no intersection +- case NC_SORTS_AFTER: // no intersection +- return GNUTLS_E_SUCCESS; +- } +- break; +- case GNUTLS_SAN_IPADDRESS: +- rel = compare_ip_ncs(&node1->name, &node2->name); +- switch (rel) { +- case NC_EQUAL: // equal means doesn't matter which one +- case NC_INCLUDES: // node2 is more specific +- to_copy = node2; +- break; +- case NC_INCLUDED_BY: // node1 is more specific +- to_copy = node1; +- break; +- case NC_SORTS_BEFORE: // no intersection +- case NC_SORTS_AFTER: // no intersection +- return GNUTLS_E_SUCCESS; +- } +- break; +- default: +- // for other types, we don't know how to do the intersection, assume empty +- return GNUTLS_E_SUCCESS; +- } +- +- // copy existing node if applicable +- if (to_copy != NULL) { +- *_intersection = name_constraints_node_new(nc, to_copy->type, +- to_copy->name.data, +- to_copy->name.size); +- if (*_intersection == NULL) +- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); +- intersection = *_intersection; +- +- assert(intersection->name.data != NULL); +- } +- +- return GNUTLS_E_SUCCESS; +-} +- + /* + * Returns: true if the certification is acceptable, and false otherwise. + */ +-- +2.52.0 + diff --git a/SOURCES/gnutls-3.8.10-CVE-2025-9820.patch b/SOURCES/gnutls-3.8.10-CVE-2025-9820.patch new file mode 100644 index 0000000..19e6008 --- /dev/null +++ b/SOURCES/gnutls-3.8.10-CVE-2025-9820.patch @@ -0,0 +1,411 @@ +From f23de850c8f37bd498bbdb1adc491ee05614ca11 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Fri, 6 Feb 2026 15:43:54 +0100 +Subject: [PATCH 1/2] tests/pkcs11/pkcs11-mock4: add, modified for 3.8.10 + +--- + tests/Makefile.am | 6 ++ + tests/pkcs11/pkcs11-mock4.c | 125 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 131 insertions(+) + create mode 100644 tests/pkcs11/pkcs11-mock4.c + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 9e5c7de84..62c4ec2f9 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -358,6 +358,11 @@ libpkcs11mock3_la_SOURCES = pkcs11/pkcs11-mock3.c + libpkcs11mock3_la_LDFLAGS = -shared -rpath $(pkglibdir) -module -no-undefined -avoid-version + libpkcs11mock3_la_LIBADD = ../gl/libgnu.la + ++noinst_LTLIBRARIES += libpkcs11mock4.la ++libpkcs11mock4_la_SOURCES = pkcs11/pkcs11-mock4.c ++libpkcs11mock4_la_LDFLAGS = -shared -rpath $(pkglibdir) -module -no-undefined -avoid-version ++libpkcs11mock4_la_LIBADD = ../gl/libgnu.la ++ + pkcs11_cert_import_url_exts_SOURCES = pkcs11/pkcs11-cert-import-url-exts.c + pkcs11_cert_import_url_exts_DEPENDENCIES = libpkcs11mock1.la libutils.la + +@@ -655,6 +660,7 @@ TESTS_ENVIRONMENT += \ + P11MOCKLIB1=$(abs_builddir)/.libs/libpkcs11mock1.so \ + P11MOCKLIB2=$(abs_builddir)/.libs/libpkcs11mock2.so \ + P11MOCKLIB3=$(abs_builddir)/.libs/libpkcs11mock3.so \ ++ P11MOCKLIB4=$(abs_builddir)/.libs/libpkcs11mock4.so \ + PKCS12_MANY_CERTS_FILE=$(srcdir)/cert-tests/data/pkcs12_5certs.p12 \ + PKCS12FILE=$(srcdir)/cert-tests/data/client.p12 \ + PKCS12PASSWORD=foobar \ +diff --git a/tests/pkcs11/pkcs11-mock4.c b/tests/pkcs11/pkcs11-mock4.c +new file mode 100644 +index 000000000..a6dd21cdd +--- /dev/null ++++ b/tests/pkcs11/pkcs11-mock4.c +@@ -0,0 +1,125 @@ ++/* ++ * Copyright (C) 2025 Red Hat, Inc. ++ * ++ * Author: Daiki Ueno ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program. If not, see ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "softhsm.h" ++ ++/* This provides a mock PKCS #11 module that delegates all the ++ * operations to SoftHSM except that it returns CKR_CANT_LOCK upon ++ * C_Initialize if CKF_OS_LOCKING_OK is set. ++ */ ++ ++static void *dl; ++static CK_C_Initialize base_C_Initialize; ++static CK_FUNCTION_LIST override_funcs; ++ ++#ifdef __sun ++#pragma fini(mock_deinit) ++#pragma init(mock_init) ++#define _CONSTRUCTOR ++#define _DESTRUCTOR ++#else ++#define _CONSTRUCTOR __attribute__((constructor)) ++#define _DESTRUCTOR __attribute__((destructor)) ++#endif ++ ++#define LOCK_FLAGS (CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_OS_LOCKING_OK) ++ ++static CK_RV override_C_Initialize(void *args) ++{ ++ CK_C_INITIALIZE_ARGS *init_args = args; ++ static bool first = true; ++ ++ // we don't have threadsafe initialization/fallback in 3.8.10... ++ /* ++ if (first) { ++ assert(init_args && ++ (init_args->flags & LOCK_FLAGS) == LOCK_FLAGS); ++ first = false; ++ return CKR_CANT_LOCK; ++ } else { ++ assert(!init_args || ++ (init_args->flags & LOCK_FLAGS) != LOCK_FLAGS); ++ } ++ */ ++ // ... so we expect 3.8.10 behaviour ++ assert(first); ++ assert(init_args); ++ assert(!(init_args->flags & LOCK_FLAGS) != LOCK_FLAGS); ++ first = false; ++ ++ return base_C_Initialize(args); ++} ++ ++CK_RV C_GetFunctionList(CK_FUNCTION_LIST **function_list) ++{ ++ CK_C_GetFunctionList func; ++ CK_FUNCTION_LIST *funcs; ++ ++ assert(dl); ++ ++ func = dlsym(dl, "C_GetFunctionList"); ++ if (func == NULL) { ++ return CKR_GENERAL_ERROR; ++ } ++ ++ func(&funcs); ++ ++ base_C_Initialize = funcs->C_Initialize; ++ ++ memcpy(&override_funcs, funcs, sizeof(CK_FUNCTION_LIST)); ++ override_funcs.C_Initialize = override_C_Initialize; ++ *function_list = &override_funcs; ++ ++ return CKR_OK; ++} ++ ++static _CONSTRUCTOR void mock_init(void) ++{ ++ const char *lib; ++ ++ /* suppress compiler warning */ ++ (void)set_softhsm_conf; ++ ++ lib = softhsm_lib(); ++ ++ dl = dlopen(lib, RTLD_NOW); ++ if (dl == NULL) ++ exit(77); ++} ++ ++static _DESTRUCTOR void mock_deinit(void) ++{ ++ dlclose(dl); ++} +-- +2.52.0 + + +From 87fc01fb853911e412e0fe238b069a68376ad8de Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 18 Nov 2025 13:17:55 +0900 +Subject: [PATCH 2/2] pkcs11: avoid stack overwrite when initializing a token + +If gnutls_pkcs11_token_init is called with label longer than 32 +characters, the internal storage used to blank-fill it would +overflow. This adds a guard to prevent that. + +Signed-off-by: Daiki Ueno +--- + lib/pkcs11_write.c | 5 +- + tests/Makefile.am | 4 +- + tests/pkcs11/long-label.c | 164 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 170 insertions(+), 3 deletions(-) + create mode 100644 tests/pkcs11/long-label.c + +diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c +index f5e9058e0..64b85a2df 100644 +--- a/lib/pkcs11_write.c ++++ b/lib/pkcs11_write.c +@@ -28,6 +28,7 @@ + #include "pkcs11x.h" + #include "x509/common.h" + #include "pk.h" ++#include "minmax.h" + + static const ck_bool_t tval = 1; + static const ck_bool_t fval = 0; +@@ -1172,7 +1173,7 @@ int gnutls_pkcs11_delete_url(const char *object_url, unsigned int flags) + * gnutls_pkcs11_token_init: + * @token_url: A PKCS #11 URL specifying a token + * @so_pin: Security Officer's PIN +- * @label: A name to be used for the token ++ * @label: A name to be used for the token, at most 32 characters + * + * This function will initialize (format) a token. If the token is + * at a factory defaults state the security officer's PIN given will be +@@ -1210,7 +1211,7 @@ int gnutls_pkcs11_token_init(const char *token_url, const char *so_pin, + /* so it seems memset has other uses than zeroing! */ + memset(flabel, ' ', sizeof(flabel)); + if (label != NULL) +- memcpy(flabel, label, strlen(label)); ++ memcpy(flabel, label, MIN(sizeof(flabel), strlen(label))); + + rv = pkcs11_init_token(module, slot, (uint8_t *)so_pin, strlen(so_pin), + (uint8_t *)flabel); +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 62c4ec2f9..0e4d04342 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -508,13 +508,15 @@ pathbuf_CPPFLAGS = $(AM_CPPFLAGS) \ + if ENABLE_PKCS11 + if !WINDOWS + ctests += tls13/post-handshake-with-cert-pkcs11 pkcs11/tls-neg-pkcs11-no-key \ +- global-init-override pkcs11/distrust-after ++ global-init-override pkcs11/distrust-after pkcs11/long-label + tls13_post_handshake_with_cert_pkcs11_DEPENDENCIES = libpkcs11mock2.la libutils.la + tls13_post_handshake_with_cert_pkcs11_LDADD = $(LDADD) $(LIBDL) + pkcs11_tls_neg_pkcs11_no_key_DEPENDENCIES = libpkcs11mock2.la libutils.la + pkcs11_tls_neg_pkcs11_no_key_LDADD = $(LDADD) $(LIBDL) + pkcs11_distrust_after_DEPENDENCIES = libpkcs11mock3.la libutils.la + pkcs11_distrust_after_LDADD = $(LDADD) $(LIBDL) ++pkcs11_long_label_DEPENDENCIES = libpkcs11mock4.la libutils.la ++pkcs11_long_label_LDADD = $(LDADD) $(LIBDL) + endif + endif + +diff --git a/tests/pkcs11/long-label.c b/tests/pkcs11/long-label.c +new file mode 100644 +index 000000000..a70bc9728 +--- /dev/null ++++ b/tests/pkcs11/long-label.c +@@ -0,0 +1,164 @@ ++/* ++ * Copyright (C) 2025 Red Hat, Inc. ++ * ++ * Author: Daiki Ueno ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program. If not, see ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++#if defined(_WIN32) ++ ++int main(void) ++{ ++ exit(77); ++} ++ ++#else ++ ++#include ++#include ++#include ++ ++#include "cert-common.h" ++#include "pkcs11/softhsm.h" ++#include "utils.h" ++ ++/* This program tests that a token can be initialized with ++ * a label longer than 32 characters. ++ */ ++ ++static void tls_log_func(int level, const char *str) ++{ ++ fprintf(stderr, "server|<%d>| %s", level, str); ++} ++ ++#define PIN "1234" ++ ++#define CONFIG_NAME "softhsm-long-label" ++#define CONFIG CONFIG_NAME ".config" ++ ++static int pin_func(void *userdata, int attempt, const char *url, ++ const char *label, unsigned flags, char *pin, ++ size_t pin_max) ++{ ++ if (attempt == 0) { ++ strcpy(pin, PIN); ++ return 0; ++ } ++ return -1; ++} ++ ++static void test(const char *provider) ++{ ++ int ret; ++ size_t i; ++ ++ gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL); ++ ++ success("test with %s\n", provider); ++ ++ if (debug) { ++ gnutls_global_set_log_function(tls_log_func); ++ gnutls_global_set_log_level(4711); ++ } ++ ++ /* point to SoftHSM token that libpkcs11mock4.so internally uses */ ++ setenv(SOFTHSM_ENV, CONFIG, 1); ++ ++ gnutls_pkcs11_set_pin_function(pin_func, NULL); ++ ++ ret = gnutls_pkcs11_add_provider(provider, "trusted"); ++ if (ret != 0) { ++ fail("gnutls_pkcs11_add_provider: %s\n", gnutls_strerror(ret)); ++ } ++ ++ /* initialize softhsm token */ ++ ret = gnutls_pkcs11_token_init( ++ SOFTHSM_URL, PIN, ++ "this is a very long label whose length exceeds 32"); ++ if (ret < 0) { ++ fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret)); ++ } ++ ++ for (i = 0;; i++) { ++ char *url = NULL; ++ ++ ret = gnutls_pkcs11_token_get_url(i, 0, &url); ++ if (ret < 0) ++ break; ++ if (strstr(url, ++ "token=this%20is%20a%20very%20long%20label%20whose")) ++ break; ++ } ++ if (ret < 0) ++ fail("gnutls_pkcs11_token_get_url: %s\n", gnutls_strerror(ret)); ++ ++ gnutls_pkcs11_deinit(); ++} ++ ++void doit(void) ++{ ++ const char *bin; ++ const char *lib; ++ char buf[128]; ++ ++ if (gnutls_fips140_mode_enabled()) ++ exit(77); ++ ++ /* this must be called once in the program */ ++ global_init(); ++ ++ /* we call gnutls_pkcs11_init manually */ ++ gnutls_pkcs11_deinit(); ++ ++ /* check if softhsm module is loadable */ ++ lib = softhsm_lib(); ++ ++ /* initialize SoftHSM token that libpkcs11mock4.so internally uses */ ++ bin = softhsm_bin(); ++ ++ set_softhsm_conf(CONFIG); ++ snprintf(buf, sizeof(buf), ++ "%s --init-token --slot 0 --label test --so-pin " PIN ++ " --pin " PIN, ++ bin); ++ system(buf); ++ ++ test(lib); ++ ++ lib = getenv("P11MOCKLIB4"); ++ if (lib == NULL) { ++ fail("P11MOCKLIB4 is not set\n"); ++ } ++ ++ set_softhsm_conf(CONFIG); ++ snprintf(buf, sizeof(buf), ++ "%s --init-token --slot 0 --label test --so-pin " PIN ++ " --pin " PIN, ++ bin); ++ system(buf); ++ ++ test(lib); ++} ++#endif /* _WIN32 */ +-- +2.52.0 + diff --git a/SOURCES/gnutls-3.8.3-keyupdate.patch b/SOURCES/gnutls-3.8.10-keyupdate.patch similarity index 96% rename from SOURCES/gnutls-3.8.3-keyupdate.patch rename to SOURCES/gnutls-3.8.10-keyupdate.patch index 6cc5176..b882686 100644 --- a/SOURCES/gnutls-3.8.3-keyupdate.patch +++ b/SOURCES/gnutls-3.8.10-keyupdate.patch @@ -1,4 +1,4 @@ -From 3f5dd79d8abd40193ab3ce9b3ee9a30bf77b34ba Mon Sep 17 00:00:00 2001 +From 5376a0cabf94314316005e6bf411ffcc7628b386 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 22 Jul 2025 10:49:33 +0900 Subject: [PATCH 1/3] key_update: fix state transition in KTLS code path @@ -22,10 +22,10 @@ index d37f79a550..ebc75addec 100644 session->internals.record_key_update_buffer.data, session->internals.record_key_update_buffer -- -2.50.1 +GitLab -From fee06c4ac19129e0f5f4b639919a4ff244bf174c Mon Sep 17 00:00:00 2001 +From 30c264b661d49d135ef342426c6c4cd853209c06 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Thu, 31 Jul 2025 15:34:48 +0900 Subject: [PATCH 2/3] constate: switch epoch lookup to linear search @@ -119,10 +119,10 @@ index ca253a2bea..b091d891ff 100644 _gnutls_record_log("REC[%p]: End of epoch cleanup\n", session); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h -index e9ec36d585..cc5d965593 100644 +index 539486bc7d..e083520055 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h -@@ -860,9 +860,6 @@ typedef struct { +@@ -876,9 +876,6 @@ typedef struct { /* The epoch that the next handshake will initialize. */ uint16_t epoch_next; @@ -133,10 +133,10 @@ index e9ec36d585..cc5d965593 100644 * moved here from internals in order to be restored * on resume; -- -2.50.1 +GitLab -From 0d25525656d3bcf2d8ca9d17d5ebe7cb738ed4c2 Mon Sep 17 00:00:00 2001 +From 1d830baac2f8a08a40b13e9eecfcc64ad032e7b5 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sat, 19 Jul 2025 07:08:24 +0900 Subject: [PATCH 3/3] key_update: rework the rekeying logic @@ -158,10 +158,10 @@ Signed-off-by: Daiki Ueno 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h -index cc5d965593..a7684f75c1 100644 +index e083520055..f3caea1170 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h -@@ -1652,7 +1652,7 @@ typedef struct { +@@ -1672,7 +1672,7 @@ typedef struct { } internals_st; /* Maximum number of epochs we keep around. */ @@ -291,5 +291,5 @@ index 41243651b5..beee1dc41a 100644 return gnutls_assert_val(ret); -- -2.50.1 +GitLab diff --git a/SOURCES/gnutls-3.8.10-rhel9-revert-pbmac1-fips-default.patch b/SOURCES/gnutls-3.8.10-rhel9-revert-pbmac1-fips-default.patch new file mode 100644 index 0000000..879fa61 --- /dev/null +++ b/SOURCES/gnutls-3.8.10-rhel9-revert-pbmac1-fips-default.patch @@ -0,0 +1,51 @@ +commit b493de9ba31636de2f3b0c1dafab39b6412550bd +Author: Alexander Sosedkin +Date: Wed Nov 19 10:46:52 2025 +0100 + + Revert "pkcs12: enable PBMAC1 by default in FIPS mode" + + This reverts commit e52c7ca885798c40efb4ed6505e0690fc38c7dde. + +diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c +index a71f3ee561..18aae0bd49 100644 +--- a/lib/x509/pkcs12.c ++++ b/lib/x509/pkcs12.c +@@ -997,12 +997,6 @@ int gnutls_pkcs12_generate_mac3(gnutls_pkcs12_t pkcs12, + if (me->oid == NULL) + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); + +- /* Enable PBMAC1 by default in FIPS mode; otherwise the MAC +- * calculation will be FIPS non-compliant. +- */ +- if (_gnutls_fips_mode_enabled()) +- flags |= GNUTLS_PKCS12_USE_PBMAC1; +- + /* Generate the salt. + */ + salt.data = salt_data; +diff --git a/tests/cert-tests/pkcs12-pbmac1.sh b/tests/cert-tests/pkcs12-pbmac1.sh +index 0c2a16b52c..ef72c0a1c4 100644 +--- a/tests/cert-tests/pkcs12-pbmac1.sh ++++ b/tests/cert-tests/pkcs12-pbmac1.sh +@@ -109,21 +109,6 @@ if test ${rc} != 0; then + exit 1 + fi + +-# check if PBMAC1 is used by default in FIPS mode +-if test "$GNUTLS_FORCE_FIPS_MODE" = 1; then +- ${VALGRIND} "$CERTTOOL" --to-p12 --password 1234 --p12-name "my-key" --load-certificate "$srcdir/../certs/cert-ecc256.pem" --load-privkey "$srcdir/../certs/ecc256.pem" --outder --outfile "$TMPFILE" >/dev/null +- rc=$? +- if test $rc != 0; then +- echo "PKCS12 FATAL encoding" +- exit 1 +- fi +- ${VALGRIND} "$CERTTOOL" -d 99 --p12-info --inder --password 1234 \ +- --infile "$TMPFILE" | grep "^ MAC: PBMAC1" || { +- echo "Generated PKCS12 file doesn't use PBMAC1 in FIPS mode" +- exit 1 +- } +-fi +- + rm -rf "${testdir}" + + exit 0 diff --git a/SOURCES/gnutls-3.8.10-rhel9-revert-rsa-less-than-2048.patch b/SOURCES/gnutls-3.8.10-rhel9-revert-rsa-less-than-2048.patch new file mode 100644 index 0000000..1b53dc6 --- /dev/null +++ b/SOURCES/gnutls-3.8.10-rhel9-revert-rsa-less-than-2048.patch @@ -0,0 +1,75 @@ +commit bf374b4151c7f6cf4b94e9eb911ceb730904a44c +Author: Alexander Sosedkin +Date: Wed Nov 19 10:48:51 2025 +0100 + + Revert "fips: Allow SigVer only with RSA keys with modulus >= 2048 bits" + + This reverts commit da1df0a3167ec96605fed267d97f9081cf498eec. + +diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c +index 5986a410c2..d14efbaaf0 100644 +--- a/lib/nettle/pk.c ++++ b/lib/nettle/pk.c +@@ -2474,12 +2474,16 @@ static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + + bits = mpz_sizeinbase(pub.n, 2); + +- /* In FIPS 140-3, RSA key size should be larger than 2048-bit. ++ /* In FIPS 140-3, RSA key size should be larger than ++ * 2048-bit or one of the known lengths (1024, 1280, ++ * 1536, 1792; i.e., multiple of 256-bits). ++ * + * In addition to this, only SHA-2 is allowed + * for SigVer; it is checked in _pkcs1_rsa_verify_sig in + * lib/pubkey.c. + */ +- if (unlikely(bits < 2048)) { ++ if (unlikely(bits < 2048 && bits != 1024 && bits != 1280 && ++ bits != 1536 && bits != 1792)) { + not_approved = true; + } + +diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c +index 61a76d3c09..d134a35f8c 100644 +--- a/tests/fips-rsa-sizes.c ++++ b/tests/fips-rsa-sizes.c +@@ -250,24 +250,35 @@ void doit(void) + + assert(gnutls_fips140_context_init(&fips_context) == 0); + ++ /* 512-bit RSA: no generate, no sign, no verify */ + generate_unsuccessfully(&privkey, &pubkey, 512); + sign_verify_unsuccessfully(privkey, pubkey); ++ /* 512-bit RSA again (to be safer about going in and out of FIPS) */ + generate_unsuccessfully(&privkey, &pubkey, 512); + sign_verify_unsuccessfully(privkey, pubkey); ++ /* 600-bit RSA: no generate, no sign, no verify */ + generate_unsuccessfully(&privkey, &pubkey, 600); + sign_verify_unsuccessfully(privkey, pubkey); ++ ++ /* 768-bit RSA not-an-exception: nogenerate, nosign, verify */ + generate_unsuccessfully(&privkey, &pubkey, 768); + sign_verify_unsuccessfully(privkey, pubkey); ++ /* 1024-bit RSA exception: nogenerate, nosign, verify */ + generate_unsuccessfully(&privkey, &pubkey, 1024); +- sign_verify_unsuccessfully(privkey, pubkey); ++ nosign_verify(privkey, pubkey); ++ /* 1280-bit RSA exception: nogenerate, nosign, verify */ + generate_unsuccessfully(&privkey, &pubkey, 1280); +- sign_verify_unsuccessfully(privkey, pubkey); ++ nosign_verify(privkey, pubkey); ++ /* 1500-bit RSA not-an-exception: nogenerate, nosign, noverify */ + generate_unsuccessfully(&privkey, &pubkey, 1500); + sign_verify_unsuccessfully(privkey, pubkey); ++ /* 1536-bit RSA exception: nogenerate, nosign, verify */ + generate_unsuccessfully(&privkey, &pubkey, 1536); +- sign_verify_unsuccessfully(privkey, pubkey); ++ nosign_verify(privkey, pubkey); ++ /* 1792-bit RSA exception: nogenerate, nosign, verify */ + generate_unsuccessfully(&privkey, &pubkey, 1792); +- sign_verify_unsuccessfully(privkey, pubkey); ++ nosign_verify(privkey, pubkey); ++ /* 2000-bit RSA not-an-exception: nogenerate, nosign, noverify */ + generate_unsuccessfully(&privkey, &pubkey, 2000); + sign_verify_unsuccessfully(privkey, pubkey); + diff --git a/SOURCES/gnutls-3.8.10-tests-ktls.patch b/SOURCES/gnutls-3.8.10-tests-ktls.patch new file mode 100644 index 0000000..1b23124 --- /dev/null +++ b/SOURCES/gnutls-3.8.10-tests-ktls.patch @@ -0,0 +1,114 @@ +From e0eb2bbb212a5c9d72311c59e7235832a0075dcc Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 9 Jul 2025 18:54:48 +0900 +Subject: [PATCH] add tests/ktls_utils.h + +Signed-off-by: rpm-build +--- + tests/ktls_utils.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 94 insertions(+) + create mode 100644 tests/ktls_utils.h + +diff --git a/tests/ktls_utils.h b/tests/ktls_utils.h +new file mode 100644 +index 0000000..231618d +--- /dev/null ++++ b/tests/ktls_utils.h +@@ -0,0 +1,94 @@ ++#ifndef GNUTLS_TESTS_KTLS_UTILS_H ++#define GNUTLS_TESTS_KTLS_UTILS_H ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++/* Sets the NONBLOCK flag on the socket(fd) */ ++inline static int set_nonblocking(int fd) ++{ ++ int flags = fcntl(fd, F_GETFL, 0); ++ if (flags == -1) { ++ return 1; ++ } ++ ++ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { ++ return 2; ++ } ++ ++ return 0; ++} ++ ++/* Creates a pair of TCP connected sockets */ ++static int create_socket_pair(int *client_fd, int *server_fd) ++{ ++ int ret; ++ struct sockaddr_in saddr; ++ socklen_t addrlen; ++ int listener; ++ ++ listener = socket(AF_INET, SOCK_STREAM, 0); ++ if (listener == -1) { ++ fail("error in listener(): %s\n", strerror(errno)); ++ return 1; ++ } ++ ++ int opt = 0; ++ setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); ++ ++ memset(&saddr, 0, sizeof(saddr)); ++ saddr.sin_family = AF_INET; ++ saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); ++ saddr.sin_port = 0; ++ ++ ret = bind(listener, (struct sockaddr *)&saddr, sizeof(saddr)); ++ if (ret == -1) { ++ fail("error in bind(): %s\n", strerror(errno)); ++ return 1; ++ } ++ ++ addrlen = sizeof(saddr); ++ ret = getsockname(listener, (struct sockaddr *)&saddr, &addrlen); ++ if (ret == -1) { ++ fail("error in getsockname(): %s\n", strerror(errno)); ++ return 1; ++ } ++ ++ ret = listen(listener, 1); ++ if (ret == -1) { ++ fail("error in listen(): %s\n", strerror(errno)); ++ close(listener); ++ return 1; ++ } ++ ++ *client_fd = socket(AF_INET, SOCK_STREAM, 0); ++ if (*client_fd < 0) { ++ fail("error in socket(): %s\n", strerror(errno)); ++ return 1; ++ } ++ ++ ret = connect(*client_fd, (struct sockaddr *)&saddr, addrlen); ++ if (ret < 0) { ++ fail("error in connect(): %s\n", strerror(errno)); ++ close(listener); ++ close(*client_fd); ++ return 1; ++ } ++ ++ *server_fd = accept(listener, NULL, NULL); ++ if (*server_fd < 0) { ++ fail("error in accept(): %s\n", strerror(errno)); ++ close(listener); ++ close(*client_fd); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#endif //GNUTLS_TESTS_KTLS_UTILS_H +-- +2.49.0 + diff --git a/SOURCES/gnutls-3.8.3-cve-2025-32988.patch b/SOURCES/gnutls-3.8.3-cve-2025-32988.patch deleted file mode 100644 index 6500742..0000000 --- a/SOURCES/gnutls-3.8.3-cve-2025-32988.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f1fe8d2a7669c4cdcdaaabd8969d358040c142ad Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 7 Jul 2025 10:44:12 +0900 -Subject: [PATCH] x509: avoid double free when exporting othernames in SAN - -Previously, the _gnutls_write_new_othername function, called by -gnutls_x509_ext_export_subject_alt_names to export "otherName" in a -certificate's SAN extension, freed the caller allocated ASN.1 -structure upon error, resulting in a potential double-free. - -Reported by OpenAI Security Research Team. - -Signed-off-by: Daiki Ueno ---- - lib/x509/extensions.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c -index 6c2da8fd10..e8be12eaf5 100644 ---- a/lib/x509/extensions.c -+++ b/lib/x509/extensions.c -@@ -754,7 +754,6 @@ int _gnutls_write_new_othername(asn1_node ext, const char *ext_name, - result = asn1_write_value(ext, name2, oid, 1); - if (result != ASN1_SUCCESS) { - gnutls_assert(); -- asn1_delete_structure(&ext); - return _gnutls_asn2err(result); - } - -@@ -763,7 +762,6 @@ int _gnutls_write_new_othername(asn1_node ext, const char *ext_name, - result = asn1_write_value(ext, name2, data, data_size); - if (result != ASN1_SUCCESS) { - gnutls_assert(); -- asn1_delete_structure(&ext); - return _gnutls_asn2err(result); - } - --- -2.50.0 - diff --git a/SOURCES/gnutls-3.8.3-cve-2025-32989.patch b/SOURCES/gnutls-3.8.3-cve-2025-32989.patch deleted file mode 100644 index d838a90..0000000 --- a/SOURCES/gnutls-3.8.3-cve-2025-32989.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 639a551c6d4707c7fb880412d695dbdd31f60cf3 Mon Sep 17 00:00:00 2001 -From: Andrew Hamilton -Date: Mon, 7 Jul 2025 10:23:59 +0900 -Subject: [PATCH] x509: fix read buffer overrun in SCT timestamps - -Prevent reading beyond heap buffer in call to _gnutls_parse_ct_sct -when processing x509 Signed Certificate Timestamps with certain -malformed data. Spotted by oss-fuzz at: -https://issues.oss-fuzz.com/issues/42530513 - -Signed-off-by: Andrew Hamilton -Signed-off-by: Daiki Ueno ---- - lib/x509/x509_ext.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c -index ad3af1430a..9a36f3536b 100644 ---- a/lib/x509/x509_ext.c -+++ b/lib/x509/x509_ext.c -@@ -3759,7 +3759,7 @@ int gnutls_x509_ext_ct_import_scts(const gnutls_datum_t *ext, - } - - length = _gnutls_read_uint16(scts_content.data); -- if (length < 4) { -+ if (length < 4 || length > scts_content.size) { - gnutls_free(scts_content.data); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } --- -2.50.0 - diff --git a/SOURCES/gnutls-3.8.3-cve-2025-32990.patch b/SOURCES/gnutls-3.8.3-cve-2025-32990.patch deleted file mode 100644 index 8ea61e6..0000000 --- a/SOURCES/gnutls-3.8.3-cve-2025-32990.patch +++ /dev/null @@ -1,2092 +0,0 @@ -From 318d18f21b2a20e6e9d10081d46af2cafda38582 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 7 Jul 2025 10:57:10 +0900 -Subject: [PATCH] certtool: avoid 1-byte write buffer overrun when parsing - template - -Previously, when parsing a template file with a number of key value -pairs, certtool could write a NUL byte after the heap buffer, causing -a memory corruption. This fixes the issue by allocating the NUL byte. -Reported by David Aitel. - -Signed-off-by: Daiki Ueno ---- - src/certtool-cfg.c | 4 +- - tests/cert-tests/Makefile.am | 3 +- - tests/cert-tests/template-test.sh | 13 + - .../template-too-many-othernames.tmpl | 2003 +++++++++++++++++ - 4 files changed, 2020 insertions(+), 3 deletions(-) - create mode 100644 tests/cert-tests/templates/template-too-many-othernames.tmpl - -diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c -index 2d7a1dcaf6..bce2390a85 100644 ---- a/src/certtool-cfg.c -+++ b/src/certtool-cfg.c -@@ -257,7 +257,7 @@ void cfg_init(void) - if (val != NULL) { \ - if (s_name == NULL) { \ - i = 0; \ -- s_name = malloc(sizeof(char *) * MAX_ENTRIES); \ -+ s_name = calloc(MAX_ENTRIES + 1, sizeof(char *)); \ - CHECK_MALLOC(s_name); \ - do { \ - if (val && strcmp(val->name, k_name) != 0) \ -@@ -279,7 +279,7 @@ void cfg_init(void) - char *p; \ - if (s_name == NULL) { \ - i = 0; \ -- s_name = malloc(sizeof(char *) * MAX_ENTRIES); \ -+ s_name = calloc(MAX_ENTRIES + 1, sizeof(char *)); \ - CHECK_MALLOC(s_name); \ - do { \ - if (val && strcmp(val->name, k_name) != 0) \ -diff --git a/tests/cert-tests/Makefile.am b/tests/cert-tests/Makefile.am -index f419c70512..12661a26e6 100644 ---- a/tests/cert-tests/Makefile.am -+++ b/tests/cert-tests/Makefile.am -@@ -102,7 +102,8 @@ EXTRA_DIST = data/ca-no-pathlen.pem data/no-ca-or-pathlen.pem data/aki-cert.pem - data/chain-512-leaf.pem data/chain-512-subca.pem data/chain-512-ca.pem \ - templates/template-no-ca-honor.tmpl templates/template-no-ca-explicit.tmpl \ - data/crq-cert-no-ca-explicit.pem data/crq-cert-no-ca-honor.pem data/commonName.cer \ -- templates/simple-policy.tmpl data/simple-policy.pem templates/template-negative-serial.tmpl -+ templates/simple-policy.tmpl data/simple-policy.pem templates/template-negative-serial.tmpl \ -+ templates/template-too-many-othernames.tmpl - - dist_check_SCRIPTS = pathlen.sh aki.sh invalid-sig.sh email.sh \ - pkcs7.sh pkcs7-broken-sigs.sh privkey-import.sh name-constraints.sh certtool-long-cn.sh crl.sh provable-privkey.sh \ -diff --git a/tests/cert-tests/template-test.sh b/tests/cert-tests/template-test.sh -index 5d7410eb3d..34e3027ae6 100644 ---- a/tests/cert-tests/template-test.sh -+++ b/tests/cert-tests/template-test.sh -@@ -297,6 +297,19 @@ if test "${rc}" != "0"; then - exit ${rc} - fi - -+# Test generation with too many other names -+ -+"${CERTTOOL}" --generate-request \ -+ --load-privkey "${srcdir}/data/template-test.key" \ -+ --template "${srcdir}/templates/template-too-many-othernames.tmpl" \ -+ --outfile ${TMPFILE} 2>/dev/null -+rc=$? -+ -+if test "${rc}" != "0"; then -+ echo "Test with too many othernames failed" -+ exit ${rc} -+fi -+ - rm -f ${TMPFILE} - - exit 0 -diff --git a/tests/cert-tests/templates/template-too-many-othernames.tmpl b/tests/cert-tests/templates/template-too-many-othernames.tmpl -new file mode 100644 -index 0000000000..5ef9a862bd ---- /dev/null -+++ b/tests/cert-tests/templates/template-too-many-othernames.tmpl -@@ -0,0 +1,2003 @@ -+organization = "OpenAI" -+cn = "example.com" -+ -+other_name_utf8 = "1.2.3.4 testvalue0" -+other_name_utf8 = "1.2.3.4 testvalue1" -+other_name_utf8 = "1.2.3.4 testvalue2" -+other_name_utf8 = "1.2.3.4 testvalue3" -+other_name_utf8 = "1.2.3.4 testvalue4" -+other_name_utf8 = "1.2.3.4 testvalue5" -+other_name_utf8 = "1.2.3.4 testvalue6" -+other_name_utf8 = "1.2.3.4 testvalue7" -+other_name_utf8 = "1.2.3.4 testvalue8" -+other_name_utf8 = "1.2.3.4 testvalue9" -+other_name_utf8 = "1.2.3.4 testvalue10" -+other_name_utf8 = "1.2.3.4 testvalue11" -+other_name_utf8 = "1.2.3.4 testvalue12" -+other_name_utf8 = "1.2.3.4 testvalue13" -+other_name_utf8 = "1.2.3.4 testvalue14" -+other_name_utf8 = "1.2.3.4 testvalue15" -+other_name_utf8 = "1.2.3.4 testvalue16" -+other_name_utf8 = "1.2.3.4 testvalue17" -+other_name_utf8 = "1.2.3.4 testvalue18" -+other_name_utf8 = "1.2.3.4 testvalue19" -+other_name_utf8 = "1.2.3.4 testvalue20" -+other_name_utf8 = "1.2.3.4 testvalue21" -+other_name_utf8 = "1.2.3.4 testvalue22" -+other_name_utf8 = "1.2.3.4 testvalue23" -+other_name_utf8 = "1.2.3.4 testvalue24" -+other_name_utf8 = "1.2.3.4 testvalue25" -+other_name_utf8 = "1.2.3.4 testvalue26" -+other_name_utf8 = "1.2.3.4 testvalue27" -+other_name_utf8 = "1.2.3.4 testvalue28" -+other_name_utf8 = "1.2.3.4 testvalue29" -+other_name_utf8 = "1.2.3.4 testvalue30" -+other_name_utf8 = "1.2.3.4 testvalue31" -+other_name_utf8 = "1.2.3.4 testvalue32" -+other_name_utf8 = "1.2.3.4 testvalue33" -+other_name_utf8 = "1.2.3.4 testvalue34" -+other_name_utf8 = "1.2.3.4 testvalue35" -+other_name_utf8 = "1.2.3.4 testvalue36" -+other_name_utf8 = "1.2.3.4 testvalue37" -+other_name_utf8 = "1.2.3.4 testvalue38" -+other_name_utf8 = "1.2.3.4 testvalue39" -+other_name_utf8 = "1.2.3.4 testvalue40" -+other_name_utf8 = "1.2.3.4 testvalue41" -+other_name_utf8 = "1.2.3.4 testvalue42" -+other_name_utf8 = "1.2.3.4 testvalue43" -+other_name_utf8 = "1.2.3.4 testvalue44" -+other_name_utf8 = "1.2.3.4 testvalue45" -+other_name_utf8 = "1.2.3.4 testvalue46" -+other_name_utf8 = "1.2.3.4 testvalue47" -+other_name_utf8 = "1.2.3.4 testvalue48" -+other_name_utf8 = "1.2.3.4 testvalue49" -+other_name_utf8 = "1.2.3.4 testvalue50" -+other_name_utf8 = "1.2.3.4 testvalue51" -+other_name_utf8 = "1.2.3.4 testvalue52" -+other_name_utf8 = "1.2.3.4 testvalue53" -+other_name_utf8 = "1.2.3.4 testvalue54" -+other_name_utf8 = "1.2.3.4 testvalue55" -+other_name_utf8 = "1.2.3.4 testvalue56" -+other_name_utf8 = "1.2.3.4 testvalue57" -+other_name_utf8 = "1.2.3.4 testvalue58" -+other_name_utf8 = "1.2.3.4 testvalue59" -+other_name_utf8 = "1.2.3.4 testvalue60" -+other_name_utf8 = "1.2.3.4 testvalue61" -+other_name_utf8 = "1.2.3.4 testvalue62" -+other_name_utf8 = "1.2.3.4 testvalue63" -+other_name_utf8 = "1.2.3.4 testvalue64" -+other_name_utf8 = "1.2.3.4 testvalue65" -+other_name_utf8 = "1.2.3.4 testvalue66" -+other_name_utf8 = "1.2.3.4 testvalue67" -+other_name_utf8 = "1.2.3.4 testvalue68" -+other_name_utf8 = "1.2.3.4 testvalue69" -+other_name_utf8 = "1.2.3.4 testvalue70" -+other_name_utf8 = "1.2.3.4 testvalue71" -+other_name_utf8 = "1.2.3.4 testvalue72" -+other_name_utf8 = "1.2.3.4 testvalue73" -+other_name_utf8 = "1.2.3.4 testvalue74" -+other_name_utf8 = "1.2.3.4 testvalue75" -+other_name_utf8 = "1.2.3.4 testvalue76" -+other_name_utf8 = "1.2.3.4 testvalue77" -+other_name_utf8 = "1.2.3.4 testvalue78" -+other_name_utf8 = "1.2.3.4 testvalue79" -+other_name_utf8 = "1.2.3.4 testvalue80" -+other_name_utf8 = "1.2.3.4 testvalue81" -+other_name_utf8 = "1.2.3.4 testvalue82" -+other_name_utf8 = "1.2.3.4 testvalue83" -+other_name_utf8 = "1.2.3.4 testvalue84" -+other_name_utf8 = "1.2.3.4 testvalue85" -+other_name_utf8 = "1.2.3.4 testvalue86" -+other_name_utf8 = "1.2.3.4 testvalue87" -+other_name_utf8 = "1.2.3.4 testvalue88" -+other_name_utf8 = "1.2.3.4 testvalue89" -+other_name_utf8 = "1.2.3.4 testvalue90" -+other_name_utf8 = "1.2.3.4 testvalue91" -+other_name_utf8 = "1.2.3.4 testvalue92" -+other_name_utf8 = "1.2.3.4 testvalue93" -+other_name_utf8 = "1.2.3.4 testvalue94" -+other_name_utf8 = "1.2.3.4 testvalue95" -+other_name_utf8 = "1.2.3.4 testvalue96" -+other_name_utf8 = "1.2.3.4 testvalue97" -+other_name_utf8 = "1.2.3.4 testvalue98" -+other_name_utf8 = "1.2.3.4 testvalue99" -+other_name_utf8 = "1.2.3.4 testvalue100" -+other_name_utf8 = "1.2.3.4 testvalue101" -+other_name_utf8 = "1.2.3.4 testvalue102" -+other_name_utf8 = "1.2.3.4 testvalue103" -+other_name_utf8 = "1.2.3.4 testvalue104" -+other_name_utf8 = "1.2.3.4 testvalue105" -+other_name_utf8 = "1.2.3.4 testvalue106" -+other_name_utf8 = "1.2.3.4 testvalue107" -+other_name_utf8 = "1.2.3.4 testvalue108" -+other_name_utf8 = "1.2.3.4 testvalue109" -+other_name_utf8 = "1.2.3.4 testvalue110" -+other_name_utf8 = "1.2.3.4 testvalue111" -+other_name_utf8 = "1.2.3.4 testvalue112" -+other_name_utf8 = "1.2.3.4 testvalue113" -+other_name_utf8 = "1.2.3.4 testvalue114" -+other_name_utf8 = "1.2.3.4 testvalue115" -+other_name_utf8 = "1.2.3.4 testvalue116" -+other_name_utf8 = "1.2.3.4 testvalue117" -+other_name_utf8 = "1.2.3.4 testvalue118" -+other_name_utf8 = "1.2.3.4 testvalue119" -+other_name_utf8 = "1.2.3.4 testvalue120" -+other_name_utf8 = "1.2.3.4 testvalue121" -+other_name_utf8 = "1.2.3.4 testvalue122" -+other_name_utf8 = "1.2.3.4 testvalue123" -+other_name_utf8 = "1.2.3.4 testvalue124" -+other_name_utf8 = "1.2.3.4 testvalue125" -+other_name_utf8 = "1.2.3.4 testvalue126" -+other_name_utf8 = "1.2.3.4 testvalue127" -+other_name_utf8 = "1.2.3.4 testvalue128" -+other_name_utf8 = "1.2.3.4 testvalue129" -+other_name_utf8 = "1.2.3.4 testvalue130" -+other_name_utf8 = "1.2.3.4 testvalue131" -+other_name_utf8 = "1.2.3.4 testvalue132" -+other_name_utf8 = "1.2.3.4 testvalue133" -+other_name_utf8 = "1.2.3.4 testvalue134" -+other_name_utf8 = "1.2.3.4 testvalue135" -+other_name_utf8 = "1.2.3.4 testvalue136" -+other_name_utf8 = "1.2.3.4 testvalue137" -+other_name_utf8 = "1.2.3.4 testvalue138" -+other_name_utf8 = "1.2.3.4 testvalue139" -+other_name_utf8 = "1.2.3.4 testvalue140" -+other_name_utf8 = "1.2.3.4 testvalue141" -+other_name_utf8 = "1.2.3.4 testvalue142" -+other_name_utf8 = "1.2.3.4 testvalue143" -+other_name_utf8 = "1.2.3.4 testvalue144" -+other_name_utf8 = "1.2.3.4 testvalue145" -+other_name_utf8 = "1.2.3.4 testvalue146" -+other_name_utf8 = "1.2.3.4 testvalue147" -+other_name_utf8 = "1.2.3.4 testvalue148" -+other_name_utf8 = "1.2.3.4 testvalue149" -+other_name_utf8 = "1.2.3.4 testvalue150" -+other_name_utf8 = "1.2.3.4 testvalue151" -+other_name_utf8 = "1.2.3.4 testvalue152" -+other_name_utf8 = "1.2.3.4 testvalue153" -+other_name_utf8 = "1.2.3.4 testvalue154" -+other_name_utf8 = "1.2.3.4 testvalue155" -+other_name_utf8 = "1.2.3.4 testvalue156" -+other_name_utf8 = "1.2.3.4 testvalue157" -+other_name_utf8 = "1.2.3.4 testvalue158" -+other_name_utf8 = "1.2.3.4 testvalue159" -+other_name_utf8 = "1.2.3.4 testvalue160" -+other_name_utf8 = "1.2.3.4 testvalue161" -+other_name_utf8 = "1.2.3.4 testvalue162" -+other_name_utf8 = "1.2.3.4 testvalue163" -+other_name_utf8 = "1.2.3.4 testvalue164" -+other_name_utf8 = "1.2.3.4 testvalue165" -+other_name_utf8 = "1.2.3.4 testvalue166" -+other_name_utf8 = "1.2.3.4 testvalue167" -+other_name_utf8 = "1.2.3.4 testvalue168" -+other_name_utf8 = "1.2.3.4 testvalue169" -+other_name_utf8 = "1.2.3.4 testvalue170" -+other_name_utf8 = "1.2.3.4 testvalue171" -+other_name_utf8 = "1.2.3.4 testvalue172" -+other_name_utf8 = "1.2.3.4 testvalue173" -+other_name_utf8 = "1.2.3.4 testvalue174" -+other_name_utf8 = "1.2.3.4 testvalue175" -+other_name_utf8 = "1.2.3.4 testvalue176" -+other_name_utf8 = "1.2.3.4 testvalue177" -+other_name_utf8 = "1.2.3.4 testvalue178" -+other_name_utf8 = "1.2.3.4 testvalue179" -+other_name_utf8 = "1.2.3.4 testvalue180" -+other_name_utf8 = "1.2.3.4 testvalue181" -+other_name_utf8 = "1.2.3.4 testvalue182" -+other_name_utf8 = "1.2.3.4 testvalue183" -+other_name_utf8 = "1.2.3.4 testvalue184" -+other_name_utf8 = "1.2.3.4 testvalue185" -+other_name_utf8 = "1.2.3.4 testvalue186" -+other_name_utf8 = "1.2.3.4 testvalue187" -+other_name_utf8 = "1.2.3.4 testvalue188" -+other_name_utf8 = "1.2.3.4 testvalue189" -+other_name_utf8 = "1.2.3.4 testvalue190" -+other_name_utf8 = "1.2.3.4 testvalue191" -+other_name_utf8 = "1.2.3.4 testvalue192" -+other_name_utf8 = "1.2.3.4 testvalue193" -+other_name_utf8 = "1.2.3.4 testvalue194" -+other_name_utf8 = "1.2.3.4 testvalue195" -+other_name_utf8 = "1.2.3.4 testvalue196" -+other_name_utf8 = "1.2.3.4 testvalue197" -+other_name_utf8 = "1.2.3.4 testvalue198" -+other_name_utf8 = "1.2.3.4 testvalue199" -+other_name_utf8 = "1.2.3.4 testvalue200" -+other_name_utf8 = "1.2.3.4 testvalue201" -+other_name_utf8 = "1.2.3.4 testvalue202" -+other_name_utf8 = "1.2.3.4 testvalue203" -+other_name_utf8 = "1.2.3.4 testvalue204" -+other_name_utf8 = "1.2.3.4 testvalue205" -+other_name_utf8 = "1.2.3.4 testvalue206" -+other_name_utf8 = "1.2.3.4 testvalue207" -+other_name_utf8 = "1.2.3.4 testvalue208" -+other_name_utf8 = "1.2.3.4 testvalue209" -+other_name_utf8 = "1.2.3.4 testvalue210" -+other_name_utf8 = "1.2.3.4 testvalue211" -+other_name_utf8 = "1.2.3.4 testvalue212" -+other_name_utf8 = "1.2.3.4 testvalue213" -+other_name_utf8 = "1.2.3.4 testvalue214" -+other_name_utf8 = "1.2.3.4 testvalue215" -+other_name_utf8 = "1.2.3.4 testvalue216" -+other_name_utf8 = "1.2.3.4 testvalue217" -+other_name_utf8 = "1.2.3.4 testvalue218" -+other_name_utf8 = "1.2.3.4 testvalue219" -+other_name_utf8 = "1.2.3.4 testvalue220" -+other_name_utf8 = "1.2.3.4 testvalue221" -+other_name_utf8 = "1.2.3.4 testvalue222" -+other_name_utf8 = "1.2.3.4 testvalue223" -+other_name_utf8 = "1.2.3.4 testvalue224" -+other_name_utf8 = "1.2.3.4 testvalue225" -+other_name_utf8 = "1.2.3.4 testvalue226" -+other_name_utf8 = "1.2.3.4 testvalue227" -+other_name_utf8 = "1.2.3.4 testvalue228" -+other_name_utf8 = "1.2.3.4 testvalue229" -+other_name_utf8 = "1.2.3.4 testvalue230" -+other_name_utf8 = "1.2.3.4 testvalue231" -+other_name_utf8 = "1.2.3.4 testvalue232" -+other_name_utf8 = "1.2.3.4 testvalue233" -+other_name_utf8 = "1.2.3.4 testvalue234" -+other_name_utf8 = "1.2.3.4 testvalue235" -+other_name_utf8 = "1.2.3.4 testvalue236" -+other_name_utf8 = "1.2.3.4 testvalue237" -+other_name_utf8 = "1.2.3.4 testvalue238" -+other_name_utf8 = "1.2.3.4 testvalue239" -+other_name_utf8 = "1.2.3.4 testvalue240" -+other_name_utf8 = "1.2.3.4 testvalue241" -+other_name_utf8 = "1.2.3.4 testvalue242" -+other_name_utf8 = "1.2.3.4 testvalue243" -+other_name_utf8 = "1.2.3.4 testvalue244" -+other_name_utf8 = "1.2.3.4 testvalue245" -+other_name_utf8 = "1.2.3.4 testvalue246" -+other_name_utf8 = "1.2.3.4 testvalue247" -+other_name_utf8 = "1.2.3.4 testvalue248" -+other_name_utf8 = "1.2.3.4 testvalue249" -+other_name_utf8 = "1.2.3.4 testvalue250" -+other_name_utf8 = "1.2.3.4 testvalue251" -+other_name_utf8 = "1.2.3.4 testvalue252" -+other_name_utf8 = "1.2.3.4 testvalue253" -+other_name_utf8 = "1.2.3.4 testvalue254" -+other_name_utf8 = "1.2.3.4 testvalue255" -+other_name_utf8 = "1.2.3.4 testvalue256" -+other_name_utf8 = "1.2.3.4 testvalue257" -+other_name_utf8 = "1.2.3.4 testvalue258" -+other_name_utf8 = "1.2.3.4 testvalue259" -+other_name_utf8 = "1.2.3.4 testvalue260" -+other_name_utf8 = "1.2.3.4 testvalue261" -+other_name_utf8 = "1.2.3.4 testvalue262" -+other_name_utf8 = "1.2.3.4 testvalue263" -+other_name_utf8 = "1.2.3.4 testvalue264" -+other_name_utf8 = "1.2.3.4 testvalue265" -+other_name_utf8 = "1.2.3.4 testvalue266" -+other_name_utf8 = "1.2.3.4 testvalue267" -+other_name_utf8 = "1.2.3.4 testvalue268" -+other_name_utf8 = "1.2.3.4 testvalue269" -+other_name_utf8 = "1.2.3.4 testvalue270" -+other_name_utf8 = "1.2.3.4 testvalue271" -+other_name_utf8 = "1.2.3.4 testvalue272" -+other_name_utf8 = "1.2.3.4 testvalue273" -+other_name_utf8 = "1.2.3.4 testvalue274" -+other_name_utf8 = "1.2.3.4 testvalue275" -+other_name_utf8 = "1.2.3.4 testvalue276" -+other_name_utf8 = "1.2.3.4 testvalue277" -+other_name_utf8 = "1.2.3.4 testvalue278" -+other_name_utf8 = "1.2.3.4 testvalue279" -+other_name_utf8 = "1.2.3.4 testvalue280" -+other_name_utf8 = "1.2.3.4 testvalue281" -+other_name_utf8 = "1.2.3.4 testvalue282" -+other_name_utf8 = "1.2.3.4 testvalue283" -+other_name_utf8 = "1.2.3.4 testvalue284" -+other_name_utf8 = "1.2.3.4 testvalue285" -+other_name_utf8 = "1.2.3.4 testvalue286" -+other_name_utf8 = "1.2.3.4 testvalue287" -+other_name_utf8 = "1.2.3.4 testvalue288" -+other_name_utf8 = "1.2.3.4 testvalue289" -+other_name_utf8 = "1.2.3.4 testvalue290" -+other_name_utf8 = "1.2.3.4 testvalue291" -+other_name_utf8 = "1.2.3.4 testvalue292" -+other_name_utf8 = "1.2.3.4 testvalue293" -+other_name_utf8 = "1.2.3.4 testvalue294" -+other_name_utf8 = "1.2.3.4 testvalue295" -+other_name_utf8 = "1.2.3.4 testvalue296" -+other_name_utf8 = "1.2.3.4 testvalue297" -+other_name_utf8 = "1.2.3.4 testvalue298" -+other_name_utf8 = "1.2.3.4 testvalue299" -+other_name_utf8 = "1.2.3.4 testvalue300" -+other_name_utf8 = "1.2.3.4 testvalue301" -+other_name_utf8 = "1.2.3.4 testvalue302" -+other_name_utf8 = "1.2.3.4 testvalue303" -+other_name_utf8 = "1.2.3.4 testvalue304" -+other_name_utf8 = "1.2.3.4 testvalue305" -+other_name_utf8 = "1.2.3.4 testvalue306" -+other_name_utf8 = "1.2.3.4 testvalue307" -+other_name_utf8 = "1.2.3.4 testvalue308" -+other_name_utf8 = "1.2.3.4 testvalue309" -+other_name_utf8 = "1.2.3.4 testvalue310" -+other_name_utf8 = "1.2.3.4 testvalue311" -+other_name_utf8 = "1.2.3.4 testvalue312" -+other_name_utf8 = "1.2.3.4 testvalue313" -+other_name_utf8 = "1.2.3.4 testvalue314" -+other_name_utf8 = "1.2.3.4 testvalue315" -+other_name_utf8 = "1.2.3.4 testvalue316" -+other_name_utf8 = "1.2.3.4 testvalue317" -+other_name_utf8 = "1.2.3.4 testvalue318" -+other_name_utf8 = "1.2.3.4 testvalue319" -+other_name_utf8 = "1.2.3.4 testvalue320" -+other_name_utf8 = "1.2.3.4 testvalue321" -+other_name_utf8 = "1.2.3.4 testvalue322" -+other_name_utf8 = "1.2.3.4 testvalue323" -+other_name_utf8 = "1.2.3.4 testvalue324" -+other_name_utf8 = "1.2.3.4 testvalue325" -+other_name_utf8 = "1.2.3.4 testvalue326" -+other_name_utf8 = "1.2.3.4 testvalue327" -+other_name_utf8 = "1.2.3.4 testvalue328" -+other_name_utf8 = "1.2.3.4 testvalue329" -+other_name_utf8 = "1.2.3.4 testvalue330" -+other_name_utf8 = "1.2.3.4 testvalue331" -+other_name_utf8 = "1.2.3.4 testvalue332" -+other_name_utf8 = "1.2.3.4 testvalue333" -+other_name_utf8 = "1.2.3.4 testvalue334" -+other_name_utf8 = "1.2.3.4 testvalue335" -+other_name_utf8 = "1.2.3.4 testvalue336" -+other_name_utf8 = "1.2.3.4 testvalue337" -+other_name_utf8 = "1.2.3.4 testvalue338" -+other_name_utf8 = "1.2.3.4 testvalue339" -+other_name_utf8 = "1.2.3.4 testvalue340" -+other_name_utf8 = "1.2.3.4 testvalue341" -+other_name_utf8 = "1.2.3.4 testvalue342" -+other_name_utf8 = "1.2.3.4 testvalue343" -+other_name_utf8 = "1.2.3.4 testvalue344" -+other_name_utf8 = "1.2.3.4 testvalue345" -+other_name_utf8 = "1.2.3.4 testvalue346" -+other_name_utf8 = "1.2.3.4 testvalue347" -+other_name_utf8 = "1.2.3.4 testvalue348" -+other_name_utf8 = "1.2.3.4 testvalue349" -+other_name_utf8 = "1.2.3.4 testvalue350" -+other_name_utf8 = "1.2.3.4 testvalue351" -+other_name_utf8 = "1.2.3.4 testvalue352" -+other_name_utf8 = "1.2.3.4 testvalue353" -+other_name_utf8 = "1.2.3.4 testvalue354" -+other_name_utf8 = "1.2.3.4 testvalue355" -+other_name_utf8 = "1.2.3.4 testvalue356" -+other_name_utf8 = "1.2.3.4 testvalue357" -+other_name_utf8 = "1.2.3.4 testvalue358" -+other_name_utf8 = "1.2.3.4 testvalue359" -+other_name_utf8 = "1.2.3.4 testvalue360" -+other_name_utf8 = "1.2.3.4 testvalue361" -+other_name_utf8 = "1.2.3.4 testvalue362" -+other_name_utf8 = "1.2.3.4 testvalue363" -+other_name_utf8 = "1.2.3.4 testvalue364" -+other_name_utf8 = "1.2.3.4 testvalue365" -+other_name_utf8 = "1.2.3.4 testvalue366" -+other_name_utf8 = "1.2.3.4 testvalue367" -+other_name_utf8 = "1.2.3.4 testvalue368" -+other_name_utf8 = "1.2.3.4 testvalue369" -+other_name_utf8 = "1.2.3.4 testvalue370" -+other_name_utf8 = "1.2.3.4 testvalue371" -+other_name_utf8 = "1.2.3.4 testvalue372" -+other_name_utf8 = "1.2.3.4 testvalue373" -+other_name_utf8 = "1.2.3.4 testvalue374" -+other_name_utf8 = "1.2.3.4 testvalue375" -+other_name_utf8 = "1.2.3.4 testvalue376" -+other_name_utf8 = "1.2.3.4 testvalue377" -+other_name_utf8 = "1.2.3.4 testvalue378" -+other_name_utf8 = "1.2.3.4 testvalue379" -+other_name_utf8 = "1.2.3.4 testvalue380" -+other_name_utf8 = "1.2.3.4 testvalue381" -+other_name_utf8 = "1.2.3.4 testvalue382" -+other_name_utf8 = "1.2.3.4 testvalue383" -+other_name_utf8 = "1.2.3.4 testvalue384" -+other_name_utf8 = "1.2.3.4 testvalue385" -+other_name_utf8 = "1.2.3.4 testvalue386" -+other_name_utf8 = "1.2.3.4 testvalue387" -+other_name_utf8 = "1.2.3.4 testvalue388" -+other_name_utf8 = "1.2.3.4 testvalue389" -+other_name_utf8 = "1.2.3.4 testvalue390" -+other_name_utf8 = "1.2.3.4 testvalue391" -+other_name_utf8 = "1.2.3.4 testvalue392" -+other_name_utf8 = "1.2.3.4 testvalue393" -+other_name_utf8 = "1.2.3.4 testvalue394" -+other_name_utf8 = "1.2.3.4 testvalue395" -+other_name_utf8 = "1.2.3.4 testvalue396" -+other_name_utf8 = "1.2.3.4 testvalue397" -+other_name_utf8 = "1.2.3.4 testvalue398" -+other_name_utf8 = "1.2.3.4 testvalue399" -+other_name_utf8 = "1.2.3.4 testvalue400" -+other_name_utf8 = "1.2.3.4 testvalue401" -+other_name_utf8 = "1.2.3.4 testvalue402" -+other_name_utf8 = "1.2.3.4 testvalue403" -+other_name_utf8 = "1.2.3.4 testvalue404" -+other_name_utf8 = "1.2.3.4 testvalue405" -+other_name_utf8 = "1.2.3.4 testvalue406" -+other_name_utf8 = "1.2.3.4 testvalue407" -+other_name_utf8 = "1.2.3.4 testvalue408" -+other_name_utf8 = "1.2.3.4 testvalue409" -+other_name_utf8 = "1.2.3.4 testvalue410" -+other_name_utf8 = "1.2.3.4 testvalue411" -+other_name_utf8 = "1.2.3.4 testvalue412" -+other_name_utf8 = "1.2.3.4 testvalue413" -+other_name_utf8 = "1.2.3.4 testvalue414" -+other_name_utf8 = "1.2.3.4 testvalue415" -+other_name_utf8 = "1.2.3.4 testvalue416" -+other_name_utf8 = "1.2.3.4 testvalue417" -+other_name_utf8 = "1.2.3.4 testvalue418" -+other_name_utf8 = "1.2.3.4 testvalue419" -+other_name_utf8 = "1.2.3.4 testvalue420" -+other_name_utf8 = "1.2.3.4 testvalue421" -+other_name_utf8 = "1.2.3.4 testvalue422" -+other_name_utf8 = "1.2.3.4 testvalue423" -+other_name_utf8 = "1.2.3.4 testvalue424" -+other_name_utf8 = "1.2.3.4 testvalue425" -+other_name_utf8 = "1.2.3.4 testvalue426" -+other_name_utf8 = "1.2.3.4 testvalue427" -+other_name_utf8 = "1.2.3.4 testvalue428" -+other_name_utf8 = "1.2.3.4 testvalue429" -+other_name_utf8 = "1.2.3.4 testvalue430" -+other_name_utf8 = "1.2.3.4 testvalue431" -+other_name_utf8 = "1.2.3.4 testvalue432" -+other_name_utf8 = "1.2.3.4 testvalue433" -+other_name_utf8 = "1.2.3.4 testvalue434" -+other_name_utf8 = "1.2.3.4 testvalue435" -+other_name_utf8 = "1.2.3.4 testvalue436" -+other_name_utf8 = "1.2.3.4 testvalue437" -+other_name_utf8 = "1.2.3.4 testvalue438" -+other_name_utf8 = "1.2.3.4 testvalue439" -+other_name_utf8 = "1.2.3.4 testvalue440" -+other_name_utf8 = "1.2.3.4 testvalue441" -+other_name_utf8 = "1.2.3.4 testvalue442" -+other_name_utf8 = "1.2.3.4 testvalue443" -+other_name_utf8 = "1.2.3.4 testvalue444" -+other_name_utf8 = "1.2.3.4 testvalue445" -+other_name_utf8 = "1.2.3.4 testvalue446" -+other_name_utf8 = "1.2.3.4 testvalue447" -+other_name_utf8 = "1.2.3.4 testvalue448" -+other_name_utf8 = "1.2.3.4 testvalue449" -+other_name_utf8 = "1.2.3.4 testvalue450" -+other_name_utf8 = "1.2.3.4 testvalue451" -+other_name_utf8 = "1.2.3.4 testvalue452" -+other_name_utf8 = "1.2.3.4 testvalue453" -+other_name_utf8 = "1.2.3.4 testvalue454" -+other_name_utf8 = "1.2.3.4 testvalue455" -+other_name_utf8 = "1.2.3.4 testvalue456" -+other_name_utf8 = "1.2.3.4 testvalue457" -+other_name_utf8 = "1.2.3.4 testvalue458" -+other_name_utf8 = "1.2.3.4 testvalue459" -+other_name_utf8 = "1.2.3.4 testvalue460" -+other_name_utf8 = "1.2.3.4 testvalue461" -+other_name_utf8 = "1.2.3.4 testvalue462" -+other_name_utf8 = "1.2.3.4 testvalue463" -+other_name_utf8 = "1.2.3.4 testvalue464" -+other_name_utf8 = "1.2.3.4 testvalue465" -+other_name_utf8 = "1.2.3.4 testvalue466" -+other_name_utf8 = "1.2.3.4 testvalue467" -+other_name_utf8 = "1.2.3.4 testvalue468" -+other_name_utf8 = "1.2.3.4 testvalue469" -+other_name_utf8 = "1.2.3.4 testvalue470" -+other_name_utf8 = "1.2.3.4 testvalue471" -+other_name_utf8 = "1.2.3.4 testvalue472" -+other_name_utf8 = "1.2.3.4 testvalue473" -+other_name_utf8 = "1.2.3.4 testvalue474" -+other_name_utf8 = "1.2.3.4 testvalue475" -+other_name_utf8 = "1.2.3.4 testvalue476" -+other_name_utf8 = "1.2.3.4 testvalue477" -+other_name_utf8 = "1.2.3.4 testvalue478" -+other_name_utf8 = "1.2.3.4 testvalue479" -+other_name_utf8 = "1.2.3.4 testvalue480" -+other_name_utf8 = "1.2.3.4 testvalue481" -+other_name_utf8 = "1.2.3.4 testvalue482" -+other_name_utf8 = "1.2.3.4 testvalue483" -+other_name_utf8 = "1.2.3.4 testvalue484" -+other_name_utf8 = "1.2.3.4 testvalue485" -+other_name_utf8 = "1.2.3.4 testvalue486" -+other_name_utf8 = "1.2.3.4 testvalue487" -+other_name_utf8 = "1.2.3.4 testvalue488" -+other_name_utf8 = "1.2.3.4 testvalue489" -+other_name_utf8 = "1.2.3.4 testvalue490" -+other_name_utf8 = "1.2.3.4 testvalue491" -+other_name_utf8 = "1.2.3.4 testvalue492" -+other_name_utf8 = "1.2.3.4 testvalue493" -+other_name_utf8 = "1.2.3.4 testvalue494" -+other_name_utf8 = "1.2.3.4 testvalue495" -+other_name_utf8 = "1.2.3.4 testvalue496" -+other_name_utf8 = "1.2.3.4 testvalue497" -+other_name_utf8 = "1.2.3.4 testvalue498" -+other_name_utf8 = "1.2.3.4 testvalue499" -+other_name_utf8 = "1.2.3.4 testvalue500" -+other_name_utf8 = "1.2.3.4 testvalue501" -+other_name_utf8 = "1.2.3.4 testvalue502" -+other_name_utf8 = "1.2.3.4 testvalue503" -+other_name_utf8 = "1.2.3.4 testvalue504" -+other_name_utf8 = "1.2.3.4 testvalue505" -+other_name_utf8 = "1.2.3.4 testvalue506" -+other_name_utf8 = "1.2.3.4 testvalue507" -+other_name_utf8 = "1.2.3.4 testvalue508" -+other_name_utf8 = "1.2.3.4 testvalue509" -+other_name_utf8 = "1.2.3.4 testvalue510" -+other_name_utf8 = "1.2.3.4 testvalue511" -+other_name_utf8 = "1.2.3.4 testvalue512" -+other_name_utf8 = "1.2.3.4 testvalue513" -+other_name_utf8 = "1.2.3.4 testvalue514" -+other_name_utf8 = "1.2.3.4 testvalue515" -+other_name_utf8 = "1.2.3.4 testvalue516" -+other_name_utf8 = "1.2.3.4 testvalue517" -+other_name_utf8 = "1.2.3.4 testvalue518" -+other_name_utf8 = "1.2.3.4 testvalue519" -+other_name_utf8 = "1.2.3.4 testvalue520" -+other_name_utf8 = "1.2.3.4 testvalue521" -+other_name_utf8 = "1.2.3.4 testvalue522" -+other_name_utf8 = "1.2.3.4 testvalue523" -+other_name_utf8 = "1.2.3.4 testvalue524" -+other_name_utf8 = "1.2.3.4 testvalue525" -+other_name_utf8 = "1.2.3.4 testvalue526" -+other_name_utf8 = "1.2.3.4 testvalue527" -+other_name_utf8 = "1.2.3.4 testvalue528" -+other_name_utf8 = "1.2.3.4 testvalue529" -+other_name_utf8 = "1.2.3.4 testvalue530" -+other_name_utf8 = "1.2.3.4 testvalue531" -+other_name_utf8 = "1.2.3.4 testvalue532" -+other_name_utf8 = "1.2.3.4 testvalue533" -+other_name_utf8 = "1.2.3.4 testvalue534" -+other_name_utf8 = "1.2.3.4 testvalue535" -+other_name_utf8 = "1.2.3.4 testvalue536" -+other_name_utf8 = "1.2.3.4 testvalue537" -+other_name_utf8 = "1.2.3.4 testvalue538" -+other_name_utf8 = "1.2.3.4 testvalue539" -+other_name_utf8 = "1.2.3.4 testvalue540" -+other_name_utf8 = "1.2.3.4 testvalue541" -+other_name_utf8 = "1.2.3.4 testvalue542" -+other_name_utf8 = "1.2.3.4 testvalue543" -+other_name_utf8 = "1.2.3.4 testvalue544" -+other_name_utf8 = "1.2.3.4 testvalue545" -+other_name_utf8 = "1.2.3.4 testvalue546" -+other_name_utf8 = "1.2.3.4 testvalue547" -+other_name_utf8 = "1.2.3.4 testvalue548" -+other_name_utf8 = "1.2.3.4 testvalue549" -+other_name_utf8 = "1.2.3.4 testvalue550" -+other_name_utf8 = "1.2.3.4 testvalue551" -+other_name_utf8 = "1.2.3.4 testvalue552" -+other_name_utf8 = "1.2.3.4 testvalue553" -+other_name_utf8 = "1.2.3.4 testvalue554" -+other_name_utf8 = "1.2.3.4 testvalue555" -+other_name_utf8 = "1.2.3.4 testvalue556" -+other_name_utf8 = "1.2.3.4 testvalue557" -+other_name_utf8 = "1.2.3.4 testvalue558" -+other_name_utf8 = "1.2.3.4 testvalue559" -+other_name_utf8 = "1.2.3.4 testvalue560" -+other_name_utf8 = "1.2.3.4 testvalue561" -+other_name_utf8 = "1.2.3.4 testvalue562" -+other_name_utf8 = "1.2.3.4 testvalue563" -+other_name_utf8 = "1.2.3.4 testvalue564" -+other_name_utf8 = "1.2.3.4 testvalue565" -+other_name_utf8 = "1.2.3.4 testvalue566" -+other_name_utf8 = "1.2.3.4 testvalue567" -+other_name_utf8 = "1.2.3.4 testvalue568" -+other_name_utf8 = "1.2.3.4 testvalue569" -+other_name_utf8 = "1.2.3.4 testvalue570" -+other_name_utf8 = "1.2.3.4 testvalue571" -+other_name_utf8 = "1.2.3.4 testvalue572" -+other_name_utf8 = "1.2.3.4 testvalue573" -+other_name_utf8 = "1.2.3.4 testvalue574" -+other_name_utf8 = "1.2.3.4 testvalue575" -+other_name_utf8 = "1.2.3.4 testvalue576" -+other_name_utf8 = "1.2.3.4 testvalue577" -+other_name_utf8 = "1.2.3.4 testvalue578" -+other_name_utf8 = "1.2.3.4 testvalue579" -+other_name_utf8 = "1.2.3.4 testvalue580" -+other_name_utf8 = "1.2.3.4 testvalue581" -+other_name_utf8 = "1.2.3.4 testvalue582" -+other_name_utf8 = "1.2.3.4 testvalue583" -+other_name_utf8 = "1.2.3.4 testvalue584" -+other_name_utf8 = "1.2.3.4 testvalue585" -+other_name_utf8 = "1.2.3.4 testvalue586" -+other_name_utf8 = "1.2.3.4 testvalue587" -+other_name_utf8 = "1.2.3.4 testvalue588" -+other_name_utf8 = "1.2.3.4 testvalue589" -+other_name_utf8 = "1.2.3.4 testvalue590" -+other_name_utf8 = "1.2.3.4 testvalue591" -+other_name_utf8 = "1.2.3.4 testvalue592" -+other_name_utf8 = "1.2.3.4 testvalue593" -+other_name_utf8 = "1.2.3.4 testvalue594" -+other_name_utf8 = "1.2.3.4 testvalue595" -+other_name_utf8 = "1.2.3.4 testvalue596" -+other_name_utf8 = "1.2.3.4 testvalue597" -+other_name_utf8 = "1.2.3.4 testvalue598" -+other_name_utf8 = "1.2.3.4 testvalue599" -+other_name_utf8 = "1.2.3.4 testvalue600" -+other_name_utf8 = "1.2.3.4 testvalue601" -+other_name_utf8 = "1.2.3.4 testvalue602" -+other_name_utf8 = "1.2.3.4 testvalue603" -+other_name_utf8 = "1.2.3.4 testvalue604" -+other_name_utf8 = "1.2.3.4 testvalue605" -+other_name_utf8 = "1.2.3.4 testvalue606" -+other_name_utf8 = "1.2.3.4 testvalue607" -+other_name_utf8 = "1.2.3.4 testvalue608" -+other_name_utf8 = "1.2.3.4 testvalue609" -+other_name_utf8 = "1.2.3.4 testvalue610" -+other_name_utf8 = "1.2.3.4 testvalue611" -+other_name_utf8 = "1.2.3.4 testvalue612" -+other_name_utf8 = "1.2.3.4 testvalue613" -+other_name_utf8 = "1.2.3.4 testvalue614" -+other_name_utf8 = "1.2.3.4 testvalue615" -+other_name_utf8 = "1.2.3.4 testvalue616" -+other_name_utf8 = "1.2.3.4 testvalue617" -+other_name_utf8 = "1.2.3.4 testvalue618" -+other_name_utf8 = "1.2.3.4 testvalue619" -+other_name_utf8 = "1.2.3.4 testvalue620" -+other_name_utf8 = "1.2.3.4 testvalue621" -+other_name_utf8 = "1.2.3.4 testvalue622" -+other_name_utf8 = "1.2.3.4 testvalue623" -+other_name_utf8 = "1.2.3.4 testvalue624" -+other_name_utf8 = "1.2.3.4 testvalue625" -+other_name_utf8 = "1.2.3.4 testvalue626" -+other_name_utf8 = "1.2.3.4 testvalue627" -+other_name_utf8 = "1.2.3.4 testvalue628" -+other_name_utf8 = "1.2.3.4 testvalue629" -+other_name_utf8 = "1.2.3.4 testvalue630" -+other_name_utf8 = "1.2.3.4 testvalue631" -+other_name_utf8 = "1.2.3.4 testvalue632" -+other_name_utf8 = "1.2.3.4 testvalue633" -+other_name_utf8 = "1.2.3.4 testvalue634" -+other_name_utf8 = "1.2.3.4 testvalue635" -+other_name_utf8 = "1.2.3.4 testvalue636" -+other_name_utf8 = "1.2.3.4 testvalue637" -+other_name_utf8 = "1.2.3.4 testvalue638" -+other_name_utf8 = "1.2.3.4 testvalue639" -+other_name_utf8 = "1.2.3.4 testvalue640" -+other_name_utf8 = "1.2.3.4 testvalue641" -+other_name_utf8 = "1.2.3.4 testvalue642" -+other_name_utf8 = "1.2.3.4 testvalue643" -+other_name_utf8 = "1.2.3.4 testvalue644" -+other_name_utf8 = "1.2.3.4 testvalue645" -+other_name_utf8 = "1.2.3.4 testvalue646" -+other_name_utf8 = "1.2.3.4 testvalue647" -+other_name_utf8 = "1.2.3.4 testvalue648" -+other_name_utf8 = "1.2.3.4 testvalue649" -+other_name_utf8 = "1.2.3.4 testvalue650" -+other_name_utf8 = "1.2.3.4 testvalue651" -+other_name_utf8 = "1.2.3.4 testvalue652" -+other_name_utf8 = "1.2.3.4 testvalue653" -+other_name_utf8 = "1.2.3.4 testvalue654" -+other_name_utf8 = "1.2.3.4 testvalue655" -+other_name_utf8 = "1.2.3.4 testvalue656" -+other_name_utf8 = "1.2.3.4 testvalue657" -+other_name_utf8 = "1.2.3.4 testvalue658" -+other_name_utf8 = "1.2.3.4 testvalue659" -+other_name_utf8 = "1.2.3.4 testvalue660" -+other_name_utf8 = "1.2.3.4 testvalue661" -+other_name_utf8 = "1.2.3.4 testvalue662" -+other_name_utf8 = "1.2.3.4 testvalue663" -+other_name_utf8 = "1.2.3.4 testvalue664" -+other_name_utf8 = "1.2.3.4 testvalue665" -+other_name_utf8 = "1.2.3.4 testvalue666" -+other_name_utf8 = "1.2.3.4 testvalue667" -+other_name_utf8 = "1.2.3.4 testvalue668" -+other_name_utf8 = "1.2.3.4 testvalue669" -+other_name_utf8 = "1.2.3.4 testvalue670" -+other_name_utf8 = "1.2.3.4 testvalue671" -+other_name_utf8 = "1.2.3.4 testvalue672" -+other_name_utf8 = "1.2.3.4 testvalue673" -+other_name_utf8 = "1.2.3.4 testvalue674" -+other_name_utf8 = "1.2.3.4 testvalue675" -+other_name_utf8 = "1.2.3.4 testvalue676" -+other_name_utf8 = "1.2.3.4 testvalue677" -+other_name_utf8 = "1.2.3.4 testvalue678" -+other_name_utf8 = "1.2.3.4 testvalue679" -+other_name_utf8 = "1.2.3.4 testvalue680" -+other_name_utf8 = "1.2.3.4 testvalue681" -+other_name_utf8 = "1.2.3.4 testvalue682" -+other_name_utf8 = "1.2.3.4 testvalue683" -+other_name_utf8 = "1.2.3.4 testvalue684" -+other_name_utf8 = "1.2.3.4 testvalue685" -+other_name_utf8 = "1.2.3.4 testvalue686" -+other_name_utf8 = "1.2.3.4 testvalue687" -+other_name_utf8 = "1.2.3.4 testvalue688" -+other_name_utf8 = "1.2.3.4 testvalue689" -+other_name_utf8 = "1.2.3.4 testvalue690" -+other_name_utf8 = "1.2.3.4 testvalue691" -+other_name_utf8 = "1.2.3.4 testvalue692" -+other_name_utf8 = "1.2.3.4 testvalue693" -+other_name_utf8 = "1.2.3.4 testvalue694" -+other_name_utf8 = "1.2.3.4 testvalue695" -+other_name_utf8 = "1.2.3.4 testvalue696" -+other_name_utf8 = "1.2.3.4 testvalue697" -+other_name_utf8 = "1.2.3.4 testvalue698" -+other_name_utf8 = "1.2.3.4 testvalue699" -+other_name_utf8 = "1.2.3.4 testvalue700" -+other_name_utf8 = "1.2.3.4 testvalue701" -+other_name_utf8 = "1.2.3.4 testvalue702" -+other_name_utf8 = "1.2.3.4 testvalue703" -+other_name_utf8 = "1.2.3.4 testvalue704" -+other_name_utf8 = "1.2.3.4 testvalue705" -+other_name_utf8 = "1.2.3.4 testvalue706" -+other_name_utf8 = "1.2.3.4 testvalue707" -+other_name_utf8 = "1.2.3.4 testvalue708" -+other_name_utf8 = "1.2.3.4 testvalue709" -+other_name_utf8 = "1.2.3.4 testvalue710" -+other_name_utf8 = "1.2.3.4 testvalue711" -+other_name_utf8 = "1.2.3.4 testvalue712" -+other_name_utf8 = "1.2.3.4 testvalue713" -+other_name_utf8 = "1.2.3.4 testvalue714" -+other_name_utf8 = "1.2.3.4 testvalue715" -+other_name_utf8 = "1.2.3.4 testvalue716" -+other_name_utf8 = "1.2.3.4 testvalue717" -+other_name_utf8 = "1.2.3.4 testvalue718" -+other_name_utf8 = "1.2.3.4 testvalue719" -+other_name_utf8 = "1.2.3.4 testvalue720" -+other_name_utf8 = "1.2.3.4 testvalue721" -+other_name_utf8 = "1.2.3.4 testvalue722" -+other_name_utf8 = "1.2.3.4 testvalue723" -+other_name_utf8 = "1.2.3.4 testvalue724" -+other_name_utf8 = "1.2.3.4 testvalue725" -+other_name_utf8 = "1.2.3.4 testvalue726" -+other_name_utf8 = "1.2.3.4 testvalue727" -+other_name_utf8 = "1.2.3.4 testvalue728" -+other_name_utf8 = "1.2.3.4 testvalue729" -+other_name_utf8 = "1.2.3.4 testvalue730" -+other_name_utf8 = "1.2.3.4 testvalue731" -+other_name_utf8 = "1.2.3.4 testvalue732" -+other_name_utf8 = "1.2.3.4 testvalue733" -+other_name_utf8 = "1.2.3.4 testvalue734" -+other_name_utf8 = "1.2.3.4 testvalue735" -+other_name_utf8 = "1.2.3.4 testvalue736" -+other_name_utf8 = "1.2.3.4 testvalue737" -+other_name_utf8 = "1.2.3.4 testvalue738" -+other_name_utf8 = "1.2.3.4 testvalue739" -+other_name_utf8 = "1.2.3.4 testvalue740" -+other_name_utf8 = "1.2.3.4 testvalue741" -+other_name_utf8 = "1.2.3.4 testvalue742" -+other_name_utf8 = "1.2.3.4 testvalue743" -+other_name_utf8 = "1.2.3.4 testvalue744" -+other_name_utf8 = "1.2.3.4 testvalue745" -+other_name_utf8 = "1.2.3.4 testvalue746" -+other_name_utf8 = "1.2.3.4 testvalue747" -+other_name_utf8 = "1.2.3.4 testvalue748" -+other_name_utf8 = "1.2.3.4 testvalue749" -+other_name_utf8 = "1.2.3.4 testvalue750" -+other_name_utf8 = "1.2.3.4 testvalue751" -+other_name_utf8 = "1.2.3.4 testvalue752" -+other_name_utf8 = "1.2.3.4 testvalue753" -+other_name_utf8 = "1.2.3.4 testvalue754" -+other_name_utf8 = "1.2.3.4 testvalue755" -+other_name_utf8 = "1.2.3.4 testvalue756" -+other_name_utf8 = "1.2.3.4 testvalue757" -+other_name_utf8 = "1.2.3.4 testvalue758" -+other_name_utf8 = "1.2.3.4 testvalue759" -+other_name_utf8 = "1.2.3.4 testvalue760" -+other_name_utf8 = "1.2.3.4 testvalue761" -+other_name_utf8 = "1.2.3.4 testvalue762" -+other_name_utf8 = "1.2.3.4 testvalue763" -+other_name_utf8 = "1.2.3.4 testvalue764" -+other_name_utf8 = "1.2.3.4 testvalue765" -+other_name_utf8 = "1.2.3.4 testvalue766" -+other_name_utf8 = "1.2.3.4 testvalue767" -+other_name_utf8 = "1.2.3.4 testvalue768" -+other_name_utf8 = "1.2.3.4 testvalue769" -+other_name_utf8 = "1.2.3.4 testvalue770" -+other_name_utf8 = "1.2.3.4 testvalue771" -+other_name_utf8 = "1.2.3.4 testvalue772" -+other_name_utf8 = "1.2.3.4 testvalue773" -+other_name_utf8 = "1.2.3.4 testvalue774" -+other_name_utf8 = "1.2.3.4 testvalue775" -+other_name_utf8 = "1.2.3.4 testvalue776" -+other_name_utf8 = "1.2.3.4 testvalue777" -+other_name_utf8 = "1.2.3.4 testvalue778" -+other_name_utf8 = "1.2.3.4 testvalue779" -+other_name_utf8 = "1.2.3.4 testvalue780" -+other_name_utf8 = "1.2.3.4 testvalue781" -+other_name_utf8 = "1.2.3.4 testvalue782" -+other_name_utf8 = "1.2.3.4 testvalue783" -+other_name_utf8 = "1.2.3.4 testvalue784" -+other_name_utf8 = "1.2.3.4 testvalue785" -+other_name_utf8 = "1.2.3.4 testvalue786" -+other_name_utf8 = "1.2.3.4 testvalue787" -+other_name_utf8 = "1.2.3.4 testvalue788" -+other_name_utf8 = "1.2.3.4 testvalue789" -+other_name_utf8 = "1.2.3.4 testvalue790" -+other_name_utf8 = "1.2.3.4 testvalue791" -+other_name_utf8 = "1.2.3.4 testvalue792" -+other_name_utf8 = "1.2.3.4 testvalue793" -+other_name_utf8 = "1.2.3.4 testvalue794" -+other_name_utf8 = "1.2.3.4 testvalue795" -+other_name_utf8 = "1.2.3.4 testvalue796" -+other_name_utf8 = "1.2.3.4 testvalue797" -+other_name_utf8 = "1.2.3.4 testvalue798" -+other_name_utf8 = "1.2.3.4 testvalue799" -+other_name_utf8 = "1.2.3.4 testvalue800" -+other_name_utf8 = "1.2.3.4 testvalue801" -+other_name_utf8 = "1.2.3.4 testvalue802" -+other_name_utf8 = "1.2.3.4 testvalue803" -+other_name_utf8 = "1.2.3.4 testvalue804" -+other_name_utf8 = "1.2.3.4 testvalue805" -+other_name_utf8 = "1.2.3.4 testvalue806" -+other_name_utf8 = "1.2.3.4 testvalue807" -+other_name_utf8 = "1.2.3.4 testvalue808" -+other_name_utf8 = "1.2.3.4 testvalue809" -+other_name_utf8 = "1.2.3.4 testvalue810" -+other_name_utf8 = "1.2.3.4 testvalue811" -+other_name_utf8 = "1.2.3.4 testvalue812" -+other_name_utf8 = "1.2.3.4 testvalue813" -+other_name_utf8 = "1.2.3.4 testvalue814" -+other_name_utf8 = "1.2.3.4 testvalue815" -+other_name_utf8 = "1.2.3.4 testvalue816" -+other_name_utf8 = "1.2.3.4 testvalue817" -+other_name_utf8 = "1.2.3.4 testvalue818" -+other_name_utf8 = "1.2.3.4 testvalue819" -+other_name_utf8 = "1.2.3.4 testvalue820" -+other_name_utf8 = "1.2.3.4 testvalue821" -+other_name_utf8 = "1.2.3.4 testvalue822" -+other_name_utf8 = "1.2.3.4 testvalue823" -+other_name_utf8 = "1.2.3.4 testvalue824" -+other_name_utf8 = "1.2.3.4 testvalue825" -+other_name_utf8 = "1.2.3.4 testvalue826" -+other_name_utf8 = "1.2.3.4 testvalue827" -+other_name_utf8 = "1.2.3.4 testvalue828" -+other_name_utf8 = "1.2.3.4 testvalue829" -+other_name_utf8 = "1.2.3.4 testvalue830" -+other_name_utf8 = "1.2.3.4 testvalue831" -+other_name_utf8 = "1.2.3.4 testvalue832" -+other_name_utf8 = "1.2.3.4 testvalue833" -+other_name_utf8 = "1.2.3.4 testvalue834" -+other_name_utf8 = "1.2.3.4 testvalue835" -+other_name_utf8 = "1.2.3.4 testvalue836" -+other_name_utf8 = "1.2.3.4 testvalue837" -+other_name_utf8 = "1.2.3.4 testvalue838" -+other_name_utf8 = "1.2.3.4 testvalue839" -+other_name_utf8 = "1.2.3.4 testvalue840" -+other_name_utf8 = "1.2.3.4 testvalue841" -+other_name_utf8 = "1.2.3.4 testvalue842" -+other_name_utf8 = "1.2.3.4 testvalue843" -+other_name_utf8 = "1.2.3.4 testvalue844" -+other_name_utf8 = "1.2.3.4 testvalue845" -+other_name_utf8 = "1.2.3.4 testvalue846" -+other_name_utf8 = "1.2.3.4 testvalue847" -+other_name_utf8 = "1.2.3.4 testvalue848" -+other_name_utf8 = "1.2.3.4 testvalue849" -+other_name_utf8 = "1.2.3.4 testvalue850" -+other_name_utf8 = "1.2.3.4 testvalue851" -+other_name_utf8 = "1.2.3.4 testvalue852" -+other_name_utf8 = "1.2.3.4 testvalue853" -+other_name_utf8 = "1.2.3.4 testvalue854" -+other_name_utf8 = "1.2.3.4 testvalue855" -+other_name_utf8 = "1.2.3.4 testvalue856" -+other_name_utf8 = "1.2.3.4 testvalue857" -+other_name_utf8 = "1.2.3.4 testvalue858" -+other_name_utf8 = "1.2.3.4 testvalue859" -+other_name_utf8 = "1.2.3.4 testvalue860" -+other_name_utf8 = "1.2.3.4 testvalue861" -+other_name_utf8 = "1.2.3.4 testvalue862" -+other_name_utf8 = "1.2.3.4 testvalue863" -+other_name_utf8 = "1.2.3.4 testvalue864" -+other_name_utf8 = "1.2.3.4 testvalue865" -+other_name_utf8 = "1.2.3.4 testvalue866" -+other_name_utf8 = "1.2.3.4 testvalue867" -+other_name_utf8 = "1.2.3.4 testvalue868" -+other_name_utf8 = "1.2.3.4 testvalue869" -+other_name_utf8 = "1.2.3.4 testvalue870" -+other_name_utf8 = "1.2.3.4 testvalue871" -+other_name_utf8 = "1.2.3.4 testvalue872" -+other_name_utf8 = "1.2.3.4 testvalue873" -+other_name_utf8 = "1.2.3.4 testvalue874" -+other_name_utf8 = "1.2.3.4 testvalue875" -+other_name_utf8 = "1.2.3.4 testvalue876" -+other_name_utf8 = "1.2.3.4 testvalue877" -+other_name_utf8 = "1.2.3.4 testvalue878" -+other_name_utf8 = "1.2.3.4 testvalue879" -+other_name_utf8 = "1.2.3.4 testvalue880" -+other_name_utf8 = "1.2.3.4 testvalue881" -+other_name_utf8 = "1.2.3.4 testvalue882" -+other_name_utf8 = "1.2.3.4 testvalue883" -+other_name_utf8 = "1.2.3.4 testvalue884" -+other_name_utf8 = "1.2.3.4 testvalue885" -+other_name_utf8 = "1.2.3.4 testvalue886" -+other_name_utf8 = "1.2.3.4 testvalue887" -+other_name_utf8 = "1.2.3.4 testvalue888" -+other_name_utf8 = "1.2.3.4 testvalue889" -+other_name_utf8 = "1.2.3.4 testvalue890" -+other_name_utf8 = "1.2.3.4 testvalue891" -+other_name_utf8 = "1.2.3.4 testvalue892" -+other_name_utf8 = "1.2.3.4 testvalue893" -+other_name_utf8 = "1.2.3.4 testvalue894" -+other_name_utf8 = "1.2.3.4 testvalue895" -+other_name_utf8 = "1.2.3.4 testvalue896" -+other_name_utf8 = "1.2.3.4 testvalue897" -+other_name_utf8 = "1.2.3.4 testvalue898" -+other_name_utf8 = "1.2.3.4 testvalue899" -+other_name_utf8 = "1.2.3.4 testvalue900" -+other_name_utf8 = "1.2.3.4 testvalue901" -+other_name_utf8 = "1.2.3.4 testvalue902" -+other_name_utf8 = "1.2.3.4 testvalue903" -+other_name_utf8 = "1.2.3.4 testvalue904" -+other_name_utf8 = "1.2.3.4 testvalue905" -+other_name_utf8 = "1.2.3.4 testvalue906" -+other_name_utf8 = "1.2.3.4 testvalue907" -+other_name_utf8 = "1.2.3.4 testvalue908" -+other_name_utf8 = "1.2.3.4 testvalue909" -+other_name_utf8 = "1.2.3.4 testvalue910" -+other_name_utf8 = "1.2.3.4 testvalue911" -+other_name_utf8 = "1.2.3.4 testvalue912" -+other_name_utf8 = "1.2.3.4 testvalue913" -+other_name_utf8 = "1.2.3.4 testvalue914" -+other_name_utf8 = "1.2.3.4 testvalue915" -+other_name_utf8 = "1.2.3.4 testvalue916" -+other_name_utf8 = "1.2.3.4 testvalue917" -+other_name_utf8 = "1.2.3.4 testvalue918" -+other_name_utf8 = "1.2.3.4 testvalue919" -+other_name_utf8 = "1.2.3.4 testvalue920" -+other_name_utf8 = "1.2.3.4 testvalue921" -+other_name_utf8 = "1.2.3.4 testvalue922" -+other_name_utf8 = "1.2.3.4 testvalue923" -+other_name_utf8 = "1.2.3.4 testvalue924" -+other_name_utf8 = "1.2.3.4 testvalue925" -+other_name_utf8 = "1.2.3.4 testvalue926" -+other_name_utf8 = "1.2.3.4 testvalue927" -+other_name_utf8 = "1.2.3.4 testvalue928" -+other_name_utf8 = "1.2.3.4 testvalue929" -+other_name_utf8 = "1.2.3.4 testvalue930" -+other_name_utf8 = "1.2.3.4 testvalue931" -+other_name_utf8 = "1.2.3.4 testvalue932" -+other_name_utf8 = "1.2.3.4 testvalue933" -+other_name_utf8 = "1.2.3.4 testvalue934" -+other_name_utf8 = "1.2.3.4 testvalue935" -+other_name_utf8 = "1.2.3.4 testvalue936" -+other_name_utf8 = "1.2.3.4 testvalue937" -+other_name_utf8 = "1.2.3.4 testvalue938" -+other_name_utf8 = "1.2.3.4 testvalue939" -+other_name_utf8 = "1.2.3.4 testvalue940" -+other_name_utf8 = "1.2.3.4 testvalue941" -+other_name_utf8 = "1.2.3.4 testvalue942" -+other_name_utf8 = "1.2.3.4 testvalue943" -+other_name_utf8 = "1.2.3.4 testvalue944" -+other_name_utf8 = "1.2.3.4 testvalue945" -+other_name_utf8 = "1.2.3.4 testvalue946" -+other_name_utf8 = "1.2.3.4 testvalue947" -+other_name_utf8 = "1.2.3.4 testvalue948" -+other_name_utf8 = "1.2.3.4 testvalue949" -+other_name_utf8 = "1.2.3.4 testvalue950" -+other_name_utf8 = "1.2.3.4 testvalue951" -+other_name_utf8 = "1.2.3.4 testvalue952" -+other_name_utf8 = "1.2.3.4 testvalue953" -+other_name_utf8 = "1.2.3.4 testvalue954" -+other_name_utf8 = "1.2.3.4 testvalue955" -+other_name_utf8 = "1.2.3.4 testvalue956" -+other_name_utf8 = "1.2.3.4 testvalue957" -+other_name_utf8 = "1.2.3.4 testvalue958" -+other_name_utf8 = "1.2.3.4 testvalue959" -+other_name_utf8 = "1.2.3.4 testvalue960" -+other_name_utf8 = "1.2.3.4 testvalue961" -+other_name_utf8 = "1.2.3.4 testvalue962" -+other_name_utf8 = "1.2.3.4 testvalue963" -+other_name_utf8 = "1.2.3.4 testvalue964" -+other_name_utf8 = "1.2.3.4 testvalue965" -+other_name_utf8 = "1.2.3.4 testvalue966" -+other_name_utf8 = "1.2.3.4 testvalue967" -+other_name_utf8 = "1.2.3.4 testvalue968" -+other_name_utf8 = "1.2.3.4 testvalue969" -+other_name_utf8 = "1.2.3.4 testvalue970" -+other_name_utf8 = "1.2.3.4 testvalue971" -+other_name_utf8 = "1.2.3.4 testvalue972" -+other_name_utf8 = "1.2.3.4 testvalue973" -+other_name_utf8 = "1.2.3.4 testvalue974" -+other_name_utf8 = "1.2.3.4 testvalue975" -+other_name_utf8 = "1.2.3.4 testvalue976" -+other_name_utf8 = "1.2.3.4 testvalue977" -+other_name_utf8 = "1.2.3.4 testvalue978" -+other_name_utf8 = "1.2.3.4 testvalue979" -+other_name_utf8 = "1.2.3.4 testvalue980" -+other_name_utf8 = "1.2.3.4 testvalue981" -+other_name_utf8 = "1.2.3.4 testvalue982" -+other_name_utf8 = "1.2.3.4 testvalue983" -+other_name_utf8 = "1.2.3.4 testvalue984" -+other_name_utf8 = "1.2.3.4 testvalue985" -+other_name_utf8 = "1.2.3.4 testvalue986" -+other_name_utf8 = "1.2.3.4 testvalue987" -+other_name_utf8 = "1.2.3.4 testvalue988" -+other_name_utf8 = "1.2.3.4 testvalue989" -+other_name_utf8 = "1.2.3.4 testvalue990" -+other_name_utf8 = "1.2.3.4 testvalue991" -+other_name_utf8 = "1.2.3.4 testvalue992" -+other_name_utf8 = "1.2.3.4 testvalue993" -+other_name_utf8 = "1.2.3.4 testvalue994" -+other_name_utf8 = "1.2.3.4 testvalue995" -+other_name_utf8 = "1.2.3.4 testvalue996" -+other_name_utf8 = "1.2.3.4 testvalue997" -+other_name_utf8 = "1.2.3.4 testvalue998" -+other_name_utf8 = "1.2.3.4 testvalue999" -+other_name_utf8 = "1.2.3.4 testvalue1000" -+other_name_utf8 = "1.2.3.4 testvalue1001" -+other_name_utf8 = "1.2.3.4 testvalue1002" -+other_name_utf8 = "1.2.3.4 testvalue1003" -+other_name_utf8 = "1.2.3.4 testvalue1004" -+other_name_utf8 = "1.2.3.4 testvalue1005" -+other_name_utf8 = "1.2.3.4 testvalue1006" -+other_name_utf8 = "1.2.3.4 testvalue1007" -+other_name_utf8 = "1.2.3.4 testvalue1008" -+other_name_utf8 = "1.2.3.4 testvalue1009" -+other_name_utf8 = "1.2.3.4 testvalue1010" -+other_name_utf8 = "1.2.3.4 testvalue1011" -+other_name_utf8 = "1.2.3.4 testvalue1012" -+other_name_utf8 = "1.2.3.4 testvalue1013" -+other_name_utf8 = "1.2.3.4 testvalue1014" -+other_name_utf8 = "1.2.3.4 testvalue1015" -+other_name_utf8 = "1.2.3.4 testvalue1016" -+other_name_utf8 = "1.2.3.4 testvalue1017" -+other_name_utf8 = "1.2.3.4 testvalue1018" -+other_name_utf8 = "1.2.3.4 testvalue1019" -+other_name_utf8 = "1.2.3.4 testvalue1020" -+other_name_utf8 = "1.2.3.4 testvalue1021" -+other_name_utf8 = "1.2.3.4 testvalue1022" -+other_name_utf8 = "1.2.3.4 testvalue1023" -+other_name_utf8 = "1.2.3.4 testvalue1024" -+other_name_utf8 = "1.2.3.4 testvalue1025" -+other_name_utf8 = "1.2.3.4 testvalue1026" -+other_name_utf8 = "1.2.3.4 testvalue1027" -+other_name_utf8 = "1.2.3.4 testvalue1028" -+other_name_utf8 = "1.2.3.4 testvalue1029" -+other_name_utf8 = "1.2.3.4 testvalue1030" -+other_name_utf8 = "1.2.3.4 testvalue1031" -+other_name_utf8 = "1.2.3.4 testvalue1032" -+other_name_utf8 = "1.2.3.4 testvalue1033" -+other_name_utf8 = "1.2.3.4 testvalue1034" -+other_name_utf8 = "1.2.3.4 testvalue1035" -+other_name_utf8 = "1.2.3.4 testvalue1036" -+other_name_utf8 = "1.2.3.4 testvalue1037" -+other_name_utf8 = "1.2.3.4 testvalue1038" -+other_name_utf8 = "1.2.3.4 testvalue1039" -+other_name_utf8 = "1.2.3.4 testvalue1040" -+other_name_utf8 = "1.2.3.4 testvalue1041" -+other_name_utf8 = "1.2.3.4 testvalue1042" -+other_name_utf8 = "1.2.3.4 testvalue1043" -+other_name_utf8 = "1.2.3.4 testvalue1044" -+other_name_utf8 = "1.2.3.4 testvalue1045" -+other_name_utf8 = "1.2.3.4 testvalue1046" -+other_name_utf8 = "1.2.3.4 testvalue1047" -+other_name_utf8 = "1.2.3.4 testvalue1048" -+other_name_utf8 = "1.2.3.4 testvalue1049" -+other_name_utf8 = "1.2.3.4 testvalue1050" -+other_name_utf8 = "1.2.3.4 testvalue1051" -+other_name_utf8 = "1.2.3.4 testvalue1052" -+other_name_utf8 = "1.2.3.4 testvalue1053" -+other_name_utf8 = "1.2.3.4 testvalue1054" -+other_name_utf8 = "1.2.3.4 testvalue1055" -+other_name_utf8 = "1.2.3.4 testvalue1056" -+other_name_utf8 = "1.2.3.4 testvalue1057" -+other_name_utf8 = "1.2.3.4 testvalue1058" -+other_name_utf8 = "1.2.3.4 testvalue1059" -+other_name_utf8 = "1.2.3.4 testvalue1060" -+other_name_utf8 = "1.2.3.4 testvalue1061" -+other_name_utf8 = "1.2.3.4 testvalue1062" -+other_name_utf8 = "1.2.3.4 testvalue1063" -+other_name_utf8 = "1.2.3.4 testvalue1064" -+other_name_utf8 = "1.2.3.4 testvalue1065" -+other_name_utf8 = "1.2.3.4 testvalue1066" -+other_name_utf8 = "1.2.3.4 testvalue1067" -+other_name_utf8 = "1.2.3.4 testvalue1068" -+other_name_utf8 = "1.2.3.4 testvalue1069" -+other_name_utf8 = "1.2.3.4 testvalue1070" -+other_name_utf8 = "1.2.3.4 testvalue1071" -+other_name_utf8 = "1.2.3.4 testvalue1072" -+other_name_utf8 = "1.2.3.4 testvalue1073" -+other_name_utf8 = "1.2.3.4 testvalue1074" -+other_name_utf8 = "1.2.3.4 testvalue1075" -+other_name_utf8 = "1.2.3.4 testvalue1076" -+other_name_utf8 = "1.2.3.4 testvalue1077" -+other_name_utf8 = "1.2.3.4 testvalue1078" -+other_name_utf8 = "1.2.3.4 testvalue1079" -+other_name_utf8 = "1.2.3.4 testvalue1080" -+other_name_utf8 = "1.2.3.4 testvalue1081" -+other_name_utf8 = "1.2.3.4 testvalue1082" -+other_name_utf8 = "1.2.3.4 testvalue1083" -+other_name_utf8 = "1.2.3.4 testvalue1084" -+other_name_utf8 = "1.2.3.4 testvalue1085" -+other_name_utf8 = "1.2.3.4 testvalue1086" -+other_name_utf8 = "1.2.3.4 testvalue1087" -+other_name_utf8 = "1.2.3.4 testvalue1088" -+other_name_utf8 = "1.2.3.4 testvalue1089" -+other_name_utf8 = "1.2.3.4 testvalue1090" -+other_name_utf8 = "1.2.3.4 testvalue1091" -+other_name_utf8 = "1.2.3.4 testvalue1092" -+other_name_utf8 = "1.2.3.4 testvalue1093" -+other_name_utf8 = "1.2.3.4 testvalue1094" -+other_name_utf8 = "1.2.3.4 testvalue1095" -+other_name_utf8 = "1.2.3.4 testvalue1096" -+other_name_utf8 = "1.2.3.4 testvalue1097" -+other_name_utf8 = "1.2.3.4 testvalue1098" -+other_name_utf8 = "1.2.3.4 testvalue1099" -+other_name_utf8 = "1.2.3.4 testvalue1100" -+other_name_utf8 = "1.2.3.4 testvalue1101" -+other_name_utf8 = "1.2.3.4 testvalue1102" -+other_name_utf8 = "1.2.3.4 testvalue1103" -+other_name_utf8 = "1.2.3.4 testvalue1104" -+other_name_utf8 = "1.2.3.4 testvalue1105" -+other_name_utf8 = "1.2.3.4 testvalue1106" -+other_name_utf8 = "1.2.3.4 testvalue1107" -+other_name_utf8 = "1.2.3.4 testvalue1108" -+other_name_utf8 = "1.2.3.4 testvalue1109" -+other_name_utf8 = "1.2.3.4 testvalue1110" -+other_name_utf8 = "1.2.3.4 testvalue1111" -+other_name_utf8 = "1.2.3.4 testvalue1112" -+other_name_utf8 = "1.2.3.4 testvalue1113" -+other_name_utf8 = "1.2.3.4 testvalue1114" -+other_name_utf8 = "1.2.3.4 testvalue1115" -+other_name_utf8 = "1.2.3.4 testvalue1116" -+other_name_utf8 = "1.2.3.4 testvalue1117" -+other_name_utf8 = "1.2.3.4 testvalue1118" -+other_name_utf8 = "1.2.3.4 testvalue1119" -+other_name_utf8 = "1.2.3.4 testvalue1120" -+other_name_utf8 = "1.2.3.4 testvalue1121" -+other_name_utf8 = "1.2.3.4 testvalue1122" -+other_name_utf8 = "1.2.3.4 testvalue1123" -+other_name_utf8 = "1.2.3.4 testvalue1124" -+other_name_utf8 = "1.2.3.4 testvalue1125" -+other_name_utf8 = "1.2.3.4 testvalue1126" -+other_name_utf8 = "1.2.3.4 testvalue1127" -+other_name_utf8 = "1.2.3.4 testvalue1128" -+other_name_utf8 = "1.2.3.4 testvalue1129" -+other_name_utf8 = "1.2.3.4 testvalue1130" -+other_name_utf8 = "1.2.3.4 testvalue1131" -+other_name_utf8 = "1.2.3.4 testvalue1132" -+other_name_utf8 = "1.2.3.4 testvalue1133" -+other_name_utf8 = "1.2.3.4 testvalue1134" -+other_name_utf8 = "1.2.3.4 testvalue1135" -+other_name_utf8 = "1.2.3.4 testvalue1136" -+other_name_utf8 = "1.2.3.4 testvalue1137" -+other_name_utf8 = "1.2.3.4 testvalue1138" -+other_name_utf8 = "1.2.3.4 testvalue1139" -+other_name_utf8 = "1.2.3.4 testvalue1140" -+other_name_utf8 = "1.2.3.4 testvalue1141" -+other_name_utf8 = "1.2.3.4 testvalue1142" -+other_name_utf8 = "1.2.3.4 testvalue1143" -+other_name_utf8 = "1.2.3.4 testvalue1144" -+other_name_utf8 = "1.2.3.4 testvalue1145" -+other_name_utf8 = "1.2.3.4 testvalue1146" -+other_name_utf8 = "1.2.3.4 testvalue1147" -+other_name_utf8 = "1.2.3.4 testvalue1148" -+other_name_utf8 = "1.2.3.4 testvalue1149" -+other_name_utf8 = "1.2.3.4 testvalue1150" -+other_name_utf8 = "1.2.3.4 testvalue1151" -+other_name_utf8 = "1.2.3.4 testvalue1152" -+other_name_utf8 = "1.2.3.4 testvalue1153" -+other_name_utf8 = "1.2.3.4 testvalue1154" -+other_name_utf8 = "1.2.3.4 testvalue1155" -+other_name_utf8 = "1.2.3.4 testvalue1156" -+other_name_utf8 = "1.2.3.4 testvalue1157" -+other_name_utf8 = "1.2.3.4 testvalue1158" -+other_name_utf8 = "1.2.3.4 testvalue1159" -+other_name_utf8 = "1.2.3.4 testvalue1160" -+other_name_utf8 = "1.2.3.4 testvalue1161" -+other_name_utf8 = "1.2.3.4 testvalue1162" -+other_name_utf8 = "1.2.3.4 testvalue1163" -+other_name_utf8 = "1.2.3.4 testvalue1164" -+other_name_utf8 = "1.2.3.4 testvalue1165" -+other_name_utf8 = "1.2.3.4 testvalue1166" -+other_name_utf8 = "1.2.3.4 testvalue1167" -+other_name_utf8 = "1.2.3.4 testvalue1168" -+other_name_utf8 = "1.2.3.4 testvalue1169" -+other_name_utf8 = "1.2.3.4 testvalue1170" -+other_name_utf8 = "1.2.3.4 testvalue1171" -+other_name_utf8 = "1.2.3.4 testvalue1172" -+other_name_utf8 = "1.2.3.4 testvalue1173" -+other_name_utf8 = "1.2.3.4 testvalue1174" -+other_name_utf8 = "1.2.3.4 testvalue1175" -+other_name_utf8 = "1.2.3.4 testvalue1176" -+other_name_utf8 = "1.2.3.4 testvalue1177" -+other_name_utf8 = "1.2.3.4 testvalue1178" -+other_name_utf8 = "1.2.3.4 testvalue1179" -+other_name_utf8 = "1.2.3.4 testvalue1180" -+other_name_utf8 = "1.2.3.4 testvalue1181" -+other_name_utf8 = "1.2.3.4 testvalue1182" -+other_name_utf8 = "1.2.3.4 testvalue1183" -+other_name_utf8 = "1.2.3.4 testvalue1184" -+other_name_utf8 = "1.2.3.4 testvalue1185" -+other_name_utf8 = "1.2.3.4 testvalue1186" -+other_name_utf8 = "1.2.3.4 testvalue1187" -+other_name_utf8 = "1.2.3.4 testvalue1188" -+other_name_utf8 = "1.2.3.4 testvalue1189" -+other_name_utf8 = "1.2.3.4 testvalue1190" -+other_name_utf8 = "1.2.3.4 testvalue1191" -+other_name_utf8 = "1.2.3.4 testvalue1192" -+other_name_utf8 = "1.2.3.4 testvalue1193" -+other_name_utf8 = "1.2.3.4 testvalue1194" -+other_name_utf8 = "1.2.3.4 testvalue1195" -+other_name_utf8 = "1.2.3.4 testvalue1196" -+other_name_utf8 = "1.2.3.4 testvalue1197" -+other_name_utf8 = "1.2.3.4 testvalue1198" -+other_name_utf8 = "1.2.3.4 testvalue1199" -+other_name_utf8 = "1.2.3.4 testvalue1200" -+other_name_utf8 = "1.2.3.4 testvalue1201" -+other_name_utf8 = "1.2.3.4 testvalue1202" -+other_name_utf8 = "1.2.3.4 testvalue1203" -+other_name_utf8 = "1.2.3.4 testvalue1204" -+other_name_utf8 = "1.2.3.4 testvalue1205" -+other_name_utf8 = "1.2.3.4 testvalue1206" -+other_name_utf8 = "1.2.3.4 testvalue1207" -+other_name_utf8 = "1.2.3.4 testvalue1208" -+other_name_utf8 = "1.2.3.4 testvalue1209" -+other_name_utf8 = "1.2.3.4 testvalue1210" -+other_name_utf8 = "1.2.3.4 testvalue1211" -+other_name_utf8 = "1.2.3.4 testvalue1212" -+other_name_utf8 = "1.2.3.4 testvalue1213" -+other_name_utf8 = "1.2.3.4 testvalue1214" -+other_name_utf8 = "1.2.3.4 testvalue1215" -+other_name_utf8 = "1.2.3.4 testvalue1216" -+other_name_utf8 = "1.2.3.4 testvalue1217" -+other_name_utf8 = "1.2.3.4 testvalue1218" -+other_name_utf8 = "1.2.3.4 testvalue1219" -+other_name_utf8 = "1.2.3.4 testvalue1220" -+other_name_utf8 = "1.2.3.4 testvalue1221" -+other_name_utf8 = "1.2.3.4 testvalue1222" -+other_name_utf8 = "1.2.3.4 testvalue1223" -+other_name_utf8 = "1.2.3.4 testvalue1224" -+other_name_utf8 = "1.2.3.4 testvalue1225" -+other_name_utf8 = "1.2.3.4 testvalue1226" -+other_name_utf8 = "1.2.3.4 testvalue1227" -+other_name_utf8 = "1.2.3.4 testvalue1228" -+other_name_utf8 = "1.2.3.4 testvalue1229" -+other_name_utf8 = "1.2.3.4 testvalue1230" -+other_name_utf8 = "1.2.3.4 testvalue1231" -+other_name_utf8 = "1.2.3.4 testvalue1232" -+other_name_utf8 = "1.2.3.4 testvalue1233" -+other_name_utf8 = "1.2.3.4 testvalue1234" -+other_name_utf8 = "1.2.3.4 testvalue1235" -+other_name_utf8 = "1.2.3.4 testvalue1236" -+other_name_utf8 = "1.2.3.4 testvalue1237" -+other_name_utf8 = "1.2.3.4 testvalue1238" -+other_name_utf8 = "1.2.3.4 testvalue1239" -+other_name_utf8 = "1.2.3.4 testvalue1240" -+other_name_utf8 = "1.2.3.4 testvalue1241" -+other_name_utf8 = "1.2.3.4 testvalue1242" -+other_name_utf8 = "1.2.3.4 testvalue1243" -+other_name_utf8 = "1.2.3.4 testvalue1244" -+other_name_utf8 = "1.2.3.4 testvalue1245" -+other_name_utf8 = "1.2.3.4 testvalue1246" -+other_name_utf8 = "1.2.3.4 testvalue1247" -+other_name_utf8 = "1.2.3.4 testvalue1248" -+other_name_utf8 = "1.2.3.4 testvalue1249" -+other_name_utf8 = "1.2.3.4 testvalue1250" -+other_name_utf8 = "1.2.3.4 testvalue1251" -+other_name_utf8 = "1.2.3.4 testvalue1252" -+other_name_utf8 = "1.2.3.4 testvalue1253" -+other_name_utf8 = "1.2.3.4 testvalue1254" -+other_name_utf8 = "1.2.3.4 testvalue1255" -+other_name_utf8 = "1.2.3.4 testvalue1256" -+other_name_utf8 = "1.2.3.4 testvalue1257" -+other_name_utf8 = "1.2.3.4 testvalue1258" -+other_name_utf8 = "1.2.3.4 testvalue1259" -+other_name_utf8 = "1.2.3.4 testvalue1260" -+other_name_utf8 = "1.2.3.4 testvalue1261" -+other_name_utf8 = "1.2.3.4 testvalue1262" -+other_name_utf8 = "1.2.3.4 testvalue1263" -+other_name_utf8 = "1.2.3.4 testvalue1264" -+other_name_utf8 = "1.2.3.4 testvalue1265" -+other_name_utf8 = "1.2.3.4 testvalue1266" -+other_name_utf8 = "1.2.3.4 testvalue1267" -+other_name_utf8 = "1.2.3.4 testvalue1268" -+other_name_utf8 = "1.2.3.4 testvalue1269" -+other_name_utf8 = "1.2.3.4 testvalue1270" -+other_name_utf8 = "1.2.3.4 testvalue1271" -+other_name_utf8 = "1.2.3.4 testvalue1272" -+other_name_utf8 = "1.2.3.4 testvalue1273" -+other_name_utf8 = "1.2.3.4 testvalue1274" -+other_name_utf8 = "1.2.3.4 testvalue1275" -+other_name_utf8 = "1.2.3.4 testvalue1276" -+other_name_utf8 = "1.2.3.4 testvalue1277" -+other_name_utf8 = "1.2.3.4 testvalue1278" -+other_name_utf8 = "1.2.3.4 testvalue1279" -+other_name_utf8 = "1.2.3.4 testvalue1280" -+other_name_utf8 = "1.2.3.4 testvalue1281" -+other_name_utf8 = "1.2.3.4 testvalue1282" -+other_name_utf8 = "1.2.3.4 testvalue1283" -+other_name_utf8 = "1.2.3.4 testvalue1284" -+other_name_utf8 = "1.2.3.4 testvalue1285" -+other_name_utf8 = "1.2.3.4 testvalue1286" -+other_name_utf8 = "1.2.3.4 testvalue1287" -+other_name_utf8 = "1.2.3.4 testvalue1288" -+other_name_utf8 = "1.2.3.4 testvalue1289" -+other_name_utf8 = "1.2.3.4 testvalue1290" -+other_name_utf8 = "1.2.3.4 testvalue1291" -+other_name_utf8 = "1.2.3.4 testvalue1292" -+other_name_utf8 = "1.2.3.4 testvalue1293" -+other_name_utf8 = "1.2.3.4 testvalue1294" -+other_name_utf8 = "1.2.3.4 testvalue1295" -+other_name_utf8 = "1.2.3.4 testvalue1296" -+other_name_utf8 = "1.2.3.4 testvalue1297" -+other_name_utf8 = "1.2.3.4 testvalue1298" -+other_name_utf8 = "1.2.3.4 testvalue1299" -+other_name_utf8 = "1.2.3.4 testvalue1300" -+other_name_utf8 = "1.2.3.4 testvalue1301" -+other_name_utf8 = "1.2.3.4 testvalue1302" -+other_name_utf8 = "1.2.3.4 testvalue1303" -+other_name_utf8 = "1.2.3.4 testvalue1304" -+other_name_utf8 = "1.2.3.4 testvalue1305" -+other_name_utf8 = "1.2.3.4 testvalue1306" -+other_name_utf8 = "1.2.3.4 testvalue1307" -+other_name_utf8 = "1.2.3.4 testvalue1308" -+other_name_utf8 = "1.2.3.4 testvalue1309" -+other_name_utf8 = "1.2.3.4 testvalue1310" -+other_name_utf8 = "1.2.3.4 testvalue1311" -+other_name_utf8 = "1.2.3.4 testvalue1312" -+other_name_utf8 = "1.2.3.4 testvalue1313" -+other_name_utf8 = "1.2.3.4 testvalue1314" -+other_name_utf8 = "1.2.3.4 testvalue1315" -+other_name_utf8 = "1.2.3.4 testvalue1316" -+other_name_utf8 = "1.2.3.4 testvalue1317" -+other_name_utf8 = "1.2.3.4 testvalue1318" -+other_name_utf8 = "1.2.3.4 testvalue1319" -+other_name_utf8 = "1.2.3.4 testvalue1320" -+other_name_utf8 = "1.2.3.4 testvalue1321" -+other_name_utf8 = "1.2.3.4 testvalue1322" -+other_name_utf8 = "1.2.3.4 testvalue1323" -+other_name_utf8 = "1.2.3.4 testvalue1324" -+other_name_utf8 = "1.2.3.4 testvalue1325" -+other_name_utf8 = "1.2.3.4 testvalue1326" -+other_name_utf8 = "1.2.3.4 testvalue1327" -+other_name_utf8 = "1.2.3.4 testvalue1328" -+other_name_utf8 = "1.2.3.4 testvalue1329" -+other_name_utf8 = "1.2.3.4 testvalue1330" -+other_name_utf8 = "1.2.3.4 testvalue1331" -+other_name_utf8 = "1.2.3.4 testvalue1332" -+other_name_utf8 = "1.2.3.4 testvalue1333" -+other_name_utf8 = "1.2.3.4 testvalue1334" -+other_name_utf8 = "1.2.3.4 testvalue1335" -+other_name_utf8 = "1.2.3.4 testvalue1336" -+other_name_utf8 = "1.2.3.4 testvalue1337" -+other_name_utf8 = "1.2.3.4 testvalue1338" -+other_name_utf8 = "1.2.3.4 testvalue1339" -+other_name_utf8 = "1.2.3.4 testvalue1340" -+other_name_utf8 = "1.2.3.4 testvalue1341" -+other_name_utf8 = "1.2.3.4 testvalue1342" -+other_name_utf8 = "1.2.3.4 testvalue1343" -+other_name_utf8 = "1.2.3.4 testvalue1344" -+other_name_utf8 = "1.2.3.4 testvalue1345" -+other_name_utf8 = "1.2.3.4 testvalue1346" -+other_name_utf8 = "1.2.3.4 testvalue1347" -+other_name_utf8 = "1.2.3.4 testvalue1348" -+other_name_utf8 = "1.2.3.4 testvalue1349" -+other_name_utf8 = "1.2.3.4 testvalue1350" -+other_name_utf8 = "1.2.3.4 testvalue1351" -+other_name_utf8 = "1.2.3.4 testvalue1352" -+other_name_utf8 = "1.2.3.4 testvalue1353" -+other_name_utf8 = "1.2.3.4 testvalue1354" -+other_name_utf8 = "1.2.3.4 testvalue1355" -+other_name_utf8 = "1.2.3.4 testvalue1356" -+other_name_utf8 = "1.2.3.4 testvalue1357" -+other_name_utf8 = "1.2.3.4 testvalue1358" -+other_name_utf8 = "1.2.3.4 testvalue1359" -+other_name_utf8 = "1.2.3.4 testvalue1360" -+other_name_utf8 = "1.2.3.4 testvalue1361" -+other_name_utf8 = "1.2.3.4 testvalue1362" -+other_name_utf8 = "1.2.3.4 testvalue1363" -+other_name_utf8 = "1.2.3.4 testvalue1364" -+other_name_utf8 = "1.2.3.4 testvalue1365" -+other_name_utf8 = "1.2.3.4 testvalue1366" -+other_name_utf8 = "1.2.3.4 testvalue1367" -+other_name_utf8 = "1.2.3.4 testvalue1368" -+other_name_utf8 = "1.2.3.4 testvalue1369" -+other_name_utf8 = "1.2.3.4 testvalue1370" -+other_name_utf8 = "1.2.3.4 testvalue1371" -+other_name_utf8 = "1.2.3.4 testvalue1372" -+other_name_utf8 = "1.2.3.4 testvalue1373" -+other_name_utf8 = "1.2.3.4 testvalue1374" -+other_name_utf8 = "1.2.3.4 testvalue1375" -+other_name_utf8 = "1.2.3.4 testvalue1376" -+other_name_utf8 = "1.2.3.4 testvalue1377" -+other_name_utf8 = "1.2.3.4 testvalue1378" -+other_name_utf8 = "1.2.3.4 testvalue1379" -+other_name_utf8 = "1.2.3.4 testvalue1380" -+other_name_utf8 = "1.2.3.4 testvalue1381" -+other_name_utf8 = "1.2.3.4 testvalue1382" -+other_name_utf8 = "1.2.3.4 testvalue1383" -+other_name_utf8 = "1.2.3.4 testvalue1384" -+other_name_utf8 = "1.2.3.4 testvalue1385" -+other_name_utf8 = "1.2.3.4 testvalue1386" -+other_name_utf8 = "1.2.3.4 testvalue1387" -+other_name_utf8 = "1.2.3.4 testvalue1388" -+other_name_utf8 = "1.2.3.4 testvalue1389" -+other_name_utf8 = "1.2.3.4 testvalue1390" -+other_name_utf8 = "1.2.3.4 testvalue1391" -+other_name_utf8 = "1.2.3.4 testvalue1392" -+other_name_utf8 = "1.2.3.4 testvalue1393" -+other_name_utf8 = "1.2.3.4 testvalue1394" -+other_name_utf8 = "1.2.3.4 testvalue1395" -+other_name_utf8 = "1.2.3.4 testvalue1396" -+other_name_utf8 = "1.2.3.4 testvalue1397" -+other_name_utf8 = "1.2.3.4 testvalue1398" -+other_name_utf8 = "1.2.3.4 testvalue1399" -+other_name_utf8 = "1.2.3.4 testvalue1400" -+other_name_utf8 = "1.2.3.4 testvalue1401" -+other_name_utf8 = "1.2.3.4 testvalue1402" -+other_name_utf8 = "1.2.3.4 testvalue1403" -+other_name_utf8 = "1.2.3.4 testvalue1404" -+other_name_utf8 = "1.2.3.4 testvalue1405" -+other_name_utf8 = "1.2.3.4 testvalue1406" -+other_name_utf8 = "1.2.3.4 testvalue1407" -+other_name_utf8 = "1.2.3.4 testvalue1408" -+other_name_utf8 = "1.2.3.4 testvalue1409" -+other_name_utf8 = "1.2.3.4 testvalue1410" -+other_name_utf8 = "1.2.3.4 testvalue1411" -+other_name_utf8 = "1.2.3.4 testvalue1412" -+other_name_utf8 = "1.2.3.4 testvalue1413" -+other_name_utf8 = "1.2.3.4 testvalue1414" -+other_name_utf8 = "1.2.3.4 testvalue1415" -+other_name_utf8 = "1.2.3.4 testvalue1416" -+other_name_utf8 = "1.2.3.4 testvalue1417" -+other_name_utf8 = "1.2.3.4 testvalue1418" -+other_name_utf8 = "1.2.3.4 testvalue1419" -+other_name_utf8 = "1.2.3.4 testvalue1420" -+other_name_utf8 = "1.2.3.4 testvalue1421" -+other_name_utf8 = "1.2.3.4 testvalue1422" -+other_name_utf8 = "1.2.3.4 testvalue1423" -+other_name_utf8 = "1.2.3.4 testvalue1424" -+other_name_utf8 = "1.2.3.4 testvalue1425" -+other_name_utf8 = "1.2.3.4 testvalue1426" -+other_name_utf8 = "1.2.3.4 testvalue1427" -+other_name_utf8 = "1.2.3.4 testvalue1428" -+other_name_utf8 = "1.2.3.4 testvalue1429" -+other_name_utf8 = "1.2.3.4 testvalue1430" -+other_name_utf8 = "1.2.3.4 testvalue1431" -+other_name_utf8 = "1.2.3.4 testvalue1432" -+other_name_utf8 = "1.2.3.4 testvalue1433" -+other_name_utf8 = "1.2.3.4 testvalue1434" -+other_name_utf8 = "1.2.3.4 testvalue1435" -+other_name_utf8 = "1.2.3.4 testvalue1436" -+other_name_utf8 = "1.2.3.4 testvalue1437" -+other_name_utf8 = "1.2.3.4 testvalue1438" -+other_name_utf8 = "1.2.3.4 testvalue1439" -+other_name_utf8 = "1.2.3.4 testvalue1440" -+other_name_utf8 = "1.2.3.4 testvalue1441" -+other_name_utf8 = "1.2.3.4 testvalue1442" -+other_name_utf8 = "1.2.3.4 testvalue1443" -+other_name_utf8 = "1.2.3.4 testvalue1444" -+other_name_utf8 = "1.2.3.4 testvalue1445" -+other_name_utf8 = "1.2.3.4 testvalue1446" -+other_name_utf8 = "1.2.3.4 testvalue1447" -+other_name_utf8 = "1.2.3.4 testvalue1448" -+other_name_utf8 = "1.2.3.4 testvalue1449" -+other_name_utf8 = "1.2.3.4 testvalue1450" -+other_name_utf8 = "1.2.3.4 testvalue1451" -+other_name_utf8 = "1.2.3.4 testvalue1452" -+other_name_utf8 = "1.2.3.4 testvalue1453" -+other_name_utf8 = "1.2.3.4 testvalue1454" -+other_name_utf8 = "1.2.3.4 testvalue1455" -+other_name_utf8 = "1.2.3.4 testvalue1456" -+other_name_utf8 = "1.2.3.4 testvalue1457" -+other_name_utf8 = "1.2.3.4 testvalue1458" -+other_name_utf8 = "1.2.3.4 testvalue1459" -+other_name_utf8 = "1.2.3.4 testvalue1460" -+other_name_utf8 = "1.2.3.4 testvalue1461" -+other_name_utf8 = "1.2.3.4 testvalue1462" -+other_name_utf8 = "1.2.3.4 testvalue1463" -+other_name_utf8 = "1.2.3.4 testvalue1464" -+other_name_utf8 = "1.2.3.4 testvalue1465" -+other_name_utf8 = "1.2.3.4 testvalue1466" -+other_name_utf8 = "1.2.3.4 testvalue1467" -+other_name_utf8 = "1.2.3.4 testvalue1468" -+other_name_utf8 = "1.2.3.4 testvalue1469" -+other_name_utf8 = "1.2.3.4 testvalue1470" -+other_name_utf8 = "1.2.3.4 testvalue1471" -+other_name_utf8 = "1.2.3.4 testvalue1472" -+other_name_utf8 = "1.2.3.4 testvalue1473" -+other_name_utf8 = "1.2.3.4 testvalue1474" -+other_name_utf8 = "1.2.3.4 testvalue1475" -+other_name_utf8 = "1.2.3.4 testvalue1476" -+other_name_utf8 = "1.2.3.4 testvalue1477" -+other_name_utf8 = "1.2.3.4 testvalue1478" -+other_name_utf8 = "1.2.3.4 testvalue1479" -+other_name_utf8 = "1.2.3.4 testvalue1480" -+other_name_utf8 = "1.2.3.4 testvalue1481" -+other_name_utf8 = "1.2.3.4 testvalue1482" -+other_name_utf8 = "1.2.3.4 testvalue1483" -+other_name_utf8 = "1.2.3.4 testvalue1484" -+other_name_utf8 = "1.2.3.4 testvalue1485" -+other_name_utf8 = "1.2.3.4 testvalue1486" -+other_name_utf8 = "1.2.3.4 testvalue1487" -+other_name_utf8 = "1.2.3.4 testvalue1488" -+other_name_utf8 = "1.2.3.4 testvalue1489" -+other_name_utf8 = "1.2.3.4 testvalue1490" -+other_name_utf8 = "1.2.3.4 testvalue1491" -+other_name_utf8 = "1.2.3.4 testvalue1492" -+other_name_utf8 = "1.2.3.4 testvalue1493" -+other_name_utf8 = "1.2.3.4 testvalue1494" -+other_name_utf8 = "1.2.3.4 testvalue1495" -+other_name_utf8 = "1.2.3.4 testvalue1496" -+other_name_utf8 = "1.2.3.4 testvalue1497" -+other_name_utf8 = "1.2.3.4 testvalue1498" -+other_name_utf8 = "1.2.3.4 testvalue1499" -+other_name_utf8 = "1.2.3.4 testvalue1500" -+other_name_utf8 = "1.2.3.4 testvalue1501" -+other_name_utf8 = "1.2.3.4 testvalue1502" -+other_name_utf8 = "1.2.3.4 testvalue1503" -+other_name_utf8 = "1.2.3.4 testvalue1504" -+other_name_utf8 = "1.2.3.4 testvalue1505" -+other_name_utf8 = "1.2.3.4 testvalue1506" -+other_name_utf8 = "1.2.3.4 testvalue1507" -+other_name_utf8 = "1.2.3.4 testvalue1508" -+other_name_utf8 = "1.2.3.4 testvalue1509" -+other_name_utf8 = "1.2.3.4 testvalue1510" -+other_name_utf8 = "1.2.3.4 testvalue1511" -+other_name_utf8 = "1.2.3.4 testvalue1512" -+other_name_utf8 = "1.2.3.4 testvalue1513" -+other_name_utf8 = "1.2.3.4 testvalue1514" -+other_name_utf8 = "1.2.3.4 testvalue1515" -+other_name_utf8 = "1.2.3.4 testvalue1516" -+other_name_utf8 = "1.2.3.4 testvalue1517" -+other_name_utf8 = "1.2.3.4 testvalue1518" -+other_name_utf8 = "1.2.3.4 testvalue1519" -+other_name_utf8 = "1.2.3.4 testvalue1520" -+other_name_utf8 = "1.2.3.4 testvalue1521" -+other_name_utf8 = "1.2.3.4 testvalue1522" -+other_name_utf8 = "1.2.3.4 testvalue1523" -+other_name_utf8 = "1.2.3.4 testvalue1524" -+other_name_utf8 = "1.2.3.4 testvalue1525" -+other_name_utf8 = "1.2.3.4 testvalue1526" -+other_name_utf8 = "1.2.3.4 testvalue1527" -+other_name_utf8 = "1.2.3.4 testvalue1528" -+other_name_utf8 = "1.2.3.4 testvalue1529" -+other_name_utf8 = "1.2.3.4 testvalue1530" -+other_name_utf8 = "1.2.3.4 testvalue1531" -+other_name_utf8 = "1.2.3.4 testvalue1532" -+other_name_utf8 = "1.2.3.4 testvalue1533" -+other_name_utf8 = "1.2.3.4 testvalue1534" -+other_name_utf8 = "1.2.3.4 testvalue1535" -+other_name_utf8 = "1.2.3.4 testvalue1536" -+other_name_utf8 = "1.2.3.4 testvalue1537" -+other_name_utf8 = "1.2.3.4 testvalue1538" -+other_name_utf8 = "1.2.3.4 testvalue1539" -+other_name_utf8 = "1.2.3.4 testvalue1540" -+other_name_utf8 = "1.2.3.4 testvalue1541" -+other_name_utf8 = "1.2.3.4 testvalue1542" -+other_name_utf8 = "1.2.3.4 testvalue1543" -+other_name_utf8 = "1.2.3.4 testvalue1544" -+other_name_utf8 = "1.2.3.4 testvalue1545" -+other_name_utf8 = "1.2.3.4 testvalue1546" -+other_name_utf8 = "1.2.3.4 testvalue1547" -+other_name_utf8 = "1.2.3.4 testvalue1548" -+other_name_utf8 = "1.2.3.4 testvalue1549" -+other_name_utf8 = "1.2.3.4 testvalue1550" -+other_name_utf8 = "1.2.3.4 testvalue1551" -+other_name_utf8 = "1.2.3.4 testvalue1552" -+other_name_utf8 = "1.2.3.4 testvalue1553" -+other_name_utf8 = "1.2.3.4 testvalue1554" -+other_name_utf8 = "1.2.3.4 testvalue1555" -+other_name_utf8 = "1.2.3.4 testvalue1556" -+other_name_utf8 = "1.2.3.4 testvalue1557" -+other_name_utf8 = "1.2.3.4 testvalue1558" -+other_name_utf8 = "1.2.3.4 testvalue1559" -+other_name_utf8 = "1.2.3.4 testvalue1560" -+other_name_utf8 = "1.2.3.4 testvalue1561" -+other_name_utf8 = "1.2.3.4 testvalue1562" -+other_name_utf8 = "1.2.3.4 testvalue1563" -+other_name_utf8 = "1.2.3.4 testvalue1564" -+other_name_utf8 = "1.2.3.4 testvalue1565" -+other_name_utf8 = "1.2.3.4 testvalue1566" -+other_name_utf8 = "1.2.3.4 testvalue1567" -+other_name_utf8 = "1.2.3.4 testvalue1568" -+other_name_utf8 = "1.2.3.4 testvalue1569" -+other_name_utf8 = "1.2.3.4 testvalue1570" -+other_name_utf8 = "1.2.3.4 testvalue1571" -+other_name_utf8 = "1.2.3.4 testvalue1572" -+other_name_utf8 = "1.2.3.4 testvalue1573" -+other_name_utf8 = "1.2.3.4 testvalue1574" -+other_name_utf8 = "1.2.3.4 testvalue1575" -+other_name_utf8 = "1.2.3.4 testvalue1576" -+other_name_utf8 = "1.2.3.4 testvalue1577" -+other_name_utf8 = "1.2.3.4 testvalue1578" -+other_name_utf8 = "1.2.3.4 testvalue1579" -+other_name_utf8 = "1.2.3.4 testvalue1580" -+other_name_utf8 = "1.2.3.4 testvalue1581" -+other_name_utf8 = "1.2.3.4 testvalue1582" -+other_name_utf8 = "1.2.3.4 testvalue1583" -+other_name_utf8 = "1.2.3.4 testvalue1584" -+other_name_utf8 = "1.2.3.4 testvalue1585" -+other_name_utf8 = "1.2.3.4 testvalue1586" -+other_name_utf8 = "1.2.3.4 testvalue1587" -+other_name_utf8 = "1.2.3.4 testvalue1588" -+other_name_utf8 = "1.2.3.4 testvalue1589" -+other_name_utf8 = "1.2.3.4 testvalue1590" -+other_name_utf8 = "1.2.3.4 testvalue1591" -+other_name_utf8 = "1.2.3.4 testvalue1592" -+other_name_utf8 = "1.2.3.4 testvalue1593" -+other_name_utf8 = "1.2.3.4 testvalue1594" -+other_name_utf8 = "1.2.3.4 testvalue1595" -+other_name_utf8 = "1.2.3.4 testvalue1596" -+other_name_utf8 = "1.2.3.4 testvalue1597" -+other_name_utf8 = "1.2.3.4 testvalue1598" -+other_name_utf8 = "1.2.3.4 testvalue1599" -+other_name_utf8 = "1.2.3.4 testvalue1600" -+other_name_utf8 = "1.2.3.4 testvalue1601" -+other_name_utf8 = "1.2.3.4 testvalue1602" -+other_name_utf8 = "1.2.3.4 testvalue1603" -+other_name_utf8 = "1.2.3.4 testvalue1604" -+other_name_utf8 = "1.2.3.4 testvalue1605" -+other_name_utf8 = "1.2.3.4 testvalue1606" -+other_name_utf8 = "1.2.3.4 testvalue1607" -+other_name_utf8 = "1.2.3.4 testvalue1608" -+other_name_utf8 = "1.2.3.4 testvalue1609" -+other_name_utf8 = "1.2.3.4 testvalue1610" -+other_name_utf8 = "1.2.3.4 testvalue1611" -+other_name_utf8 = "1.2.3.4 testvalue1612" -+other_name_utf8 = "1.2.3.4 testvalue1613" -+other_name_utf8 = "1.2.3.4 testvalue1614" -+other_name_utf8 = "1.2.3.4 testvalue1615" -+other_name_utf8 = "1.2.3.4 testvalue1616" -+other_name_utf8 = "1.2.3.4 testvalue1617" -+other_name_utf8 = "1.2.3.4 testvalue1618" -+other_name_utf8 = "1.2.3.4 testvalue1619" -+other_name_utf8 = "1.2.3.4 testvalue1620" -+other_name_utf8 = "1.2.3.4 testvalue1621" -+other_name_utf8 = "1.2.3.4 testvalue1622" -+other_name_utf8 = "1.2.3.4 testvalue1623" -+other_name_utf8 = "1.2.3.4 testvalue1624" -+other_name_utf8 = "1.2.3.4 testvalue1625" -+other_name_utf8 = "1.2.3.4 testvalue1626" -+other_name_utf8 = "1.2.3.4 testvalue1627" -+other_name_utf8 = "1.2.3.4 testvalue1628" -+other_name_utf8 = "1.2.3.4 testvalue1629" -+other_name_utf8 = "1.2.3.4 testvalue1630" -+other_name_utf8 = "1.2.3.4 testvalue1631" -+other_name_utf8 = "1.2.3.4 testvalue1632" -+other_name_utf8 = "1.2.3.4 testvalue1633" -+other_name_utf8 = "1.2.3.4 testvalue1634" -+other_name_utf8 = "1.2.3.4 testvalue1635" -+other_name_utf8 = "1.2.3.4 testvalue1636" -+other_name_utf8 = "1.2.3.4 testvalue1637" -+other_name_utf8 = "1.2.3.4 testvalue1638" -+other_name_utf8 = "1.2.3.4 testvalue1639" -+other_name_utf8 = "1.2.3.4 testvalue1640" -+other_name_utf8 = "1.2.3.4 testvalue1641" -+other_name_utf8 = "1.2.3.4 testvalue1642" -+other_name_utf8 = "1.2.3.4 testvalue1643" -+other_name_utf8 = "1.2.3.4 testvalue1644" -+other_name_utf8 = "1.2.3.4 testvalue1645" -+other_name_utf8 = "1.2.3.4 testvalue1646" -+other_name_utf8 = "1.2.3.4 testvalue1647" -+other_name_utf8 = "1.2.3.4 testvalue1648" -+other_name_utf8 = "1.2.3.4 testvalue1649" -+other_name_utf8 = "1.2.3.4 testvalue1650" -+other_name_utf8 = "1.2.3.4 testvalue1651" -+other_name_utf8 = "1.2.3.4 testvalue1652" -+other_name_utf8 = "1.2.3.4 testvalue1653" -+other_name_utf8 = "1.2.3.4 testvalue1654" -+other_name_utf8 = "1.2.3.4 testvalue1655" -+other_name_utf8 = "1.2.3.4 testvalue1656" -+other_name_utf8 = "1.2.3.4 testvalue1657" -+other_name_utf8 = "1.2.3.4 testvalue1658" -+other_name_utf8 = "1.2.3.4 testvalue1659" -+other_name_utf8 = "1.2.3.4 testvalue1660" -+other_name_utf8 = "1.2.3.4 testvalue1661" -+other_name_utf8 = "1.2.3.4 testvalue1662" -+other_name_utf8 = "1.2.3.4 testvalue1663" -+other_name_utf8 = "1.2.3.4 testvalue1664" -+other_name_utf8 = "1.2.3.4 testvalue1665" -+other_name_utf8 = "1.2.3.4 testvalue1666" -+other_name_utf8 = "1.2.3.4 testvalue1667" -+other_name_utf8 = "1.2.3.4 testvalue1668" -+other_name_utf8 = "1.2.3.4 testvalue1669" -+other_name_utf8 = "1.2.3.4 testvalue1670" -+other_name_utf8 = "1.2.3.4 testvalue1671" -+other_name_utf8 = "1.2.3.4 testvalue1672" -+other_name_utf8 = "1.2.3.4 testvalue1673" -+other_name_utf8 = "1.2.3.4 testvalue1674" -+other_name_utf8 = "1.2.3.4 testvalue1675" -+other_name_utf8 = "1.2.3.4 testvalue1676" -+other_name_utf8 = "1.2.3.4 testvalue1677" -+other_name_utf8 = "1.2.3.4 testvalue1678" -+other_name_utf8 = "1.2.3.4 testvalue1679" -+other_name_utf8 = "1.2.3.4 testvalue1680" -+other_name_utf8 = "1.2.3.4 testvalue1681" -+other_name_utf8 = "1.2.3.4 testvalue1682" -+other_name_utf8 = "1.2.3.4 testvalue1683" -+other_name_utf8 = "1.2.3.4 testvalue1684" -+other_name_utf8 = "1.2.3.4 testvalue1685" -+other_name_utf8 = "1.2.3.4 testvalue1686" -+other_name_utf8 = "1.2.3.4 testvalue1687" -+other_name_utf8 = "1.2.3.4 testvalue1688" -+other_name_utf8 = "1.2.3.4 testvalue1689" -+other_name_utf8 = "1.2.3.4 testvalue1690" -+other_name_utf8 = "1.2.3.4 testvalue1691" -+other_name_utf8 = "1.2.3.4 testvalue1692" -+other_name_utf8 = "1.2.3.4 testvalue1693" -+other_name_utf8 = "1.2.3.4 testvalue1694" -+other_name_utf8 = "1.2.3.4 testvalue1695" -+other_name_utf8 = "1.2.3.4 testvalue1696" -+other_name_utf8 = "1.2.3.4 testvalue1697" -+other_name_utf8 = "1.2.3.4 testvalue1698" -+other_name_utf8 = "1.2.3.4 testvalue1699" -+other_name_utf8 = "1.2.3.4 testvalue1700" -+other_name_utf8 = "1.2.3.4 testvalue1701" -+other_name_utf8 = "1.2.3.4 testvalue1702" -+other_name_utf8 = "1.2.3.4 testvalue1703" -+other_name_utf8 = "1.2.3.4 testvalue1704" -+other_name_utf8 = "1.2.3.4 testvalue1705" -+other_name_utf8 = "1.2.3.4 testvalue1706" -+other_name_utf8 = "1.2.3.4 testvalue1707" -+other_name_utf8 = "1.2.3.4 testvalue1708" -+other_name_utf8 = "1.2.3.4 testvalue1709" -+other_name_utf8 = "1.2.3.4 testvalue1710" -+other_name_utf8 = "1.2.3.4 testvalue1711" -+other_name_utf8 = "1.2.3.4 testvalue1712" -+other_name_utf8 = "1.2.3.4 testvalue1713" -+other_name_utf8 = "1.2.3.4 testvalue1714" -+other_name_utf8 = "1.2.3.4 testvalue1715" -+other_name_utf8 = "1.2.3.4 testvalue1716" -+other_name_utf8 = "1.2.3.4 testvalue1717" -+other_name_utf8 = "1.2.3.4 testvalue1718" -+other_name_utf8 = "1.2.3.4 testvalue1719" -+other_name_utf8 = "1.2.3.4 testvalue1720" -+other_name_utf8 = "1.2.3.4 testvalue1721" -+other_name_utf8 = "1.2.3.4 testvalue1722" -+other_name_utf8 = "1.2.3.4 testvalue1723" -+other_name_utf8 = "1.2.3.4 testvalue1724" -+other_name_utf8 = "1.2.3.4 testvalue1725" -+other_name_utf8 = "1.2.3.4 testvalue1726" -+other_name_utf8 = "1.2.3.4 testvalue1727" -+other_name_utf8 = "1.2.3.4 testvalue1728" -+other_name_utf8 = "1.2.3.4 testvalue1729" -+other_name_utf8 = "1.2.3.4 testvalue1730" -+other_name_utf8 = "1.2.3.4 testvalue1731" -+other_name_utf8 = "1.2.3.4 testvalue1732" -+other_name_utf8 = "1.2.3.4 testvalue1733" -+other_name_utf8 = "1.2.3.4 testvalue1734" -+other_name_utf8 = "1.2.3.4 testvalue1735" -+other_name_utf8 = "1.2.3.4 testvalue1736" -+other_name_utf8 = "1.2.3.4 testvalue1737" -+other_name_utf8 = "1.2.3.4 testvalue1738" -+other_name_utf8 = "1.2.3.4 testvalue1739" -+other_name_utf8 = "1.2.3.4 testvalue1740" -+other_name_utf8 = "1.2.3.4 testvalue1741" -+other_name_utf8 = "1.2.3.4 testvalue1742" -+other_name_utf8 = "1.2.3.4 testvalue1743" -+other_name_utf8 = "1.2.3.4 testvalue1744" -+other_name_utf8 = "1.2.3.4 testvalue1745" -+other_name_utf8 = "1.2.3.4 testvalue1746" -+other_name_utf8 = "1.2.3.4 testvalue1747" -+other_name_utf8 = "1.2.3.4 testvalue1748" -+other_name_utf8 = "1.2.3.4 testvalue1749" -+other_name_utf8 = "1.2.3.4 testvalue1750" -+other_name_utf8 = "1.2.3.4 testvalue1751" -+other_name_utf8 = "1.2.3.4 testvalue1752" -+other_name_utf8 = "1.2.3.4 testvalue1753" -+other_name_utf8 = "1.2.3.4 testvalue1754" -+other_name_utf8 = "1.2.3.4 testvalue1755" -+other_name_utf8 = "1.2.3.4 testvalue1756" -+other_name_utf8 = "1.2.3.4 testvalue1757" -+other_name_utf8 = "1.2.3.4 testvalue1758" -+other_name_utf8 = "1.2.3.4 testvalue1759" -+other_name_utf8 = "1.2.3.4 testvalue1760" -+other_name_utf8 = "1.2.3.4 testvalue1761" -+other_name_utf8 = "1.2.3.4 testvalue1762" -+other_name_utf8 = "1.2.3.4 testvalue1763" -+other_name_utf8 = "1.2.3.4 testvalue1764" -+other_name_utf8 = "1.2.3.4 testvalue1765" -+other_name_utf8 = "1.2.3.4 testvalue1766" -+other_name_utf8 = "1.2.3.4 testvalue1767" -+other_name_utf8 = "1.2.3.4 testvalue1768" -+other_name_utf8 = "1.2.3.4 testvalue1769" -+other_name_utf8 = "1.2.3.4 testvalue1770" -+other_name_utf8 = "1.2.3.4 testvalue1771" -+other_name_utf8 = "1.2.3.4 testvalue1772" -+other_name_utf8 = "1.2.3.4 testvalue1773" -+other_name_utf8 = "1.2.3.4 testvalue1774" -+other_name_utf8 = "1.2.3.4 testvalue1775" -+other_name_utf8 = "1.2.3.4 testvalue1776" -+other_name_utf8 = "1.2.3.4 testvalue1777" -+other_name_utf8 = "1.2.3.4 testvalue1778" -+other_name_utf8 = "1.2.3.4 testvalue1779" -+other_name_utf8 = "1.2.3.4 testvalue1780" -+other_name_utf8 = "1.2.3.4 testvalue1781" -+other_name_utf8 = "1.2.3.4 testvalue1782" -+other_name_utf8 = "1.2.3.4 testvalue1783" -+other_name_utf8 = "1.2.3.4 testvalue1784" -+other_name_utf8 = "1.2.3.4 testvalue1785" -+other_name_utf8 = "1.2.3.4 testvalue1786" -+other_name_utf8 = "1.2.3.4 testvalue1787" -+other_name_utf8 = "1.2.3.4 testvalue1788" -+other_name_utf8 = "1.2.3.4 testvalue1789" -+other_name_utf8 = "1.2.3.4 testvalue1790" -+other_name_utf8 = "1.2.3.4 testvalue1791" -+other_name_utf8 = "1.2.3.4 testvalue1792" -+other_name_utf8 = "1.2.3.4 testvalue1793" -+other_name_utf8 = "1.2.3.4 testvalue1794" -+other_name_utf8 = "1.2.3.4 testvalue1795" -+other_name_utf8 = "1.2.3.4 testvalue1796" -+other_name_utf8 = "1.2.3.4 testvalue1797" -+other_name_utf8 = "1.2.3.4 testvalue1798" -+other_name_utf8 = "1.2.3.4 testvalue1799" -+other_name_utf8 = "1.2.3.4 testvalue1800" -+other_name_utf8 = "1.2.3.4 testvalue1801" -+other_name_utf8 = "1.2.3.4 testvalue1802" -+other_name_utf8 = "1.2.3.4 testvalue1803" -+other_name_utf8 = "1.2.3.4 testvalue1804" -+other_name_utf8 = "1.2.3.4 testvalue1805" -+other_name_utf8 = "1.2.3.4 testvalue1806" -+other_name_utf8 = "1.2.3.4 testvalue1807" -+other_name_utf8 = "1.2.3.4 testvalue1808" -+other_name_utf8 = "1.2.3.4 testvalue1809" -+other_name_utf8 = "1.2.3.4 testvalue1810" -+other_name_utf8 = "1.2.3.4 testvalue1811" -+other_name_utf8 = "1.2.3.4 testvalue1812" -+other_name_utf8 = "1.2.3.4 testvalue1813" -+other_name_utf8 = "1.2.3.4 testvalue1814" -+other_name_utf8 = "1.2.3.4 testvalue1815" -+other_name_utf8 = "1.2.3.4 testvalue1816" -+other_name_utf8 = "1.2.3.4 testvalue1817" -+other_name_utf8 = "1.2.3.4 testvalue1818" -+other_name_utf8 = "1.2.3.4 testvalue1819" -+other_name_utf8 = "1.2.3.4 testvalue1820" -+other_name_utf8 = "1.2.3.4 testvalue1821" -+other_name_utf8 = "1.2.3.4 testvalue1822" -+other_name_utf8 = "1.2.3.4 testvalue1823" -+other_name_utf8 = "1.2.3.4 testvalue1824" -+other_name_utf8 = "1.2.3.4 testvalue1825" -+other_name_utf8 = "1.2.3.4 testvalue1826" -+other_name_utf8 = "1.2.3.4 testvalue1827" -+other_name_utf8 = "1.2.3.4 testvalue1828" -+other_name_utf8 = "1.2.3.4 testvalue1829" -+other_name_utf8 = "1.2.3.4 testvalue1830" -+other_name_utf8 = "1.2.3.4 testvalue1831" -+other_name_utf8 = "1.2.3.4 testvalue1832" -+other_name_utf8 = "1.2.3.4 testvalue1833" -+other_name_utf8 = "1.2.3.4 testvalue1834" -+other_name_utf8 = "1.2.3.4 testvalue1835" -+other_name_utf8 = "1.2.3.4 testvalue1836" -+other_name_utf8 = "1.2.3.4 testvalue1837" -+other_name_utf8 = "1.2.3.4 testvalue1838" -+other_name_utf8 = "1.2.3.4 testvalue1839" -+other_name_utf8 = "1.2.3.4 testvalue1840" -+other_name_utf8 = "1.2.3.4 testvalue1841" -+other_name_utf8 = "1.2.3.4 testvalue1842" -+other_name_utf8 = "1.2.3.4 testvalue1843" -+other_name_utf8 = "1.2.3.4 testvalue1844" -+other_name_utf8 = "1.2.3.4 testvalue1845" -+other_name_utf8 = "1.2.3.4 testvalue1846" -+other_name_utf8 = "1.2.3.4 testvalue1847" -+other_name_utf8 = "1.2.3.4 testvalue1848" -+other_name_utf8 = "1.2.3.4 testvalue1849" -+other_name_utf8 = "1.2.3.4 testvalue1850" -+other_name_utf8 = "1.2.3.4 testvalue1851" -+other_name_utf8 = "1.2.3.4 testvalue1852" -+other_name_utf8 = "1.2.3.4 testvalue1853" -+other_name_utf8 = "1.2.3.4 testvalue1854" -+other_name_utf8 = "1.2.3.4 testvalue1855" -+other_name_utf8 = "1.2.3.4 testvalue1856" -+other_name_utf8 = "1.2.3.4 testvalue1857" -+other_name_utf8 = "1.2.3.4 testvalue1858" -+other_name_utf8 = "1.2.3.4 testvalue1859" -+other_name_utf8 = "1.2.3.4 testvalue1860" -+other_name_utf8 = "1.2.3.4 testvalue1861" -+other_name_utf8 = "1.2.3.4 testvalue1862" -+other_name_utf8 = "1.2.3.4 testvalue1863" -+other_name_utf8 = "1.2.3.4 testvalue1864" -+other_name_utf8 = "1.2.3.4 testvalue1865" -+other_name_utf8 = "1.2.3.4 testvalue1866" -+other_name_utf8 = "1.2.3.4 testvalue1867" -+other_name_utf8 = "1.2.3.4 testvalue1868" -+other_name_utf8 = "1.2.3.4 testvalue1869" -+other_name_utf8 = "1.2.3.4 testvalue1870" -+other_name_utf8 = "1.2.3.4 testvalue1871" -+other_name_utf8 = "1.2.3.4 testvalue1872" -+other_name_utf8 = "1.2.3.4 testvalue1873" -+other_name_utf8 = "1.2.3.4 testvalue1874" -+other_name_utf8 = "1.2.3.4 testvalue1875" -+other_name_utf8 = "1.2.3.4 testvalue1876" -+other_name_utf8 = "1.2.3.4 testvalue1877" -+other_name_utf8 = "1.2.3.4 testvalue1878" -+other_name_utf8 = "1.2.3.4 testvalue1879" -+other_name_utf8 = "1.2.3.4 testvalue1880" -+other_name_utf8 = "1.2.3.4 testvalue1881" -+other_name_utf8 = "1.2.3.4 testvalue1882" -+other_name_utf8 = "1.2.3.4 testvalue1883" -+other_name_utf8 = "1.2.3.4 testvalue1884" -+other_name_utf8 = "1.2.3.4 testvalue1885" -+other_name_utf8 = "1.2.3.4 testvalue1886" -+other_name_utf8 = "1.2.3.4 testvalue1887" -+other_name_utf8 = "1.2.3.4 testvalue1888" -+other_name_utf8 = "1.2.3.4 testvalue1889" -+other_name_utf8 = "1.2.3.4 testvalue1890" -+other_name_utf8 = "1.2.3.4 testvalue1891" -+other_name_utf8 = "1.2.3.4 testvalue1892" -+other_name_utf8 = "1.2.3.4 testvalue1893" -+other_name_utf8 = "1.2.3.4 testvalue1894" -+other_name_utf8 = "1.2.3.4 testvalue1895" -+other_name_utf8 = "1.2.3.4 testvalue1896" -+other_name_utf8 = "1.2.3.4 testvalue1897" -+other_name_utf8 = "1.2.3.4 testvalue1898" -+other_name_utf8 = "1.2.3.4 testvalue1899" -+other_name_utf8 = "1.2.3.4 testvalue1900" -+other_name_utf8 = "1.2.3.4 testvalue1901" -+other_name_utf8 = "1.2.3.4 testvalue1902" -+other_name_utf8 = "1.2.3.4 testvalue1903" -+other_name_utf8 = "1.2.3.4 testvalue1904" -+other_name_utf8 = "1.2.3.4 testvalue1905" -+other_name_utf8 = "1.2.3.4 testvalue1906" -+other_name_utf8 = "1.2.3.4 testvalue1907" -+other_name_utf8 = "1.2.3.4 testvalue1908" -+other_name_utf8 = "1.2.3.4 testvalue1909" -+other_name_utf8 = "1.2.3.4 testvalue1910" -+other_name_utf8 = "1.2.3.4 testvalue1911" -+other_name_utf8 = "1.2.3.4 testvalue1912" -+other_name_utf8 = "1.2.3.4 testvalue1913" -+other_name_utf8 = "1.2.3.4 testvalue1914" -+other_name_utf8 = "1.2.3.4 testvalue1915" -+other_name_utf8 = "1.2.3.4 testvalue1916" -+other_name_utf8 = "1.2.3.4 testvalue1917" -+other_name_utf8 = "1.2.3.4 testvalue1918" -+other_name_utf8 = "1.2.3.4 testvalue1919" -+other_name_utf8 = "1.2.3.4 testvalue1920" -+other_name_utf8 = "1.2.3.4 testvalue1921" -+other_name_utf8 = "1.2.3.4 testvalue1922" -+other_name_utf8 = "1.2.3.4 testvalue1923" -+other_name_utf8 = "1.2.3.4 testvalue1924" -+other_name_utf8 = "1.2.3.4 testvalue1925" -+other_name_utf8 = "1.2.3.4 testvalue1926" -+other_name_utf8 = "1.2.3.4 testvalue1927" -+other_name_utf8 = "1.2.3.4 testvalue1928" -+other_name_utf8 = "1.2.3.4 testvalue1929" -+other_name_utf8 = "1.2.3.4 testvalue1930" -+other_name_utf8 = "1.2.3.4 testvalue1931" -+other_name_utf8 = "1.2.3.4 testvalue1932" -+other_name_utf8 = "1.2.3.4 testvalue1933" -+other_name_utf8 = "1.2.3.4 testvalue1934" -+other_name_utf8 = "1.2.3.4 testvalue1935" -+other_name_utf8 = "1.2.3.4 testvalue1936" -+other_name_utf8 = "1.2.3.4 testvalue1937" -+other_name_utf8 = "1.2.3.4 testvalue1938" -+other_name_utf8 = "1.2.3.4 testvalue1939" -+other_name_utf8 = "1.2.3.4 testvalue1940" -+other_name_utf8 = "1.2.3.4 testvalue1941" -+other_name_utf8 = "1.2.3.4 testvalue1942" -+other_name_utf8 = "1.2.3.4 testvalue1943" -+other_name_utf8 = "1.2.3.4 testvalue1944" -+other_name_utf8 = "1.2.3.4 testvalue1945" -+other_name_utf8 = "1.2.3.4 testvalue1946" -+other_name_utf8 = "1.2.3.4 testvalue1947" -+other_name_utf8 = "1.2.3.4 testvalue1948" -+other_name_utf8 = "1.2.3.4 testvalue1949" -+other_name_utf8 = "1.2.3.4 testvalue1950" -+other_name_utf8 = "1.2.3.4 testvalue1951" -+other_name_utf8 = "1.2.3.4 testvalue1952" -+other_name_utf8 = "1.2.3.4 testvalue1953" -+other_name_utf8 = "1.2.3.4 testvalue1954" -+other_name_utf8 = "1.2.3.4 testvalue1955" -+other_name_utf8 = "1.2.3.4 testvalue1956" -+other_name_utf8 = "1.2.3.4 testvalue1957" -+other_name_utf8 = "1.2.3.4 testvalue1958" -+other_name_utf8 = "1.2.3.4 testvalue1959" -+other_name_utf8 = "1.2.3.4 testvalue1960" -+other_name_utf8 = "1.2.3.4 testvalue1961" -+other_name_utf8 = "1.2.3.4 testvalue1962" -+other_name_utf8 = "1.2.3.4 testvalue1963" -+other_name_utf8 = "1.2.3.4 testvalue1964" -+other_name_utf8 = "1.2.3.4 testvalue1965" -+other_name_utf8 = "1.2.3.4 testvalue1966" -+other_name_utf8 = "1.2.3.4 testvalue1967" -+other_name_utf8 = "1.2.3.4 testvalue1968" -+other_name_utf8 = "1.2.3.4 testvalue1969" -+other_name_utf8 = "1.2.3.4 testvalue1970" -+other_name_utf8 = "1.2.3.4 testvalue1971" -+other_name_utf8 = "1.2.3.4 testvalue1972" -+other_name_utf8 = "1.2.3.4 testvalue1973" -+other_name_utf8 = "1.2.3.4 testvalue1974" -+other_name_utf8 = "1.2.3.4 testvalue1975" -+other_name_utf8 = "1.2.3.4 testvalue1976" -+other_name_utf8 = "1.2.3.4 testvalue1977" -+other_name_utf8 = "1.2.3.4 testvalue1978" -+other_name_utf8 = "1.2.3.4 testvalue1979" -+other_name_utf8 = "1.2.3.4 testvalue1980" -+other_name_utf8 = "1.2.3.4 testvalue1981" -+other_name_utf8 = "1.2.3.4 testvalue1982" -+other_name_utf8 = "1.2.3.4 testvalue1983" -+other_name_utf8 = "1.2.3.4 testvalue1984" -+other_name_utf8 = "1.2.3.4 testvalue1985" -+other_name_utf8 = "1.2.3.4 testvalue1986" -+other_name_utf8 = "1.2.3.4 testvalue1987" -+other_name_utf8 = "1.2.3.4 testvalue1988" -+other_name_utf8 = "1.2.3.4 testvalue1989" -+other_name_utf8 = "1.2.3.4 testvalue1990" -+other_name_utf8 = "1.2.3.4 testvalue1991" -+other_name_utf8 = "1.2.3.4 testvalue1992" -+other_name_utf8 = "1.2.3.4 testvalue1993" -+other_name_utf8 = "1.2.3.4 testvalue1994" -+other_name_utf8 = "1.2.3.4 testvalue1995" -+other_name_utf8 = "1.2.3.4 testvalue1996" -+other_name_utf8 = "1.2.3.4 testvalue1997" -+other_name_utf8 = "1.2.3.4 testvalue1998" -+other_name_utf8 = "1.2.3.4 testvalue1999" --- -2.50.0 - diff --git a/SOURCES/gnutls-3.8.3-cve-2025-6395.patch b/SOURCES/gnutls-3.8.3-cve-2025-6395.patch deleted file mode 100644 index c376850..0000000 --- a/SOURCES/gnutls-3.8.3-cve-2025-6395.patch +++ /dev/null @@ -1,282 +0,0 @@ -From 853a64f5e92bedd2ebf97baadba39f2d2bfa95ef Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 7 Jul 2025 11:15:45 +0900 -Subject: [PATCH] handshake: clear HSK_PSK_SELECTED is when resetting binders -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When a TLS 1.3 handshake involves HRR and resumption or PSK, and the -second Client Hello omits PSK, the server would result in a NULL -pointer dereference as the PSK binder information is cleared while the -HSK_PSK_SELECTED flag is still set. This makes sure that -HSK_PSK_SELECTED flag is always cleared when the PSK binders are -reset. This also makes it clear the HSK_PSK_SELECTED flag is valid -only during a handshake; after that, whether PSK is used can be -checked with gnutls_auth_client_get_type. - -Reported by Stefan Bühler. - -Signed-off-by: Daiki Ueno ---- - .gitignore | 1 + - lib/handshake.c | 25 +++- - lib/state.c | 4 +- - tests/Makefile.am | 2 + - tests/tls13/hello_retry_request_psk.c | 173 ++++++++++++++++++++++++++ - 5 files changed, 201 insertions(+), 4 deletions(-) - create mode 100644 tests/tls13/hello_retry_request_psk.c - -diff --git a/lib/handshake.c b/lib/handshake.c -index 722307be7c..489d021945 100644 ---- a/lib/handshake.c -+++ b/lib/handshake.c -@@ -589,9 +589,28 @@ static int set_auth_types(gnutls_session_t session) - /* Under TLS1.3 this returns a KX which matches the negotiated - * groups from the key shares; if we are resuming then the KX seen - * here doesn't match the original session. */ -- if (!session->internals.resumed) -- kx = gnutls_kx_get(session); -- else -+ if (!session->internals.resumed) { -+ const gnutls_group_entry_st *group = get_group(session); -+ -+ if (session->internals.hsk_flags & HSK_PSK_SELECTED) { -+ if (group) { -+ kx = group->pk == GNUTLS_PK_DH ? -+ GNUTLS_KX_DHE_PSK : -+ GNUTLS_KX_ECDHE_PSK; -+ } else { -+ kx = GNUTLS_KX_PSK; -+ } -+ } else if (group) { -+ /* Not necessarily be RSA, but just to -+ * make _gnutls_map_kx_get_cred below -+ * work. -+ */ -+ kx = group->pk == GNUTLS_PK_DH ? -+ GNUTLS_KX_DHE_RSA : -+ GNUTLS_KX_ECDHE_RSA; -+ } else -+ kx = GNUTLS_KX_UNKNOWN; -+ } else - kx = GNUTLS_KX_UNKNOWN; - } else { - /* TLS1.2 or earlier, kx is associated with ciphersuite */ -diff --git a/lib/state.c b/lib/state.c -index ec514c0cd2..10ec0eadb6 100644 ---- a/lib/state.c -+++ b/lib/state.c -@@ -202,7 +202,8 @@ gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session) - const gnutls_group_entry_st *group = get_group(session); - - if (ver->tls13_sem) { -- if (session->internals.hsk_flags & HSK_PSK_SELECTED) { -+ if (gnutls_auth_client_get_type(session) == -+ GNUTLS_CRD_PSK) { - if (group) { - if (group->pk == GNUTLS_PK_DH) - return GNUTLS_KX_DHE_PSK; -@@ -349,6 +350,7 @@ void reset_binders(gnutls_session_t session) - _gnutls_free_temp_key_datum(&session->key.binders[0].psk); - _gnutls_free_temp_key_datum(&session->key.binders[1].psk); - memset(session->key.binders, 0, sizeof(session->key.binders)); -+ session->internals.hsk_flags &= ~HSK_PSK_SELECTED; - } - - /* Check whether certificate credentials of type @cert_type are set -diff --git a/tests/Makefile.am b/tests/Makefile.am -index babf3be108..f6a16552d1 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -128,6 +128,8 @@ ctests += tls13/hello_retry_request - - ctests += tls13/hello_retry_request_resume - -+ctests += tls13/hello_retry_request_psk -+ - ctests += tls13/psk-ext - - ctests += tls13/key_update -diff --git a/tests/tls13/hello_retry_request_psk.c b/tests/tls13/hello_retry_request_psk.c -new file mode 100644 -index 0000000000..a20cb0d965 ---- /dev/null -+++ b/tests/tls13/hello_retry_request_psk.c -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2017-2025 Red Hat, Inc. -+ * -+ * Author: Nikos Mavrogiannopoulos, Daiki Ueno -+ * -+ * This file is part of GnuTLS. -+ * -+ * GnuTLS is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GnuTLS is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program. If not, see -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include "config.h" -+#endif -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "cert-common.h" -+#include "utils.h" -+#include "tls13/ext-parse.h" -+#include "eagain-common.h" -+ -+/* This program exercises the case where a TLS 1.3 handshake ends up -+ * with HRR, and the first CH includes PSK while the 2nd CH omits -+ * it */ -+ -+const char *testname = "hello entry request"; -+ -+const char *side = ""; -+ -+#define myfail(fmt, ...) fail("%s: " fmt, testname, ##__VA_ARGS__) -+ -+static void tls_log_func(int level, const char *str) -+{ -+ fprintf(stderr, "%s|<%d>| %s", side, level, str); -+} -+ -+struct ctx_st { -+ unsigned hrr_seen; -+ unsigned hello_counter; -+}; -+ -+static int pskfunc(gnutls_session_t session, const char *username, -+ gnutls_datum_t *key) -+{ -+ if (debug) -+ printf("psk: username %s\n", username); -+ key->data = gnutls_malloc(4); -+ key->data[0] = 0xDE; -+ key->data[1] = 0xAD; -+ key->data[2] = 0xBE; -+ key->data[3] = 0xEF; -+ key->size = 4; -+ return 0; -+} -+ -+static int hello_callback(gnutls_session_t session, unsigned int htype, -+ unsigned post, unsigned int incoming, -+ const gnutls_datum_t *msg) -+{ -+ struct ctx_st *ctx = gnutls_session_get_ptr(session); -+ assert(ctx != NULL); -+ -+ if (htype == GNUTLS_HANDSHAKE_HELLO_RETRY_REQUEST) -+ ctx->hrr_seen = 1; -+ -+ if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO) { -+ if (post == GNUTLS_HOOK_POST) -+ ctx->hello_counter++; -+ else { -+ /* Unset the PSK credential to omit the extension */ -+ gnutls_credentials_set(session, GNUTLS_CRD_PSK, NULL); -+ } -+ } -+ -+ return 0; -+} -+ -+void doit(void) -+{ -+ int sret, cret; -+ gnutls_psk_server_credentials_t scred; -+ gnutls_psk_client_credentials_t ccred; -+ gnutls_certificate_credentials_t ccred2; -+ gnutls_session_t server, client; -+ /* Need to enable anonymous KX specifically. */ -+ const gnutls_datum_t key = { (void *)"DEADBEEF", 8 }; -+ -+ struct ctx_st ctx; -+ memset(&ctx, 0, sizeof(ctx)); -+ -+ global_init(); -+ -+ gnutls_global_set_log_function(tls_log_func); -+ if (debug) -+ gnutls_global_set_log_level(9); -+ -+ /* Init server */ -+ assert(gnutls_psk_allocate_server_credentials(&scred) >= 0); -+ gnutls_psk_set_server_credentials_function(scred, pskfunc); -+ -+ gnutls_init(&server, GNUTLS_SERVER); -+ -+ assert(gnutls_priority_set_direct( -+ server, -+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+DHE-PSK", -+ NULL) >= 0); -+ -+ gnutls_credentials_set(server, GNUTLS_CRD_PSK, scred); -+ gnutls_transport_set_push_function(server, server_push); -+ gnutls_transport_set_pull_function(server, server_pull); -+ gnutls_transport_set_ptr(server, server); -+ -+ /* Init client */ -+ assert(gnutls_psk_allocate_client_credentials(&ccred) >= 0); -+ gnutls_psk_set_client_credentials(ccred, "test", &key, -+ GNUTLS_PSK_KEY_HEX); -+ assert(gnutls_certificate_allocate_credentials(&ccred2) >= 0); -+ -+ assert(gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_KEY_SHARE_TOP) >= 0); -+ -+ gnutls_session_set_ptr(client, &ctx); -+ -+ cret = gnutls_priority_set_direct( -+ client, -+ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519:+DHE-PSK", -+ NULL); -+ if (cret < 0) -+ myfail("cannot set TLS 1.3 priorities\n"); -+ -+ gnutls_credentials_set(client, GNUTLS_CRD_PSK, ccred); -+ gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, ccred2); -+ gnutls_transport_set_push_function(client, client_push); -+ gnutls_transport_set_pull_function(client, client_pull); -+ gnutls_transport_set_ptr(client, client); -+ -+ gnutls_handshake_set_hook_function(client, GNUTLS_HANDSHAKE_ANY, -+ GNUTLS_HOOK_BOTH, hello_callback); -+ -+ HANDSHAKE_EXPECT(client, server, GNUTLS_E_AGAIN, -+ GNUTLS_E_INSUFFICIENT_CREDENTIALS); -+ -+ assert(ctx.hrr_seen != 0); -+ -+ gnutls_bye(client, GNUTLS_SHUT_WR); -+ gnutls_bye(server, GNUTLS_SHUT_WR); -+ -+ gnutls_deinit(client); -+ gnutls_deinit(server); -+ -+ gnutls_psk_free_server_credentials(scred); -+ gnutls_psk_free_client_credentials(ccred); -+ gnutls_certificate_free_credentials(ccred2); -+ -+ gnutls_global_deinit(); -+ reset_buffers(); -+} --- -2.50.0 - diff --git a/SOURCES/gnutls-3.8.3-deterministic-ecdsa-fixes.patch b/SOURCES/gnutls-3.8.3-deterministic-ecdsa-fixes.patch deleted file mode 100644 index 635cad8..0000000 --- a/SOURCES/gnutls-3.8.3-deterministic-ecdsa-fixes.patch +++ /dev/null @@ -1,418 +0,0 @@ -From 1c4701ffc342259fc5965d5a0de90d87f780e3e5 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Fri, 12 Jan 2024 17:56:58 +0900 -Subject: [PATCH] nettle: avoid normalization of mpz_t in deterministic ECDSA - -This removes function calls that potentially leak bit-length of a -private key used to calculate a nonce in deterministic ECDSA. Namely: - -- _gnutls_dsa_compute_k has been rewritten to work on always - zero-padded mp_limb_t arrays instead of mpz_t -- rnd_mpz_func has been replaced with rnd_datum_func, which is backed - by a byte array instead of an mpz_t value - -Signed-off-by: Daiki Ueno ---- - lib/nettle/int/dsa-compute-k.c | 70 +++++++++++++++++++++---------- - lib/nettle/int/dsa-compute-k.h | 23 +++++++++- - lib/nettle/int/ecdsa-compute-k.c | 28 +++---------- - lib/nettle/int/ecdsa-compute-k.h | 4 +- - lib/nettle/pk.c | 65 +++++++++++++++++++++------- - tests/sign-verify-deterministic.c | 2 +- - 6 files changed, 127 insertions(+), 65 deletions(-) - -diff --git a/lib/nettle/int/dsa-compute-k.c b/lib/nettle/int/dsa-compute-k.c -index 8ff5739c2b..2fcb2bb80e 100644 ---- a/lib/nettle/int/dsa-compute-k.c -+++ b/lib/nettle/int/dsa-compute-k.c -@@ -31,19 +31,30 @@ - #include "mpn-base256.h" - #include - --#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) -+/* For mini-gmp */ -+#ifndef GMP_LIMB_BITS -+#define GMP_LIMB_BITS GMP_NUMB_BITS -+#endif - --/* The maximum size of q, chosen from the fact that we support -- * 521-bit elliptic curve generator and 512-bit DSA subgroup at -- * maximum. */ --#define MAX_Q_BITS 521 --#define MAX_Q_SIZE ((MAX_Q_BITS + 7) / 8) --#define MAX_Q_LIMBS BITS_TO_LIMBS(MAX_Q_BITS) -+static inline int is_zero_limb(mp_limb_t x) -+{ -+ x |= (x << 1); -+ return ((x >> 1) - 1) >> (GMP_LIMB_BITS - 1); -+} -+ -+static int sec_zero_p(const mp_limb_t *ap, mp_size_t n) -+{ -+ volatile mp_limb_t w; -+ mp_size_t i; - --#define MAX_HASH_BITS (MAX_HASH_SIZE * 8) --#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS) -+ for (i = 0, w = 0; i < n; i++) -+ w |= ap[i]; - --int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, -+ return is_zero_limb(w); -+} -+ -+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x, -+ mp_size_t qn, mp_bitcnt_t q_bits, - gnutls_mac_algorithm_t mac, const uint8_t *digest, - size_t length) - { -@@ -51,9 +62,6 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, - uint8_t K[MAX_HASH_SIZE]; - uint8_t xp[MAX_Q_SIZE]; - uint8_t tp[MAX_Q_SIZE]; -- mp_limb_t h[MAX(MAX_Q_LIMBS, MAX_HASH_LIMBS)]; -- mp_bitcnt_t q_bits = mpz_sizeinbase(q, 2); -- mp_size_t qn = mpz_size(q); - mp_bitcnt_t h_bits = length * 8; - mp_size_t hn = BITS_TO_LIMBS(h_bits); - size_t nbytes = (q_bits + 7) / 8; -@@ -62,6 +70,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, - mp_limb_t cy; - gnutls_hmac_hd_t hd; - int ret = 0; -+ mp_limb_t scratch[MAX_Q_LIMBS]; - - if (unlikely(q_bits > MAX_Q_BITS)) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -@@ -69,7 +78,7 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - /* int2octets(x) */ -- mpn_get_base256(xp, nbytes, mpz_limbs_read(x), qn); -+ mpn_get_base256(xp, nbytes, x, qn); - - /* bits2octets(h) */ - mpn_set_base256(h, hn, digest, length); -@@ -93,12 +102,12 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, - mpn_rshift(h, h, hn, shift % GMP_NUMB_BITS); - } - -- cy = mpn_sub_n(h, h, mpz_limbs_read(q), qn); -+ cy = mpn_sub_n(h, h, q, qn); - /* Fall back to addmul_1, if nettle is linked with mini-gmp. */ - #ifdef mpn_cnd_add_n -- mpn_cnd_add_n(cy, h, h, mpz_limbs_read(q), qn); -+ mpn_cnd_add_n(cy, h, h, q, qn); - #else -- mpn_addmul_1(h, mpz_limbs_read(q), qn, cy != 0); -+ mpn_addmul_1(h, q, qn, cy != 0); - #endif - mpn_get_base256(tp, nbytes, h, qn); - -@@ -174,12 +183,8 @@ int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, - if (tlen * 8 > q_bits) - mpn_rshift(h, h, qn, tlen * 8 - q_bits); - /* Check if k is in [1,q-1] */ -- if (!mpn_zero_p(h, qn) && -- mpn_cmp(h, mpz_limbs_read(q), qn) < 0) { -- mpn_copyi(mpz_limbs_write(k, qn), h, qn); -- mpz_limbs_finish(k, qn); -+ if (!sec_zero_p(h, qn) && mpn_sub_n(scratch, h, q, qn)) - break; -- } - - ret = gnutls_hmac_init(&hd, mac, K, length); - if (ret < 0) -@@ -203,3 +208,24 @@ out: - - return ret; - } -+ -+/* cancel-out dsa_sign's addition of 1 to random data */ -+void _gnutls_dsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h, -+ mp_size_t n) -+{ -+ /* Fall back to sub_1, if nettle is linked with mini-gmp. */ -+#ifdef mpn_sec_sub_1 -+ mp_limb_t t[MAX_Q_LIMBS]; -+ -+ mpn_sec_sub_1(h, h, n, 1, t); -+#else -+ mpn_sub_1(h, h, n, 1); -+#endif -+ mpn_get_base256(k, nbytes, h, n); -+} -+ -+void _gnutls_ecdsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h, -+ mp_size_t n) -+{ -+ mpn_get_base256(k, nbytes, h, n); -+} -diff --git a/lib/nettle/int/dsa-compute-k.h b/lib/nettle/int/dsa-compute-k.h -index 49d243acb4..2f0667a01e 100644 ---- a/lib/nettle/int/dsa-compute-k.h -+++ b/lib/nettle/int/dsa-compute-k.h -@@ -26,8 +26,29 @@ - #include - #include /* includes gmp.h */ - --int _gnutls_dsa_compute_k(mpz_t k, const mpz_t q, const mpz_t x, -+#define BITS_TO_LIMBS(bits) (((bits) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) -+ -+/* The maximum size of q, chosen from the fact that we support -+ * 521-bit elliptic curve generator and 512-bit DSA subgroup at -+ * maximum. */ -+#define MAX_Q_BITS 521 -+#define MAX_Q_SIZE ((MAX_Q_BITS + 7) / 8) -+#define MAX_Q_LIMBS BITS_TO_LIMBS(MAX_Q_BITS) -+ -+#define MAX_HASH_BITS (MAX_HASH_SIZE * 8) -+#define MAX_HASH_LIMBS BITS_TO_LIMBS(MAX_HASH_BITS) -+ -+#define DSA_COMPUTE_K_ITCH MAX(MAX_Q_LIMBS, MAX_HASH_LIMBS) -+ -+int _gnutls_dsa_compute_k(mp_limb_t *h, const mp_limb_t *q, const mp_limb_t *x, -+ mp_size_t qn, mp_bitcnt_t q_bits, - gnutls_mac_algorithm_t mac, const uint8_t *digest, - size_t length); - -+void _gnutls_dsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h, -+ mp_size_t n); -+ -+void _gnutls_ecdsa_compute_k_finish(uint8_t *k, size_t nbytes, mp_limb_t *h, -+ mp_size_t n); -+ - #endif /* GNUTLS_LIB_NETTLE_INT_DSA_COMPUTE_K_H */ -diff --git a/lib/nettle/int/ecdsa-compute-k.c b/lib/nettle/int/ecdsa-compute-k.c -index 3b7f886160..4e25235c40 100644 ---- a/lib/nettle/int/ecdsa-compute-k.c -+++ b/lib/nettle/int/ecdsa-compute-k.c -@@ -29,38 +29,38 @@ - #include "dsa-compute-k.h" - #include "gnutls_int.h" - --static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve) -+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve) - { - switch (curve) { - #ifdef ENABLE_NON_SUITEB_CURVES - case GNUTLS_ECC_CURVE_SECP192R1: -- mpz_init_set_str(*q, -+ mpz_init_set_str(q, - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836" - "146BC9B1B4D22831", - 16); - return 0; - case GNUTLS_ECC_CURVE_SECP224R1: -- mpz_init_set_str(*q, -+ mpz_init_set_str(q, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2" - "E0B8F03E13DD29455C5C2A3D", - 16); - return 0; - #endif - case GNUTLS_ECC_CURVE_SECP256R1: -- mpz_init_set_str(*q, -+ mpz_init_set_str(q, - "FFFFFFFF00000000FFFFFFFFFFFFFFFF" - "BCE6FAADA7179E84F3B9CAC2FC632551", - 16); - return 0; - case GNUTLS_ECC_CURVE_SECP384R1: -- mpz_init_set_str(*q, -+ mpz_init_set_str(q, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFC7634D81F4372DDF" - "581A0DB248B0A77AECEC196ACCC52973", - 16); - return 0; - case GNUTLS_ECC_CURVE_SECP521R1: -- mpz_init_set_str(*q, -+ mpz_init_set_str(q, - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFA51868783BF2F966B7FCC0148F709A" -@@ -73,19 +73,3 @@ static inline int _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnutls_ecc_curve_t curve) - GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM); - } - } -- --int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x, -- gnutls_mac_algorithm_t mac, const uint8_t *digest, -- size_t length) --{ -- mpz_t q; -- int ret; -- -- ret = _gnutls_ecc_curve_to_dsa_q(&q, curve); -- if (ret < 0) -- return gnutls_assert_val(ret); -- -- ret = _gnutls_dsa_compute_k(k, q, x, mac, digest, length); -- mpz_clear(q); -- return ret; --} -diff --git a/lib/nettle/int/ecdsa-compute-k.h b/lib/nettle/int/ecdsa-compute-k.h -index be8beddb5d..207685763f 100644 ---- a/lib/nettle/int/ecdsa-compute-k.h -+++ b/lib/nettle/int/ecdsa-compute-k.h -@@ -26,8 +26,6 @@ - #include - #include /* includes gmp.h */ - --int _gnutls_ecdsa_compute_k(mpz_t k, gnutls_ecc_curve_t curve, const mpz_t x, -- gnutls_mac_algorithm_t mac, const uint8_t *digest, -- size_t length); -+int _gnutls_ecc_curve_to_dsa_q(mpz_t q, gnutls_ecc_curve_t curve); - - #endif /* GNUTLS_LIB_NETTLE_INT_ECDSA_COMPUTE_K_H */ -diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c -index 305548f4d1..dd6b9936a8 100644 ---- a/lib/nettle/pk.c -+++ b/lib/nettle/pk.c -@@ -103,10 +103,16 @@ static void rnd_nonce_func(void *_ctx, size_t length, uint8_t *data) - } - } - --static void rnd_mpz_func(void *_ctx, size_t length, uint8_t *data) -+static void rnd_datum_func(void *ctx, size_t length, uint8_t *data) - { -- mpz_t *k = _ctx; -- nettle_mpz_get_str_256(length, data, *k); -+ gnutls_datum_t *d = ctx; -+ -+ if (length > d->size) { -+ memset(data, 0, length - d->size); -+ memcpy(data + (length - d->size), d->data, d->size); -+ } else { -+ memcpy(data, d->data, length); -+ } - } - - static void rnd_nonce_func_fallback(void *_ctx, size_t length, uint8_t *data) -@@ -1403,7 +1409,10 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - struct dsa_signature sig; - int curve_id = pk_params->curve; - const struct ecc_curve *curve; -- mpz_t k; -+ mpz_t q; -+ /* 521-bit elliptic curve generator at maximum */ -+ uint8_t buf[(521 + 7) / 8]; -+ gnutls_datum_t k = { NULL, 0 }; - void *random_ctx; - nettle_random_func *random_func; - -@@ -1447,17 +1456,32 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - not_approved = true; - } - -- mpz_init(k); -+ mpz_init(q); -+ - if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST || - (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) { -- ret = _gnutls_ecdsa_compute_k( -- k, curve_id, pk_params->params[ECC_K], -+ mp_limb_t h[DSA_COMPUTE_K_ITCH]; -+ -+ ret = _gnutls_ecc_curve_to_dsa_q(q, curve_id); -+ if (ret < 0) -+ goto ecdsa_cleanup; -+ -+ ret = _gnutls_dsa_compute_k( -+ h, mpz_limbs_read(q), priv.p, -+ ecc_size(priv.ecc), ecc_bit_size(priv.ecc), - DIG_TO_MAC(sign_params->dsa_dig), vdata->data, - vdata->size); - if (ret < 0) - goto ecdsa_cleanup; -+ -+ k.data = buf; -+ k.size = (ecc_bit_size(priv.ecc) + 7) / 8; -+ -+ _gnutls_ecdsa_compute_k_finish(k.data, k.size, h, -+ ecc_size(priv.ecc)); -+ - random_ctx = &k; -- random_func = rnd_mpz_func; -+ random_func = rnd_datum_func; - } else { - random_ctx = NULL; - random_func = rnd_nonce_func; -@@ -1476,7 +1500,7 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - ecdsa_cleanup: - dsa_signature_clear(&sig); - ecc_scalar_zclear(&priv); -- mpz_clear(k); -+ mpz_clear(q); - - if (ret < 0) { - gnutls_assert(); -@@ -1488,7 +1512,9 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - struct dsa_params pub; - bigint_t priv; - struct dsa_signature sig; -- mpz_t k; -+ /* 512-bit DSA subgroup at maximum */ -+ uint8_t buf[(512 + 7) / 8]; -+ gnutls_datum_t k = { NULL, 0 }; - void *random_ctx; - nettle_random_func *random_func; - -@@ -1515,19 +1541,27 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - hash_len = vdata->size; - } - -- mpz_init(k); - if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST || - (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) { -+ mp_limb_t h[DSA_COMPUTE_K_ITCH]; -+ - ret = _gnutls_dsa_compute_k( -- k, pub.q, TOMPZ(priv), -+ h, mpz_limbs_read(pub.q), -+ mpz_limbs_read(TOMPZ(priv)), mpz_size(pub.q), -+ mpz_sizeinbase(pub.q, 2), - DIG_TO_MAC(sign_params->dsa_dig), vdata->data, - vdata->size); - if (ret < 0) - goto dsa_fail; -- /* cancel-out dsa_sign's addition of 1 to random data */ -- mpz_sub_ui(k, k, 1); -+ -+ k.data = buf; -+ k.size = (mpz_sizeinbase(pub.q, 2) + 7) / 8; -+ -+ _gnutls_dsa_compute_k_finish(k.data, k.size, h, -+ mpz_size(pub.q)); -+ - random_ctx = &k; -- random_func = rnd_mpz_func; -+ random_func = rnd_datum_func; - } else { - random_ctx = NULL; - random_func = rnd_nonce_func; -@@ -1544,7 +1578,6 @@ static int _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, - - dsa_fail: - dsa_signature_clear(&sig); -- mpz_clear(k); - - if (ret < 0) { - gnutls_assert(); -diff --git a/tests/sign-verify-deterministic.c b/tests/sign-verify-deterministic.c -index 6969b57a11..bdd5a49c7d 100644 ---- a/tests/sign-verify-deterministic.c -+++ b/tests/sign-verify-deterministic.c -@@ -198,7 +198,7 @@ void doit(void) - &tests[i].msg, &signature); - if (ret < 0) - testfail("gnutls_pubkey_verify_data2\n"); -- success(" - pass"); -+ success(" - pass\n"); - - next: - gnutls_free(signature.data); --- -2.44.0 - diff --git a/SOURCES/gnutls-3.8.3-ktls-utsname.patch b/SOURCES/gnutls-3.8.3-ktls-utsname.patch deleted file mode 100644 index 415d505..0000000 --- a/SOURCES/gnutls-3.8.3-ktls-utsname.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 945c2f10eeda441f32404d1328761e311915add0 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Tue, 23 Jan 2024 11:54:32 +0900 -Subject: [PATCH] ktls: fix kernel version checking using utsname - -Signed-off-by: Daiki Ueno ---- - lib/system/ktls.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/lib/system/ktls.c b/lib/system/ktls.c -index 8efb913cda..432c70c5a2 100644 ---- a/lib/system/ktls.c -+++ b/lib/system/ktls.c -@@ -482,7 +482,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, - return GNUTLS_E_INTERNAL_ERROR; - } - -- if (strcmp(utsname.sysname, "Linux") == 0) { -+ if (strcmp(utsname.sysname, "Linux") != 0) { - return GNUTLS_E_INTERNAL_ERROR; - } - -@@ -495,6 +495,9 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, - return GNUTLS_E_INTERNAL_ERROR; - } - -+ _gnutls_debug_log("Linux kernel version %lu.%lu has been detected\n", -+ major, minor); -+ - /* setsockopt(SOL_TLS, TLS_RX) support added in 5.10 */ - if (major < 5 || (major == 5 && minor < 10)) { - return GNUTLS_E_UNIMPLEMENTED_FEATURE; --- -2.43.0 - diff --git a/SOURCES/gnutls-3.8.3-verify-chain.patch b/SOURCES/gnutls-3.8.3-verify-chain.patch deleted file mode 100644 index 96fbfc4..0000000 --- a/SOURCES/gnutls-3.8.3-verify-chain.patch +++ /dev/null @@ -1,410 +0,0 @@ -From e369e67a62f44561d417cb233acc566cc696d82d Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 29 Jan 2024 13:52:46 +0900 -Subject: [PATCH] gnutls_x509_trust_list_verify_crt2: remove length limit of - input - -Previously, if cert_list_size exceeded DEFAULT_MAX_VERIFY_DEPTH, the -chain verification logic crashed with assertion failure. This patch -removes the restriction while keeping the maximum number of -retrieved certificates being DEFAULT_MAX_VERIFY_DEPTH. - -Signed-off-by: Daiki Ueno ---- - lib/gnutls_int.h | 5 +- - lib/x509/common.c | 10 +- - lib/x509/verify-high.c | 51 ++++++---- - tests/test-chains.h | 211 ++++++++++++++++++++++++++++++++++++++++- - 4 files changed, 258 insertions(+), 19 deletions(-) - -diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h -index d8561ebe3a..8cf9a87157 100644 ---- a/lib/gnutls_int.h -+++ b/lib/gnutls_int.h -@@ -232,7 +232,10 @@ typedef enum record_send_state_t { - - #define MAX_PK_PARAM_SIZE 2048 - --/* defaults for verification functions -+/* Defaults for verification functions. -+ * -+ * update many_icas in tests/test-chains.h when increasing -+ * DEFAULT_MAX_VERIFY_DEPTH. - */ - #define DEFAULT_MAX_VERIFY_DEPTH 16 - #define DEFAULT_MAX_VERIFY_BITS (MAX_PK_PARAM_SIZE * 8) -diff --git a/lib/x509/common.c b/lib/x509/common.c -index 2cc83c9155..705aa868bc 100644 ---- a/lib/x509/common.c -+++ b/lib/x509/common.c -@@ -1725,7 +1725,15 @@ unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist, - bool insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */ - gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH]; - -- assert(clist_size <= DEFAULT_MAX_VERIFY_DEPTH); -+ /* Limit the number of certificates in the chain, to avoid DoS -+ * because of the O(n^2) sorting below. FIXME: Switch to a -+ * topological sort algorithm which should be linear to the -+ * number of certificates and subject-issuer relationships. -+ */ -+ if (clist_size > DEFAULT_MAX_VERIFY_DEPTH) { -+ _gnutls_debug_log("too many certificates; skipping sorting\n"); -+ return 1; -+ } - - for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) { - issuer[i] = -1; -diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c -index 4e7361eb63..aacc24a7d8 100644 ---- a/lib/x509/verify-high.c -+++ b/lib/x509/verify-high.c -@@ -25,7 +25,7 @@ - #include "errors.h" - #include - #include "global.h" --#include "num.h" /* MAX */ -+#include "num.h" /* MIN */ - #include "tls-sig.h" - #include "str.h" - #include "datum.h" -@@ -1361,7 +1361,8 @@ int gnutls_x509_trust_list_verify_crt2( - int ret = 0; - unsigned int i; - size_t hash; -- gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH]; -+ gnutls_x509_crt_t *cert_list_copy = NULL; -+ unsigned int cert_list_max_size = 0; - gnutls_x509_crt_t retrieved[DEFAULT_MAX_VERIFY_DEPTH]; - unsigned int retrieved_size = 0; - const char *hostname = NULL, *purpose = NULL, *email = NULL; -@@ -1421,16 +1422,28 @@ int gnutls_x509_trust_list_verify_crt2( - } - } - -- memcpy(sorted, cert_list, cert_list_size * sizeof(gnutls_x509_crt_t)); -- cert_list = sorted; -+ /* Allocate extra for retrieved certificates. */ -+ if (!INT_ADD_OK(cert_list_size, DEFAULT_MAX_VERIFY_DEPTH, -+ &cert_list_max_size)) -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+ -+ cert_list_copy = _gnutls_reallocarray(NULL, cert_list_max_size, -+ sizeof(gnutls_x509_crt_t)); -+ if (!cert_list_copy) -+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ -+ memcpy(cert_list_copy, cert_list, -+ cert_list_size * sizeof(gnutls_x509_crt_t)); -+ cert_list = cert_list_copy; - - records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq, - cert_hashcode, NULL, false); -- if (records == NULL) -- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ if (records == NULL) { -+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ goto cleanup; -+ } - -- for (i = 0; i < cert_list_size && -- cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH;) { -+ for (i = 0; i < cert_list_size;) { - unsigned int sorted_size = 1; - unsigned int j, k; - gnutls_x509_crt_t issuer; -@@ -1442,8 +1455,7 @@ int gnutls_x509_trust_list_verify_crt2( - - assert(sorted_size > 0); - -- /* Remove duplicates. Start with index 1, as the first element -- * may be re-checked after issuer retrieval. */ -+ /* Remove duplicates. */ - for (j = 0; j < sorted_size; j++) { - if (gl_list_search(records, cert_list[i + j])) { - if (i + j < cert_list_size - 1) { -@@ -1495,13 +1507,15 @@ int gnutls_x509_trust_list_verify_crt2( - - ret = retrieve_issuers( - list, cert_list[i - 1], &retrieved[retrieved_size], -- DEFAULT_MAX_VERIFY_DEPTH - -- MAX(retrieved_size, cert_list_size)); -+ MIN(DEFAULT_MAX_VERIFY_DEPTH - retrieved_size, -+ cert_list_max_size - cert_list_size)); - if (ret < 0) { - break; - } else if (ret > 0) { - assert((unsigned int)ret <= -- DEFAULT_MAX_VERIFY_DEPTH - cert_list_size); -+ DEFAULT_MAX_VERIFY_DEPTH - retrieved_size); -+ assert((unsigned int)ret <= -+ cert_list_max_size - cert_list_size); - memmove(&cert_list[i + ret], &cert_list[i], - (cert_list_size - i) * - sizeof(gnutls_x509_crt_t)); -@@ -1517,8 +1531,10 @@ int gnutls_x509_trust_list_verify_crt2( - } - - cert_list_size = shorten_clist(list, cert_list, cert_list_size); -- if (cert_list_size <= 0) -- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); -+ if (cert_list_size <= 0) { -+ ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); -+ goto cleanup; -+ } - - hash = hash_pjw_bare(cert_list[cert_list_size - 1]->raw_issuer_dn.data, - cert_list[cert_list_size - 1]->raw_issuer_dn.size); -@@ -1661,10 +1677,13 @@ int gnutls_x509_trust_list_verify_crt2( - } - - cleanup: -+ gnutls_free(cert_list_copy); - for (i = 0; i < retrieved_size; i++) { - gnutls_x509_crt_deinit(retrieved[i]); - } -- gl_list_free(records); -+ if (records) { -+ gl_list_free(records); -+ } - return ret; - } - -diff --git a/tests/test-chains.h b/tests/test-chains.h -index 3e559fecd5..a7fe1cdecc 100644 ---- a/tests/test-chains.h -+++ b/tests/test-chains.h -@@ -23,7 +23,7 @@ - #ifndef GNUTLS_TESTS_TEST_CHAINS_H - #define GNUTLS_TESTS_TEST_CHAINS_H - --#define MAX_CHAIN 10 -+#define MAX_CHAIN 17 - - static const char *chain_with_no_subject_id_in_ca_ok[] = { - "-----BEGIN CERTIFICATE-----\n" -@@ -4383,6 +4383,213 @@ static const char *cross_signed_ca[] = { - NULL - }; - -+/* This assumes DEFAULT_MAX_VERIFY_DEPTH to be 16 */ -+static const char *many_icas[] = { -+ /* Server */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBqzCCAV2gAwIBAgIUIK3+SD3GmqJlRLZ/ESyhTzkSDL8wBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowNzEbMBkGA1UEChMSR251VExTIHRlc3Qgc2VydmVyMRgwFgYD\n" -+ "VQQDEw90ZXN0LmdudXRscy5vcmcwKjAFBgMrZXADIQAWGjx45NIJiKFsNBxxRRjm\n" -+ "NxUT5KYK7xXr5HPVywwgLaOBkjCBjzAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGC\n" -+ "D3Rlc3QuZ251dGxzLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8E\n" -+ "BAMCB4AwHQYDVR0OBBYEFKgNAQWZPx76/vXqQOdIi5mTftsaMB8GA1UdIwQYMBaA\n" -+ "FDaPsY6WAGuRtrhYJE6Gk/bg5qbdMAUGAytlcANBAMIDh8aGcIIFDTUrzfV7tnkX\n" -+ "hHrxyFKBH/cApf6xcJQTfDXm23po627Ibp+WgLaWMY08Fn9Y2V6Ev8ADfqXNbQ8=\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA16 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUSnE0PKdm/dsnZSWBh5Ct4pS6DcwwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAxq9SI8vp0QH1dDBBuZW+t+bLLROppQbjSQ4O1BEonDOjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ2j7GOlgBrkba4\n" -+ "WCROhpP24Oam3TAfBgNVHSMEGDAWgBRvdUKX0aw3nfUIdvivXGSfRO7zyjAFBgMr\n" -+ "ZXADQQBsI2Hc7X5hXoHTvk01qMc5a1I27QHAFRARJnvIQ15wxNS2LVLzGk+AUmwr\n" -+ "sOhBKAcVfS55uWtYdjoWQ80h238H\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA15 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUQk4XkgQVImnp6OPZas7ctwgBza4wBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAs3yVKLJd3sKbNVmj6Bxy2j1x025rksyQpZZWnCx5a+CjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRvdUKX0aw3nfUI\n" -+ "dvivXGSfRO7zyjAfBgNVHSMEGDAWgBRhGfUXYPh4YQsdtTWYUozLphGgfzAFBgMr\n" -+ "ZXADQQBXTtm56x6/pHXdW8dTvZLc/8RufNQrMlc23TCgX0apUnrZdTsNAb7OE4Uu\n" -+ "9PBuxK+CC9NL/BL2hXsKvAT+NWME\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA14 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUKfwz7UUYRvYlvqwmnLJlTOS9o1AwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAXbUetQ08t+F4+IcKL++HpeclqTxXZ7cG4mwqvHmTUEWjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRhGfUXYPh4YQsd\n" -+ "tTWYUozLphGgfzAfBgNVHSMEGDAWgBQYRQqO+V1kefF7QvNnFU1fX5H9+jAFBgMr\n" -+ "ZXADQQAiSHNMTLPFP3oa6q13Dj8jSxF9trQDJGM1ArWffFcPZUt2U4/ODHdcMTHx\n" -+ "kGwhIj+ghBlu6ykgu6J2wewCUooC\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA13 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUUKOs59gyCPAZzoC7zMZQSh6AnQgwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAmvqhj5GYqsXIpsr1BXBfD+2mTP/m/TEpKIYSZHM62dijYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQYRQqO+V1kefF7\n" -+ "QvNnFU1fX5H9+jAfBgNVHSMEGDAWgBQ27HzvP5hl2xR+LOzRcPfmY5ndXjAFBgMr\n" -+ "ZXADQQBrB3NkrYC7EQ74qgeesVOE71rW012dPOOKPAV0laR+JLEgsv9sfus+AdBF\n" -+ "WBNwR3KeYBTi/MFDuecxBHU2m5gD\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA12 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUUQooGfH21+sR7/pSgCWm13gg2H4wBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAK2of/B4wMpk6k/KdugC5dMS+jo2fseUM7/PvXkE6HASjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ27HzvP5hl2xR+\n" -+ "LOzRcPfmY5ndXjAfBgNVHSMEGDAWgBSJDHU0Mj1Xr0e8ErCnRK24w7XwTTAFBgMr\n" -+ "ZXADQQDY8d2bAZpj7oGhdl2dBsCE48jEWj49da0PbgN12koAj3gf4hjMPd8G7p5z\n" -+ "8RsURAwQmCkE8ShvdNw/Qr2tDL0E\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA11 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUW9Dw0hU2pfjXhb5Stip+mk9SndIwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAn5ISjLVV6RBWsnxDWHDicpye7SjFwGOTwzF01/psiJ2jYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSJDHU0Mj1Xr0e8\n" -+ "ErCnRK24w7XwTTAfBgNVHSMEGDAWgBSR9UU27RI0XohiEgHDxNo/9HP4djAFBgMr\n" -+ "ZXADQQCfQg6MDHk71vhyrEo4/5PcLb2Li5F/FKURyux7snv2TbkSdInloAqca9UR\n" -+ "DtqHSLCNLXCNdSPr5QwIt5p29rsE\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA10 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUR4uTedG8e6MibKViQ3eX7QzXG1swBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAnslX04kSVOL5LAf1e+Ze3ggNnDJcEAxLDk8I/IhyjTyjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSR9UU27RI0Xohi\n" -+ "EgHDxNo/9HP4djAfBgNVHSMEGDAWgBRC7US5gJYnvd5F7EN+C4anMgd2NzAFBgMr\n" -+ "ZXADQQDo+jHt07Tvz3T5Lbz6apBrSln8xKYfJk2W1wP85XAnf7sZT9apM1bS4EyD\n" -+ "Kckw+KG+9x7myOZz6AXJgZB5OGAO\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA9 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUSIIIRjrNpE+kEPkiJMOqaNAazvQwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAZKy7p1Gn4W/reRxKJN99+QkHt2q9aELktCKe5PqrX5ejYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRC7US5gJYnvd5F\n" -+ "7EN+C4anMgd2NzAfBgNVHSMEGDAWgBSOhR7Ornis2x8g0J+bvTTwMnW60zAFBgMr\n" -+ "ZXADQQA0MEcC4FgKZEAfalVpApU2to0G158MVz/WTNcSc7fnl8ifJ/g56dVHL1jr\n" -+ "REvC/S28dn/CGAlbVXUAgxnHAbgE\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA8 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUGGFSgD95vOTSj7iFxfXA5vq6vsYwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAg3W/bTdW0fR32NeZEVMXICpa30d7rSdddLOYDvqqUO+jYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSOhR7Ornis2x8g\n" -+ "0J+bvTTwMnW60zAfBgNVHSMEGDAWgBT3zK8Hbn9aVTAOOFY6RSxJ2o5x2jAFBgMr\n" -+ "ZXADQQBl4gnzE463iMFg57gPvjHdVzA39sJBpiu0kUGfRcLnoRI/VOaLcx7WnJ9+\n" -+ "c3KxPZBec76EdIoQDkTmI6m2FIAM\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA7 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUGktMGXhNuaMhKyAlecymmLD+/GIwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEA/Z1oc76hOQ0Hi+2hePaGIntnMIDqBlb7RDMjRpYONP2jYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBT3zK8Hbn9aVTAO\n" -+ "OFY6RSxJ2o5x2jAfBgNVHSMEGDAWgBSPae3JUN3jP0NgUJqDV3eYxcaM3DAFBgMr\n" -+ "ZXADQQBMkwKaUZlvG/hax8rv3nnDv8kJOr6KVHBnxSx3hZ+8HIBT7GFm1+YDeYOB\n" -+ "jhNg66kyeFPGXXBCe+mvNQFFjCEE\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA6 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUKn3gz5lAUpKqWlHKLKYDbOJ4rygwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAZ/eD4eTe91ddvHusm7YlLPxU4ByGFc6suAmlP1CxXkWjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSPae3JUN3jP0Ng\n" -+ "UJqDV3eYxcaM3DAfBgNVHSMEGDAWgBT9f/qSI/jhxvGI7aMtkpraDcjBnjAFBgMr\n" -+ "ZXADQQAMRnkmRhnLGdmJaY8B42gfyaAsqCMyds/Tw4OHYy+N48XuAxRjKkhf3szC\n" -+ "0lY71oU043mNP1yx/dzAuCTrVSgI\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA5 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUEgEYbBXXEyGv3vOq10JQv1SBiUUwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAs2xEDPw8RVal53nX9GVwUd1blq1wjtVFC8S1V7up7MWjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBT9f/qSI/jhxvGI\n" -+ "7aMtkpraDcjBnjAfBgNVHSMEGDAWgBRBVkLu9BmCKz7HNI8md4vPpoE/7jAFBgMr\n" -+ "ZXADQQCCufAyLijtzzmeCuO3K50rBSbGvB3FQfep7g6kVsQKM3bw/olWK5/Ji0dD\n" -+ "ubJ0cFl1FmfAda7aVxLBtJOvO6MI\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA4 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIULj8GkaHw+92HuOTnXnXlxCy3VrEwBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAiedxh4dvtwDellMAHc/pZH0MAOXobRenTUgF1yj5l12jYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBRBVkLu9BmCKz7H\n" -+ "NI8md4vPpoE/7jAfBgNVHSMEGDAWgBSDtNRgQ36KwW/ASaMyr6WeDt0STDAFBgMr\n" -+ "ZXADQQDL8U2ckzur7CktdrVUNvfLhVCOz33d/62F28vQFHUa8h/4h+Mi1MMbXOKT\n" -+ "1bL2TvpFpU7Fx/vcIPXDielVqr4C\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA3 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUQXl74TDDw6MQRMbQUSPa6Qrvba8wBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEA7l0jQ0f4fJRw7Qja/Hz2qn8y91SI7CokxhSf+FT+9M6jYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBSDtNRgQ36KwW/A\n" -+ "SaMyr6WeDt0STDAfBgNVHSMEGDAWgBQ2inEK4KH6ATftmybxKE1dZUzOozAFBgMr\n" -+ "ZXADQQCnP7Oqx1epGnFnO7TrTJwcUukXDEYsINve2GeUsi8HEIeKKlMcLZ2Cnaj7\n" -+ "5v9NGuWh3QJpmmSGpEemiv8dJc4A\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA2 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBYTCCAROgAwIBAgIUP7Nmof8H2F1LyDkjqlYIUpGdXE8wBQYDK2VwMB0xGzAZ\n" -+ "BgNVBAMMEkdudVRMUyB0ZXN0IElDQSAkaTAgFw0yNDAzMTIyMjUzMzlaGA85OTk5\n" -+ "MTIzMTIzNTk1OVowHTEbMBkGA1UEAwwSR251VExTIHRlc3QgSUNBICRpMCowBQYD\n" -+ "K2VwAyEAkW9Rod3CXAnha6nlaHkDbCOegq94lgmjqclA9sOIt3yjYzBhMA8GA1Ud\n" -+ "EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQ2inEK4KH6ATft\n" -+ "mybxKE1dZUzOozAfBgNVHSMEGDAWgBRPq/CQlK/zuXkjZvTCibu+vejD+jAFBgMr\n" -+ "ZXADQQBU+A+uF0yrtO/yv9cRUdCoL3Y1NKM35INg8BQDnkv724cW9zk1x0q9Fuou\n" -+ "zvfSVb8S3vT8fF5ZDOxarQs6ZH0C\n" -+ "-----END CERTIFICATE-----\n", -+ /* ICA1 */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBXTCCAQ+gAwIBAgIUfUWP+AQHpdFTRKTf21mMzjaJsp0wBQYDK2VwMBkxFzAV\n" -+ "BgNVBAMTDkdudVRMUyB0ZXN0IENBMCAXDTI0MDMxMjIyNTMzOVoYDzk5OTkxMjMx\n" -+ "MjM1OTU5WjAdMRswGQYDVQQDDBJHbnVUTFMgdGVzdCBJQ0EgJGkwKjAFBgMrZXAD\n" -+ "IQAVmfBAvLbT+pTD24pQrr6S0jEIFIV/qOv93yYvAUzpzKNjMGEwDwYDVR0TAQH/\n" -+ "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQwHQYDVR0OBBYEFE+r8JCUr/O5eSNm9MKJ\n" -+ "u7696MP6MB8GA1UdIwQYMBaAFAFpt5wrFsqCtHc4PpluPDvwcxQLMAUGAytlcANB\n" -+ "AC6+XZnthjlUD0TbBKRF3qT5if3Pp29Bgvutw8859unzUZW8FkHg5KeDBj9ncgJc\n" -+ "O2tFnNH2hV6LDPJzU0rtLQc=\n" -+ "-----END CERTIFICATE-----\n", -+ NULL -+}; -+ -+static const char *many_icas_ca[] = { -+ /* CA (self-signed) */ -+ "-----BEGIN CERTIFICATE-----\n" -+ "MIIBNzCB6qADAgECAhRjaokcQwcrtW8tjuVFz3A33F8POjAFBgMrZXAwGTEXMBUG\n" -+ "A1UEAxMOR251VExTIHRlc3QgQ0EwIBcNMjQwMzEyMjI1MzM5WhgPOTk5OTEyMzEy\n" -+ "MzU5NTlaMBkxFzAVBgNVBAMTDkdudVRMUyB0ZXN0IENBMCowBQYDK2VwAyEAvoxP\n" -+ "TNdbWktxA8qQNNH+25Cx9rzP+DxLGeI/7ODwrQGjQjBAMA8GA1UdEwEB/wQFMAMB\n" -+ "Af8wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBQBabecKxbKgrR3OD6Zbjw78HMU\n" -+ "CzAFBgMrZXADQQCP5IUD74M7WrUx20uqzrzuj+s2jnBVmLQfWf/Ucetx+oTRFeq4\n" -+ "xZB/adWhycSeJUAB1zKqYUV9hgT8FWHbnHII\n" -+ "-----END CERTIFICATE-----\n", -+ NULL -+}; -+ - #if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-variable" -@@ -4696,6 +4903,8 @@ static struct { - 1620118136, 1 }, - { "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0, - 1704955300 }, -+ { "many intermediates - ok", many_icas, many_icas_ca, 0, 0, 0, -+ 1710284400 }, - { NULL, NULL, NULL, 0, 0 } - }; - --- -2.44.0 - diff --git a/SOURCES/gnutls-3.8.9-CVE-2024-12243.patch b/SOURCES/gnutls-3.8.9-CVE-2024-12243.patch deleted file mode 100644 index 096f95d..0000000 --- a/SOURCES/gnutls-3.8.9-CVE-2024-12243.patch +++ /dev/null @@ -1,1148 +0,0 @@ -From 4760bc63531e3f5039e70ede91a20e1194410892 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Mon, 18 Nov 2024 17:23:46 +0900 -Subject: [PATCH] x509: optimize name constraints processing - -This switches the representation name constraints from linked lists to -array lists to optimize the lookup performance from O(n) to O(1), also -enforces a limit of name constraint checks against subject alternative -names. - -Signed-off-by: Daiki Ueno ---- - lib/datum.c | 7 +- - lib/x509/name_constraints.c | 595 +++++++++++++++++++++--------------- - lib/x509/x509_ext.c | 80 +++-- - lib/x509/x509_ext_int.h | 5 + - lib/x509/x509_int.h | 21 +- - 5 files changed, 399 insertions(+), 309 deletions(-) - -diff --git a/lib/datum.c b/lib/datum.c -index 66e016965d..5577c2b4ab 100644 ---- a/lib/datum.c -+++ b/lib/datum.c -@@ -29,6 +29,7 @@ - #include "num.h" - #include "datum.h" - #include "errors.h" -+#include "intprops.h" - - /* On error, @dat is not changed. */ - int _gnutls_set_datum(gnutls_datum_t *dat, const void *data, size_t data_size) -@@ -60,7 +61,11 @@ int _gnutls_set_strdatum(gnutls_datum_t *dat, const void *data, - if (data == NULL) - return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); - -- unsigned char *m = gnutls_malloc(data_size + 1); -+ size_t capacity; -+ if (!INT_ADD_OK(data_size, 1, &capacity)) -+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ -+ unsigned char *m = gnutls_malloc(capacity); - if (!m) - return GNUTLS_E_MEMORY_ERROR; - -diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c -index 8327a9d94e..3c6e306303 100644 ---- a/lib/x509/name_constraints.c -+++ b/lib/x509/name_constraints.c -@@ -33,51 +33,98 @@ - #include - #include "x509_b64.h" - #include "x509_int.h" -+#include "x509_ext_int.h" - #include - - #include "ip.h" - #include "ip-in-cidr.h" -+#include "intprops.h" -+ -+#define MAX_NC_CHECKS (1 << 20) -+ -+struct name_constraints_node_st { -+ unsigned type; -+ gnutls_datum_t name; -+}; -+ -+struct name_constraints_node_list_st { -+ struct name_constraints_node_st **data; -+ size_t size; -+ size_t capacity; -+}; -+ -+struct gnutls_name_constraints_st { -+ struct name_constraints_node_list_st nodes; /* owns elements */ -+ struct name_constraints_node_list_st permitted; /* borrows elements */ -+ struct name_constraints_node_list_st excluded; /* borrows elements */ -+}; -+ -+static struct name_constraints_node_st * -+name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, -+ unsigned char *data, unsigned int size); - --// for documentation see the implementation - static int --name_constraints_intersect_nodes(name_constraints_node_st *nc1, -- name_constraints_node_st *nc2, -- name_constraints_node_st **intersection); -+name_constraints_node_list_add(struct name_constraints_node_list_st *list, -+ struct name_constraints_node_st *node) -+{ -+ if (!list->capacity || list->size == list->capacity) { -+ size_t new_capacity = list->capacity; -+ struct name_constraints_node_st **new_data; -+ -+ if (!INT_MULTIPLY_OK(new_capacity, 2, &new_capacity) || -+ !INT_ADD_OK(new_capacity, 1, &new_capacity)) -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+ new_data = _gnutls_reallocarray( -+ list->data, new_capacity, -+ sizeof(struct name_constraints_node_st *)); -+ if (!new_data) -+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ list->capacity = new_capacity; -+ list->data = new_data; -+ } -+ list->data[list->size++] = node; -+ return 0; -+} -+ -+// for documentation see the implementation -+static int name_constraints_intersect_nodes( -+ gnutls_x509_name_constraints_t nc, -+ const struct name_constraints_node_st *node1, -+ const struct name_constraints_node_st *node2, -+ struct name_constraints_node_st **intersection); - - /*- -- * is_nc_empty: -+ * _gnutls_x509_name_constraints_is_empty: - * @nc: name constraints structure -- * @type: type (gnutls_x509_subject_alt_name_t) -+ * @type: type (gnutls_x509_subject_alt_name_t or 0) - * - * Test whether given name constraints structure has any constraints (permitted - * or excluded) of a given type. @nc must be allocated (not NULL) before the call. -+ * If @type is 0, type checking will be skipped. - * -- * Returns: 0 if @nc contains constraints of type @type, 1 otherwise -+ * Returns: false if @nc contains constraints of type @type, true otherwise - -*/ --static unsigned is_nc_empty(struct gnutls_name_constraints_st *nc, -- unsigned type) -+bool _gnutls_x509_name_constraints_is_empty(gnutls_x509_name_constraints_t nc, -+ unsigned type) - { -- name_constraints_node_st *t; -+ if (nc->permitted.size == 0 && nc->excluded.size == 0) -+ return true; - -- if (nc->permitted == NULL && nc->excluded == NULL) -- return 1; -+ if (type == 0) -+ return false; - -- t = nc->permitted; -- while (t != NULL) { -- if (t->type == type) -- return 0; -- t = t->next; -+ for (size_t i = 0; i < nc->permitted.size; i++) { -+ if (nc->permitted.data[i]->type == type) -+ return false; - } - -- t = nc->excluded; -- while (t != NULL) { -- if (t->type == type) -- return 0; -- t = t->next; -+ for (size_t i = 0; i < nc->excluded.size; i++) { -+ if (nc->excluded.data[i]->type == type) -+ return false; - } - - /* no constraint for that type exists */ -- return 1; -+ return true; - } - - /*- -@@ -115,21 +162,16 @@ static int validate_name_constraints_node(gnutls_x509_subject_alt_name_t type, - return GNUTLS_E_SUCCESS; - } - --int _gnutls_extract_name_constraints(asn1_node c2, const char *vstr, -- name_constraints_node_st **_nc) -+static int extract_name_constraints(gnutls_x509_name_constraints_t nc, -+ asn1_node c2, const char *vstr, -+ struct name_constraints_node_list_st *nodes) - { - int ret; - char tmpstr[128]; - unsigned indx; - gnutls_datum_t tmp = { NULL, 0 }; - unsigned int type; -- struct name_constraints_node_st *nc, *prev; -- -- prev = *_nc; -- if (prev != NULL) { -- while (prev->next != NULL) -- prev = prev->next; -- } -+ struct name_constraints_node_st *node; - - for (indx = 1;; indx++) { - snprintf(tmpstr, sizeof(tmpstr), "%s.?%u.base", vstr, indx); -@@ -172,25 +214,19 @@ int _gnutls_extract_name_constraints(asn1_node c2, const char *vstr, - goto cleanup; - } - -- nc = gnutls_malloc(sizeof(struct name_constraints_node_st)); -- if (nc == NULL) { -+ node = name_constraints_node_new(nc, type, tmp.data, tmp.size); -+ _gnutls_free_datum(&tmp); -+ if (node == NULL) { - gnutls_assert(); - ret = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - -- memcpy(&nc->name, &tmp, sizeof(gnutls_datum_t)); -- nc->type = type; -- nc->next = NULL; -- -- if (prev == NULL) { -- *_nc = prev = nc; -- } else { -- prev->next = nc; -- prev = nc; -+ ret = name_constraints_node_list_add(nodes, node); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; - } -- -- tmp.data = NULL; - } - - assert(ret < 0); -@@ -205,84 +241,104 @@ cleanup: - return ret; - } - -+int _gnutls_x509_name_constraints_extract(asn1_node c2, -+ const char *permitted_name, -+ const char *excluded_name, -+ gnutls_x509_name_constraints_t nc) -+{ -+ int ret; -+ -+ ret = extract_name_constraints(nc, c2, permitted_name, &nc->permitted); -+ if (ret < 0) -+ return gnutls_assert_val(ret); -+ ret = extract_name_constraints(nc, c2, excluded_name, &nc->excluded); -+ if (ret < 0) -+ return gnutls_assert_val(ret); -+ -+ return ret; -+} -+ - /*- -- * _gnutls_name_constraints_node_free: -+ * name_constraints_node_free: - * @node: name constraints node - * -- * Deallocate a list of name constraints nodes starting at the given node. -+ * Deallocate a name constraints node. - -*/ --void _gnutls_name_constraints_node_free(name_constraints_node_st *node) -+static void name_constraints_node_free(struct name_constraints_node_st *node) - { -- name_constraints_node_st *next, *t; -- -- t = node; -- while (t != NULL) { -- next = t->next; -- gnutls_free(t->name.data); -- gnutls_free(t); -- t = next; -+ if (node) { -+ gnutls_free(node->name.data); -+ gnutls_free(node); - } - } - - /*- - * name_constraints_node_new: - * @type: name constraints type to set (gnutls_x509_subject_alt_name_t) -+ * @nc: a %gnutls_x509_name_constraints_t - * @data: name.data to set or NULL - * @size: name.size to set - * - * Allocate a new name constraints node and set its type, name size and name data. -- * If @data is set to NULL, name data will be an array of \x00 (the length of @size). -- * The .next pointer is set to NULL. - * - * Returns: Pointer to newly allocated node or NULL in case of memory error. - -*/ --static name_constraints_node_st * --name_constraints_node_new(unsigned type, unsigned char *data, unsigned int size) -+static struct name_constraints_node_st * -+name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type, -+ unsigned char *data, unsigned int size) - { -- name_constraints_node_st *tmp = -- gnutls_malloc(sizeof(struct name_constraints_node_st)); -+ struct name_constraints_node_st *tmp; -+ int ret; -+ -+ tmp = gnutls_calloc(1, sizeof(struct name_constraints_node_st)); - if (tmp == NULL) - return NULL; - tmp->type = type; -- tmp->next = NULL; -- tmp->name.size = size; -- tmp->name.data = NULL; -- if (tmp->name.size > 0) { -- tmp->name.data = gnutls_malloc(tmp->name.size); -- if (tmp->name.data == NULL) { -+ -+ if (data) { -+ ret = _gnutls_set_strdatum(&tmp->name, data, size); -+ if (ret < 0) { -+ gnutls_assert(); - gnutls_free(tmp); - return NULL; - } -- if (data != NULL) { -- memcpy(tmp->name.data, data, size); -- } else { -- memset(tmp->name.data, 0, size); -- } - } -+ -+ ret = name_constraints_node_list_add(&nc->nodes, tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ name_constraints_node_free(tmp); -+ return NULL; -+ } -+ - return tmp; - } - - /*- -- * @brief _gnutls_name_constraints_intersect: -- * @_nc: first name constraints list (permitted) -- * @_nc2: name constraints list to merge with (permitted) -- * @_nc_excluded: Corresponding excluded name constraints list -+ * @brief name_constraints_node_list_intersect: -+ * @nc: %gnutls_x509_name_constraints_t -+ * @permitted: first name constraints list (permitted) -+ * @permitted2: name constraints list to merge with (permitted) -+ * @excluded: Corresponding excluded name constraints list - * -- * This function finds the intersection of @_nc and @_nc2. The result is placed in @_nc, -- * the original @_nc is deallocated. @_nc2 is not changed. If necessary, a universal -+ * This function finds the intersection of @permitted and @permitted2. The result is placed in @permitted, -+ * the original @permitted is modified. @permitted2 is not changed. If necessary, a universal - * excluded name constraint node of the right type is added to the list provided -- * in @_nc_excluded. -+ * in @excluded. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value. - -*/ --static int --_gnutls_name_constraints_intersect(name_constraints_node_st **_nc, -- name_constraints_node_st *_nc2, -- name_constraints_node_st **_nc_excluded) -+static int name_constraints_node_list_intersect( -+ gnutls_x509_name_constraints_t nc, -+ struct name_constraints_node_list_st *permitted, -+ const struct name_constraints_node_list_st *permitted2, -+ struct name_constraints_node_list_st *excluded) - { -- name_constraints_node_st *nc, *nc2, *t, *tmp, *dest = NULL, -- *prev = NULL; -+ struct name_constraints_node_st *tmp; - int ret, type, used; -+ struct name_constraints_node_list_st removed = { .data = NULL, -+ .size = 0, -+ .capacity = 0 }; - - /* temporary array to see, if we need to add universal excluded constraints - * (see phase 3 for details) -@@ -291,61 +347,73 @@ _gnutls_name_constraints_intersect(name_constraints_node_st **_nc, - memset(types_with_empty_intersection, 0, - sizeof(types_with_empty_intersection)); - -- if (*_nc == NULL || _nc2 == NULL) -+ if (permitted->size == 0 || permitted2->size == 0) - return 0; - - /* Phase 1 -- * For each name in _NC, if a _NC2 does not contain a name -- * with the same type, preserve the original name. -- * Do this also for node of unknown type (not DNS, email, IP */ -- t = nc = *_nc; -- while (t != NULL) { -- name_constraints_node_st *next = t->next; -- nc2 = _nc2; -- while (nc2 != NULL) { -- if (t->type == nc2->type) { -+ * For each name in PERMITTED, if a PERMITTED2 does not contain a name -+ * with the same type, move the original name to REMOVED. -+ * Do this also for node of unknown type (not DNS, email, IP) */ -+ for (size_t i = 0; i < permitted->size;) { -+ struct name_constraints_node_st *t = permitted->data[i]; -+ const struct name_constraints_node_st *found = NULL; -+ -+ for (size_t j = 0; j < permitted2->size; j++) { -+ const struct name_constraints_node_st *t2 = -+ permitted2->data[j]; -+ if (t->type == t2->type) { - // check bounds (we will use 't->type' as index) -- if (t->type > GNUTLS_SAN_MAX || t->type == 0) -- return gnutls_assert_val( -- GNUTLS_E_INTERNAL_ERROR); -+ if (t->type > GNUTLS_SAN_MAX || t->type == 0) { -+ gnutls_assert(); -+ ret = GNUTLS_E_INTERNAL_ERROR; -+ goto cleanup; -+ } - // note the possibility of empty intersection for this type - // if we add something to the intersection in phase 2, - // we will reset this flag back to 0 then - types_with_empty_intersection[t->type - 1] = 1; -+ found = t2; - break; - } -- nc2 = nc2->next; - } -- if (nc2 == NULL || (t->type != GNUTLS_SAN_DNSNAME && -- t->type != GNUTLS_SAN_RFC822NAME && -- t->type != GNUTLS_SAN_IPADDRESS)) { -- /* move node from NC to DEST */ -- if (prev != NULL) -- prev->next = next; -- else -- prev = nc = next; -- t->next = dest; -- dest = t; -- } else { -- prev = t; -+ -+ if (found != NULL && (t->type == GNUTLS_SAN_DNSNAME || -+ t->type == GNUTLS_SAN_RFC822NAME || -+ t->type == GNUTLS_SAN_IPADDRESS)) { -+ /* move node from PERMITTED to REMOVED */ -+ ret = name_constraints_node_list_add(&removed, t); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; -+ } -+ /* remove node by swapping */ -+ if (i < permitted->size - 1) -+ permitted->data[i] = -+ permitted->data[permitted->size - 1]; -+ permitted->size--; -+ continue; - } -- t = next; -+ i++; - } - - /* Phase 2 -- * iterate through all combinations from nc2 and nc1 -+ * iterate through all combinations from PERMITTED2 and PERMITTED - * and create intersections of nodes with same type */ -- nc2 = _nc2; -- while (nc2 != NULL) { -- // current nc2 node has not yet been used for any intersection -- // (and is not in DEST either) -+ for (size_t i = 0; i < permitted2->size; i++) { -+ const struct name_constraints_node_st *t2 = permitted2->data[i]; -+ -+ // current PERMITTED2 node has not yet been used for any intersection -+ // (and is not in REMOVED either) - used = 0; -- t = nc; -- while (t != NULL) { -+ for (size_t j = 0; j < removed.size; j++) { -+ const struct name_constraints_node_st *t = -+ removed.data[j]; - // save intersection of name constraints into tmp -- ret = name_constraints_intersect_nodes(t, nc2, &tmp); -- if (ret < 0) -- return gnutls_assert_val(ret); -+ ret = name_constraints_intersect_nodes(nc, t, t2, &tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; -+ } - used = 1; - // if intersection is not empty - if (tmp != -@@ -360,32 +428,34 @@ _gnutls_name_constraints_intersect(name_constraints_node_st **_nc, - // we will not add universal excluded constraint for this type - types_with_empty_intersection[tmp->type - 1] = - 0; -- // add intersection node to DEST -- tmp->next = dest; -- dest = tmp; -+ // add intersection node to PERMITTED -+ ret = name_constraints_node_list_add(permitted, -+ tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; -+ } - } -- t = t->next; - } -- // if the node from nc2 was not used for intersection, copy it to DEST -+ // if the node from PERMITTED2 was not used for intersection, copy it to DEST - // Beware: also copies nodes other than DNS, email, IP, - // since their counterpart may have been moved in phase 1. - if (!used) { - tmp = name_constraints_node_new( -- nc2->type, nc2->name.data, nc2->name.size); -+ nc, t2->type, t2->name.data, t2->name.size); - if (tmp == NULL) { -- _gnutls_name_constraints_node_free(dest); -- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ gnutls_assert(); -+ ret = GNUTLS_E_MEMORY_ERROR; -+ goto cleanup; -+ } -+ ret = name_constraints_node_list_add(permitted, tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; - } -- tmp->next = dest; -- dest = tmp; - } -- nc2 = nc2->next; - } - -- /* replace the original with the new */ -- _gnutls_name_constraints_node_free(nc); -- *_nc = dest; -- - /* Phase 3 - * For each type: If we have empty permitted name constraints now - * and we didn't have at the beginning, we have to add a new -@@ -400,63 +470,77 @@ _gnutls_name_constraints_intersect(name_constraints_node_st **_nc, - switch (type) { - case GNUTLS_SAN_IPADDRESS: - // add universal restricted range for IPv4 -- tmp = name_constraints_node_new(GNUTLS_SAN_IPADDRESS, -- NULL, 8); -+ tmp = name_constraints_node_new( -+ nc, GNUTLS_SAN_IPADDRESS, NULL, 8); - if (tmp == NULL) { -- _gnutls_name_constraints_node_free(dest); -- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ gnutls_assert(); -+ ret = GNUTLS_E_MEMORY_ERROR; -+ goto cleanup; -+ } -+ ret = name_constraints_node_list_add(excluded, tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; - } -- tmp->next = *_nc_excluded; -- *_nc_excluded = tmp; - // add universal restricted range for IPv6 -- tmp = name_constraints_node_new(GNUTLS_SAN_IPADDRESS, -- NULL, 32); -+ tmp = name_constraints_node_new( -+ nc, GNUTLS_SAN_IPADDRESS, NULL, 32); - if (tmp == NULL) { -- _gnutls_name_constraints_node_free(dest); -- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ gnutls_assert(); -+ ret = GNUTLS_E_MEMORY_ERROR; -+ goto cleanup; -+ } -+ ret = name_constraints_node_list_add(excluded, tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; - } -- tmp->next = *_nc_excluded; -- *_nc_excluded = tmp; - break; - case GNUTLS_SAN_DNSNAME: - case GNUTLS_SAN_RFC822NAME: -- tmp = name_constraints_node_new(type, NULL, 0); -+ tmp = name_constraints_node_new(nc, type, NULL, 0); - if (tmp == NULL) { -- _gnutls_name_constraints_node_free(dest); -- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ gnutls_assert(); -+ ret = GNUTLS_E_MEMORY_ERROR; -+ goto cleanup; -+ } -+ ret = name_constraints_node_list_add(excluded, tmp); -+ if (ret < 0) { -+ gnutls_assert(); -+ goto cleanup; - } -- tmp->next = *_nc_excluded; -- *_nc_excluded = tmp; - break; - default: // do nothing, at least one node was already moved in phase 1 - break; - } - } -- return GNUTLS_E_SUCCESS; -+ ret = GNUTLS_E_SUCCESS; -+ -+cleanup: -+ gnutls_free(removed.data); -+ return ret; - } - --static int _gnutls_name_constraints_append(name_constraints_node_st **_nc, -- name_constraints_node_st *_nc2) -+static int name_constraints_node_list_concat( -+ gnutls_x509_name_constraints_t nc, -+ struct name_constraints_node_list_st *nodes, -+ const struct name_constraints_node_list_st *nodes2) - { -- name_constraints_node_st *nc, *nc2; -- struct name_constraints_node_st *tmp; -- -- if (_nc2 == NULL) -- return 0; -- -- nc2 = _nc2; -- while (nc2) { -- nc = *_nc; -- -- tmp = name_constraints_node_new(nc2->type, nc2->name.data, -- nc2->name.size); -- if (tmp == NULL) -+ for (size_t i = 0; i < nodes2->size; i++) { -+ const struct name_constraints_node_st *node = nodes2->data[i]; -+ struct name_constraints_node_st *tmp; -+ int ret; -+ -+ tmp = name_constraints_node_new(nc, node->type, node->name.data, -+ node->name.size); -+ if (tmp == NULL) { - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -- -- tmp->next = nc; -- *_nc = tmp; -- -- nc2 = nc2->next; -+ } -+ ret = name_constraints_node_list_add(nodes, tmp); -+ if (ret < 0) { -+ name_constraints_node_free(tmp); -+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -+ } - } - - return 0; -@@ -524,6 +608,25 @@ cleanup: - return ret; - } - -+void _gnutls_x509_name_constraints_clear(gnutls_x509_name_constraints_t nc) -+{ -+ for (size_t i = 0; i < nc->nodes.size; i++) { -+ struct name_constraints_node_st *node = nc->nodes.data[i]; -+ name_constraints_node_free(node); -+ } -+ gnutls_free(nc->nodes.data); -+ nc->nodes.capacity = 0; -+ nc->nodes.size = 0; -+ -+ gnutls_free(nc->permitted.data); -+ nc->permitted.capacity = 0; -+ nc->permitted.size = 0; -+ -+ gnutls_free(nc->excluded.data); -+ nc->excluded.capacity = 0; -+ nc->excluded.size = 0; -+} -+ - /** - * gnutls_x509_name_constraints_deinit: - * @nc: The nameconstraints -@@ -534,9 +637,7 @@ cleanup: - **/ - void gnutls_x509_name_constraints_deinit(gnutls_x509_name_constraints_t nc) - { -- _gnutls_name_constraints_node_free(nc->permitted); -- _gnutls_name_constraints_node_free(nc->excluded); -- -+ _gnutls_x509_name_constraints_clear(nc); - gnutls_free(nc); - } - -@@ -552,12 +653,15 @@ void gnutls_x509_name_constraints_deinit(gnutls_x509_name_constraints_t nc) - **/ - int gnutls_x509_name_constraints_init(gnutls_x509_name_constraints_t *nc) - { -- *nc = gnutls_calloc(1, sizeof(struct gnutls_name_constraints_st)); -- if (*nc == NULL) { -+ struct gnutls_name_constraints_st *tmp; -+ -+ tmp = gnutls_calloc(1, sizeof(struct gnutls_name_constraints_st)); -+ if (tmp == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - -+ *nc = tmp; - return 0; - } - -@@ -565,36 +669,25 @@ static int name_constraints_add(gnutls_x509_name_constraints_t nc, - gnutls_x509_subject_alt_name_t type, - const gnutls_datum_t *name, unsigned permitted) - { -- struct name_constraints_node_st *tmp, *prev = NULL; -+ struct name_constraints_node_st *tmp; -+ struct name_constraints_node_list_st *nodes; - int ret; - - ret = validate_name_constraints_node(type, name); - if (ret < 0) - return gnutls_assert_val(ret); - -- if (permitted != 0) -- prev = tmp = nc->permitted; -- else -- prev = tmp = nc->excluded; -- -- while (tmp != NULL) { -- tmp = tmp->next; -- if (tmp != NULL) -- prev = tmp; -- } -+ nodes = permitted ? &nc->permitted : &nc->excluded; - -- tmp = name_constraints_node_new(type, name->data, name->size); -+ tmp = name_constraints_node_new(nc, type, name->data, name->size); - if (tmp == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); -- tmp->next = NULL; - -- if (prev == NULL) { -- if (permitted != 0) -- nc->permitted = tmp; -- else -- nc->excluded = tmp; -- } else -- prev->next = tmp; -+ ret = name_constraints_node_list_add(nodes, tmp); -+ if (ret < 0) { -+ name_constraints_node_free(tmp); -+ return gnutls_assert_val(ret); -+ } - - return 0; - } -@@ -620,14 +713,15 @@ int _gnutls_x509_name_constraints_merge(gnutls_x509_name_constraints_t nc, - { - int ret; - -- ret = _gnutls_name_constraints_intersect(&nc->permitted, nc2->permitted, -- &nc->excluded); -+ ret = name_constraints_node_list_intersect( -+ nc, &nc->permitted, &nc2->permitted, &nc->excluded); - if (ret < 0) { - gnutls_assert(); - return ret; - } - -- ret = _gnutls_name_constraints_append(&nc->excluded, nc2->excluded); -+ ret = name_constraints_node_list_concat(nc, &nc->excluded, -+ &nc2->excluded); - if (ret < 0) { - gnutls_assert(); - return ret; -@@ -804,50 +898,51 @@ static unsigned email_matches(const gnutls_datum_t *name, - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value. - -*/ --static int --name_constraints_intersect_nodes(name_constraints_node_st *nc1, -- name_constraints_node_st *nc2, -- name_constraints_node_st **_intersection) -+static int name_constraints_intersect_nodes( -+ gnutls_x509_name_constraints_t nc, -+ const struct name_constraints_node_st *node1, -+ const struct name_constraints_node_st *node2, -+ struct name_constraints_node_st **_intersection) - { - // presume empty intersection -- name_constraints_node_st *intersection = NULL; -- name_constraints_node_st *to_copy = NULL; -+ struct name_constraints_node_st *intersection = NULL; -+ const struct name_constraints_node_st *to_copy = NULL; - unsigned iplength = 0; - unsigned byte; - - *_intersection = NULL; - -- if (nc1->type != nc2->type) { -+ if (node1->type != node2->type) { - return GNUTLS_E_SUCCESS; - } -- switch (nc1->type) { -+ switch (node1->type) { - case GNUTLS_SAN_DNSNAME: -- if (!dnsname_matches(&nc2->name, &nc1->name)) -+ if (!dnsname_matches(&node2->name, &node1->name)) - return GNUTLS_E_SUCCESS; -- to_copy = nc2; -+ to_copy = node2; - break; - case GNUTLS_SAN_RFC822NAME: -- if (!email_matches(&nc2->name, &nc1->name)) -+ if (!email_matches(&node2->name, &node1->name)) - return GNUTLS_E_SUCCESS; -- to_copy = nc2; -+ to_copy = node2; - break; - case GNUTLS_SAN_IPADDRESS: -- if (nc1->name.size != nc2->name.size) -+ if (node1->name.size != node2->name.size) - return GNUTLS_E_SUCCESS; -- iplength = nc1->name.size / 2; -+ iplength = node1->name.size / 2; - for (byte = 0; byte < iplength; byte++) { -- if (((nc1->name.data[byte] ^ -- nc2->name.data[byte]) // XOR of addresses -- & -- nc1->name.data[byte + iplength] // AND mask from nc1 -- & -- nc2->name.data[byte + iplength]) // AND mask from nc2 -+ if (((node1->name.data[byte] ^ -+ node2->name.data[byte]) // XOR of addresses -+ & node1->name.data[byte + -+ iplength] // AND mask from nc1 -+ & node2->name.data[byte + -+ iplength]) // AND mask from nc2 - != 0) { - // CIDRS do not intersect - return GNUTLS_E_SUCCESS; - } - } -- to_copy = nc2; -+ to_copy = node2; - break; - default: - // for other types, we don't know how to do the intersection, assume empty -@@ -856,8 +951,9 @@ name_constraints_intersect_nodes(name_constraints_node_st *nc1, - - // copy existing node if applicable - if (to_copy != NULL) { -- *_intersection = name_constraints_node_new( -- to_copy->type, to_copy->name.data, to_copy->name.size); -+ *_intersection = name_constraints_node_new(nc, to_copy->type, -+ to_copy->name.data, -+ to_copy->name.size); - if (*_intersection == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - intersection = *_intersection; -@@ -869,12 +965,12 @@ name_constraints_intersect_nodes(name_constraints_node_st *nc1, - _gnutls_mask_ip(intersection->name.data, - intersection->name.data + iplength, - iplength); -- _gnutls_mask_ip(nc1->name.data, -- nc1->name.data + iplength, iplength); -+ _gnutls_mask_ip(node1->name.data, -+ node1->name.data + iplength, iplength); - // update intersection, if necessary (we already know one is subset of other) - for (byte = 0; byte < 2 * iplength; byte++) { - intersection->name.data[byte] |= -- nc1->name.data[byte]; -+ node1->name.data[byte]; - } - } - } -@@ -1177,10 +1273,17 @@ gnutls_x509_name_constraints_check_crt(gnutls_x509_name_constraints_t nc, - unsigned idx, t, san_type; - gnutls_datum_t n; - unsigned found_one; -+ size_t checks; - -- if (is_nc_empty(nc, type) != 0) -+ if (_gnutls_x509_name_constraints_is_empty(nc, type) != 0) - return 1; /* shortcut; no constraints to check */ - -+ if (!INT_ADD_OK(nc->permitted.size, nc->excluded.size, &checks) || -+ !INT_MULTIPLY_OK(checks, cert->san->size, &checks) || -+ checks > MAX_NC_CHECKS) { -+ return gnutls_assert_val(0); -+ } -+ - if (type == GNUTLS_SAN_RFC822NAME) { - found_one = 0; - for (idx = 0;; idx++) { -@@ -1378,20 +1481,13 @@ int gnutls_x509_name_constraints_get_permitted(gnutls_x509_name_constraints_t nc - unsigned idx, unsigned *type, - gnutls_datum_t *name) - { -- unsigned int i; -- struct name_constraints_node_st *tmp = nc->permitted; -+ const struct name_constraints_node_st *tmp; - -- for (i = 0; i < idx; i++) { -- if (tmp == NULL) -- return gnutls_assert_val( -- GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); -- -- tmp = tmp->next; -- } -- -- if (tmp == NULL) -+ if (idx >= nc->permitted.size) - return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); - -+ tmp = nc->permitted.data[idx]; -+ - *type = tmp->type; - *name = tmp->name; - -@@ -1421,20 +1517,13 @@ int gnutls_x509_name_constraints_get_excluded(gnutls_x509_name_constraints_t nc, - unsigned idx, unsigned *type, - gnutls_datum_t *name) - { -- unsigned int i; -- struct name_constraints_node_st *tmp = nc->excluded; -- -- for (i = 0; i < idx; i++) { -- if (tmp == NULL) -- return gnutls_assert_val( -- GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); -+ const struct name_constraints_node_st *tmp; - -- tmp = tmp->next; -- } -- -- if (tmp == NULL) -+ if (idx >= nc->excluded.size) - return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); - -+ tmp = nc->excluded.data[idx]; -+ - *type = tmp->type; - *name = tmp->name; - -diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c -index ae7216f23f..1714578de6 100644 ---- a/lib/x509/x509_ext.c -+++ b/lib/x509/x509_ext.c -@@ -34,10 +34,6 @@ - #include "intprops.h" - - #define MAX_ENTRIES 64 --struct gnutls_subject_alt_names_st { -- struct name_st *names; -- unsigned int size; --}; - - /** - * gnutls_subject_alt_names_init: -@@ -389,22 +385,15 @@ int gnutls_x509_ext_import_name_constraints(const gnutls_datum_t *ext, - } - - if (flags & GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND && -- (nc->permitted != NULL || nc->excluded != NULL)) { -+ !_gnutls_x509_name_constraints_is_empty(nc, 0)) { - ret = gnutls_x509_name_constraints_init(&nc2); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - -- ret = _gnutls_extract_name_constraints(c2, "permittedSubtrees", -- &nc2->permitted); -- if (ret < 0) { -- gnutls_assert(); -- goto cleanup; -- } -- -- ret = _gnutls_extract_name_constraints(c2, "excludedSubtrees", -- &nc2->excluded); -+ ret = _gnutls_x509_name_constraints_extract( -+ c2, "permittedSubtrees", "excludedSubtrees", nc2); - if (ret < 0) { - gnutls_assert(); - goto cleanup; -@@ -416,18 +405,10 @@ int gnutls_x509_ext_import_name_constraints(const gnutls_datum_t *ext, - goto cleanup; - } - } else { -- _gnutls_name_constraints_node_free(nc->permitted); -- _gnutls_name_constraints_node_free(nc->excluded); -- -- ret = _gnutls_extract_name_constraints(c2, "permittedSubtrees", -- &nc->permitted); -- if (ret < 0) { -- gnutls_assert(); -- goto cleanup; -- } -+ _gnutls_x509_name_constraints_clear(nc); - -- ret = _gnutls_extract_name_constraints(c2, "excludedSubtrees", -- &nc->excluded); -+ ret = _gnutls_x509_name_constraints_extract( -+ c2, "permittedSubtrees", "excludedSubtrees", nc); - if (ret < 0) { - gnutls_assert(); - goto cleanup; -@@ -463,9 +444,10 @@ int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc, - int ret, result; - uint8_t null = 0; - asn1_node c2 = NULL; -- struct name_constraints_node_st *tmp; -+ unsigned rtype; -+ gnutls_datum_t rname; - -- if (nc->permitted == NULL && nc->excluded == NULL) -+ if (_gnutls_x509_name_constraints_is_empty(nc, 0)) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - result = asn1_create_element(_gnutls_get_pkix(), -@@ -475,11 +457,20 @@ int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc, - return _gnutls_asn2err(result); - } - -- if (nc->permitted == NULL) { -+ ret = gnutls_x509_name_constraints_get_permitted(nc, 0, &rtype, &rname); -+ if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - (void)asn1_write_value(c2, "permittedSubtrees", NULL, 0); - } else { -- tmp = nc->permitted; -- do { -+ for (unsigned i = 0;; i++) { -+ ret = gnutls_x509_name_constraints_get_permitted( -+ nc, i, &rtype, &rname); -+ if (ret < 0) { -+ if (ret == -+ GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) -+ break; -+ gnutls_assert(); -+ goto cleanup; -+ } - result = asn1_write_value(c2, "permittedSubtrees", - "NEW", 1); - if (result != ASN1_SUCCESS) { -@@ -506,21 +497,29 @@ int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc, - } - - ret = _gnutls_write_general_name( -- c2, "permittedSubtrees.?LAST.base", tmp->type, -- tmp->name.data, tmp->name.size); -+ c2, "permittedSubtrees.?LAST.base", rtype, -+ rname.data, rname.size); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } -- tmp = tmp->next; -- } while (tmp != NULL); -+ } - } - -- if (nc->excluded == NULL) { -+ ret = gnutls_x509_name_constraints_get_excluded(nc, 0, &rtype, &rname); -+ if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - (void)asn1_write_value(c2, "excludedSubtrees", NULL, 0); - } else { -- tmp = nc->excluded; -- do { -+ for (unsigned i = 0;; i++) { -+ ret = gnutls_x509_name_constraints_get_excluded( -+ nc, i, &rtype, &rname); -+ if (ret < 0) { -+ if (ret == -+ GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) -+ break; -+ gnutls_assert(); -+ goto cleanup; -+ } - result = asn1_write_value(c2, "excludedSubtrees", "NEW", - 1); - if (result != ASN1_SUCCESS) { -@@ -546,14 +545,13 @@ int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc, - } - - ret = _gnutls_write_general_name( -- c2, "excludedSubtrees.?LAST.base", tmp->type, -- tmp->name.data, tmp->name.size); -+ c2, "excludedSubtrees.?LAST.base", rtype, -+ rname.data, rname.size); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } -- tmp = tmp->next; -- } while (tmp != NULL); -+ } - } - - ret = _gnutls_x509_der_encode(c2, "", ext, 0); -diff --git a/lib/x509/x509_ext_int.h b/lib/x509/x509_ext_int.h -index 558d619565..b37d749976 100644 ---- a/lib/x509/x509_ext_int.h -+++ b/lib/x509/x509_ext_int.h -@@ -29,6 +29,11 @@ struct name_st { - gnutls_datum_t othername_oid; - }; - -+struct gnutls_subject_alt_names_st { -+ struct name_st *names; -+ unsigned int size; -+}; -+ - int _gnutls_alt_name_process(gnutls_datum_t *out, unsigned type, - const gnutls_datum_t *san, unsigned raw); - -diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h -index 693a4dd924..30f8051a70 100644 ---- a/lib/x509/x509_int.h -+++ b/lib/x509/x509_int.h -@@ -503,20 +503,13 @@ int _gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert, - int crl_list_length, - gnutls_verify_output_function func); - --typedef struct gnutls_name_constraints_st { -- struct name_constraints_node_st *permitted; -- struct name_constraints_node_st *excluded; --} gnutls_name_constraints_st; -- --typedef struct name_constraints_node_st { -- unsigned type; -- gnutls_datum_t name; -- struct name_constraints_node_st *next; --} name_constraints_node_st; -- --int _gnutls_extract_name_constraints(asn1_node c2, const char *vstr, -- name_constraints_node_st **_nc); --void _gnutls_name_constraints_node_free(name_constraints_node_st *node); -+bool _gnutls_x509_name_constraints_is_empty(gnutls_x509_name_constraints_t nc, -+ unsigned type); -+int _gnutls_x509_name_constraints_extract(asn1_node c2, -+ const char *permitted_name, -+ const char *excluded_name, -+ gnutls_x509_name_constraints_t nc); -+void _gnutls_x509_name_constraints_clear(gnutls_x509_name_constraints_t nc); - int _gnutls_x509_name_constraints_merge(gnutls_x509_name_constraints_t nc, - gnutls_x509_name_constraints_t nc2); - --- -GitLab - diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec index 81bb212..683145d 100644 --- a/SPECS/gnutls.spec +++ b/SPECS/gnutls.spec @@ -12,29 +12,35 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } -Version: 3.8.3 -Release: 9%{?dist} +Version: 3.8.10 +Release: 3%{?dist} # not upstreamed Patch: gnutls-3.2.7-rpath.patch Patch: gnutls-3.7.2-enable-intel-cet.patch Patch: gnutls-3.7.2-no-explicit-init.patch Patch: gnutls-3.7.3-disable-config-reload.patch -Patch: gnutls-3.7.3-fips-dsa-post.patch Patch: gnutls-3.7.6-drbg-reseed.patch -Patch: gnutls-3.7.6-fips-sha1-sigver.patch -Patch: gnutls-3.7.6-gmp-static.patch -Patch: gnutls-3.7.8-ktls_skip_tls12_chachapoly_test.patch # upstreamed -Patch: gnutls-3.8.3-ktls-utsname.patch -Patch: gnutls-3.8.3-deterministic-ecdsa-fixes.patch -Patch: gnutls-3.8.3-verify-chain.patch -Patch: gnutls-3.8.9-CVE-2024-12243.patch -Patch: gnutls-3.8.3-cve-2025-32988.patch -Patch: gnutls-3.8.3-cve-2025-32989.patch -Patch: gnutls-3.8.3-cve-2025-32990.patch -Patch: gnutls-3.8.3-cve-2025-6395.patch -Patch: gnutls-3.8.3-keyupdate.patch +# * 5376a0cabf@3.8.11: key_update: fix state transition in KTLS code path +# * 30c264b661@3.8.11: constate: switch epoch lookup to linear search +# * 1d830baac2@3.8.11: key_update: rework the rekeying logic +Patch: gnutls-3.8.10-keyupdate.patch +# * 0992505881@3.8.11: tests: distribute ktls_utils.h +Patch: gnutls-3.8.10-tests-ktls.patch + +# reverts +# * e52c7ca885 pkcs12: enable PBMAC1 by default in FIPS mode +Patch: gnutls-3.8.10-rhel9-revert-pbmac1-fips-default.patch +# * da1df0a31 fips: Allow SigVer only with RSA keys with modulus >= 2048 bits +Patch: gnutls-3.8.10-rhel9-revert-rsa-less-than-2048.patch + +# upstreamed: https://gitlab.com/gnutls/gnutls/-/merge_requests/2041 +Patch: gnutls-3.8.10-CVE-2025-9820.patch +# upstreamed: https://gitlab.com/gnutls/gnutls/-/merge_requests/2062 +Patch: gnutls-3.8.10-CVE-2025-14831.patch + +# intentionally omitted: CVE-2026-1584, since 3.8.10 is not vulnerable %bcond_without bootstrap %bcond_without dane @@ -48,7 +54,8 @@ Patch: gnutls-3.8.3-keyupdate.patch %bcond_with tpm12 %bcond_without tpm2 %bcond_with gost -%bcond_with certificate_compression +%bcond_without certificate_compression +%bcond_without leancrypto %bcond_without tests %bcond_without srp %bcond_without heartbeat @@ -63,10 +70,14 @@ BuildRequires: readline-devel, libtasn1-devel >= 4.3 BuildRequires: zlib-devel, brotli-devel, libzstd-devel %endif %if %{with bootstrap} -BuildRequires: automake, autoconf, gperf, libtool +BuildRequires: automake, autoconf271, gperf, libtool + %endif BuildRequires: texinfo BuildRequires: nettle-devel >= 3.10.1 +%if %{with leancrypto} +BuildRequires: meson +%endif %if %{with tpm12} BuildRequires: trousers-devel >= 0.3.11.2 %endif @@ -75,7 +86,7 @@ BuildRequires: tpm2-tss-devel >= 3.0.3 %endif BuildRequires: libidn2-devel BuildRequires: libunistring-devel -BuildRequires: net-tools, datefudge, softhsm, gcc, gcc-c++ +BuildRequires: net-tools, softhsm, gcc, gcc-c++ BuildRequires: gnupg2 BuildRequires: git-core @@ -95,7 +106,7 @@ BuildRequires: unbound-devel unbound-libs %if %{with guile} BuildRequires: guile22-devel %endif -BuildRequires: make +BuildRequires: make gtk-doc URL: http://www.gnutls.org/ Source0: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8/%{name}-%{version}.tar.xz Source1: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8/%{name}-%{version}.tar.xz.sig @@ -105,6 +116,10 @@ Source100: gmp-6.2.1.tar.xz # Taken from the main gmp package Source101: gmp-6.2.1-intel-cet.patch +%if %{with leancrypto} +Source200: leancrypto-1.5.0.tar.gz +%endif + # Wildcard bundling exception https://fedorahosted.org/fpc/ticket/174 Provides: bundled(gnulib) = 20130424 @@ -208,6 +223,13 @@ patch -p1 < %{SOURCE101} popd %endif +%if %{with leancrypto} +mkdir -p bundled_leancrypto +pushd bundled_leancrypto +tar --strip-components=1 -xf %{SOURCE200} +popd +%endif + %build %ifarch aarch64 ppc64le %define _lto_cflags %{nil} @@ -215,7 +237,7 @@ popd %if %{with fips} pushd bundled_gmp -autoreconf -ifv +/opt/rh/autoconf271/bin/autoreconf -ifv %configure --disable-cxx --disable-shared --enable-fat --with-pic %make_build popd @@ -224,8 +246,41 @@ export GMP_CFLAGS="-I$PWD/bundled_gmp" export GMP_LIBS="$PWD/bundled_gmp/.libs/libgmp.a" %endif +%if %{with leancrypto} +pushd bundled_leancrypto +%set_build_flags +meson setup -Dprefix="$PWD/install" -Dlibdir="$PWD/install/lib" \ + -Ddefault_library=static \ + -Dascon=disabled -Dascon_keccak=disabled \ + -Dbike_5=disabled -Dbike_3=disabled -Dbike_1=disabled \ + -Dkyber_x25519=disabled -Ddilithium_ed25519=disabled \ + -Dx509_parser=disabled -Dx509_generator=disabled \ + -Dpkcs7_parser=disabled -Dpkcs7_generator=disabled \ + -Dsha2-256=disabled \ + -Dchacha20=disabled -Dchacha20_drng=disabled \ + -Ddrbg_hash=disabled -Ddrbg_hmac=disabled \ + -Dhash_crypt=disabled \ + -Dhmac=disabled -Dhkdf=disabled \ + -Dkdf_ctr=disabled -Dkdf_fb=disabled -Dkdf_dpi=disabled \ + -Dpbkdf2=disabled \ + -Dkmac_drng=disabled -Dcshake_drng=disabled \ + -Dhotp=disabled -Dtotp=disabled \ + -Daes_block=disabled -Daes_cbc=disabled -Daes_ctr=disabled \ + -Daes_kw=disabled -Dapps=disabled \ + _build +meson compile -v -C _build +meson install -C _build + +popd + +export LEANCRYPTO_DIR="$PWD/bundled_leancrypto/install" + +export LEANCRYPTO_CFLAGS="-I$LEANCRYPTO_DIR/include" +export LEANCRYPTO_LIBS="$LEANCRYPTO_DIR/lib/libleancrypto.a" +%endif + %if %{with bootstrap} -autoreconf -fi +/opt/rh/autoconf271/bin/autoreconf -fi %endif sed -i -e 's|sys_lib_dlsearch_path_spec="/lib /usr/lib|sys_lib_dlsearch_path_spec="/lib /usr/lib %{_libdir}|g' configure @@ -248,13 +303,14 @@ export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name" %endif %configure \ + --enable-dsa \ %if %{with fips} --enable-fips140-mode \ --with-fips140-module-name="$FIPS_MODULE_NAME" \ --with-fips140-module-version=%{version}-%{srpmhash} \ %endif %if %{with gost} - --enable-gost \ + --enable-gost \ %else --disable-gost \ %endif @@ -299,13 +355,22 @@ export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name" --disable-libdane \ %endif %if %{with certificate_compression} - --with-zlib --with-brotli --with-zstd \ + --with-zlib=dlopen --with-brotli=dlopen --with-zstd=dlopen \ %else --without-zlib --without-brotli --without-zstd \ +%endif +%if %{with leancrypto} + --with-leancrypto \ +%else + --without-leancrypto \ %endif --disable-rpath \ --with-default-priority-string="@SYSTEM" +%if %{with leancrypto} +sed -i '/^Requires.private:/s/leancrypto[ ,]*//g' lib/gnutls.pc +%endif + # build libgnutlsxx.so with older SONAME make %{?_smp_mflags} V=1 CXX_LT_CURRENT=29 CXX_LT_REVISION=0 CXX_LT_AGE=1 @@ -376,7 +441,7 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null XFAIL_TESTS="$x %{_libdir}/.libgnutls.so.30*.hmac %endif %doc README.md AUTHORS NEWS THANKS -%license LICENSE doc/COPYING doc/COPYING.LESSER +%license COPYING COPYING.LESSERv2 %files c++ %{_libdir}/libgnutlsxx.so.* @@ -421,6 +486,18 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null XFAIL_TESTS="$x %endif %changelog +* Fri Feb 6 2026 Alexander Sosedkin - 3.8.10-3 +- Fix PKCS#11 token initialization label overflow (CVE-2025-9820) +- Fix name constraint processing performance issue (CVE-2025-14831) + +* Wed Jan 14 2026 Alexander Sosedkin - 3.8.10-2 +- Reinstate and update the prematurely dropped rekeying patch + +* Thu Nov 6 2025 Alexander Sosedkin - 3.8.10-1 +- Rebase to 3.8.10 +- Revert defaulting to PBMAC1 in FIPS mode +- Revert unapproving 1024-, 1280-, 1536- and 1792-bit RSA verification + * Tue Aug 5 2025 Daiki Ueno - 3.8.3-9 - key_update: rework the rekeying logic (RHEL-107499)