diff options
12 files changed, 1650 insertions, 31 deletions
diff --git a/debian/changelog b/debian/changelog index 34bc950..8c432bb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,33 @@ +gnutls28 (3.7.9-2+deb12u3) bookworm; urgency=medium + + * Update to 3.7.11: + + Replace 60-auth-rsa_psk-side-step-potential-side-channel.patch + 61-x509-detect-loop-in-certificate-chain.patch + 62-rsa-psk-minimize-branching-after-decryption.patch with versions from + gnutls_3_7_x branch instead of manual backports from 3.8.x. + + Add 53-fips-fix-checking-on-hash-algorithm-used-in-ECDSA.patch (Fix + checking on hash algorithm used in ECDSA in FIPS mode) and + 54-fips-mark-composite-signature-API-not-approved.patch (Mark composite + signature API non-approved in FIPS mode.) to allow + straight cherry-picking of later patches. + + 63_01-gnutls_x509_trust_list_verify_crt2-remove-length-lim.patch + libgnutls: Fixed a bug where certtool crashed when verifying a + certificate chain with more than 16 certificates. Reported by William + Woodruff (#1525) and yixiangzhike (#1527). [GNUTLS-SA-2024-01-23, CVSS: + medium] [CVE-2024-28835] Closes: #1067463 + + 63_02-nettle-avoid-normalization-of-mpz_t-in-deterministic.patch + libgnutls: Fix side-channel in the deterministic ECDSA. + Reported by George Pantelakis (#1516). [GNUTLS-SA-2023-12-04, CVSS: + medium] [CVE-2024-28834] Closes: #1067464 + + 63_03-serv-fix-memleak-when-a-connected-client-disappears.patch + Fix a memleak in gnutls-serv when a connected client disappears. + + 63_04-lib-fix-a-segfault-in-_gnutls13_recv_end_of_early_da.patch + Fix a segfault in _gnutls13_recv_end_of_early_data(). + + 63_05-lib-fix-a-potential-segfault-in-_gnutls13_recv_finis.patch + Fix a potential segfault in _gnutls13_recv_finished(). + + -- Andreas Metzler <ametzler@debian.org> Sat, 15 Jun 2024 13:22:35 +0200 + gnutls28 (3.7.9-2+deb12u2) bookworm; urgency=medium * Cherrypick two CVE fixes from 3.8.3: diff --git a/debian/patches/53-fips-fix-checking-on-hash-algorithm-used-in-ECDSA.patch b/debian/patches/53-fips-fix-checking-on-hash-algorithm-used-in-ECDSA.patch new file mode 100644 index 0000000..5e9080f --- /dev/null +++ b/debian/patches/53-fips-fix-checking-on-hash-algorithm-used-in-ECDSA.patch @@ -0,0 +1,306 @@ +From 48bb9d0cf5de06cfb483aea66ff5a2c7aa3eb46f Mon Sep 17 00:00:00 2001 +From: Daiki Ueno <ueno@gnu.org> +Date: Tue, 20 Sep 2022 16:06:13 +0900 +Subject: [PATCH 08/29] fips: fix checking on hash algorithm used in ECDSA + +Previously we checked against the "preferred" hash algorithm based on +the curve, instead of the one actually used. + +Signed-off-by: Daiki Ueno <ueno@gnu.org> +--- + lib/crypto-backend.h | 12 ++++--- + lib/nettle/pk.c | 33 ++++++++--------- + lib/pubkey.c | 5 ++- + tests/fips-test.c | 86 ++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 111 insertions(+), 25 deletions(-) + +--- a/lib/crypto-backend.h ++++ b/lib/crypto-backend.h +@@ -245,15 +245,17 @@ typedef enum { + GNUTLS_PK_FLAG_PROVABLE = 1, + GNUTLS_PK_FLAG_REPRODUCIBLE = 2, + GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH = 4 + } gnutls_pk_flag_t; + +-#define FIX_SIGN_PARAMS(params, flags, dig) do { \ +- if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \ +- (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \ +- (params).dsa_dig = (dig); \ +- } \ ++#define FIX_SIGN_PARAMS(params, flags, dig) do { \ ++ if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \ ++ (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \ ++ } \ ++ if ((params).pk == GNUTLS_PK_DSA || (params).pk == GNUTLS_PK_ECDSA) { \ ++ (params).dsa_dig = (dig); \ ++ } \ + } while (0) + + void gnutls_pk_params_release(gnutls_pk_params_st * p); + void gnutls_pk_params_clear(gnutls_pk_params_st * p); + void gnutls_pk_params_init(gnutls_pk_params_st * p); +--- a/lib/nettle/pk.c ++++ b/lib/nettle/pk.c +@@ -1102,29 +1102,29 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + dsa_signature_init(&sig); + + me = _gnutls_dsa_q_to_hash(pk_params, + &hash_len); + ++ if (hash_len > vdata->size) { ++ gnutls_assert(); ++ _gnutls_debug_log ++ ("Security level of algorithm requires hash %s(%d) or better\n", ++ _gnutls_mac_get_name(me), hash_len); ++ hash_len = vdata->size; ++ } ++ + /* Only SHA-2 is allowed in FIPS 140-3 */ +- switch (me->id) { ++ switch (DIG_TO_MAC(sign_params->dsa_dig)) { + case GNUTLS_MAC_SHA256: + case GNUTLS_MAC_SHA384: + case GNUTLS_MAC_SHA512: + case GNUTLS_MAC_SHA224: + break; + default: + not_approved = true; + } + +- if (hash_len > vdata->size) { +- gnutls_assert(); +- _gnutls_debug_log +- ("Security level of algorithm requires hash %s(%d) or better\n", +- _gnutls_mac_get_name(me), hash_len); +- hash_len = vdata->size; +- } +- + mpz_init(k); + if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST || + (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) { + ret = _gnutls_ecdsa_compute_k(k, + curve_id, +@@ -1543,11 +1543,10 @@ _wrap_nettle_pk_verify(gnutls_pk_algorit + { + struct ecc_point pub; + struct dsa_signature sig; + int curve_id = pk_params->curve; + const struct ecc_curve *curve; +- const mac_entry_st *me; + + curve = get_supported_nist_curve(curve_id); + if (curve == NULL) { + ret = gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); + goto cleanup; +@@ -1569,28 +1568,28 @@ _wrap_nettle_pk_verify(gnutls_pk_algorit + } + + memcpy(sig.r, tmp[0], SIZEOF_MPZT); + memcpy(sig.s, tmp[1], SIZEOF_MPZT); + +- me = _gnutls_dsa_q_to_hash(pk_params, &hash_len); ++ (void)_gnutls_dsa_q_to_hash(pk_params, &hash_len); ++ ++ if (hash_len > vdata->size) ++ hash_len = vdata->size; + + /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy + * mode */ +- switch (me->id) { ++ switch (DIG_TO_MAC(sign_params->dsa_dig)) { + case GNUTLS_MAC_SHA1: + case GNUTLS_MAC_SHA256: + case GNUTLS_MAC_SHA384: + case GNUTLS_MAC_SHA512: + case GNUTLS_MAC_SHA224: + break; + default: + not_approved = true; + } + +- if (hash_len > vdata->size) +- hash_len = vdata->size; +- + ret = + ecdsa_verify(&pub, hash_len, vdata->data, + &sig); + if (ret == 0) { + gnutls_assert(); +@@ -2388,12 +2387,14 @@ static int pct_test(gnutls_pk_algorithm_ + + memcpy(&spki, ¶ms->spki, sizeof(spki)); + + if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) { + unsigned hash_len; ++ const mac_entry_st *me; + +- _gnutls_dsa_q_to_hash(params, &hash_len); ++ me = _gnutls_dsa_q_to_hash(params, &hash_len); ++ spki.dsa_dig = MAC_TO_DIG(me->id); + gen_data = gnutls_malloc(hash_len); + gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len); + + ddata.data = (void*)gen_data; + ddata.size = hash_len; +--- a/lib/pubkey.c ++++ b/lib/pubkey.c +@@ -1983,11 +1983,11 @@ gnutls_pubkey_import_dsa_raw(gnutls_pubk + /* Updates the gnutls_x509_spki_st parameters based on the signature + * information, and reports any incompatibilities between the existing + * parameters (if any) with the signature algorithm */ + static + int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_entry_st *se, +- const mac_entry_st *me, gnutls_x509_spki_st *params) ++ const mac_entry_st *me, gnutls_x509_spki_st *params) + { + unsigned bits; + + if (se->pk != key_params->algo) { + if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) { +@@ -2016,10 +2016,13 @@ int fixup_spki_params(const gnutls_pk_pa + params->salt_size = ret; + } + + if (params->rsa_pss_dig != se->hash) + return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR); ++ } else if (params->pk == GNUTLS_PK_DSA || ++ params->pk == GNUTLS_PK_ECDSA) { ++ params->dsa_dig = se->hash; + } + + return 0; + } + +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -78,12 +78,26 @@ static const uint8_t rsa2342_sha1_sig_da + static const gnutls_datum_t rsa2342_sha1_sig = { + .data = (unsigned char *)rsa2342_sha1_sig_data, + .size = sizeof(rsa2342_sha1_sig_data), + }; + ++static const uint8_t ecc256_sha1_sig_data[] = { ++ 0x30, 0x45, 0x02, 0x21, 0x00, 0x9a, 0x28, 0xc9, 0xbf, 0xc8, 0x70, 0x4f, ++ 0x27, 0x2d, 0xe1, 0x66, 0xc4, 0xa5, 0xc6, 0xf2, 0xdc, 0x33, 0xb9, 0x41, ++ 0xdf, 0x78, 0x98, 0x8a, 0x22, 0x4d, 0x29, 0x37, 0xa0, 0x0f, 0x6f, 0xd4, ++ 0xed, 0x02, 0x20, 0x0b, 0x15, 0xca, 0x30, 0x09, 0x2d, 0x55, 0x44, 0xb4, ++ 0x1d, 0x3f, 0x48, 0x7a, 0xc3, 0xd1, 0x2a, 0xc1, 0x0e, 0x47, 0xfa, 0xe6, ++ 0xe9, 0x0f, 0x03, 0xe2, 0x01, 0x4e, 0xe4, 0x73, 0x37, 0xa7, 0x90, ++}; ++ ++static const gnutls_datum_t ecc256_sha1_sig = { ++ .data = (unsigned char *)ecc256_sha1_sig_data, ++ .size = sizeof(ecc256_sha1_sig_data), ++}; ++ + static void +-rsa_import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey, ++import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey, + const char *filename) + { + const char *srcdir; + char path[256]; + gnutls_datum_t tmp; +@@ -422,11 +436,11 @@ void doit(void) + gnutls_x509_privkey_deinit(xprivkey); + FIPS_POP_CONTEXT(ERROR); + + /* Import 2432-bit RSA key; not a security function */ + FIPS_PUSH_CONTEXT(); +- rsa_import_keypair(&privkey, &pubkey, "rsa-2432.pem"); ++ import_keypair(&privkey, &pubkey, "rsa-2432.pem"); + FIPS_POP_CONTEXT(INITIAL); + + /* Create a signature with 2432-bit RSA and SHA256; approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, +@@ -468,11 +482,11 @@ void doit(void) + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); + + /* Import 512-bit RSA key; not a security function */ + FIPS_PUSH_CONTEXT(); +- rsa_import_keypair(&privkey, &pubkey, "rsa-512.pem"); ++ import_keypair(&privkey, &pubkey, "rsa-512.pem"); + FIPS_POP_CONTEXT(INITIAL); + + /* Create a signature with 512-bit RSA and SHA256; not approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, +@@ -491,10 +505,76 @@ void doit(void) + } + FIPS_POP_CONTEXT(NOT_APPROVED); + gnutls_free(signature.data); + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); ++ ++ /* Import ECDSA key; not a security function */ ++ FIPS_PUSH_CONTEXT(); ++ import_keypair(&privkey, &pubkey, "ecc256.pem"); ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA256; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* Verify a signature with ECDSA and SHA256; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA256 (old API); approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA-1; not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* Verify a signature created with ECDSA and SHA-1; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1, ++ GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data, ++ &ecc256_sha1_sig); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA-1 (old API); not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ gnutls_pubkey_deinit(pubkey); ++ gnutls_privkey_deinit(privkey); + + /* Test RND functions */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16)); + if (ret < 0) { diff --git a/debian/patches/54-fips-mark-composite-signature-API-not-approved.patch b/debian/patches/54-fips-mark-composite-signature-API-not-approved.patch new file mode 100644 index 0000000..6091367 --- /dev/null +++ b/debian/patches/54-fips-mark-composite-signature-API-not-approved.patch @@ -0,0 +1,215 @@ +From 02faaf6f8b490fee465d07e020473386425ffdd2 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno <ueno@gnu.org> +Date: Thu, 29 Sep 2022 17:13:00 +0900 +Subject: [PATCH 09/29] fips: mark composite signature API not-approved + +This makes the FIPS service indicator to transit to not-approved when +gnutls_privkey_sign_hash* is used. In FIPS, single-shot +API (gnutls_privkey_sign_data*) is preferred over composite API. + +Signed-off-by: Daiki Ueno <ueno@gnu.org> +--- + lib/privkey.c | 42 ++++++++++++++++++++++--------- + tests/fips-test.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 94 insertions(+), 12 deletions(-) + +--- a/lib/privkey.c ++++ b/lib/privkey.c +@@ -1249,31 +1249,40 @@ gnutls_privkey_sign_hash2(gnutls_privkey + /* the corresponding signature algorithm is SIGN_RSA_RAW, + * irrespective of hash algorithm. */ + se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW); + } else { + se = _gnutls_sign_to_entry(algo); +- if (unlikely(se == NULL)) +- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +- ++ if (unlikely(se == NULL)) { ++ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ goto cleanup; ++ } + } + + ret = _gnutls_privkey_get_spki_params(signer, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash, + flags, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + FIX_SIGN_PARAMS(params, flags, se->hash); + +- return privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms); ++ ret = privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms); ++ ++ cleanup: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); ++ } ++ return ret; + } + + int + privkey_sign_and_hash_data(gnutls_privkey_t signer, + const gnutls_sign_entry_st *se, +@@ -1364,18 +1373,18 @@ gnutls_privkey_sign_hash(gnutls_privkey_ + const gnutls_sign_entry_st *se; + + ret = _gnutls_privkey_get_spki_params(signer, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm, + hash_algo, flags, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + /* legacy callers of this API could use a hash algorithm of 0 (unknown) + * to indicate raw hashing. As we now always want to know the signing + * algorithm involved, we try discovering the hash algorithm. */ +@@ -1389,17 +1398,26 @@ gnutls_privkey_sign_hash(gnutls_privkey_ + se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW); + } else { + se = _gnutls_pk_to_sign_entry(params.pk, hash_algo); + } + +- if (unlikely(se == NULL)) +- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ if (unlikely(se == NULL)) { ++ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ goto cleanup; ++ } + + FIX_SIGN_PARAMS(params, flags, hash_algo); + +- return privkey_sign_prehashed(signer, se, +- hash_data, signature, ¶ms); ++ ret = privkey_sign_prehashed(signer, se, ++ hash_data, signature, ¶ms); ++ cleanup: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); ++ } ++ return ret; + } + + static int + privkey_sign_prehashed(gnutls_privkey_t signer, + const gnutls_sign_entry_st *se, +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -286,10 +286,12 @@ void doit(void) + gnutls_datum_t key = { key16, sizeof(key16) }; + gnutls_datum_t iv = { iv16, sizeof(iv16) }; + gnutls_datum_t signature; + unsigned int bits; + uint8_t hmac[64]; ++ uint8_t hash[64]; ++ gnutls_datum_t hashed_data; + + fprintf(stderr, + "Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n"); + + gnutls_global_set_log_function(tls_log_func); +@@ -538,10 +540,40 @@ void doit(void) + &data, &signature); + if (ret < 0) { + fail("gnutls_privkey_sign_data failed\n"); + } + FIPS_POP_CONTEXT(APPROVED); ++ ++ /* Create a SHA256 hashed data for 2-pass signature API; not a ++ * crypto operation */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_hash_fast(GNUTLS_DIG_SHA256, data.data, data.size, hash); ++ if (ret < 0) { ++ fail("gnutls_hash_fast failed\n"); ++ } ++ hashed_data.data = hash; ++ hashed_data.size = 32; ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA256 (2-pass API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA256 (2-pass old API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA256, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); + gnutls_free(signature.data); + + /* Create a signature with ECDSA and SHA-1; not approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0, +@@ -569,10 +601,42 @@ void doit(void) + if (ret < 0) { + fail("gnutls_privkey_sign_data failed\n"); + } + FIPS_POP_CONTEXT(NOT_APPROVED); + gnutls_free(signature.data); ++ ++ /* Create a SHA1 hashed data for 2-pass signature API; not a ++ * crypto operation */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, data.data, data.size, hash); ++ if (ret < 0) { ++ fail("gnutls_hash_fast failed\n"); ++ } ++ hashed_data.data = hash; ++ hashed_data.size = 20; ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA1 (2-pass API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA1 (2-pass old API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); + + /* Test RND functions */ + FIPS_PUSH_CONTEXT(); diff --git a/debian/patches/60-auth-rsa_psk-side-step-potential-side-channel.patch b/debian/patches/60-auth-rsa_psk-side-step-potential-side-channel.patch index e85c16a..d87bb10 100644 --- a/debian/patches/60-auth-rsa_psk-side-step-potential-side-channel.patch +++ b/debian/patches/60-auth-rsa_psk-side-step-potential-side-channel.patch @@ -1,7 +1,7 @@ -From 29d6298d0b04cfff970b993915db71ba3f580b6d Mon Sep 17 00:00:00 2001 +From c176c35e17d0add934785cb8db1a6c2d14ae9659 Mon Sep 17 00:00:00 2001 From: Daiki Ueno <ueno@gnu.org> Date: Mon, 23 Oct 2023 09:26:57 +0900 -Subject: [PATCH] auth/rsa_psk: side-step potential side-channel +Subject: [PATCH 11/29] auth/rsa_psk: side-step potential side-channel This removes branching that depends on secret data, porting changes for regular RSA key exchange from @@ -13,10 +13,10 @@ depending on the branching. Signed-off-by: Daiki Ueno <ueno@gnu.org> --- lib/auth/rsa.c | 2 +- - lib/auth/rsa_psk.c | 90 ++++++++++++++++++---------------------------- - lib/gnutls_int.h | 4 --- + lib/auth/rsa_psk.c | 93 +++++++++++++++++----------------------------- + lib/gnutls_int.h | 4 -- lib/priority.c | 1 - - 4 files changed, 35 insertions(+), 62 deletions(-) + 4 files changed, 35 insertions(+), 65 deletions(-) --- a/lib/auth/rsa.c +++ b/lib/auth/rsa.c @@ -55,7 +55,7 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> _gnutls_get_cred(session, GNUTLS_CRD_PSK); if (cred == NULL) { -@@ -327,75 +326,53 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se +@@ -327,75 +326,51 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } @@ -101,6 +101,10 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> + premaster_secret.data = gnutls_malloc(GNUTLS_MASTER_SIZE); + if (premaster_secret.data == NULL) { ++ gnutls_assert(); ++ return GNUTLS_E_MEMORY_ERROR; ++ } ++ premaster_secret.size = GNUTLS_MASTER_SIZE; - if (randomize_key != 0) { - premaster_secret.size = GNUTLS_MASTER_SIZE; @@ -122,19 +126,14 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> - } else { - premaster_secret.data = plaintext.data; - premaster_secret.size = plaintext.size; -+ gnutls_assert(); -+ return GNUTLS_E_MEMORY_ERROR; - } -+ premaster_secret.size = GNUTLS_MASTER_SIZE; -+ + /* Fallback value when decryption fails. Needs to be unpredictable. */ + ret = gnutls_rnd(GNUTLS_RND_NONCE, premaster_secret.data, + premaster_secret.size); + if (ret < 0) { + gnutls_assert(); + goto cleanup; -+ } -+ + } + + gnutls_privkey_decrypt_data2(session->internals.selected_key, 0, + &ciphertext, premaster_secret.data, + premaster_secret.size); @@ -152,11 +151,11 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> + * in the paper "Attacking RSA-based sessions in SSL/TLS" by + * Vlastimil Klima, Ondej Pokorny and Tomas Rosa. + */ - ++ /* This is here to avoid the version check attack * discussed above. */ - +- - premaster_secret.data[0] = _gnutls_get_adv_version_major(session); - premaster_secret.data[1] = _gnutls_get_adv_version_minor(session); + premaster_secret.data[0] = ver_maj; diff --git a/debian/patches/61-x509-detect-loop-in-certificate-chain.patch b/debian/patches/61-x509-detect-loop-in-certificate-chain.patch index 8464ca4..9959931 100644 --- a/debian/patches/61-x509-detect-loop-in-certificate-chain.patch +++ b/debian/patches/61-x509-detect-loop-in-certificate-chain.patch @@ -1,7 +1,7 @@ -From 9edbdaa84e38b1bfb53a7d72c1de44f8de373405 Mon Sep 17 00:00:00 2001 +From 2774bd6db7968d62297c97d36e28d8d9cb508cb9 Mon Sep 17 00:00:00 2001 From: Daiki Ueno <ueno@gnu.org> Date: Thu, 11 Jan 2024 15:45:11 +0900 -Subject: [PATCH 1/2] x509: detect loop in certificate chain +Subject: [PATCH 12/29] x509: detect loop in certificate chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -17,8 +17,8 @@ manner. Signed-off-by: Daiki Ueno <ueno@gnu.org> --- lib/x509/common.c | 4 ++ - tests/test-chains.h | 125 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 129 insertions(+) + tests/test-chains.h | 124 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 128 insertions(+) --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -173,14 +173,13 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> # pragma GCC diagnostic ignored "-Wunused-variable" #endif -@@ -4440,10 +4563,12 @@ static struct +@@ -4440,10 +4563,11 @@ static struct 0, NULL, 1620052390, 1}, { "rsa-sha1 not in trusted - not ok", rsa_sha1_not_in_trusted, rsa_sha1_not_in_trusted_ca, GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM), GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1620118136, 1}, -+ { "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0, -+ 1704955300 }, ++ { "cross signed - ok", cross_signed, cross_signed_ca, 0, 0, 0, 1704955300 }, { NULL, NULL, NULL, 0, 0} }; diff --git a/debian/patches/62-rsa-psk-minimize-branching-after-decryption.patch b/debian/patches/62-rsa-psk-minimize-branching-after-decryption.patch index 47de317..b0ba2ce 100644 --- a/debian/patches/62-rsa-psk-minimize-branching-after-decryption.patch +++ b/debian/patches/62-rsa-psk-minimize-branching-after-decryption.patch @@ -1,7 +1,7 @@ -From 40dbbd8de499668590e8af51a15799fbc430595e Mon Sep 17 00:00:00 2001 +From f0aa7285c3ef702d4e5c13e54d6fe741e44244c3 Mon Sep 17 00:00:00 2001 From: Daiki Ueno <ueno@gnu.org> Date: Wed, 10 Jan 2024 19:13:17 +0900 -Subject: [PATCH 2/2] rsa-psk: minimize branching after decryption +Subject: [PATCH 13/29] rsa-psk: minimize branching after decryption This moves any non-trivial code between gnutls_privkey_decrypt_data2 and the function return in _gnutls_proc_rsa_psk_client_kx up until the @@ -9,8 +9,8 @@ decryption. This also avoids an extra memcpy to session->key.key. Signed-off-by: Daiki Ueno <ueno@gnu.org> --- - lib/auth/rsa_psk.c | 69 ++++++++++++++++++++++++---------------------- - 1 file changed, 36 insertions(+), 33 deletions(-) + lib/auth/rsa_psk.c | 68 ++++++++++++++++++++++++---------------------- + 1 file changed, 35 insertions(+), 33 deletions(-) --- a/lib/auth/rsa_psk.c +++ b/lib/auth/rsa_psk.c @@ -26,7 +26,7 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> cred = (gnutls_psk_server_credentials_t) _gnutls_get_cred(session, GNUTLS_CRD_PSK); -@@ -329,29 +328,52 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se +@@ -329,28 +328,52 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se ciphertext.size = dsize; ver_maj = _gnutls_get_adv_version_major(session); @@ -34,6 +34,7 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> - premaster_secret.data = gnutls_malloc(GNUTLS_MASTER_SIZE); - if (premaster_secret.data == NULL) { +- gnutls_assert(); + /* Find the key of this username. A random value will be + * filled in if the key is not found. + */ @@ -41,8 +42,7 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> + strlen(info->username), &pwd_psk); + if (ret < 0) + return gnutls_assert_val(ret); - -- gnutls_assert(); ++ + /* Allocate memory for premaster secret, and fill in the + * fields except the decryption result. + */ @@ -88,12 +88,12 @@ Signed-off-by: Daiki Ueno <ueno@gnu.org> * channel that can be used as an oracle, so tread carefully */ /* Error handling logic: -@@ -367,35 +389,14 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se +@@ -365,35 +388,14 @@ _gnutls_proc_rsa_psk_client_kx(gnutls_se + */ /* This is here to avoid the version check attack * discussed above. */ - - premaster_secret.data[0] = ver_maj; - premaster_secret.data[1] = ver_min; - diff --git a/debian/patches/63_01-gnutls_x509_trust_list_verify_crt2-remove-length-lim.patch b/debian/patches/63_01-gnutls_x509_trust_list_verify_crt2-remove-length-lim.patch new file mode 100644 index 0000000..e211d66 --- /dev/null +++ b/debian/patches/63_01-gnutls_x509_trust_list_verify_crt2-remove-length-lim.patch @@ -0,0 +1,467 @@ +From af594c776a8502dab04e61e97228efdcff32bf19 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno <ueno@gnu.org> +Date: Mon, 29 Jan 2024 13:52:46 +0900 +Subject: [PATCH 1/5] 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 <ueno@gnu.org> +--- + lib/gnutls_int.h | 5 +- + lib/x509/common.c | 10 +- + lib/x509/verify-high.c | 73 ++++++++------ + tests/test-chains.h | 212 ++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 268 insertions(+), 32 deletions(-) + +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -222,11 +222,14 @@ typedef enum record_send_state_t { + processes before aborting. */ + #define MAX_HANDSHAKE_HELLO_VERIFY_REQUESTS 5 + + #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) + #define MAX_VERIFY_DEPTH 4096 + +--- a/lib/x509/common.c ++++ b/lib/x509/common.c +@@ -1753,11 +1753,19 @@ unsigned int _gnutls_sort_clist(gnutls_x + unsigned int i, j, k; + int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */ + 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; + insorted[i] = 0; + } +--- a/lib/x509/verify-high.c ++++ b/lib/x509/verify-high.c +@@ -22,15 +22,15 @@ + */ + + #include "gnutls_int.h" + #include "errors.h" + #include <libtasn1.h> +-#include <global.h> +-#include <num.h> /* MAX */ +-#include <tls-sig.h> +-#include <str.h> +-#include <datum.h> ++#include "global.h" ++#include "num.h" /* MIN */ ++#include "tls-sig.h" ++#include "str.h" ++#include "datum.h" + #include <hash-pjw-bare.h> + #include "x509_int.h" + #include <common.h> + #include <gnutls/x509-ext.h> + #include "verify-high.h" +@@ -1355,11 +1355,12 @@ gnutls_x509_trust_list_verify_crt2(gnutl + gnutls_verify_output_function func) + { + 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; + unsigned hostname_size = 0; + unsigned have_set_name = 0; +@@ -1409,30 +1410,44 @@ gnutls_x509_trust_list_verify_crt2(gnutl + *voutput = vtmp; + return 0; + } + } + +- 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); + +- records = gl_list_nx_create_empty(GL_LINKEDHASH_LIST, cert_eq, cert_hashcode, NULL, false); +- if (records == NULL) ++ 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); + +- for (i = 0; i < cert_list_size && +- cert_list_size <= DEFAULT_MAX_VERIFY_DEPTH; ) { ++ 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) { ++ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ++ goto cleanup; ++ } ++ ++ for (i = 0; i < cert_list_size;) { + unsigned int sorted_size = 1; + unsigned int j; + gnutls_x509_crt_t issuer; + + if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN)) { + sorted_size = _gnutls_sort_clist(&cert_list[i], + cert_list_size - i); + } + +- /* Remove duplicates. Start with index 1, as the first element +- * may be re-checked after issuer retrieval. */ ++ assert(sorted_size > 0); ++ ++ /* 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) { + memmove(&cert_list[i + j], + &cert_list[i + j + 1], +@@ -1472,23 +1487,22 @@ gnutls_x509_trust_list_verify_crt2(gnutl + gnutls_x509_crt_check_issuer(cert_list[i - 1], + cert_list[i])) { + continue; + } + +- ret = retrieve_issuers(list, +- cert_list[i - 1], +- &retrieved[retrieved_size], +- DEFAULT_MAX_VERIFY_DEPTH - +- MAX(retrieved_size, +- cert_list_size)); ++ ret = retrieve_issuers( ++ list, cert_list[i - 1], &retrieved[retrieved_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); +- memmove(&cert_list[i + ret], +- &cert_list[i], ++ 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)); + memcpy(&cert_list[i], + &retrieved[retrieved_size], + ret * sizeof(gnutls_x509_crt_t)); +@@ -1500,12 +1514,14 @@ gnutls_x509_trust_list_verify_crt2(gnutl + gl_list_remove(records, cert_list[i]); + } + } + + 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 - +@@ -1651,15 +1667,18 @@ gnutls_x509_trust_list_verify_crt2(gnutl + ret = 0; + goto cleanup; + } + } + +- cleanup: ++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; + } + + /** + * gnutls_x509_trust_list_verify_named_crt: +--- a/tests/test-chains.h ++++ b/tests/test-chains.h +@@ -21,13 +21,11 @@ + */ + + #ifndef GNUTLS_TESTS_TEST_CHAINS_H + #define GNUTLS_TESTS_TEST_CHAINS_H + +-/* *INDENT-OFF* */ +- +-#define MAX_CHAIN 10 ++#define MAX_CHAIN 17 + + static const char *chain_with_no_subject_id_in_ca_ok[] = { + "-----BEGIN CERTIFICATE-----\n" + "MIIFVDCCBDygAwIBAgIQR+AAAAAAXtwVoBdbGUjUQDANBgkqhkiG9w0BAQsFADBv\n" + "MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRowGAYDVQQLExFTZWN1\n" +@@ -4384,10 +4382,217 @@ static const char *cross_signed_ca[] = { + "bDeZ2XJH+BdVFwg=\n" + "-----END CERTIFICATE-----\n", + 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" + #endif + +@@ -4564,10 +4769,11 @@ static struct + { "rsa-sha1 not in trusted - not ok", + rsa_sha1_not_in_trusted, rsa_sha1_not_in_trusted_ca, + GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM), + GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 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} + }; + + #if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + # pragma GCC diagnostic pop diff --git a/debian/patches/63_02-nettle-avoid-normalization-of-mpz_t-in-deterministic.patch b/debian/patches/63_02-nettle-avoid-normalization-of-mpz_t-in-deterministic.patch new file mode 100644 index 0000000..71a751d --- /dev/null +++ b/debian/patches/63_02-nettle-avoid-normalization-of-mpz_t-in-deterministic.patch @@ -0,0 +1,493 @@ +From 6f6c8db008e943967a5d0f706e2884c23baa0aa7 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno <ueno@gnu.org> +Date: Fri, 12 Jan 2024 17:56:58 +0900 +Subject: [PATCH 2/5] 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 <ueno@gnu.org> +--- + lib/nettle/int/dsa-compute-k.c | 84 +++++++++++++++++++------------ + lib/nettle/int/dsa-compute-k.h | 31 +++++++++--- + lib/nettle/int/ecdsa-compute-k.c | 33 +++--------- + lib/nettle/int/ecdsa-compute-k.h | 8 +-- + lib/nettle/pk.c | 79 ++++++++++++++++++++--------- + tests/sign-verify-deterministic.c | 2 +- + 6 files changed, 139 insertions(+), 98 deletions(-) + +--- a/lib/nettle/int/dsa-compute-k.c ++++ b/lib/nettle/int/dsa-compute-k.c +@@ -29,53 +29,58 @@ + #include "gnutls_int.h" + #include "mem.h" + #include "mpn-base256.h" + #include <string.h> + +-#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 ++ ++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; ++ ++ for (i = 0, w = 0; i < n; i++) ++ w |= ap[i]; + +-/* 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) +- +-int +-_gnutls_dsa_compute_k(mpz_t k, +- const mpz_t q, +- const mpz_t x, +- gnutls_mac_algorithm_t mac, +- const uint8_t *digest, +- size_t length) ++ 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) + { + uint8_t V[MAX_HASH_SIZE]; + 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; + const uint8_t c0 = 0x00; + const uint8_t c1 = 0x01; + 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); + if (unlikely(length > MAX_HASH_SIZE)) + 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); + + if (hn < qn) +@@ -95,16 +100,16 @@ _gnutls_dsa_compute_k(mpz_t k, + + if (shift % GMP_NUMB_BITS > 0) + 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); + + /* Step b */ + memset(V, c1, length); +@@ -176,16 +181,12 @@ _gnutls_dsa_compute_k(mpz_t k, + /* Step 3 */ + mpn_set_base256 (h, qn, tp, tlen); + 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) + goto out; + ret = gnutls_hmac(hd, V, length); +@@ -205,5 +206,26 @@ _gnutls_dsa_compute_k(mpz_t k, + zeroize_key(xp, sizeof(xp)); + zeroize_key(tp, sizeof(tp)); + + 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); ++} +--- a/lib/nettle/int/dsa-compute-k.h ++++ b/lib/nettle/int/dsa-compute-k.h +@@ -24,14 +24,31 @@ + #define GNUTLS_LIB_NETTLE_INT_DSA_COMPUTE_K_H + + #include <gnutls/gnutls.h> + #include <nettle/bignum.h> /* includes gmp.h */ + +-int +-_gnutls_dsa_compute_k(mpz_t k, +- const mpz_t q, +- const mpz_t x, +- gnutls_mac_algorithm_t mac, +- const uint8_t *digest, +- size_t length); ++#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 */ +--- a/lib/nettle/int/ecdsa-compute-k.c ++++ b/lib/nettle/int/ecdsa-compute-k.c +@@ -27,43 +27,42 @@ + #include "ecdsa-compute-k.h" + + #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" + "5D03BB5C9B8899C47AEBB6FB71E91386" + "409", +@@ -71,25 +70,5 @@ _gnutls_ecc_curve_to_dsa_q(mpz_t *q, gnu + return 0; + default: + return gnutls_assert_val(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; +-} +--- a/lib/nettle/int/ecdsa-compute-k.h ++++ b/lib/nettle/int/ecdsa-compute-k.h +@@ -24,14 +24,8 @@ + #define GNUTLS_LIB_NETTLE_INT_ECDSA_COMPUTE_K_H + + #include <gnutls/gnutls.h> + #include <nettle/bignum.h> /* 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 */ +--- a/lib/nettle/pk.c ++++ b/lib/nettle/pk.c +@@ -95,14 +95,20 @@ static void rnd_nonce_func(void *_ctx, s + if (gnutls_rnd(GNUTLS_RND_NONCE, data, length) < 0) { + _gnutls_switch_lib_state(LIB_STATE_ERROR); + } + } + +-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) + { + if (unlikely(_gnutls_get_lib_state() != LIB_STATE_SELFTEST)) { +@@ -1074,11 +1080,14 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + { + struct ecc_scalar priv; + 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; + + curve = get_supported_nist_curve(curve_id); + if (curve == NULL) { +@@ -1121,23 +1130,36 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + break; + default: + 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], +- DIG_TO_MAC(sign_params->dsa_dig), +- vdata->data, +- vdata->size); ++ 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; + } + ecdsa_sign(&priv, random_ctx, random_func, hash_len, +@@ -1154,11 +1176,11 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + &sig.s); + + ecdsa_cleanup: + dsa_signature_clear(&sig); + ecc_scalar_zclear(&priv); +- mpz_clear(k); ++ mpz_clear(q); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } +@@ -1167,11 +1189,13 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + case GNUTLS_PK_DSA: + { + 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; + + /* DSA is currently being defined as sunset with the + * current draft of FIPS 186-5 */ +@@ -1194,25 +1218,31 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + ("Security level of algorithm requires hash %s(%d) or better (have: %d)\n", + _gnutls_mac_get_name(me), hash_len, (int)vdata->size); + hash_len = vdata->size; + } + +- mpz_init(k); + if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST || + (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) { +- ret = _gnutls_dsa_compute_k(k, +- pub.q, +- TOMPZ(priv), +- DIG_TO_MAC(sign_params->dsa_dig), +- vdata->data, +- vdata->size); ++ mp_limb_t h[DSA_COMPUTE_K_ITCH]; ++ ++ ret = _gnutls_dsa_compute_k( ++ 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; + } + ret = +@@ -1228,11 +1258,10 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm + _gnutls_encode_ber_rs(signature, &sig.r, + &sig.s); + + dsa_fail: + dsa_signature_clear(&sig); +- mpz_clear(k); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } +--- a/tests/sign-verify-deterministic.c ++++ b/tests/sign-verify-deterministic.c +@@ -195,11 +195,11 @@ void doit(void) + ret = + gnutls_pubkey_verify_data2(pubkey, tests[i].sigalgo, 0, &tests[i].msg, + &signature); + if (ret < 0) + testfail("gnutls_pubkey_verify_data2\n"); +- success(" - pass"); ++ success(" - pass\n"); + + next: + gnutls_free(signature.data); + gnutls_privkey_deinit(privkey); + gnutls_pubkey_deinit(pubkey); diff --git a/debian/patches/63_03-serv-fix-memleak-when-a-connected-client-disappears.patch b/debian/patches/63_03-serv-fix-memleak-when-a-connected-client-disappears.patch new file mode 100644 index 0000000..b54a9d8 --- /dev/null +++ b/debian/patches/63_03-serv-fix-memleak-when-a-connected-client-disappears.patch @@ -0,0 +1,26 @@ +From 88e9d7f27fa23dead8b0da21f5461a9810d48286 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno <ueno@gnu.org> +Date: Sat, 27 Jan 2024 11:09:18 +0900 +Subject: [PATCH 3/5] serv: fix memleak when a connected client disappears + +Reported by Hubert Kario. + +Signed-off-by: Daiki Ueno <ueno@gnu.org> +--- + src/serv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/serv.c ++++ b/src/serv.c +@@ -183,10 +183,11 @@ static void listener_free(const void *el + gnutls_bye(j->tls_session, GNUTLS_SHUT_WR); + shutdown(j->fd, 2); + close(j->fd); + gnutls_deinit(j->tls_session); + } ++ free(j); + } + + + /* we use primes up to 1024 in this server. + * otherwise we should add them here. diff --git a/debian/patches/63_04-lib-fix-a-segfault-in-_gnutls13_recv_end_of_early_da.patch b/debian/patches/63_04-lib-fix-a-segfault-in-_gnutls13_recv_end_of_early_da.patch new file mode 100644 index 0000000..7a51305 --- /dev/null +++ b/debian/patches/63_04-lib-fix-a-segfault-in-_gnutls13_recv_end_of_early_da.patch @@ -0,0 +1,40 @@ +From 8b648e99d2d16f228a63b4075c487c9f3ec26927 Mon Sep 17 00:00:00 2001 +From: Xin Long <lucien.xin@gmail.com> +Date: Thu, 1 Feb 2024 16:50:22 -0500 +Subject: [PATCH 4/5] lib: fix a segfault in _gnutls13_recv_end_of_early_data + +A crash occur in my app that uses gnutls13 early data, stack trace: + + #0 free (libc.so.6 + 0x97bf0) + #1 _gnutls_buffer_clear (libgnutls.so.30 + 0x77c8c) + #2 _gnutls13_recv_end_of_early_data (libgnutls.so.30 + 0xaf308) + #3 _gnutls13_handshake_server (libgnutls.so.30 + 0x42d6c) + #4 handshake_server (libgnutls.so.30 + 0x4ff6c) + +The root cause is that _gnutls_buffer_clear() was trying to free +'buf' that is not initialized or set if GNUTLS_NO_END_OF_EARLY_DATA +flag is set on server side. + +This patch fixes it by simply initializing buf at the begginning of +_gnutls13_recv_end_of_early_data(). + +Signed-off-by: Xin Long <lucien.xin@gmail.com> +--- + lib/tls13/early_data.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/lib/tls13/early_data.c ++++ b/lib/tls13/early_data.c +@@ -79,10 +79,12 @@ int _gnutls13_send_end_of_early_data(gnu + int _gnutls13_recv_end_of_early_data(gnutls_session_t session) + { + int ret; + gnutls_buffer_st buf; + ++ _gnutls_buffer_init(&buf); ++ + if (!(session->security_parameters.entity == GNUTLS_SERVER && + session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED)) + return 0; + + if (!(session->internals.flags & GNUTLS_NO_END_OF_EARLY_DATA)) { diff --git a/debian/patches/63_05-lib-fix-a-potential-segfault-in-_gnutls13_recv_finis.patch b/debian/patches/63_05-lib-fix-a-potential-segfault-in-_gnutls13_recv_finis.patch new file mode 100644 index 0000000..c23dbb2 --- /dev/null +++ b/debian/patches/63_05-lib-fix-a-potential-segfault-in-_gnutls13_recv_finis.patch @@ -0,0 +1,37 @@ +From 263917ec9fe00e9767487636593921444fb0b0af Mon Sep 17 00:00:00 2001 +From: Xin Long <lucien.xin@gmail.com> +Date: Thu, 1 Feb 2024 17:21:05 -0500 +Subject: [PATCH 5/5] lib: fix a potential segfault in _gnutls13_recv_finished + +In _gnutls13_recv_finished(), 'buf' is not initialized or set when +_gnutls13_compute_finished() returns an err, and goto cleanup may +cause a segfault crash as it frees the uninitialized buf.allocd in +_gnutls_buffer_clear(). + +So fix it by return if _gnutls13_compute_finished() returns an err +in _gnutls13_recv_finished(). + +Signed-off-by: Xin Long <lucien.xin@gmail.com> +--- + lib/tls13/finished.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/lib/tls13/finished.c ++++ b/lib/tls13/finished.c +@@ -89,14 +89,12 @@ int _gnutls13_recv_finished(gnutls_sessi + + ret = _gnutls13_compute_finished(session->security_parameters.prf, + base_key, + &session->internals.handshake_hash_buffer, + verifier); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } ++ if (ret < 0) ++ return gnutls_assert_val(ret); + + ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_FINISHED, 0, &buf); + if (ret < 0) + return gnutls_assert_val(ret); + diff --git a/debian/patches/series b/debian/patches/series index 7e7162f..ed4b28c 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,6 +3,13 @@ 40_srptest_doubletimeout.diff 50_Fix-removal-of-duplicate-certs-during-verification.patch 51_add-gnulib-linkedhash-list-module.diff +53-fips-fix-checking-on-hash-algorithm-used-in-ECDSA.patch +54-fips-mark-composite-signature-API-not-approved.patch 60-auth-rsa_psk-side-step-potential-side-channel.patch 61-x509-detect-loop-in-certificate-chain.patch 62-rsa-psk-minimize-branching-after-decryption.patch +63_01-gnutls_x509_trust_list_verify_crt2-remove-length-lim.patch +63_02-nettle-avoid-normalization-of-mpz_t-in-deterministic.patch +63_03-serv-fix-memleak-when-a-connected-client-disappears.patch +63_04-lib-fix-a-segfault-in-_gnutls13_recv_end_of_early_da.patch +63_05-lib-fix-a-potential-segfault-in-_gnutls13_recv_finis.patch |