Skip to content
Snippets Groups Projects
Commit a63ece01 authored by Alexander Schultz's avatar Alexander Schultz Committed by Daniel Salzman
Browse files

kdig: add support for connecting over TLS with a client cert/keyfile pair

parent 378c0aba
No related branches found
No related tags found
No related merge requests found
Pipeline #49586 passed with warnings
......@@ -257,6 +257,12 @@ Use TLS with a remote server hostname check.
\fB+\fP[\fBno\fP]\fBtls\-sni\fP=\fISTR\fP
Use TLS with a Server Name Indication.
.TP
\fB+\fP[\fBno\fP]\fBtls\-keyfile\fP=\fIFILE\fP
Use TLS with a client keyfile.
.TP
\fB+\fP[\fBno\fP]\fBtls\-certfile\fP=\fIFILE\fP
Use TLS with a client certfile.
.TP
\fB+\fP[\fBno\fP]\fBnsid\fP
Request the nameserver identifier (NSID).
.TP
......
......@@ -236,6 +236,12 @@ Options
**+**\ [\ **no**\ ]\ **tls-sni**\ =\ *STR*
Use TLS with a Server Name Indication.
**+**\ [\ **no**\ ]\ **tls-keyfile**\ =\ *FILE*
Use TLS with a client keyfile.
**+**\ [\ **no**\ ]\ **tls-certfile**\ =\ *FILE*
Use TLS with a client certfile.
**+**\ [\ **no**\ ]\ **nsid**
Request the nameserver identifier (NSID).
......
......@@ -65,6 +65,22 @@ int tls_params_copy(tls_params_t *dst, const tls_params_t *src)
}
}
if (src->keyfile != NULL) {
dst->keyfile = strdup(src->keyfile);
if (dst->keyfile == NULL) {
tls_params_clean(dst);
return KNOT_ENOMEM;
}
}
if (src->certfile != NULL) {
dst->certfile = strdup(src->certfile);
if (dst->certfile == NULL) {
tls_params_clean(dst);
return KNOT_ENOMEM;
}
}
ptrnode_t *n = NULL;
WALK_LIST(n, src->ca_files) {
char *src_file = (char *)n->d;
......@@ -106,6 +122,8 @@ void tls_params_clean(tls_params_t *params)
free(params->hostname);
free(params->sni);
free(params->keyfile);
free(params->certfile);
memset(params, 0, sizeof(*params));
}
......@@ -301,6 +319,33 @@ int tls_ctx_init(tls_ctx_t *ctx, const tls_params_t *params, int wait)
gnutls_certificate_set_verify_function(ctx->credentials, verify_certificate);
// Setup client keypair if specified. Both key and cert files must be provided.
if (params->keyfile != NULL && params->certfile != NULL) {
// First, try PEM.
ret = gnutls_certificate_set_x509_key_file(ctx->credentials,
params->certfile, params->keyfile, GNUTLS_X509_FMT_PEM);
if (ret != GNUTLS_E_SUCCESS) {
// If PEM didn't work, try DER.
ret = gnutls_certificate_set_x509_key_file(ctx->credentials,
params->certfile, params->keyfile, GNUTLS_X509_FMT_DER);
}
if (ret != GNUTLS_E_SUCCESS) {
WARN("TLS, failed to add client certfile '%s' and keyfile '%s'\n",
params->certfile, params->keyfile);
return KNOT_ERROR;
} else {
DBG("TLS, added client certfile '%s' and keyfile '%s'\n",
params->certfile, params->keyfile);
}
} else if (params->keyfile != NULL) {
WARN("TLS, cannot use client keyfile without a certfile\n");
return KNOT_ERROR;
} else if (params->certfile != NULL) {
WARN("TLS, cannot use client certfile without a keyfile\n");
return KNOT_ERROR;
}
return KNOT_EOK;
}
......
......@@ -35,6 +35,10 @@ typedef struct {
char *hostname;
/*! Optional server name indicator. */
char *sni;
/*! Optional client keyfile name. */
char *keyfile;
/*! Optional client certfile name. */
char *certfile;
} tls_params_t;
/*! \brief TLS context. */
......
......@@ -737,6 +737,46 @@ static int opt_notls_sni(const char *arg, void *query)
return KNOT_EOK;
}
static int opt_tls_keyfile(const char *arg, void *query)
{
query_t *q = query;
free(q->tls.keyfile);
q->tls.keyfile = strdup(arg);
return opt_tls(arg, query);
}
static int opt_notls_keyfile(const char *arg, void *query)
{
query_t *q = query;
free(q->tls.keyfile);
q->tls.keyfile = NULL;
return KNOT_EOK;
}
static int opt_tls_certfile(const char *arg, void *query)
{
query_t *q = query;
free(q->tls.certfile);
q->tls.certfile = strdup(arg);
return opt_tls(arg, query);
}
static int opt_notls_certfile(const char *arg, void *query)
{
query_t *q = query;
free(q->tls.certfile);
q->tls.certfile = NULL;
return KNOT_EOK;
}
static int opt_nsid(const char *arg, void *query)
{
query_t *q = query;
......@@ -1229,6 +1269,12 @@ static const param_t kdig_opts2[] = {
{ "tls-sni", ARG_REQUIRED, opt_tls_sni },
{ "notls-sni", ARG_NONE, opt_notls_sni },
{ "tls-keyfile", ARG_REQUIRED, opt_tls_keyfile },
{ "notls-keyfile", ARG_NONE, opt_notls_keyfile },
{ "tls-certfile", ARG_REQUIRED, opt_tls_certfile },
{ "notls-certfile", ARG_NONE, opt_notls_certfile },
{ "nsid", ARG_NONE, opt_nsid },
{ "nonsid", ARG_NONE, opt_nonsid },
......@@ -1931,6 +1977,8 @@ static void print_help(void)
" +[no]tls-pin=BASE64 Use TLS with pinned certificate.\n"
" +[no]tls-hostname=STR Use TLS with remote server hostname.\n"
" +[no]tls-sni=STR Use TLS with Server Name Indication.\n"
" +[no]tls-keyfile=FILE Use TLS with a client keyfile.\n"
" +[no]tls-certfile=FILE Use TLS with a client certfile.\n"
" +[no]nsid Request NSID.\n"
" +[no]bufsize=B Set EDNS buffer size.\n"
" +[no]padding[=N] Pad with EDNS(0) (default or specify size).\n"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment