Skip to content

Commit a426a7f

Browse files
committed
tlshd: Add .conf option to specify trust store
Enable administrators to provide a trust store that is specifically for certificate verification during kernel-driven handshakes. This makes using self-signed certificates just for SunRPC more secure, for example. Partially addresses issue #21. Suggested-by: Olga Kornievskaia <kolga@netapp.com> Suggested-by: Ben Hutchings <benh@debian.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 12dc986 commit a426a7f

File tree

6 files changed

+94
-4
lines changed

6 files changed

+94
-4
lines changed

src/tlshd/client.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ static void tlshd_client_anon_handshake(struct tlshd_handshake_parms *parms)
4747
gnutls_certificate_credentials_t xcred;
4848
gnutls_session_t session;
4949
unsigned int flags;
50+
char *cafile;
5051
int ret;
5152

5253
ret = gnutls_certificate_allocate_credentials(&xcred);
@@ -63,7 +64,12 @@ static void tlshd_client_anon_handshake(struct tlshd_handshake_parms *parms)
6364
gnutls_certificate_set_flags(xcred,
6465
GNUTLS_CERTIFICATE_SKIP_KEY_CERT_MATCH | GNUTLS_CERTIFICATE_SKIP_OCSP_RESPONSE_CHECK);
6566

66-
ret = gnutls_certificate_set_x509_system_trust(xcred);
67+
if (tlshd_config_get_client_truststore(&cafile)) {
68+
ret = gnutls_certificate_set_x509_trust_file(xcred, cafile,
69+
GNUTLS_X509_FMT_PEM);
70+
free(cafile);
71+
} else
72+
ret = gnutls_certificate_set_x509_system_trust(xcred);
6773
if (ret < 0) {
6874
tlshd_log_gnutls_error(ret);
6975
goto out_free_creds;
@@ -247,6 +253,7 @@ static void tlshd_client_x509_handshake(struct tlshd_handshake_parms *parms)
247253
gnutls_certificate_credentials_t xcred;
248254
gnutls_session_t session;
249255
unsigned int flags;
256+
char *cafile;
250257
int ret;
251258

252259
ret = gnutls_certificate_allocate_credentials(&xcred);
@@ -255,7 +262,12 @@ static void tlshd_client_x509_handshake(struct tlshd_handshake_parms *parms)
255262
return;
256263
}
257264

