Compare commits
No commits in common. "c9" and "c10s" have entirely different histories.
1
.fmf/version
Normal file
1
.fmf/version
Normal file
@ -0,0 +1 @@
|
||||
1
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
||||
SOURCES/ktls-utils-0.11.tar.gz
|
||||
/ktls-utils-0.10.tar.gz
|
||||
/ktls-utils-0.11.tar.gz
|
||||
/ktls-utils-1.2.1.tar.gz
|
||||
|
||||
@ -1 +0,0 @@
|
||||
9dae5134b7af7ebb14e518f9f4013a92bb44165e SOURCES/ktls-utils-0.11.tar.gz
|
||||
14
changelog
Normal file
14
changelog
Normal file
@ -0,0 +1,14 @@
|
||||
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.10-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0.10-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Sat Oct 07 2023 Steve Dickson <steved@redhat.com> - 0.10-1
|
||||
- Updated to the latest upstream release: 0.10
|
||||
|
||||
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.9^20230627.g52ac9ff05a5e-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
|
||||
|
||||
* Tue Jun 27 2023 Jeff Layton <jlayton@kernel.org> - 0.9^20230627.g52ac9ff05a5e-1
|
||||
- Initial import (fedora#2182151)
|
||||
6
gating.yaml
Normal file
6
gating.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-10
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
@ -0,0 +1,44 @@
|
||||
From b52ca7c0a9c167340950a10d8dc56be1b95f5c40 Mon Sep 17 00:00:00 2001
|
||||
From: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Tue, 23 Sep 2025 19:30:16 -0400
|
||||
Subject: [PATCH] tlshd: Clean up logic in tlshd_start_tls_handshake()
|
||||
|
||||
gnutls_handshake() is supposed to return only a GNUTLS_E value, and
|
||||
the session_status field is supposed to contain only a positive
|
||||
errno.
|
||||
|
||||
GNUTLS_E_PREMATURE_TERMINATION is -110. It turns out that on x86,
|
||||
-ETIMEDOUT is also -110. Make sure the correct symbolic constants
|
||||
and auditing functions are utilized.
|
||||
|
||||
Fixes: b010190cfed2 ("tlshd: Pass ETIMEDOUT from gnutls to kernel")
|
||||
Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
---
|
||||
src/tlshd/handshake.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/tlshd/handshake.c b/src/tlshd/handshake.c
|
||||
index 5a28939..f688932 100644
|
||||
--- a/src/tlshd/handshake.c
|
||||
+++ b/src/tlshd/handshake.c
|
||||
@@ -97,12 +97,12 @@ void tlshd_start_tls_handshake(gnutls_session_t session,
|
||||
case GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR:
|
||||
tlshd_log_cert_verification_error(session);
|
||||
break;
|
||||
- case -ETIMEDOUT:
|
||||
- tlshd_log_gnutls_error(ret);
|
||||
- parms->session_status = -ret;
|
||||
+ case GNUTLS_E_PREMATURE_TERMINATION:
|
||||
+ tlshd_log_error("Handshake timeout, retrying");
|
||||
+ parms->session_status = ETIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
- tlshd_log_notice("tlshd_start_tls_handshake unhandled error %d, returning EACCES\n", ret);
|
||||
+ tlshd_log_gnutls_error(ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
From facd084e43fc493ae8fbaca00cb65925ae30d0e9 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Mayhew <smayhew@redhat.com>
|
||||
Date: Wed, 10 Sep 2025 21:00:09 -0400
|
||||
Subject: [PATCH 4/4] tlshd: Client-side dual certificate support
|
||||
|
||||
Add two new config options "x509.pq.certificate" and
|
||||
"x509.pq.private_key", this time to the "[authenticate.client]" stanza
|
||||
of tlshd.conf. This is for client-side handling of the server's
|
||||
certificate request when the client is mounting with "xprtsec=mtls".
|
||||
|
||||
This commit also makes sure the client-side x509.pq.certificate is using
|
||||
a post-quantum public-key algorithm, and we make sure that the server
|
||||
supports that algorithm before returning that cert in the cert callback
|
||||
(unlike the server-side cert callback, the pk_algos list is populated,
|
||||
so this check is more straightforward than on the server-side).
|
||||
|
||||
Link: https://github.com/oracle/ktls-utils/issues/113
|
||||
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
||||
---
|
||||
src/tlshd/client.c | 45 ++++++++++++++++++++++++++++++++++++--------
|
||||
src/tlshd/tlshd.conf | 2 ++
|
||||
2 files changed, 39 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/tlshd/client.c b/src/tlshd/client.c
|
||||
index 257e835..ad9a793 100644
|
||||
--- a/src/tlshd/client.c
|
||||
+++ b/src/tlshd/client.c
|
||||
@@ -134,17 +134,21 @@ out_free_creds:
|
||||
gnutls_certificate_free_credentials(xcred);
|
||||
}
|
||||
|
||||
+static gnutls_privkey_t tlshd_pq_privkey;
|
||||
static gnutls_privkey_t tlshd_privkey;
|
||||
+static unsigned int tlshd_pq_certs_len = TLSHD_MAX_CERTS;
|
||||
static unsigned int tlshd_certs_len = TLSHD_MAX_CERTS;
|
||||
static gnutls_pcert_st tlshd_certs[TLSHD_MAX_CERTS];
|
||||
+static gnutls_pk_algorithm_t tlshd_pq_pkalg = GNUTLS_PK_UNKNOWN;
|
||||
|
||||
static bool tlshd_x509_client_get_certs(struct tlshd_handshake_parms *parms)
|
||||
{
|
||||
if (parms->x509_cert != TLS_NO_CERT)
|
||||
return tlshd_keyring_get_certs(parms->x509_cert, tlshd_certs,
|
||||
&tlshd_certs_len);
|
||||
- return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs, NULL,
|
||||
- &tlshd_certs_len, NULL);
|
||||
+ return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs,
|
||||
+ &tlshd_pq_certs_len, &tlshd_certs_len,
|
||||
+ &tlshd_pq_pkalg);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_certs(void)
|
||||
@@ -160,12 +164,14 @@ static bool tlshd_x509_client_get_privkey(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_privkey != TLS_NO_PRIVKEY)
|
||||
return tlshd_keyring_get_privkey(parms->x509_privkey,
|
||||
&tlshd_privkey);
|
||||
- return tlshd_config_get_privkey(PEER_TYPE_CLIENT, NULL, &tlshd_privkey);
|
||||
+ return tlshd_config_get_privkey(PEER_TYPE_CLIENT, &tlshd_pq_privkey,
|
||||
+ &tlshd_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_privkey(void)
|
||||
{
|
||||
gnutls_privkey_deinit(tlshd_privkey);
|
||||
+ gnutls_privkey_deinit(tlshd_pq_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
|
||||
@@ -206,13 +212,15 @@ static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
|
||||
static int
|
||||
tlshd_x509_retrieve_key_cb(gnutls_session_t session,
|
||||
const gnutls_datum_t *req_ca_rdn, int nreqs,
|
||||
- __attribute__ ((unused)) const gnutls_pk_algorithm_t *pk_algos,
|
||||
- __attribute__ ((unused)) int pk_algos_length,
|
||||
+ const gnutls_pk_algorithm_t *pk_algos,
|
||||
+ int pk_algos_length,
|
||||
gnutls_pcert_st **pcert,
|
||||
unsigned int *pcert_length,
|
||||
gnutls_privkey_t *privkey)
|
||||
{
|
||||
gnutls_certificate_type_t type;
|
||||
+ bool use_pq_cert = false;
|
||||
+ int i;
|
||||
|
||||
tlshd_x509_log_issuers(req_ca_rdn, nreqs);
|
||||
|
||||
@@ -220,9 +228,30 @@ tlshd_x509_retrieve_key_cb(gnutls_session_t session,
|
||||
if (type != GNUTLS_CRT_X509)
|
||||
return -1;
|
||||
|
||||
- *pcert_length = tlshd_certs_len;
|
||||
- *pcert = tlshd_certs;
|
||||
- *privkey = tlshd_privkey;
|
||||
+ if (tlshd_pq_pkalg != GNUTLS_PK_UNKNOWN) {
|
||||
+ for (i = 0; i < pk_algos_length; i++) {
|
||||
+ if (pk_algos[i] == tlshd_pq_pkalg) {
|
||||
+ use_pq_cert = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (use_pq_cert == true) {
|
||||
+ tlshd_log_debug("%s: Server supports %s", __func__,
|
||||
+ gnutls_pk_algorithm_get_name(pk_algos[i]));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (use_pq_cert == true) {
|
||||
+ tlshd_log_debug("%s: Selecting x509.pq.certificate from conf file", __func__);
|
||||
+ *pcert_length = tlshd_pq_certs_len;
|
||||
+ *pcert = tlshd_certs;
|
||||
+ *privkey = tlshd_pq_privkey;
|
||||
+ } else {
|
||||
+ tlshd_log_debug("%s: Selecting x509.certificate from conf file", __func__);
|
||||
+ *pcert_length = tlshd_certs_len;
|
||||
+ *pcert = tlshd_certs + tlshd_pq_certs_len;
|
||||
+ *privkey = tlshd_privkey;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/tlshd/tlshd.conf b/src/tlshd/tlshd.conf
|
||||
index 5419146..1d4220e 100644
|
||||
--- a/src/tlshd/tlshd.conf
|
||||
+++ b/src/tlshd/tlshd.conf
|
||||
@@ -33,6 +33,8 @@ nl=0
|
||||
#x509.crl= <pathname>
|
||||
#x509.certificate= <pathname>
|
||||
#x509.private_key= <pathname>
|
||||
+#x509.pq.certificate= <pathname>
|
||||
+#x509.pq.private_key= <pathname>
|
||||
|
||||
[authenticate.server]
|
||||
#x509.truststore= <pathname>
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 9253f9df5ff986bddba38b8146ba6e650e7ebdd9 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Mayhew <smayhew@redhat.com>
|
||||
Date: Wed, 10 Sep 2025 17:02:16 -0400
|
||||
Subject: [PATCH 2/4] tlshd: Fix priority string to allow PQC
|
||||
|
||||
Specifying either of the SECURE256 or SECURE128 keywords in the priority
|
||||
string results in the ML-DSA algorithms being disabled because the
|
||||
post-quantum algorithms do not map nicely to the security
|
||||
classifications based on "bits of security" used for traditional
|
||||
algorithms [1].
|
||||
|
||||
Use @SYSTEM instead, which will allow PQC on systems with newer versions
|
||||
of GnuTLS. It will also allow users to disable PQC via a policy module
|
||||
(on systems with the crypto-policies package).
|
||||
|
||||
[1] https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents/call-for-proposals-final-dec-2016.pdf#page=15
|
||||
|
||||
Link: https://github.com/oracle/ktls-utils/issues/113
|
||||
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
||||
---
|
||||
src/tlshd/ktls.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tlshd/ktls.c b/src/tlshd/ktls.c
|
||||
index 883256a..50381bf 100644
|
||||
--- a/src/tlshd/ktls.c
|
||||
+++ b/src/tlshd/ktls.c
|
||||
@@ -357,7 +357,7 @@ static int tlshd_gnutls_priority_init_list(const unsigned int *ciphers,
|
||||
const char *errpos;
|
||||
int ret, i;
|
||||
|
||||
- pstring = strdup("SECURE256:+SECURE128:-COMP-ALL");
|
||||
+ pstring = strdup("@SYSTEM:-COMP-ALL");
|
||||
if (!pstring)
|
||||
return -ENOMEM;
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 9e79a86b85748ba4888da49652986b09beac2459 Mon Sep 17 00:00:00 2001
|
||||
From: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Thu, 5 Feb 2026 14:40:28 -0500
|
||||
Subject: [PATCH] tlshd: Fix session leak on error paths in x509 server
|
||||
handshake
|
||||
|
||||
Conflicts: src/tlshd/server.c - context difference in
|
||||
tlshd_tls13_server_x509_handshake() because RHEL10 doesn't have
|
||||
f11519a ("tlshd: Match ingress certificates with defined TLS session
|
||||
tags")
|
||||
|
||||
After gnutls_init() succeeds, the error paths for gnutls_credentials_set()
|
||||
and tlshd_gnutls_priority_set() failures jump to out_free_certs without
|
||||
calling gnutls_deinit(session), leaking the session object.
|
||||
|
||||
Introduce an out_deinit_session label so all post-init error paths
|
||||
properly release the session before cleaning up certificates and
|
||||
credentials.
|
||||
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
---
|
||||
src/tlshd/server.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/tlshd/server.c b/src/tlshd/server.c
|
||||
index 4850210..3bfcca3 100644
|
||||
--- a/src/tlshd/server.c
|
||||
+++ b/src/tlshd/server.c
|
||||
@@ -424,7 +424,7 @@ static void tlshd_tls13_server_x509_handshake(struct tlshd_handshake_parms *parm
|
||||
ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
tlshd_log_gnutls_error(ret);
|
||||
- goto out_free_certs;
|
||||
+ goto out_deinit_session;
|
||||
}
|
||||
gnutls_certificate_set_verify_function(xcred,
|
||||
tlshd_tls13_server_x509_verify_function);
|
||||
@@ -433,7 +433,7 @@ static void tlshd_tls13_server_x509_handshake(struct tlshd_handshake_parms *parm
|
||||
ret = tlshd_gnutls_priority_set(session, parms, 0);
|
||||
if (ret) {
|
||||
tlshd_log_gnutls_error(ret);
|
||||
- goto out_free_certs;
|
||||
+ goto out_deinit_session;
|
||||
}
|
||||
|
||||
tlshd_start_tls_handshake(session, parms);
|
||||
@@ -373,6 +373,7 @@ static void tlshd_tls13_server_x509_hand
|
||||
}
|
||||
}
|
||||
|
||||
+out_deinit_session:
|
||||
gnutls_deinit(session);
|
||||
|
||||
out_free_certs:
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,185 @@
|
||||
From a58a3600f35c16e435cdda476fe7ca0554a0a466 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Mayhew <smayhew@redhat.com>
|
||||
Date: Thu, 5 Feb 2026 12:28:43 -0500
|
||||
Subject: [PATCH] tlshd: Send fatal alert to client when there are server
|
||||
config issues
|
||||
|
||||
Conflicts: src/tlshd/log.c - context difference because RHEL10 doesn't
|
||||
have ff28f1f ("tlshd: Translate kernel-style Doxygen comments in
|
||||
src/tlshd/log.c")
|
||||
|
||||
Currently if a client attempts an x.509 handshake and the server is
|
||||
misconfigured (no certificates, no private keys, etc), the server simply
|
||||
closes the connection. Prior to b010190 ("tlshd: Pass ETIMEDOUT from
|
||||
gnutls to kernel"), this would result in a quick failure on the client.
|
||||
Now the client keeps retrying until the mount program times out, which
|
||||
takes several minutes.
|
||||
|
||||
A misconfigured server isn't a self-correcting problem, so send a fatal
|
||||
alert to the client when this occurs so the client stops retrying
|
||||
immediately. This requires some minor refactoring of
|
||||
tlshd_tls13_server_x509_handshake() so that the session is initialized
|
||||
before attempting to load the certs and keys (otherwise it is not
|
||||
possible to send an alert). Also log an error message to help the
|
||||
admin take corrective action.
|
||||
|
||||
Finally add some logging when an alert is received during the handshake.
|
||||
Following suit with handshake completions, alerts will only be logged if
|
||||
debug logging is enabled.
|
||||
|
||||
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
---
|
||||
src/tlshd/handshake.c | 4 ++++
|
||||
src/tlshd/log.c | 15 ++++++++++++
|
||||
src/tlshd/server.c | 55 ++++++++++++++++++++++++-------------------
|
||||
src/tlshd/tlshd.h | 1 +
|
||||
4 files changed, 51 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/tlshd/handshake.c b/src/tlshd/handshake.c
|
||||
index e78f78f..511a369 100644
|
||||
--- a/src/tlshd/handshake.c
|
||||
+++ b/src/tlshd/handshake.c
|
||||
@@ -115,6 +115,10 @@ void tlshd_start_tls_handshake(gnutls_session_t session,
|
||||
tlshd_log_error("Handshake timeout, retrying");
|
||||
parms->session_status = ETIMEDOUT;
|
||||
break;
|
||||
+ case GNUTLS_E_WARNING_ALERT_RECEIVED:
|
||||
+ case GNUTLS_E_FATAL_ALERT_RECEIVED:
|
||||
+ tlshd_log_alert(session);
|
||||
+ break;
|
||||
default:
|
||||
tlshd_log_gnutls_error(ret);
|
||||
}
|
||||
diff --git a/src/tlshd/log.c b/src/tlshd/log.c
|
||||
index b70d4af..a890b60 100644
|
||||
--- a/src/tlshd/log.c
|
||||
+++ b/src/tlshd/log.c
|
||||
@@ -178,6 +178,21 @@ void tlshd_log_cert_verification_error(g
|
||||
}
|
||||
|
||||
/**
|
||||
+ * @brief Report a TLS alert
|
||||
+ * @param[in] session Controlling GnuTLS session
|
||||
+ */
|
||||
+void tlshd_log_alert(gnutls_session_t session)
|
||||
+{
|
||||
+ gnutls_alert_description_t alert;
|
||||
+
|
||||
+ if (!tlshd_debug)
|
||||
+ return;
|
||||
+
|
||||
+ alert = gnutls_alert_get(session);
|
||||
+ tlshd_log_notice("Received alert: %s", gnutls_alert_get_name(alert));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* tlshd_log_gnutls_error - Emit "library call failed" notification
|
||||
* @error: GnuTLS error code to log
|
||||
*
|
||||
diff --git a/src/tlshd/server.c b/src/tlshd/server.c
|
||||
index 3bfcca3..8e0f192 100644
|
||||
--- a/src/tlshd/server.c
|
||||
+++ b/src/tlshd/server.c
|
||||
@@ -397,29 +397,46 @@ static void tlshd_tls13_server_x509_handshake(struct tlshd_handshake_parms *parm
|
||||
gnutls_session_t session;
|
||||
int ret;
|
||||
|
||||
- ret = gnutls_certificate_allocate_credentials(&xcred);
|
||||
+ ret = gnutls_init(&session, GNUTLS_SERVER);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
tlshd_log_gnutls_error(ret);
|
||||
return;
|
||||
}
|
||||
- ret = tlshd_server_get_truststore(xcred);
|
||||
- if (ret != GNUTLS_E_SUCCESS)
|
||||
- goto out_free_creds;
|
||||
+ gnutls_transport_set_int(session, parms->sockfd);
|
||||
+ gnutls_session_set_ptr(session, parms);
|
||||
|
||||
- if (!tlshd_x509_server_get_certs(parms))
|
||||
- goto out_free_creds;
|
||||
- if (!tlshd_x509_server_get_privkey(parms))
|
||||
- goto out_free_certs;
|
||||
- gnutls_certificate_set_retrieve_function2(xcred,
|
||||
- tlshd_x509_retrieve_key_cb);
|
||||
+ ret = tlshd_gnutls_priority_set(session, parms, 0);
|
||||
+ if (ret) {
|
||||
+ tlshd_log_gnutls_error(ret);
|
||||
+ gnutls_deinit(session);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- ret = gnutls_init(&session, GNUTLS_SERVER);
|
||||
+ ret = gnutls_certificate_allocate_credentials(&xcred);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
tlshd_log_gnutls_error(ret);
|
||||
- goto out_free_certs;
|
||||
+ gnutls_deinit(session);
|
||||
+ return;
|
||||
}
|
||||
- gnutls_transport_set_int(session, parms->sockfd);
|
||||
- gnutls_session_set_ptr(session, parms);
|
||||
+ ret = tlshd_server_get_truststore(xcred);
|
||||
+ if (ret != GNUTLS_E_SUCCESS) {
|
||||
+ tlshd_log_error("Failed to initialize server trust store - check the configuration");
|
||||
+ gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_ACCESS_DENIED);
|
||||
+ goto out_deinit_session;
|
||||
+ }
|
||||
+
|
||||
+ if (!tlshd_x509_server_get_certs(parms)) {
|
||||
+ tlshd_log_error("No usable server certificates were found - check the configuration");
|
||||
+ gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_ACCESS_DENIED);
|
||||
+ goto out_deinit_session;
|
||||
+ }
|
||||
+ if (!tlshd_x509_server_get_privkey(parms)) {
|
||||
+ tlshd_log_error("No usable private keys were found - check the configuration");
|
||||
+ gnutls_alert_send(session, GNUTLS_AL_FATAL, GNUTLS_A_ACCESS_DENIED);
|
||||
+ goto out_deinit_session;
|
||||
+ }
|
||||
+ gnutls_certificate_set_retrieve_function2(xcred,
|
||||
+ tlshd_x509_retrieve_key_cb);
|
||||
|
||||
ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
@@ -430,12 +447,6 @@ static void tlshd_tls13_server_x509_handshake(struct tlshd_handshake_parms *parm
|
||||
tlshd_tls13_server_x509_verify_function);
|
||||
gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUEST);
|
||||
|
||||
- ret = tlshd_gnutls_priority_set(session, parms, 0);
|
||||
- if (ret) {
|
||||
- tlshd_log_gnutls_error(ret);
|
||||
- goto out_deinit_session;
|
||||
- }
|
||||
-
|
||||
tlshd_start_tls_handshake(session, parms);
|
||||
|
||||
if (tlshd_debug &&
|
||||
@@ -464,12 +475,8 @@ static void tlshd_tls13_server_x509_handshake(struct tlshd_handshake_parms *parm
|
||||
|
||||
out_deinit_session:
|
||||
gnutls_deinit(session);
|
||||
-
|
||||
-out_free_certs:
|
||||
tlshd_x509_server_put_privkey();
|
||||
tlshd_x509_server_put_certs();
|
||||
-
|
||||
-out_free_creds:
|
||||
gnutls_certificate_free_credentials(xcred);
|
||||
}
|
||||
|
||||
diff --git a/src/tlshd/tlshd.h b/src/tlshd/tlshd.h
|
||||
index 75d9a4a..d00cfdf 100644
|
||||
--- a/src/tlshd/tlshd.h
|
||||
+++ b/src/tlshd/tlshd.h
|
||||
@@ -118,6 +118,7 @@ extern void tlshd_log_perror(const char *prefix);
|
||||
extern void tlshd_log_gai_error(int error);
|
||||
|
||||
extern void tlshd_log_cert_verification_error(gnutls_session_t session);
|
||||
+extern void tlshd_log_alert(gnutls_session_t session);
|
||||
extern void tlshd_log_gnutls_error(int error);
|
||||
extern void tlshd_gnutls_log_func(int level, const char *msg);
|
||||
extern void tlshd_gnutls_audit_func(gnutls_session_t session, const char *msg);
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -0,0 +1,445 @@
|
||||
From 14f53496509eea9cbe14eb244161b0e26699d165 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Mayhew <smayhew@redhat.com>
|
||||
Date: Wed, 10 Sep 2025 20:45:41 -0400
|
||||
Subject: [PATCH 3/4] tlshd: Server-side dual certificate support
|
||||
|
||||
Add two new config options, "x509.pq.certificate" and
|
||||
"x509.pq.private_key" to configure tlshd to use an ML-DSA certificate.
|
||||
If the cert callback determines that the client supports ML-DSA, it will
|
||||
select this certificate. Otherwise, it will fall back to the
|
||||
traditional certficate (i.e. the certificate configured via
|
||||
"x509.certificate" and "x509.private_key").
|
||||
|
||||
Note that we check to ensure that the PQ certificate is using a
|
||||
post-quantum public-key algorithm (ML-DSA-44, ML-DSA-65, or ML-DSA-87),
|
||||
and we store the algorithm value so we can later compare it to the list
|
||||
of signing algorithms supported by the client in the cert callback.
|
||||
|
||||
Link: https://github.com/oracle/ktls-utils/issues/113
|
||||
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
||||
---
|
||||
configure.ac | 12 ++++
|
||||
src/tlshd/client.c | 6 +-
|
||||
src/tlshd/config.c | 132 ++++++++++++++++++++++++++++++++++++---
|
||||
src/tlshd/server.c | 65 ++++++++++++++++++-
|
||||
src/tlshd/tlshd.conf | 2 +
|
||||
src/tlshd/tlshd.conf.man | 15 +++++
|
||||
src/tlshd/tlshd.h | 7 ++-
|
||||
7 files changed, 225 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index a6d9d09..0dd23f2 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -79,6 +79,18 @@ AC_CHECK_LIB([gnutls], [gnutls_get_system_config_file],
|
||||
AC_CHECK_LIB([gnutls], [gnutls_psk_allocate_client_credentials2],
|
||||
[AC_DEFINE([HAVE_GNUTLS_PSK_ALLOCATE_CREDENTIALS2], [1],
|
||||
[Define to 1 if you have the gnutls_psk_allocate_client_credentials2 function.])])
|
||||
+
|
||||
+AC_MSG_CHECKING(for ML-DSA support in gnutls)
|
||||
+AC_COMPILE_IFELSE(
|
||||
+ [AC_LANG_PROGRAM([[ #include <gnutls/gnutls.h> ]],
|
||||
+ [[ (void) GNUTLS_SIGN_MLDSA65; ]])],
|
||||
+ [ have_mldsa=yes ],
|
||||
+ [ have_mldsa=no ])
|
||||
+AC_MSG_RESULT([$have_mldsa])
|
||||
+if test "x$have_mldsa" = xyes ; then
|
||||
+ AC_DEFINE([HAVE_GNUTLS_MLDSA], [1], [Define to 1 if gnutls supports ML-DSA])
|
||||
+fi
|
||||
+
|
||||
AC_SUBST([AM_CPPFLAGS])
|
||||
|
||||
AC_CONFIG_FILES([Makefile src/Makefile src/tlshd/Makefile systemd/Makefile])
|
||||
diff --git a/src/tlshd/client.c b/src/tlshd/client.c
|
||||
index c07ae29..257e835 100644
|
||||
--- a/src/tlshd/client.c
|
||||
+++ b/src/tlshd/client.c
|
||||
@@ -143,8 +143,8 @@ static bool tlshd_x509_client_get_certs(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_cert != TLS_NO_CERT)
|
||||
return tlshd_keyring_get_certs(parms->x509_cert, tlshd_certs,
|
||||
&tlshd_certs_len);
|
||||
- return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs,
|
||||
- &tlshd_certs_len);
|
||||
+ return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs, NULL,
|
||||
+ &tlshd_certs_len, NULL);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_certs(void)
|
||||
@@ -160,7 +160,7 @@ static bool tlshd_x509_client_get_privkey(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_privkey != TLS_NO_PRIVKEY)
|
||||
return tlshd_keyring_get_privkey(parms->x509_privkey,
|
||||
&tlshd_privkey);
|
||||
- return tlshd_config_get_privkey(PEER_TYPE_CLIENT, &tlshd_privkey);
|
||||
+ return tlshd_config_get_privkey(PEER_TYPE_CLIENT, NULL, &tlshd_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_privkey(void)
|
||||
diff --git a/src/tlshd/config.c b/src/tlshd/config.c
|
||||
index ff1f2a5..9a3b6b2 100644
|
||||
--- a/src/tlshd/config.c
|
||||
+++ b/src/tlshd/config.c
|
||||
@@ -260,18 +260,66 @@ bool tlshd_config_get_crl(int peer_type, char **result)
|
||||
return true;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_GNUTLS_MLDSA
|
||||
+static bool tlshd_cert_check_pk_alg(gnutls_datum_t *data,
|
||||
+ gnutls_pk_algorithm_t *pkalg)
|
||||
+{
|
||||
+ gnutls_x509_crt_t cert;
|
||||
+ gnutls_pk_algorithm_t pk_alg;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = gnutls_x509_crt_init(&cert);
|
||||
+ if (ret < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ ret = gnutls_x509_crt_import(cert, data, GNUTLS_X509_FMT_PEM);
|
||||
+ if (ret < 0) {
|
||||
+ gnutls_x509_crt_deinit(cert);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ pk_alg = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
|
||||
+ tlshd_log_debug("%s: certificate pk algorithm %s", __func__,
|
||||
+ gnutls_pk_algorithm_get_name(pk_alg));
|
||||
+ switch (pk_alg) {
|
||||
+ case GNUTLS_PK_MLDSA44:
|
||||
+ case GNUTLS_PK_MLDSA65:
|
||||
+ case GNUTLS_PK_MLDSA87:
|
||||
+ *pkalg = pk_alg;
|
||||
+ break;
|
||||
+ default:
|
||||
+ gnutls_x509_crt_deinit(cert);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ gnutls_x509_crt_deinit(cert);
|
||||
+ return true;
|
||||
+}
|
||||
+#else
|
||||
+static bool tlshd_cert_check_pk_alg(__attribute__ ((unused)) gnutls_datum_t *data,
|
||||
+ __attribute__ ((unused)) gnutls_pk_algorithm_t *pkalg)
|
||||
+{
|
||||
+ tlshd_log_debug("%s: gnutls version does not have ML-DSA support",
|
||||
+ __func__);
|
||||
+ return false;
|
||||
+}
|
||||
+#endif /* HAVE_GNUTLS_MLDSA */
|
||||
+
|
||||
/**
|
||||
- * tlshd_config_get_certs - Get certs for {Client,Server} Hello from .conf
|
||||
+ * __tlshd_config_get_certs - Helper for tlshd_config_get_certs()
|
||||
* @peer_type: IN: peer type
|
||||
* @certs: OUT: in-memory certificates
|
||||
* @certs_len: IN: maximum number of certs to get, OUT: number of certs found
|
||||
+ * @pkgalg: IN: if non-NULL, indicates we want to retrieve the PQ cert,
|
||||
+ * OUT: if non-NULL, store the PQ public-key alg that was used in the PQ cert
|
||||
*
|
||||
* Return values:
|
||||
* %true: certificate retrieved successfully
|
||||
* %false: certificate not retrieved
|
||||
*/
|
||||
-bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len)
|
||||
+static bool __tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
+ unsigned int *certs_len,
|
||||
+ gnutls_pk_algorithm_t *pkalg)
|
||||
{
|
||||
gnutls_datum_t data;
|
||||
gchar *pathname;
|
||||
@@ -281,7 +329,10 @@ bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
peer_type == PEER_TYPE_CLIENT ?
|
||||
"authenticate.client" :
|
||||
"authenticate.server",
|
||||
- "x509.certificate", NULL);
|
||||
+ pkalg != NULL ?
|
||||
+ "x509.pq.certificate" :
|
||||
+ "x509.certificate",
|
||||
+ NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
|
||||
@@ -291,6 +342,15 @@ bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
return false;
|
||||
}
|
||||
|
||||
+ if (pkalg && !tlshd_cert_check_pk_alg(&data, pkalg)) {
|
||||
+ tlshd_log_debug("%s: %s not using a PQ public-key algorithm",
|
||||
+ __func__, pathname);
|
||||
+ free(data.data);
|
||||
+ g_free(pathname);
|
||||
+ *certs_len = 0;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
/* Config file supports only PEM-encoded certificates */
|
||||
ret = gnutls_pcert_list_import_x509_raw(certs, certs_len, &data,
|
||||
GNUTLS_X509_FMT_PEM, 0);
|
||||
@@ -310,15 +370,51 @@ bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
}
|
||||
|
||||
/**
|
||||
- * tlshd_config_get_privkey - Get private key for {Client,Server}Hello from .conf
|
||||
+ * tlshd_config_get_certs - Get certs for {Client,Server} Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
+ * @certs: OUT: in-memory certificates
|
||||
+ * @pq_certs_len: IN: maximum number of PQ certs to get, OUT: number of PQ certs found
|
||||
+ * @certs_len: IN: maximum number of certs to get, OUT: number of certs found
|
||||
+ * @pkgalg: OUT: the PQ public-key alg that was used in the PQ cert
|
||||
+ *
|
||||
+ * Retrieve the PQ cert(s) first, then the RSA cert(s). Both are stored in the
|
||||
+ * same list. Note that @pq_certs_len is deducted from the available @certs_len
|
||||
+ * and is also used to determine the offset to store the RSA cert(s) in the
|
||||
+ * @certs array.
|
||||
+ *
|
||||
+ * Return values:
|
||||
+ * %true: certificate retrieved successfully
|
||||
+ * %false: certificate not retrieved
|
||||
+ */
|
||||
+bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
+ unsigned int *pq_certs_len,
|
||||
+ unsigned int *certs_len,
|
||||
+ gnutls_pk_algorithm_t *pkalg)
|
||||
+{
|
||||
+ bool ret;
|
||||
+
|
||||
+ ret = __tlshd_config_get_certs(peer_type, certs, pq_certs_len, pkalg);
|
||||
+
|
||||
+ if (ret == true)
|
||||
+ *certs_len -= *pq_certs_len;
|
||||
+ else
|
||||
+ *pq_certs_len = 0;
|
||||
+
|
||||
+ return __tlshd_config_get_certs(peer_type, certs + *pq_certs_len,
|
||||
+ certs_len, NULL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * __tlshd_config_get_privkey - Helper for tlshd_config_get_privkey()
|
||||
* @peer_type: IN: peer type
|
||||
* @privkey: OUT: in-memory private key
|
||||
+ * @pq: IN: if true, retrieve the PQ private key
|
||||
*
|
||||
* Return values:
|
||||
* %true: private key retrieved successfully
|
||||
* %false: private key not retrieved
|
||||
*/
|
||||
-bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey)
|
||||
+static bool __tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey, bool pq)
|
||||
{
|
||||
gnutls_datum_t data;
|
||||
gchar *pathname;
|
||||
@@ -328,7 +424,10 @@ bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey)
|
||||
peer_type == PEER_TYPE_CLIENT ?
|
||||
"authenticate.client" :
|
||||
"authenticate.server",
|
||||
- "x509.private_key", NULL);
|
||||
+ pq == true ?
|
||||
+ "x509.pq.private_key" :
|
||||
+ "x509.private_key",
|
||||
+ NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
|
||||
@@ -360,3 +459,22 @@ bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey)
|
||||
g_free(pathname);
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * tlshd_config_get_privkey - Get private key for {Client,Server}Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
+ * @pq_privkey: OUT: in-memory PQ private key
|
||||
+ * @privkey: OUT: in-memory private key
|
||||
+ *
|
||||
+ * Retrieve the PQ private key first, then the RSA private key.
|
||||
+ *
|
||||
+ * Return values:
|
||||
+ * %true: private key retrieved successfully
|
||||
+ * %false: private key not retrieved
|
||||
+ */
|
||||
+bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *pq_privkey,
|
||||
+ gnutls_privkey_t *privkey)
|
||||
+{
|
||||
+ __tlshd_config_get_privkey(peer_type, pq_privkey, true);
|
||||
+ return __tlshd_config_get_privkey(peer_type, privkey, false);
|
||||
+}
|
||||
diff --git a/src/tlshd/server.c b/src/tlshd/server.c
|
||||
index efea387..13b805c 100644
|
||||
--- a/src/tlshd/server.c
|
||||
+++ b/src/tlshd/server.c
|
||||
@@ -42,9 +42,12 @@
|
||||
#include "tlshd.h"
|
||||
#include "netlink.h"
|
||||
|
||||
+static gnutls_privkey_t tlshd_server_pq_privkey;
|
||||
static gnutls_privkey_t tlshd_server_privkey;
|
||||
+static unsigned int tlshd_server_pq_certs_len = TLSHD_MAX_CERTS;
|
||||
static unsigned int tlshd_server_certs_len = TLSHD_MAX_CERTS;
|
||||
static gnutls_pcert_st tlshd_server_certs[TLSHD_MAX_CERTS];
|
||||
+static gnutls_pk_algorithm_t tlshd_server_pq_pkalg = GNUTLS_PK_UNKNOWN;
|
||||
|
||||
static bool tlshd_x509_server_get_certs(struct tlshd_handshake_parms *parms)
|
||||
{
|
||||
@@ -53,14 +56,16 @@ static bool tlshd_x509_server_get_certs(struct tlshd_handshake_parms *parms)
|
||||
tlshd_server_certs,
|
||||
&tlshd_server_certs_len);
|
||||
return tlshd_config_get_certs(PEER_TYPE_SERVER, tlshd_server_certs,
|
||||
- &tlshd_server_certs_len);
|
||||
+ &tlshd_server_pq_certs_len,
|
||||
+ &tlshd_server_certs_len,
|
||||
+ &tlshd_server_pq_pkalg);
|
||||
}
|
||||
|
||||
static void tlshd_x509_server_put_certs(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
- for (i = 0; i < tlshd_server_certs_len; i++)
|
||||
+ for (i = 0; i < TLSHD_MAX_CERTS; i++)
|
||||
gnutls_pcert_deinit(&tlshd_server_certs[i]);
|
||||
}
|
||||
|
||||
@@ -70,11 +75,13 @@ static bool tlshd_x509_server_get_privkey(struct tlshd_handshake_parms *parms)
|
||||
return tlshd_keyring_get_privkey(parms->x509_privkey,
|
||||
&tlshd_server_privkey);
|
||||
return tlshd_config_get_privkey(PEER_TYPE_SERVER,
|
||||
+ &tlshd_server_pq_privkey,
|
||||
&tlshd_server_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_server_put_privkey(void)
|
||||
{
|
||||
+ gnutls_privkey_deinit(tlshd_server_pq_privkey);
|
||||
gnutls_privkey_deinit(tlshd_server_privkey);
|
||||
}
|
||||
|
||||
@@ -123,6 +130,11 @@ tlshd_x509_retrieve_key_cb(gnutls_session_t session,
|
||||
gnutls_privkey_t *privkey)
|
||||
{
|
||||
gnutls_certificate_type_t type;
|
||||
+#ifdef HAVE_GNUTLS_MLDSA
|
||||
+ gnutls_sign_algorithm_t client_alg;
|
||||
+ bool use_pq_cert = false;
|
||||
+ int i, ret;
|
||||
+#endif /* HAVE_GNUTLS_MLDSA */
|
||||
|
||||
tlshd_x509_log_issuers(req_ca_rdn, nreqs);
|
||||
|
||||
@@ -130,9 +142,58 @@ tlshd_x509_retrieve_key_cb(gnutls_session_t session,
|
||||
if (type != GNUTLS_CRT_X509)
|
||||
return -1;
|
||||
|
||||
+#ifdef HAVE_GNUTLS_MLDSA
|
||||
+ /*
|
||||
+ * NB: Unfortunately when the callback function is invoked server-side,
|
||||
+ * pk_algos is NULL and pk_algos_length is 0. So we check the signature
|
||||
+ * algorithms the client supports and try to match one of them to the
|
||||
+ * public-key algorithm used by the server cert.
|
||||
+ */
|
||||
+ if (tlshd_server_pq_pkalg != GNUTLS_PK_UNKNOWN) {
|
||||
+ for (i = 0; ; i++) {
|
||||
+ ret = gnutls_sign_algorithm_get_requested(session, i, &client_alg);
|
||||
+ if (ret != GNUTLS_E_SUCCESS)
|
||||
+ break;
|
||||
+ switch (client_alg) {
|
||||
+ case GNUTLS_SIGN_MLDSA44:
|
||||
+ if (tlshd_server_pq_pkalg == GNUTLS_PK_MLDSA44)
|
||||
+ use_pq_cert = true;
|
||||
+ break;
|
||||
+ case GNUTLS_SIGN_MLDSA65:
|
||||
+ if (tlshd_server_pq_pkalg == GNUTLS_PK_MLDSA65)
|
||||
+ use_pq_cert = true;
|
||||
+ break;
|
||||
+ case GNUTLS_SIGN_MLDSA87:
|
||||
+ if (tlshd_server_pq_pkalg == GNUTLS_PK_MLDSA87)
|
||||
+ use_pq_cert = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ if (use_pq_cert == true) {
|
||||
+ tlshd_log_debug("%s: Client supports %s", __func__,
|
||||
+ gnutls_sign_get_name(client_alg));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (use_pq_cert == true) {
|
||||
+ tlshd_log_debug("%s: Selecting x509.pq.certificate from conf file", __func__);
|
||||
+ *pcert_length = tlshd_server_pq_certs_len;
|
||||
+ *pcert = tlshd_server_certs;
|
||||
+ *privkey = tlshd_server_pq_privkey;
|
||||
+ } else {
|
||||
+ tlshd_log_debug("%s: Selecting x509.certificate from conf file", __func__);
|
||||
+ *pcert_length = tlshd_server_certs_len;
|
||||
+ *pcert = tlshd_server_certs + tlshd_server_pq_certs_len;
|
||||
+ *privkey = tlshd_server_privkey;
|
||||
+ }
|
||||
+#else
|
||||
*pcert_length = tlshd_server_certs_len;
|
||||
*pcert = tlshd_server_certs;
|
||||
*privkey = tlshd_server_privkey;
|
||||
+#endif /* HAVE_GNUTLS_MLDSA */
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/tlshd/tlshd.conf b/src/tlshd/tlshd.conf
|
||||
index 620bd17..5419146 100644
|
||||
--- a/src/tlshd/tlshd.conf
|
||||
+++ b/src/tlshd/tlshd.conf
|
||||
@@ -39,3 +39,5 @@ nl=0
|
||||
#x509.crl= <pathname>
|
||||
#x509.certificate= <pathname>
|
||||
#x509.private_key= <pathname>
|
||||
+#x509.pq.certificate= <pathname>
|
||||
+#x509.pq.private_key= <pathname>
|
||||
diff --git a/src/tlshd/tlshd.conf.man b/src/tlshd/tlshd.conf.man
|
||||
index 914261e..575d88b 100644
|
||||
--- a/src/tlshd/tlshd.conf.man
|
||||
+++ b/src/tlshd/tlshd.conf.man
|
||||
@@ -125,6 +125,21 @@ a handshake request when no other certificate is available.
|
||||
.B x509.private_key
|
||||
This option specifies the pathname of a file containing
|
||||
a PEM-encoded private key associated with the above certificate.
|
||||
+.TP
|
||||
+.B x509.pq.certificate
|
||||
+This option specifies the pathname of a file containing
|
||||
+a PEM-encoded x.509 certificate that is to be presented during
|
||||
+a handshake request if the peer supports post-quantum cryptography.
|
||||
+This certificate must be using a post-quantum public-key algorithm
|
||||
+(ML-DSA-44, ML-DSA-65, or ML-DSA-87).
|
||||
+If the peer does not support post-quantum cryptography, the
|
||||
+certificate configured in the
|
||||
+.I x509.certificate
|
||||
+option will be presented instead.
|
||||
+.TP
|
||||
+.B x509.pq.private_key
|
||||
+This option specifies the pathname of a file containing
|
||||
+a PEM-encoded private key associated with the above certificate.
|
||||
.SH SEE ALSO
|
||||
.BR tlshd (8)
|
||||
.SH AUTHOR
|
||||
diff --git a/src/tlshd/tlshd.h b/src/tlshd/tlshd.h
|
||||
index 6ba45ac..664de67 100644
|
||||
--- a/src/tlshd/tlshd.h
|
||||
+++ b/src/tlshd/tlshd.h
|
||||
@@ -60,8 +60,11 @@ void tlshd_config_shutdown(void);
|
||||
bool tlshd_config_get_truststore(int peer_type, char **bundle);
|
||||
bool tlshd_config_get_crl(int peer_type, char **result);
|
||||
bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len);
|
||||
-bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey);
|
||||
+ unsigned int *pq_certs_len,
|
||||
+ unsigned int *certs_len,
|
||||
+ gnutls_pk_algorithm_t *pkalg);
|
||||
+bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *pq_privkey,
|
||||
+ gnutls_privkey_t *privkey);
|
||||
|
||||
/* handshake.c */
|
||||
extern void tlshd_start_tls_handshake(gnutls_session_t session,
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,445 @@
|
||||
From 6cea3a0e8a10aa893f42576059dcf5c74f092283 Mon Sep 17 00:00:00 2001
|
||||
From: Scott Mayhew <smayhew@redhat.com>
|
||||
Date: Wed, 10 Sep 2025 16:17:43 -0400
|
||||
Subject: [PATCH 1/4] tlshd: deduplicate client and server config functions
|
||||
|
||||
The client and server variants of tlshd_config_get_* are identical
|
||||
except for
|
||||
1) the stanza they're looking at in the config file, and
|
||||
2) whether the word "client" or "server" gets written in a log message
|
||||
|
||||
Add new parameter 'peer_type' to each of these functions so we can use
|
||||
the same function for both the client and server code.
|
||||
|
||||
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
||||
---
|
||||
src/tlshd/client.c | 9 +-
|
||||
src/tlshd/config.c | 213 +++++++++------------------------------------
|
||||
src/tlshd/server.c | 11 +--
|
||||
src/tlshd/tlshd.h | 20 ++---
|
||||
4 files changed, 62 insertions(+), 191 deletions(-)
|
||||
|
||||
diff --git a/src/tlshd/client.c b/src/tlshd/client.c
|
||||
index 8acb0aa..c07ae29 100644
|
||||
--- a/src/tlshd/client.c
|
||||
+++ b/src/tlshd/client.c
|
||||
@@ -48,7 +48,7 @@ static int tlshd_client_get_truststore(gnutls_certificate_credentials_t cred)
|
||||
char *pathname;
|
||||
int ret;
|
||||
|
||||
- if (tlshd_config_get_client_truststore(&pathname)) {
|
||||
+ if (tlshd_config_get_truststore(PEER_TYPE_CLIENT, &pathname)) {
|
||||
ret = gnutls_certificate_set_x509_trust_file(cred, pathname,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
free(pathname);
|
||||
@@ -60,7 +60,7 @@ static int tlshd_client_get_truststore(gnutls_certificate_credentials_t cred)
|
||||
}
|
||||
tlshd_log_debug("System trust: Loaded %d certificate(s).", ret);
|
||||
|
||||
- if (tlshd_config_get_client_crl(&pathname)) {
|
||||
+ if (tlshd_config_get_crl(PEER_TYPE_CLIENT, &pathname)) {
|
||||
ret = gnutls_certificate_set_x509_crl_file(cred, pathname,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
free(pathname);
|
||||
@@ -143,7 +143,8 @@ static bool tlshd_x509_client_get_certs(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_cert != TLS_NO_CERT)
|
||||
return tlshd_keyring_get_certs(parms->x509_cert, tlshd_certs,
|
||||
&tlshd_certs_len);
|
||||
- return tlshd_config_get_client_certs(tlshd_certs, &tlshd_certs_len);
|
||||
+ return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs,
|
||||
+ &tlshd_certs_len);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_certs(void)
|
||||
@@ -159,7 +160,7 @@ static bool tlshd_x509_client_get_privkey(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_privkey != TLS_NO_PRIVKEY)
|
||||
return tlshd_keyring_get_privkey(parms->x509_privkey,
|
||||
&tlshd_privkey);
|
||||
- return tlshd_config_get_client_privkey(&tlshd_privkey);
|
||||
+ return tlshd_config_get_privkey(PEER_TYPE_CLIENT, &tlshd_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_client_put_privkey(void)
|
||||
diff --git a/src/tlshd/config.c b/src/tlshd/config.c
|
||||
index 029dbcc..ff1f2a5 100644
|
||||
--- a/src/tlshd/config.c
|
||||
+++ b/src/tlshd/config.c
|
||||
@@ -187,18 +187,22 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
- * tlshd_config_get_client_truststore - Get truststore for ClientHello from .conf
|
||||
+ * tlshd_config_get_truststore - Get truststore for {Client,Server}Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
* @bundle: OUT: pathname to truststore
|
||||
*
|
||||
* Return values:
|
||||
* %false: pathname not retrieved
|
||||
* %true: pathname retrieved successfully; caller must free @bundle using free(3)
|
||||
*/
|
||||
-bool tlshd_config_get_client_truststore(char **bundle)
|
||||
+bool tlshd_config_get_truststore(int peer_type, char **bundle)
|
||||
{
|
||||
gchar *pathname;
|
||||
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.client",
|
||||
+ pathname = g_key_file_get_string(tlshd_configuration,
|
||||
+ peer_type == PEER_TYPE_CLIENT ?
|
||||
+ "authenticate.client" :
|
||||
+ "authenticate.server",
|
||||
"x509.truststore", NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
@@ -213,23 +217,29 @@ bool tlshd_config_get_client_truststore(char **bundle)
|
||||
if (!*bundle)
|
||||
return false;
|
||||
|
||||
- tlshd_log_debug("Client x.509 truststore is %s", *bundle);
|
||||
+ tlshd_log_debug("%s x.509 truststore is %s",
|
||||
+ peer_type == PEER_TYPE_CLIENT ? "Client" : "Server",
|
||||
+ *bundle);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
- * tlshd_config_get_client_crl - Get CRL for ClientHello from .conf
|
||||
+ * tlshd_config_get_crl - Get CRL for {Client,Server}Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
* @result: OUT: pathname to CRL
|
||||
*
|
||||
* Return values:
|
||||
* %false: pathname not retrieved
|
||||
* %true: pathname retrieved successfully; caller must free @result using free(3)
|
||||
*/
|
||||
-bool tlshd_config_get_client_crl(char **result)
|
||||
+bool tlshd_config_get_crl(int peer_type, char **result)
|
||||
{
|
||||
gchar *pathname;
|
||||
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.client",
|
||||
+ pathname = g_key_file_get_string(tlshd_configuration,
|
||||
+ peer_type == PEER_TYPE_CLIENT ?
|
||||
+ "authenticate.client" :
|
||||
+ "authenticate.server",
|
||||
"x509.crl", NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
@@ -244,12 +254,15 @@ bool tlshd_config_get_client_crl(char **result)
|
||||
if (!*result)
|
||||
return false;
|
||||
|
||||
- tlshd_log_debug("Client x.509 crl is %s", *result);
|
||||
+ tlshd_log_debug("%s x.509 crl is %s",
|
||||
+ peer_type == PEER_TYPE_CLIENT ? "Client" : "Server",
|
||||
+ *result);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
- * tlshd_config_get_client_certs - Get certs for ClientHello from .conf
|
||||
+ * tlshd_config_get_certs - Get certs for {Client,Server} Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
* @certs: OUT: in-memory certificates
|
||||
* @certs_len: IN: maximum number of certs to get, OUT: number of certs found
|
||||
*
|
||||
@@ -257,15 +270,18 @@ bool tlshd_config_get_client_crl(char **result)
|
||||
* %true: certificate retrieved successfully
|
||||
* %false: certificate not retrieved
|
||||
*/
|
||||
-bool tlshd_config_get_client_certs(gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len)
|
||||
+bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
+ unsigned int *certs_len)
|
||||
{
|
||||
gnutls_datum_t data;
|
||||
gchar *pathname;
|
||||
int ret;
|
||||
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.client",
|
||||
- "x509.certificate", NULL);
|
||||
+ pathname = g_key_file_get_string(tlshd_configuration,
|
||||
+ peer_type == PEER_TYPE_CLIENT ?
|
||||
+ "authenticate.client" :
|
||||
+ "authenticate.server",
|
||||
+ "x509.certificate", NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
|
||||
@@ -285,181 +301,34 @@ bool tlshd_config_get_client_certs(gnutls_pcert_st *certs,
|
||||
return false;
|
||||
}
|
||||
|
||||
- tlshd_log_debug("Retrieved %u x.509 client certificate(s) from %s",
|
||||
- *certs_len, pathname);
|
||||
+ tlshd_log_debug("Retrieved %u x.509 %s certificate(s) from %s",
|
||||
+ *certs_len,
|
||||
+ peer_type == PEER_TYPE_CLIENT ? "client" : "server",
|
||||
+ pathname);
|
||||
g_free(pathname);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
- * tlshd_config_get_client_privkey - Get private key for ClientHello from .conf
|
||||
+ * tlshd_config_get_privkey - Get private key for {Client,Server}Hello from .conf
|
||||
+ * @peer_type: IN: peer type
|
||||
* @privkey: OUT: in-memory private key
|
||||
*
|
||||
* Return values:
|
||||
* %true: private key retrieved successfully
|
||||
* %false: private key not retrieved
|
||||
*/
|
||||
-bool tlshd_config_get_client_privkey(gnutls_privkey_t *privkey)
|
||||
+bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey)
|
||||
{
|
||||
gnutls_datum_t data;
|
||||
gchar *pathname;
|
||||
int ret;
|
||||
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.client",
|
||||
- "x509.private_key", NULL);
|
||||
- if (!pathname)
|
||||
- return false;
|
||||
-
|
||||
- if (!tlshd_config_read_datum(pathname, &data, TLSHD_OWNER,
|
||||
- TLSHD_PRIVKEY_MODE)) {
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- ret = gnutls_privkey_init(privkey);
|
||||
- if (ret != GNUTLS_E_SUCCESS) {
|
||||
- tlshd_log_gnutls_error(ret);
|
||||
- free(data.data);
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- /* Config file supports only PEM-encoded keys */
|
||||
- ret = gnutls_privkey_import_x509_raw(*privkey, &data,
|
||||
- GNUTLS_X509_FMT_PEM, NULL, 0);
|
||||
- free(data.data);
|
||||
- if (ret != GNUTLS_E_SUCCESS) {
|
||||
- tlshd_log_gnutls_error(ret);
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- tlshd_log_debug("Retrieved private key from %s", pathname);
|
||||
- g_free(pathname);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * tlshd_config_get_server_truststore - Get truststore for ServerHello from .conf
|
||||
- * @bundle: OUT: pathname to truststore
|
||||
- *
|
||||
- * Return values:
|
||||
- * %false: pathname not retrieved
|
||||
- * %true: pathname retrieved successfully; caller must free @bundle using free(3)
|
||||
- */
|
||||
-bool tlshd_config_get_server_truststore(char **bundle)
|
||||
-{
|
||||
- gchar *pathname;
|
||||
-
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.server",
|
||||
- "x509.truststore", NULL);
|
||||
- if (!pathname)
|
||||
- return false;
|
||||
- if (access(pathname, F_OK)) {
|
||||
- tlshd_log_debug("tlshd cannot access \"%s\"", pathname);
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- *bundle = strdup(pathname);
|
||||
- g_free(pathname);
|
||||
- if (!*bundle)
|
||||
- return false;
|
||||
-
|
||||
- tlshd_log_debug("Server x.509 truststore is %s", *bundle);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * tlshd_config_get_server_crl - Get CRL for ServerHello from .conf
|
||||
- * @result: OUT: pathname to CRL
|
||||
- *
|
||||
- * Return values:
|
||||
- * %false: pathname not retrieved
|
||||
- * %true: pathname retrieved successfully; caller must free @result using free(3)
|
||||
- */
|
||||
-bool tlshd_config_get_server_crl(char **result)
|
||||
-{
|
||||
- gchar *pathname;
|
||||
-
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.server",
|
||||
- "x509.crl", NULL);
|
||||
- if (!pathname)
|
||||
- return false;
|
||||
- if (access(pathname, F_OK)) {
|
||||
- tlshd_log_debug("tlshd cannot access \"%s\"", pathname);
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- *result = strdup(pathname);
|
||||
- g_free(pathname);
|
||||
- if (!*result)
|
||||
- return false;
|
||||
-
|
||||
- tlshd_log_debug("Server x.509 crl is %s", *result);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * tlshd_config_get_server_certs - Get certs for ServerHello from .conf
|
||||
- * @certs: OUT: in-memory certificates
|
||||
- * @certs_len: IN: maximum number of certs to get, OUT: number of certs found
|
||||
- *
|
||||
- * Return values:
|
||||
- * %true: certificate retrieved successfully
|
||||
- * %false: certificate not retrieved
|
||||
- */
|
||||
-bool tlshd_config_get_server_certs(gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len)
|
||||
-{
|
||||
- gnutls_datum_t data;
|
||||
- gchar *pathname;
|
||||
- int ret;
|
||||
-
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.server",
|
||||
- "x509.certificate", NULL);
|
||||
- if (!pathname)
|
||||
- return false;
|
||||
-
|
||||
- if (!tlshd_config_read_datum(pathname, &data, TLSHD_OWNER,
|
||||
- TLSHD_CERT_MODE)) {
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- /* Config file supports only PEM-encoded certificates */
|
||||
- ret = gnutls_pcert_list_import_x509_raw(certs, certs_len, &data,
|
||||
- GNUTLS_X509_FMT_PEM, 0);
|
||||
- free(data.data);
|
||||
- if (ret != GNUTLS_E_SUCCESS) {
|
||||
- tlshd_log_gnutls_error(ret);
|
||||
- g_free(pathname);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- tlshd_log_debug("Retrieved %u x.509 server certificate(s) from %s",
|
||||
- *certs_len, pathname);
|
||||
- g_free(pathname);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * tlshd_config_get_server_privkey - Get private key for ServerHello from .conf
|
||||
- * @privkey: OUT: in-memory private key
|
||||
- *
|
||||
- * Return values:
|
||||
- * %true: private key retrieved successfully
|
||||
- * %false: private key not retrieved
|
||||
- */
|
||||
-bool tlshd_config_get_server_privkey(gnutls_privkey_t *privkey)
|
||||
-{
|
||||
- gnutls_datum_t data;
|
||||
- gchar *pathname;
|
||||
- int ret;
|
||||
-
|
||||
- pathname = g_key_file_get_string(tlshd_configuration, "authenticate.server",
|
||||
- "x509.private_key", NULL);
|
||||
+ pathname = g_key_file_get_string(tlshd_configuration,
|
||||
+ peer_type == PEER_TYPE_CLIENT ?
|
||||
+ "authenticate.client" :
|
||||
+ "authenticate.server",
|
||||
+ "x509.private_key", NULL);
|
||||
if (!pathname)
|
||||
return false;
|
||||
|
||||
diff --git a/src/tlshd/server.c b/src/tlshd/server.c
|
||||
index 44a91c4..efea387 100644
|
||||
--- a/src/tlshd/server.c
|
||||
+++ b/src/tlshd/server.c
|
||||
@@ -52,8 +52,8 @@ static bool tlshd_x509_server_get_certs(struct tlshd_handshake_parms *parms)
|
||||
return tlshd_keyring_get_certs(parms->x509_cert,
|
||||
tlshd_server_certs,
|
||||
&tlshd_server_certs_len);
|
||||
- return tlshd_config_get_server_certs(tlshd_server_certs,
|
||||
- &tlshd_server_certs_len);
|
||||
+ return tlshd_config_get_certs(PEER_TYPE_SERVER, tlshd_server_certs,
|
||||
+ &tlshd_server_certs_len);
|
||||
}
|
||||
|
||||
static void tlshd_x509_server_put_certs(void)
|
||||
@@ -69,7 +69,8 @@ static bool tlshd_x509_server_get_privkey(struct tlshd_handshake_parms *parms)
|
||||
if (parms->x509_privkey != TLS_NO_PRIVKEY)
|
||||
return tlshd_keyring_get_privkey(parms->x509_privkey,
|
||||
&tlshd_server_privkey);
|
||||
- return tlshd_config_get_server_privkey(&tlshd_server_privkey);
|
||||
+ return tlshd_config_get_privkey(PEER_TYPE_SERVER,
|
||||
+ &tlshd_server_privkey);
|
||||
}
|
||||
|
||||
static void tlshd_x509_server_put_privkey(void)
|
||||
@@ -140,7 +141,7 @@ static int tlshd_server_get_truststore(gnutls_certificate_credentials_t cred)
|
||||
char *pathname;
|
||||
int ret;
|
||||
|
||||
- if (tlshd_config_get_server_truststore(&pathname)) {
|
||||
+ if (tlshd_config_get_truststore(PEER_TYPE_SERVER, &pathname)) {
|
||||
ret = gnutls_certificate_set_x509_trust_file(cred, pathname,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
free(pathname);
|
||||
@@ -150,7 +151,7 @@ static int tlshd_server_get_truststore(gnutls_certificate_credentials_t cred)
|
||||
return ret;
|
||||
tlshd_log_debug("System trust: Loaded %d certificate(s).", ret);
|
||||
|
||||
- if (tlshd_config_get_server_crl(&pathname)) {
|
||||
+ if (tlshd_config_get_crl(PEER_TYPE_SERVER, &pathname)) {
|
||||
ret = gnutls_certificate_set_x509_crl_file(cred, pathname,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
free(pathname);
|
||||
diff --git a/src/tlshd/tlshd.h b/src/tlshd/tlshd.h
|
||||
index 2857804..6ba45ac 100644
|
||||
--- a/src/tlshd/tlshd.h
|
||||
+++ b/src/tlshd/tlshd.h
|
||||
@@ -45,6 +45,11 @@ struct tlshd_handshake_parms {
|
||||
unsigned int session_status;
|
||||
};
|
||||
|
||||
+enum peer_type {
|
||||
+ PEER_TYPE_CLIENT,
|
||||
+ PEER_TYPE_SERVER,
|
||||
+};
|
||||
+
|
||||
/* client.c */
|
||||
extern void tlshd_tls13_clienthello_handshake(struct tlshd_handshake_parms *parms);
|
||||
extern void tlshd_quic_clienthello_handshake(struct tlshd_handshake_parms *parms);
|
||||
@@ -52,16 +57,11 @@ extern void tlshd_quic_clienthello_handshake(struct tlshd_handshake_parms *parms
|
||||
/* config.c */
|
||||
bool tlshd_config_init(const gchar *pathname);
|
||||
void tlshd_config_shutdown(void);
|
||||
-bool tlshd_config_get_client_truststore(char **bundle);
|
||||
-bool tlshd_config_get_client_crl(char **result);
|
||||
-bool tlshd_config_get_client_certs(gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len);
|
||||
-bool tlshd_config_get_client_privkey(gnutls_privkey_t *privkey);
|
||||
-bool tlshd_config_get_server_truststore(char **bundle);
|
||||
-bool tlshd_config_get_server_crl(char **result);
|
||||
-bool tlshd_config_get_server_certs(gnutls_pcert_st *certs,
|
||||
- unsigned int *certs_len);
|
||||
-bool tlshd_config_get_server_privkey(gnutls_privkey_t *privkey);
|
||||
+bool tlshd_config_get_truststore(int peer_type, char **bundle);
|
||||
+bool tlshd_config_get_crl(int peer_type, char **result);
|
||||
+bool tlshd_config_get_certs(int peer_type, gnutls_pcert_st *certs,
|
||||
+ unsigned int *certs_len);
|
||||
+bool tlshd_config_get_privkey(int peer_type, gnutls_privkey_t *privkey);
|
||||
|
||||
/* handshake.c */
|
||||
extern void tlshd_start_tls_handshake(gnutls_session_t session,
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
%global forgeurl https://github.com/oracle/ktls-utils
|
||||
%global baseversion 0.11
|
||||
%global baseversion 1.2.1
|
||||
|
||||
Name: ktls-utils
|
||||
Version: %{baseversion}
|
||||
Release: 1%{?dist}
|
||||
# Using a base release of 3 to continue the sequence from the SRPM taken
|
||||
# from Fedora ELN.
|
||||
Release: %{autorelease}
|
||||
Summary: TLS handshake agent for kernel sockets
|
||||
|
||||
%forgemeta
|
||||
@ -14,6 +16,17 @@ URL: %{forgeurl}
|
||||
# FIXME: is this a bug in the tagging scheme or forgesource macro?
|
||||
Source0: %{forgeurl}/releases/download/%{name}-%{baseversion}/%{name}-%{baseversion}.tar.gz
|
||||
|
||||
#
|
||||
# RHEL10.2
|
||||
#
|
||||
Patch0: ktls-utils-1.2.1-tlshd-deduplicate-client-and-server-config-functions.patch
|
||||
Patch1: ktls-utils-1.2.1-tlshd-Fix-priority-string-to-allow-PQC.patch
|
||||
Patch2: ktls-utils-1.2.1-tlshd-Server-side-dual-certificate-support.patch
|
||||
Patch3: ktls-utils-1.2.1-tlshd-Client-side-dual-certificate-support.patch
|
||||
Patch4: ktls-utils-1.2.1-tlshd-Clean-up-logic-in-tlshd_start_tls_handshake.patch
|
||||
Patch5: ktls-utils-1.2.1-tlshd-Fix-session-leak-on-error-paths-in-x509-server.patch
|
||||
Patch6: ktls-utils-1.2.1-tlshd-Send-fatal-alert-to-client-when-there-are-serv.patch
|
||||
|
||||
BuildRequires: bash systemd-rpm-macros
|
||||
BuildRequires: gcc make coreutils
|
||||
BuildRequires: pkgconfig(gnutls) >= 3.3.0
|
||||
@ -66,16 +79,4 @@ standard kTLS socket options.
|
||||
%systemd_postun_with_restart tlshd.service
|
||||
|
||||
%changelog
|
||||
* Mon Jun 17 2024 Steve Dickson <steved@redhat.com> 0.11-1
|
||||
- Release ktls-utils 0.11 (RHEL-39442)
|
||||
|
||||
* Thu Feb 29 2024 Steve Dickson <steved@redhat.com> 0.10-0
|
||||
- Initial package
|
||||
- Upstream contributions by:
|
||||
- Chuck Lever <chuck.lever@oracle.com>
|
||||
- Hannes Reinecke <hare@suse.de>
|
||||
- Jeff Layton <jlayton@kernel.org>
|
||||
- Benjamin Coddington <bcodding@redhat.com>
|
||||
- David Härdeman <david@hardeman.nu>
|
||||
- Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
|
||||
- Moritz "WanzenBug" Wanzenböck <moritz.wanzenboeck@linbit.com>
|
||||
%autochangelog
|
||||
12
plans/sanity.fmf
Normal file
12
plans/sanity.fmf
Normal file
@ -0,0 +1,12 @@
|
||||
summary:
|
||||
Basic sanity test for ktls-utils
|
||||
discover:
|
||||
how: fmf
|
||||
prepare:
|
||||
how: install
|
||||
package:
|
||||
- ktls-utils
|
||||
- nfs-utils
|
||||
- openssl
|
||||
execute:
|
||||
how: tmt
|
||||
1
sources
Normal file
1
sources
Normal file
@ -0,0 +1 @@
|
||||
SHA512 (ktls-utils-1.2.1.tar.gz) = 34b5565d5c816bf4dc519b41b7dba9445c6c3dffc09b0eacb56fa7345e5d6daa909a8d682448f02a42063f7a66ed8e377047852a775723fd4cb08964bb7344ca
|
||||
2
tests/sanity/main.fmf
Normal file
2
tests/sanity/main.fmf
Normal file
@ -0,0 +1,2 @@
|
||||
summary: Basic sanity test for ktls-utils
|
||||
test: ./test.sh
|
||||
99
tests/sanity/test.sh
Executable file
99
tests/sanity/test.sh
Executable file
@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
MYOLDHOSTNAME=$(hostnamectl hostname --static)
|
||||
MYHOSTNAME=nfs.ktls-utils.test
|
||||
MYIP=$(ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p')
|
||||
|
||||
echo "Setup..."
|
||||
hostnamectl hostname --static "$MYHOSTNAME"
|
||||
cp /etc/tlshd.conf /etc/tlshd.conf.bak
|
||||
openssl req -x509 -newkey rsa:4096 -subj "/CN=ktls-utils smoketest CA" -days 365 -noenc -out ca-cert.pem -keyout ca-cert.key >/dev/null 2>&1
|
||||
openssl req -x509 -newkey rsa:4096 -subj "/CN=${MYHOSTNAME}" -addext "subjectAltName=DNS:${MYHOSTNAME},IP:${MYIP}" -days 365 -noenc -CA ca-cert.pem -CAkey ca-cert.key -extensions usr_cert -out ktls.pem -keyout ktls.key >/dev/null 2>&1
|
||||
cp ca-cert.pem /etc/pki/tls/certs
|
||||
cp ktls.pem /etc/pki/tls/certs
|
||||
cp ktls.key /etc/pki/tls/private
|
||||
|
||||
cat <<EOF >/etc/tlshd.conf
|
||||
[debug]
|
||||
loglevel=0
|
||||
tls=0
|
||||
nl=0
|
||||
|
||||
[authenticate]
|
||||
#keyrings= <keyring>;<keyring>;<keyring>
|
||||
|
||||
[authenticate.client]
|
||||
x509.truststore=/etc/pki/tls/certs/ca-cert.pem
|
||||
x509.certificate=/etc/pki/tls/certs/ktls.pem
|
||||
x509.private_key=/etc/pki/tls/private/ktls.key
|
||||
|
||||
[authenticate.server]
|
||||
x509.truststore=/etc/pki/tls/certs/ca-cert.pem
|
||||
x509.certificate=/etc/pki/tls/certs/ktls.pem
|
||||
x509.private_key=/etc/pki/tls/private/ktls.key
|
||||
EOF
|
||||
|
||||
systemctl start tlshd
|
||||
systemctl start nfs-server
|
||||
mkdir /export
|
||||
exportfs -o rw,insecure,no_root_squash,xprtsec=tls:mtls *:/export
|
||||
|
||||
# mount by hostname
|
||||
echo "Try to mount $MYHOSTNAME:/export without xprtsec=tls"
|
||||
mount -o v4.2 $MYHOSTNAME:/export /mnt
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Mounted $MYHOSTNAME:/export without xprtsec=tls!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Try to mount $MYHOSTNAME:/export with xprtsec=tls"
|
||||
mount -o v4.2,xprtsec=tls $MYHOSTNAME:/export /mnt
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to mount $MYHOSTNAME:/export with xprtsec=tls!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep "xprtsec=tls" /proc/mounts; then
|
||||
echo "Failed to find xprtsec=tls in /proc/mounts"
|
||||
exit 1
|
||||
fi
|
||||
umount /mnt
|
||||
|
||||
# mount by ip address
|
||||
echo "Try to mount $MYIP:/export without xprtsec=tls"
|
||||
mount -o v4.2 $MYIP:/export /mnt
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Mounted $MYIP:/export without xprtsec=tls!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Try to mount $MYIP:/export with xprtsec=tls"
|
||||
mount -o v4.2,xprtsec=tls $MYIP:/export /mnt
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to mount $MYIP:/export with xprtsec=tls!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep "xprtsec=tls" /proc/mounts; then
|
||||
echo "Failed to find xprtsec=tls in /proc/mounts"
|
||||
exit 1
|
||||
fi
|
||||
umount /mnt
|
||||
|
||||
echo "Success!"
|
||||
|
||||
echo "Cleanup..."
|
||||
hostnamectl hostname --static "$MYOLDHOSTNAME"
|
||||
exportfs -ua
|
||||
systemctl stop nfs-server
|
||||
rmdir /export
|
||||
systemctl stop tlshd
|
||||
cp /etc/tlshd.conf.bak /etc/tlshd.conf
|
||||
rm -f /etc/pki/tls/certs/ca-cert.pem
|
||||
rm -f /etc/pki/tls/certs/ktls.pem
|
||||
rm -f /etc/pki/tls/private/ktls.key
|
||||
rm -f ca-cert.pem
|
||||
rm -f ca-cert.key
|
||||
rm -f ktls.pem
|
||||
rm -f ktls.key
|
||||
|
||||
exit 0
|
||||
Loading…
Reference in New Issue
Block a user