Skip to content

Commit facd084

Browse files
committed
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: #113 Signed-off-by: Scott Mayhew <[email protected]>
1 parent 14f5349 commit facd084

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

src/tlshd/client.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +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_certs(PEER_TYPE_CLIENT, tlshd_certs, NULL,
147-
&tlshd_certs_len, NULL);
149+
return tlshd_config_get_certs(PEER_TYPE_CLIENT, tlshd_certs,
150+
&tlshd_pq_certs_len, &tlshd_certs_len,
151+
&tlshd_pq_pkalg);
148152
}
149153

150154
static void tlshd_x509_client_put_certs(void)
@@ -160,12 +164,14 @@ static bool tlshd_x509_client_get_privkey(struct tlshd_handshake_parms *parms)
160164
if (parms->x509_privkey != TLS_NO_PRIVKEY)
161165
return tlshd_keyring_get_privkey(parms->x509_privkey,
162166
&tlshd_privkey);
163-
return tlshd_config_get_privkey(PEER_TYPE_CLIENT, NULL, &tlshd_privkey);
167+
return tlshd_config_get_privkey(PEER_TYPE_CLIENT, &tlshd_pq_privkey,
168+
&tlshd_privkey);
164169
}
165170

166171
static void tlshd_x509_client_put_privkey(void)
167172
{
168173
gnutls_privkey_deinit(tlshd_privkey);
174+
gnutls_privkey_deinit(tlshd_pq_privkey);
169175
}
170176

171177
static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
@@ -206,23 +212,46 @@ static void tlshd_x509_log_issuers(const gnutls_datum_t *req_ca_rdn, int nreqs)
206212
static int
207213
tlshd_x509_retrieve_key_cb(gnutls_session_t session,
208214
const gnutls_datum_t *req_ca_rdn, int nreqs,
209-
__attribute__ ((unused)) const gnutls_pk_algorithm_t *pk_algos,
210-
__attribute__ ((unused)) int pk_algos_length,
215+
const gnutls_pk_algorithm_t *pk_algos,
216+
int pk_algos_length,
211217
gnutls_pcert_st **pcert,
212218
unsigned int *pcert_length,
213219
gnutls_privkey_t *privkey)
214220
{
215221
gnutls_certificate_type_t type;
222+
bool use_pq_cert = false;
223+
int i;
216224

217225
tlshd_x509_log_issuers(req_ca_rdn, nreqs);
218226

219227
type = gnutls_certificate_type_get(session);
220228
if (type != GNUTLS_CRT_X509)
221229
return -1;
222230

223-
*pcert_length = tlshd_certs_len;
224-
*pcert = tlshd_certs;
225-
*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+
}
226255
return 0;
227256
}
228257

src/tlshd/tlshd.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ nl=0
3333
#x509.crl= <pathname>
3434
#x509.certificate= <pathname>
3535
#x509.private_key= <pathname>
36+
#x509.pq.certificate= <pathname>
37+
#x509.pq.private_key= <pathname>
3638

3739
[authenticate.server]
3840
#x509.truststore= <pathname>

0 commit comments

Comments
 (0)