Skip to content

Commit 98c3e0d

Browse files
benh-debianchucklever
authored andcommitted
Revert "tlshd: Do not return remote peer IDs for x.509 handshakes"
This reverts commit d507771, which seems to break mTLS. The symptoms for NFS are that a mount seems to succeed but then all operations on the client return EPERM. Use g_array_append_val() to store the peer IDs, as is done in in the PSK callback functions. Signed-off-by: Ben Hutchings <benh@debian.org>
1 parent 6d296ef commit 98c3e0d

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/tlshd/client.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ tlshd_x509_retrieve_key_cb(gnutls_session_t session,
235235
static int tlshd_client_x509_verify_function(gnutls_session_t session,
236236
struct tlshd_handshake_parms *parms)
237237
{
238-
unsigned int status;
238+
const gnutls_datum_t *peercerts;
239+
unsigned int i, status, num_peercerts;
239240
int ret;
240241

241242
ret = gnutls_certificate_verify_peers3(session, parms->peername,
@@ -251,6 +252,32 @@ static int tlshd_client_x509_verify_function(gnutls_session_t session,
251252
* to get picky. Kernel would have to tell us what to look for
252253
* via a netlink attribute. */
253254

255+
peercerts = gnutls_certificate_get_peers(session, &num_peercerts);
256+
if (!peercerts || num_peercerts == 0) {
257+
tlshd_log_debug("The peer cert list is empty.\n");
258+
return GNUTLS_E_CERTIFICATE_ERROR;
259+
}
260+
261+
tlshd_log_debug("The peer offered %u certificate(s).\n",
262+
num_peercerts);
263+
264+
for (i = 0; i < num_peercerts; i++) {
265+
gnutls_x509_crt_t cert;
266+
key_serial_t peerid;
267+
268+
gnutls_x509_crt_init(&cert);
269+
ret = gnutls_x509_crt_import(cert, &peercerts[i],
270+
GNUTLS_X509_FMT_DER);
271+
if (ret != GNUTLS_E_SUCCESS) {
272+
tlshd_log_gnutls_error(ret);
273+
gnutls_x509_crt_deinit(cert);
274+
return GNUTLS_E_CERTIFICATE_ERROR;
275+
}
276+
peerid = tlshd_keyring_create_cert(cert, parms->peername);
277+
g_array_append_val(parms->remote_peerids, peerid);
278+
gnutls_x509_crt_deinit(cert);
279+
}
280+
254281
return GNUTLS_E_SUCCESS;
255282
}
256283

src/tlshd/server.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,10 @@ static int tlshd_server_get_truststore(gnutls_certificate_credentials_t cred)
178178
* verification failed. The server sends an ALERT to the client.
179179
*/
180180
static int tlshd_server_x509_verify_function(gnutls_session_t session,
181-
__attribute__ ((unused)) struct tlshd_handshake_parms *parms)
181+
struct tlshd_handshake_parms *parms)
182182
{
183-
unsigned int status;
183+
const gnutls_datum_t *peercerts;
184+
unsigned int i, status, num_peercerts;
184185
int ret;
185186

186187
ret = gnutls_certificate_verify_peers3(session, NULL, &status);
@@ -201,6 +202,32 @@ static int tlshd_server_x509_verify_function(gnutls_session_t session,
201202
* to get picky. Kernel would have to tell us what to look for
202203
* via a netlink attribute. */
203204

205+
peercerts = gnutls_certificate_get_peers(session, &num_peercerts);
206+
if (!peercerts || num_peercerts == 0) {
207+
tlshd_log_debug("The peer cert list is empty.");
208+
goto certificate_error;
209+
}
210+
211+
tlshd_log_debug("The peer offered %u certificate(s).",
212+
num_peercerts);
213+
214+
for (i = 0; i < num_peercerts; i++) {
215+
gnutls_x509_crt_t cert;
216+
key_serial_t peerid;
217+
218+
gnutls_x509_crt_init(&cert);
219+
ret = gnutls_x509_crt_import(cert, &peercerts[i],
220+
GNUTLS_X509_FMT_DER);
221+
if (ret != GNUTLS_E_SUCCESS) {
222+
tlshd_log_gnutls_error(ret);
223+
gnutls_x509_crt_deinit(cert);
224+
return GNUTLS_E_CERTIFICATE_ERROR;
225+
}
226+
peerid = tlshd_keyring_create_cert(cert, parms->peername);
227+
g_array_append_val(parms->remote_peerids, peerid);
228+
gnutls_x509_crt_deinit(cert);
229+
}
230+
204231
return GNUTLS_E_SUCCESS;
205232

206233
certificate_error:

0 commit comments

Comments
 (0)