summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-05-14 15:59:37 +0200
committerDaiki Ueno <ueno@gnu.org>2021-05-17 16:32:07 +0200
commit4162be982093fefaf18c9237b0d53ecfd2a7de58 (patch)
treec1406bd1fad6009e45d5642471dee5de39474f75
parente899e3200ffb3d7d8958cfa7685052a66ebfbf80 (diff)
downloadgnutls-4162be982093fefaf18c9237b0d53ecfd2a7de58.tar.gz
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>
-rw-r--r--lib/auth/cert.c76
-rw-r--r--tests/suite/tls-fuzzer/gnutls-cert.json19
2 files changed, 89 insertions, 6 deletions
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index 3073a33d34..0b0f04b2b1 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);
diff --git a/tests/suite/tls-fuzzer/gnutls-cert.json b/tests/suite/tls-fuzzer/gnutls-cert.json
index 6f5874c095..e49cb432ff 100644
--- a/tests/suite/tls-fuzzer/gnutls-cert.json
+++ b/tests/suite/tls-fuzzer/gnutls-cert.json
@@ -96,5 +96,24 @@
"-p", "@PORT@"]
}
]
+ },
+ {"server_command": ["@SERVER@", "--http",
+ "--x509keyfile", "tests/serverX509Key.pem",
+ "--x509certfile", "tests/serverX509Cert.pem",
+ "--debug=6",
+ "--priority=NORMAL:+VERS-TLS1.2",
+ "--port=@PORT@"],
+ "environment": {"PYTHONPATH" : "."},
+ "server_hostname": "localhost",
+ "server_port": @PORT@,
+ "tests" : [
+ {"name" : "test-certificate-request.py",
+ "arguments" : ["-k", "tests/clientX509Key.pem",
+ "-c", "tests/clientX509Cert.pem",
+ "-p", "@PORT@",
+ "-s", "sha256+rsa rsa_pss_pss_sha256 rsa_pss_rsae_sha256 sha256+ecdsa rsa_pss_rsae_sha256 sha384+rsa rsa_pss_pss_sha384 rsa_pss_rsae_sha384 sha384+ecdsa ed448 sha512+rsa rsa_pss_pss_sha512 rsa_pss_rsae_sha512 sha512+ecdsa sha1+rsa sha1+ecdsa",
+ "check cert types in cert request"]
+ }
+ ]
}
]