Skip to content

Commit 3f91990

Browse files
authored
Merge pull request #121 from scottmayhew/pqc
tlshd: Enable the use of post-quantum cryptography in x.509 certificates
2 parents 41ea1d4 + facd084 commit 3f91990

File tree

8 files changed

+286
-173
lines changed

8 files changed

+286
-173
lines changed

configure.ac

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ AC_CHECK_LIB([gnutls], [gnutls_get_system_config_file],
7979
AC_CHECK_LIB([gnutls], [gnutls_psk_allocate_client_credentials2],
8080
[AC_DEFINE([HAVE_GNUTLS_PSK_ALLOCATE_CREDENTIALS2], [1],
8181
[Define to 1 if you have the gnutls_psk_allocate_client_credentials2 function.])])
82+
83+
AC_MSG_CHECKING(for ML-DSA support in gnutls)
84+
AC_COMPILE_IFELSE(
85+
[AC_LANG_PROGRAM([[ #include <gnutls/gnutls.h> ]],
86+
[[ (void) GNUTLS_SIGN_MLDSA65; ]])],
87+
[ have_mldsa=yes ],
88+
[ have_mldsa=no ])
89+
AC_MSG_RESULT([$have_mldsa])
90+
if test "x$have_mldsa" = xyes ; then
91+
AC_DEFINE([HAVE_GNUTLS_MLDSA], [1], [Define to 1 if gnutls supports ML-DSA])
92+
fi
93+
8294
AC_SUBST([AM_CPPFLAGS])
8395

8496
AC_CONFIG_FILES([Makefile src/Makefile src/tlshd/Makefile systemd/Makefile])

src/tlshd/client.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int tlshd_client_get_truststore(gnutls_certificate_credentials_t cred)
4848
char *pathname;
4949
int ret;
5050

51-
if (tlshd_config_get_client_truststore(&pathname)) {
51+
if (tlshd_config_get_truststore(PEER_TYPE_CLIENT, &pathname)) {
5252
ret = gnutls_certificate_set_x509_trust_file(cred, pathname,
5353
GNUTLS_X509_FMT_PEM);
5454
free(pathname);
@@ -60,7 +60,7 @@ static int tlshd_client_get_truststore(gnutls_certificate_credentials_t cred)
6060
}
6161
tlshd_log_debug("System trust: Loaded %d certificate(s).", ret);
6262

63-
if (tlshd_config_get_client_crl(&pathname)) {
63+
if (tlshd_config_get_crl(PEER_TYPE_CLIENT, &pathname)) {
6464
ret = gnutls_certificate_set_x509_crl_file(cred, pathname,
6565
GNUTLS_X509_FMT_PEM);
6666
free(pathname);
@@ -134,16 +134,21 @@ static void tlshd_tls13_client_anon_handshake(struct tlshd_handshake_parms *parm
134134
gnutls_certificate_free_credentials(xcred);
135135
}
136136

137+
static gnutls_privkey_t tlshd_pq_privkey;
137138
static gnutls_privkey_t tlshd_privkey;
139+
static unsigned int tlshd_pq_certs_len = TLSHD_MAX_CERTS;
138140
static unsigned int tlshd_certs_len = TLSHD_MAX_CERTS;
139141
static gnutls_pcert_st tlshd_certs[TLSHD_MAX_CERTS];
142+
static gnutls_pk_algorithm_t tlshd_pq_pkalg = GNUTLS_PK_UNKNOWN;
140143

141144
static bool tlshd_x509_client_get_certs(struct tlshd_handshake_parms *parms)
142145
{
143146
if (parms->x509_cert != TLS_NO_CERT)
144147
return tlshd_keyring_get_certs(parms->x509_cert, tlshd_certs,
145148
&tlshd_certs_len);
146-
return tlshd_config_get_client_certs(tlshd_certs, &tlshd_certs_len);
149+
return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs,
150+
&tlshd_pq_certs_len, &tlshd_certs_len,
151+
&tlshd_pq_pkalg);
147152
}
148153

149154
static void tlshd_x509_client_put_certs(void)
@@ -159,12 +164,14 @@ static bool tlshd_x509_client_get_privkey(struct tlshd_handshake_parms *parms)
159164
if (parms->x509_privkey != TLS_NO_PRIVKEY)
160165
return tlshd_keyring_get_privkey(parms->x509_privkey,
161166
&tlshd_privkey);
162-
return tlshd_config_get_client_privkey(&tlshd_privkey);
167+
return tlshd_config_get_privkey(PEER_TYPE_CLIENT, &tlshd_pq_privkey,
168+
&tlshd_privkey);
163169
}
164170

165171
static void tlshd_x509_client_put_privkey(void)
166172
{
167173
gnutls_privkey_deinit(tlshd_privkey);
174+
gnutls_privkey_deinit(tlshd_pq_privkey);
168175
}
169176

170177
static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
@@ -205,23 +212,46 @@ static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
205212
static int
206213
tlshd_x509_retrieve_key_cb(gnutls_session_t session,
207214
const gnutls_datum_t *req_ca_rdn, int nreqs,
208-
__attribute__ ((unused)) const gnutls_pk_algorithm_t *pk_algos,
209-
__attribute__ ((unused)) int pk_algos_length,
215+
const gnutls_pk_algorithm_t *pk_algos,
216+
int pk_algos_length,
210217
gnutls_pcert_st **pcert,
211218
unsigned int *pcert_length,
212219
gnutls_privkey_t *privkey)
213220
{
214221
gnutls_certificate_type_t type;
222+
bool use_pq_cert = false;
223+
int i;
215224

216225
tlshd_x509_log_issuers(req_ca_rdn, nreqs);
217226

218227
type = gnutls_certificate_type_get(session);
219228
if (type != GNUTLS_CRT_X509)
220229
return -1;
221230

222-
*pcert_length = tlshd_certs_len;
223-
*pcert = tlshd_certs;
224-
*privkey = tlshd_privkey;
231+
if (tlshd_pq_pkalg != GNUTLS_PK_UNKNOWN) {
232+
for (i = 0; i < pk_algos_length; i++) {
233+
if (pk_algos[i] == tlshd_pq_pkalg) {
234+
use_pq_cert = true;
235+
break;
236+
}
237+
}
238+
if (use_pq_cert == true) {
239+
tlshd_log_debug("%s: Server supports %s", __func__,
240+
gnutls_pk_algorithm_get_name(pk_algos[i]));
241+
}
242+
}
243+
244+
if (use_pq_cert == true) {
245+
tlshd_log_debug("%s: Selecting x509.pq.certificate from conf file", __func__);
246+
*pcert_length = tlshd_pq_certs_len;
247+
*pcert = tlshd_certs;
248+
*privkey = tlshd_pq_privkey;
249+
} else {
250+
tlshd_log_debug("%s: Selecting x509.certificate from conf file", __func__);
251+
*pcert_length = tlshd_certs_len;
252+
*pcert = tlshd_certs + tlshd_pq_certs_len;
253+
*privkey = tlshd_privkey;
254+
}
225255
return 0;
226256
}
227257

0 commit comments

Comments
 (0)