126 lines
3.5 KiB
Diff
126 lines
3.5 KiB
Diff
From 339bef12f478b3a12c59571c53645e31280baf7e Mon Sep 17 00:00:00 2001
|
|
From: Daiki Ueno <ueno@gnu.org>
|
|
Date: Fri, 14 May 2021 15:59:37 +0200
|
|
Subject: [PATCH] cert auth: filter out unsupported cert types from TLS 1.2 CR
|
|
|
|
When the server is advertising signature algorithms in TLS 1.2
|
|
CertificateRequest, it shouldn't send certificate_types not backed by
|
|
any of those algorithms.
|
|
|
|
Signed-off-by: Daiki Ueno <ueno@gnu.org>
|
|
---
|
|
lib/auth/cert.c | 76 +++++++++++++++++++++++--
|
|
tests/suite/tls-fuzzer/gnutls-cert.json | 19 +++++++
|
|
2 files changed, 89 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
|
|
index 3073a33d3..0b0f04b2b 100644
|
|
--- a/lib/auth/cert.c
|
|
+++ b/lib/auth/cert.c
|
|
@@ -64,6 +64,16 @@ typedef enum CertificateSigType { RSA_SIGN = 1, DSA_SIGN = 2, ECDSA_SIGN = 64,
|
|
#endif
|
|
} CertificateSigType;
|
|
|
|
+enum CertificateSigTypeFlags {
|
|
+ RSA_SIGN_FLAG = 1,
|
|
+ DSA_SIGN_FLAG = 1 << 1,
|
|
+ ECDSA_SIGN_FLAG = 1 << 2,
|
|
+#ifdef ENABLE_GOST
|
|
+ GOSTR34102012_256_SIGN_FLAG = 1 << 3,
|
|
+ GOSTR34102012_512_SIGN_FLAG = 1 << 4
|
|
+#endif
|
|
+};
|
|
+
|
|
/* Moves data from an internal certificate struct (gnutls_pcert_st) to
|
|
* another internal certificate struct (cert_auth_info_t), and deinitializes
|
|
* the former.
|
|
@@ -1281,6 +1291,7 @@ _gnutls_gen_cert_server_cert_req(gnutls_session_t session,
|
|
uint8_t tmp_data[CERTTYPE_SIZE];
|
|
const version_entry_st *ver = get_version(session);
|
|
unsigned init_pos = data->length;
|
|
+ enum CertificateSigTypeFlags flags;
|
|
|
|
if (unlikely(ver == NULL))
|
|
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
@@ -1297,18 +1308,71 @@ _gnutls_gen_cert_server_cert_req(gnutls_session_t session,
|
|
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
|
|
}
|
|
|
|
- i = 1;
|
|
+ if (_gnutls_version_has_selectable_sighash(ver)) {
|
|
+ size_t j;
|
|
+
|
|
+ flags = 0;
|
|
+ for (j = 0; j < session->internals.priorities->sigalg.size; j++) {
|
|
+ const gnutls_sign_entry_st *se =
|
|
+ session->internals.priorities->sigalg.entry[j];
|
|
+ switch (se->pk) {
|
|
+ case GNUTLS_PK_RSA:
|
|
+ case GNUTLS_PK_RSA_PSS:
|
|
+ flags |= RSA_SIGN_FLAG;
|
|
+ break;
|
|
+ case GNUTLS_PK_DSA:
|
|
+ flags |= DSA_SIGN_FLAG;
|
|
+ break;
|
|
+ case GNUTLS_PK_ECDSA:
|
|
+ flags |= ECDSA_SIGN_FLAG;
|
|
+ break;
|
|
#ifdef ENABLE_GOST
|
|
- if (_gnutls_kx_is_vko_gost(session->security_parameters.cs->kx_algorithm)) {
|
|
- tmp_data[i++] = GOSTR34102012_256_SIGN;
|
|
- tmp_data[i++] = GOSTR34102012_512_SIGN;
|
|
- } else
|
|
+ case GNUTLS_PK_GOST_12_256:
|
|
+ flags |= GOSTR34102012_256_SIGN_FLAG;
|
|
+ break;
|
|
+ case GNUTLS_PK_GOST_12_512:
|
|
+ flags |= GOSTR34102012_512_SIGN_FLAG;
|
|
+ break;
|
|
+#endif
|
|
+ default:
|
|
+ gnutls_assert();
|
|
+ _gnutls_debug_log(
|
|
+ "%s is unsupported for cert request\n",
|
|
+ gnutls_pk_get_name(se->pk));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+#ifdef ENABLE_GOST
|
|
+ if (_gnutls_kx_is_vko_gost(session->security_parameters.
|
|
+ cs->kx_algorithm)) {
|
|
+ flags = GOSTR34102012_256_SIGN_FLAG |
|
|
+ GOSTR34102012_512_SIGN_FLAG;
|
|
+ } else
|
|
#endif
|
|
- {
|
|
+ {
|
|
+ flags = RSA_SIGN_FLAG | DSA_SIGN_FLAG | ECDSA_SIGN_FLAG;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ i = 1;
|
|
+ if (flags & RSA_SIGN_FLAG) {
|
|
tmp_data[i++] = RSA_SIGN;
|
|
+ }
|
|
+ if (flags & DSA_SIGN_FLAG) {
|
|
tmp_data[i++] = DSA_SIGN;
|
|
+ }
|
|
+ if (flags & ECDSA_SIGN_FLAG) {
|
|
tmp_data[i++] = ECDSA_SIGN;
|
|
}
|
|
+#ifdef ENABLE_GOST
|
|
+ if (flags & GOSTR34102012_256_SIGN_FLAG) {
|
|
+ tmp_data[i++] = GOSTR34102012_256_SIGN;
|
|
+ }
|
|
+ if (flags & GOSTR34102012_512_SIGN_FLAG) {
|
|
+ tmp_data[i++] = GOSTR34102012_512_SIGN;
|
|
+ }
|
|
+#endif
|
|
tmp_data[0] = i - 1;
|
|
|
|
ret = _gnutls_buffer_append_data(data, tmp_data, i);
|
|
--
|
|
2.31.1
|
|
|