From a4a128bd2fa66067170a06b3c83e64c024493641 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Fri, 15 Jan 2021 14:45:34 +0100 Subject: [PATCH] tls-server: Optionally omit CAs in CertificateRequest messages Usually, the DNs of all loaded CA certificates are included in the CertificateRequest messages sent by the server. Alas, certain EAP-TLS clients fail to process this message if the list is too long, returning the fatal TLS alert 'illegal parameter'. This new option allows configuring whether CAs are included or an empty list is sent (TLS 1.2), or the certificate_authorities extension is omitted (TLS 1.3). The list only serves as hint/constraint for clients during certificate selection, they still have to provide a certificate but are free to select any one they have available. Closes strongswan/strongswan#187. --- conf/options/charon.opt | 6 ++++++ src/libtls/tls_server.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/conf/options/charon.opt b/conf/options/charon.opt index fb69bd7a0..dd972649b 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -473,6 +473,12 @@ charon.tls.mac charon.tls.suites List of TLS cipher suites. +charon.tls.send_certreq_authorities = yes + Whether to include CAs in a server's CertificateRequest message. + + Whether to include CAs in a server's CertificateRequest message. May be + disabled if clients can't handle a long list of CAs. + charon.tls.version_min = 1.0 Minimum TLS version to negotiate. diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index 50051c143..eb3edf81f 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -163,6 +163,11 @@ struct private_tls_server_t { * Did we receive the curves from the client? */ bool curves_received; + + /** + * Whether to include CAs in CertificateRequest messages + */ + bool send_certreq_authorities; }; /** @@ -1372,7 +1377,14 @@ static status_t send_certificate_request(private_tls_server_t *this, this->crypto->get_signature_algorithms(this->crypto, writer, TRUE); } - write_certificate_authorities(writer); + if (this->send_certreq_authorities) + { + write_certificate_authorities(writer); + } + else + { + writer->write_data16(writer, chunk_empty); + } } else { @@ -1380,13 +1392,17 @@ static status_t send_certificate_request(private_tls_server_t *this, writer->write_uint8(writer, 0); extensions = bio_writer_create(32); - DBG2(DBG_TLS, "sending extension: %N", - tls_extension_names, TLS_EXT_CERTIFICATE_AUTHORITIES); - authorities = bio_writer_create(64); - write_certificate_authorities(authorities); - extensions->write_uint16(extensions, TLS_EXT_CERTIFICATE_AUTHORITIES); - extensions->write_data16(extensions, authorities->get_buf(authorities)); - authorities->destroy(authorities); + + if (this->send_certreq_authorities) + { + DBG2(DBG_TLS, "sending extension: %N", + tls_extension_names, TLS_EXT_CERTIFICATE_AUTHORITIES); + authorities = bio_writer_create(64); + write_certificate_authorities(authorities); + extensions->write_uint16(extensions, TLS_EXT_CERTIFICATE_AUTHORITIES); + extensions->write_data16(extensions, authorities->get_buf(authorities)); + authorities->destroy(authorities); + } DBG2(DBG_TLS, "sending extension: %N", tls_extension_names, TLS_EXT_SIGNATURE_ALGORITHMS); @@ -1808,6 +1824,9 @@ tls_server_t *tls_server_create(tls_t *tls, .state = STATE_INIT, .peer_auth = auth_cfg_create(), .server_auth = auth_cfg_create(), + .send_certreq_authorities = lib->settings->get_bool(lib->settings, + "%s.tls.send_certreq_authorities", + TRUE, lib->ns), ); return &this->public;