258-
ret = gnutls_certificate_set_x509_system_trust(xcred);
265+
if (tlshd_config_get_client_truststore(&cafile)) {
266+
ret = gnutls_certificate_set_x509_trust_file(xcred, cafile,
267+
GNUTLS_X509_FMT_PEM);
268+
free(cafile);
269+
} else
270+
ret = gnutls_certificate_set_x509_system_trust(xcred);
259271
if (ret < 0) {
260272
tlshd_log_gnutls_error(ret);
261273
goto out_free_creds;

src/tlshd/config.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,36 @@ static bool tlshd_config_read_datum(const char *pathname, gnutls_datum_t *data,
184184
return ret;
185185
}
186186

187+
/**
188+
* tlshd_config_get_client_truststore - Get truststore for ClientHello from .conf
189+
* @bundle: OUT: pathname to truststore
190+
*
191+
* Return values:
192+
* %false: pathname not retrieved
193+
* %true: pathname retrieved successfully; caller must free @bundle using free(3)
194+
*/
195+
bool tlshd_config_get_client_truststore(char **bundle)
196+
{
197+
GError *error = NULL;
198+
gchar *pathname;
199+
200+
pathname = g_key_file_get_string(tlshd_configuration, "authenticate.client",
201+
"x509.truststore", &error);
202+
if (!pathname) {
203+
tlshd_log_gerror("Client x.509 truststore not specified", error);
204+
g_error_free(error);
205+
return false;
206+
}
207+
208+
*bundle = strdup(pathname);
209+
g_free(pathname);
210+
if (!*bundle)
211+
return false;
212+
213+
tlshd_log_debug("Client x.509 truststore is %s", *bundle);
214+
return true;
215+
}
216+
187217
/**
188218
* tlshd_config_get_client_cert - Get cert for ClientHello from .conf
189219
* @cert: OUT: in-memory certificate
@@ -280,6 +310,36 @@ bool tlshd_config_get_client_privkey(gnutls_privkey_t *privkey)
280310
return true;
281311
}
282312

313+
/**
314+
* tlshd_config_get_server_truststore - Get truststore for ServerHello from .conf
315+
* @bundle: OUT: pathname to truststore
316+
*
317+
* Return values:
318+
* %false: pathname not retrieved
319+
* %true: pathname retrieved successfully; caller must free @bundle using free(3)
320+
*/
321+
bool tlshd_config_get_server_truststore(char **bundle)
322+
{
323+
GError *error = NULL;
324+
gchar *pathname;
325+
326+
pathname = g_key_file_get_string(tlshd_configuration, "authenticate.server",
327+
"x509.truststore", &error);
328+
if (!pathname) {
329+
tlshd_log_gerror("Server x.509 truststore not specified", error);
330+
g_error_free(error);
331+
return false;
332+
}
333+
334+
*bundle = strdup(pathname);
335+
g_free(pathname);
336+
if (!*bundle)
337+
return false;
338+
339+
tlshd_log_debug("Server x.509 truststore is %s", *bundle);
340+
return true;
341+
}
342+
283343
/**
284344
* tlshd_config_get_server_cert - Get cert for ServerHello from .conf
285345
* @cert: OUT: in-memory certificate

src/tlshd/server.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ static void tlshd_server_x509_handshake(struct tlshd_handshake_parms *parms)
201201
{
202202
gnutls_certificate_credentials_t xcred;
203203
gnutls_session_t session;
204+
char *cafile;
204205
int ret;
205206

206207
ret = gnutls_certificate_allocate_credentials(&xcred);
@@ -209,7 +210,12 @@ static void tlshd_server_x509_handshake(struct tlshd_handshake_parms *parms)
209210
return;
210211
}
211212

212-
ret = gnutls_certificate_set_x509_system_trust(xcred);
213+
if (tlshd_config_get_server_truststore(&cafile)) {
214+
ret = gnutls_certificate_set_x509_trust_file(xcred, cafile,
215+
GNUTLS_X509_FMT_PEM);
216+
free(cafile);
217+
} else
218+
ret = gnutls_certificate_set_x509_system_trust(xcred);
213219
if (ret < 0) {
214220
tlshd_log_gnutls_error(ret);
215221
goto out_free_creds;

src/tlshd/tlshd.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ nl_debug=0
2828
#keyrings= <keyring>;<keyring>;<keyring>
2929

3030
[authenticate.client]
31+
#x509.truststore= <pathname>
3132
#x509.certificate= <pathname>
3233
#x509.private_key= <pathname>
3334

3435
[authenticate.server]
36+
#x509.truststore= <pathname>
3537
#x509.certificate= <pathname>
3638
#x509.private_key= <pathname>

src/tlshd/tlshd.conf.man

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,15 @@ section specifies default authentication material when establishing
8181
TLS sessions.
8282
There are two subsections:
8383
.IR [client] and [server] .
84-
In each of these subsections, there are two available options:
84+
In each of these subsections, there are three available options:
85+
.TP
86+
.B x509.truststore
87+
This option specifies the pathname of a file containing a
88+
PEM-encoded trust store that is to be used to verify a
89+
certificate during a handshake.
90+
If this option is not specified,
91+
.B tlshd
92+
uses the system's trust store.
8593
.TP
8694
.B x509.certificate
8795
This option specifies the pathname of a file containing

src/tlshd/tlshd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ extern void tlshd_clienthello_handshake(struct tlshd_handshake_parms *parms);
5252
/* config.c */
5353
bool tlshd_config_init(const gchar *pathname);
5454
void tlshd_config_shutdown(void);
55+
bool tlshd_config_get_client_truststore(char **bundle);
5556
bool tlshd_config_get_client_cert(gnutls_pcert_st *cert);
5657
bool tlshd_config_get_client_privkey(gnutls_privkey_t *privkey);
58+
bool tlshd_config_get_server_truststore(char **bundle);
5759
bool tlshd_config_get_server_cert(gnutls_pcert_st *cert);
5860
bool tlshd_config_get_server_privkey(gnutls_privkey_t *privkey);
5961

0 commit comments

Comments
 (0)