Commit 404f1372 authored by Jan Včelák's avatar Jan Včelák 🚀

kdig: signing context outside packet creation

parent 210cf5b4
......@@ -23,6 +23,7 @@
#include "utils/common/exec.h"
#include "utils/common/msg.h"
#include "utils/common/netio.h"
#include "utils/common/sign.h"
#include "libknot/libknot.h"
#include "libknot/internal/lists.h"
#include "libknot/internal/print.h"
......@@ -388,17 +389,6 @@ static knot_pkt_t* create_query_packet(const query_t *query)
}
}
// Sign the packet if a key was specified.
if (query->tsig_key.name != NULL) {
ret = sign_packet(packet, &query->tsig_key);
if (ret != KNOT_EOK) {
ERR("failed to sign query packet (%s)\n",
knot_strerror(ret));
knot_pkt_free(&packet);
return NULL;
}
}
return packet;
}
......@@ -474,11 +464,31 @@ static bool last_serial_check(const uint32_t serial, const knot_pkt_t *reply)
}
}
static int sign_query(knot_pkt_t *pkt, const query_t *query, sign_context_t *ctx)
{
if (query->tsig_key.name == NULL) {
return KNOT_EOK;
}
int ret = sign_context_init_tsig(ctx, &query->tsig_key);
if (ret != KNOT_EOK) {
return ret;
}
ret = sign_packet(pkt, ctx);
if (ret != KNOT_EOK) {
sign_context_deinit(ctx);
return ret;
}
return KNOT_EOK;
}
static int process_query_packet(const knot_pkt_t *query,
net_t *net,
const query_t *query_ctx,
const bool ignore_tc,
const knot_tsig_key_t *tsig_key,
const sign_context_t *sign_ctx,
const style_t *style)
{
struct timeval t_start, t_query, t_end;
......@@ -589,15 +599,15 @@ static int process_query_packet(const knot_pkt_t *query,
net->socktype = SOCK_STREAM;
return process_query_packet(query, net, query_ctx, true,
tsig_key, style);
sign_ctx, style);
}
// Check for question sections equality.
check_reply_question(reply, query);
// Verify signature if a key was specified.
if (tsig_key->name != NULL) {
ret = verify_packet(reply, tsig_key);
if (sign_ctx->digest != NULL) {
ret = verify_packet(reply, sign_ctx);
if (ret != KNOT_EOK) {
ERR("reply verification for %s (%s)\n",
net->remote_str, knot_strerror(ret));
......@@ -641,6 +651,14 @@ static void process_query(const query_t *query)
return;
}
// Sign the query.
sign_context_t sign_ctx = { 0 };
ret = sign_query(out_packet, query, &sign_ctx);
if (ret != KNOT_EOK) {
ERR("can't sign the packet (%s)\n", knot_strerror(ret));
return;
}
// Get connection parameters.
int iptype = get_iptype(query->ip);
int socktype = get_socktype(query->protocol, query->type_num);
......@@ -668,7 +686,7 @@ static void process_query(const query_t *query)
ret = process_query_packet(out_packet, &net,
query,
query->ignore_tc,
&query->tsig_key,
&sign_ctx,
&query->style);
// If error try next resolved address.
if (ret != 0) {
......@@ -686,6 +704,7 @@ static void process_query(const query_t *query)
// Success.
if (ret == 0) {
net_clean(&net);
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
return;
// SERVFAIL.
......@@ -694,6 +713,7 @@ static void process_query(const query_t *query)
remote->name, remote->service,
get_sockname(socktype));
net_clean(&net);
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
return;
}
......@@ -717,13 +737,14 @@ static void process_query(const query_t *query)
}
}
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
}
static int process_xfr_packet(const knot_pkt_t *query,
net_t *net,
const query_t *query_ctx,
const knot_tsig_key_t *tsig_key,
const sign_context_t *sign_ctx,
const style_t *style)
{
struct timeval t_start, t_query, t_end;
......@@ -833,8 +854,8 @@ static int process_xfr_packet(const knot_pkt_t *query,
// The first message has a special treatment.
if (msg_count == 0) {
// Verify 1. signature if a key was specified.
if (tsig_key->name != NULL) {
ret = verify_packet(reply, tsig_key);
if (sign_ctx->digest != NULL) {
ret = verify_packet(reply, sign_ctx);
if (ret != KNOT_EOK) {
ERR("reply verification for %s (%s)\n",
net->remote_str, knot_strerror(ret));
......@@ -904,6 +925,14 @@ static void process_xfr(const query_t *query)
return;
}
// Sign the query.
sign_context_t sign_ctx = { 0 };
ret = sign_query(out_packet, query, &sign_ctx);
if (ret != KNOT_EOK) {
ERR("can't sign the packet (%s)\n", knot_strerror(ret));
return;
}
// Get connection parameters.
int iptype = get_iptype(query->ip);
int socktype = get_socktype(query->protocol, query->type_num);
......@@ -920,6 +949,7 @@ static void process_xfr(const query_t *query)
ret = net_init(query->local, remote, iptype, socktype,
query->wait, &net);
if (ret != KNOT_EOK) {
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
return;
}
......@@ -928,7 +958,7 @@ static void process_xfr(const query_t *query)
while (net.srv != NULL) {
ret = process_xfr_packet(out_packet, &net,
query,
&query->tsig_key,
&sign_ctx,
&query->style);
// If error try next resolved address.
if (ret != 0) {
......@@ -945,6 +975,7 @@ static void process_xfr(const query_t *query)
}
net_clean(&net);
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
}
......
......@@ -920,9 +920,13 @@ query_t* query_create(const char *owner, const query_t *conf)
query->dt_reader = conf->dt_reader;
query->dt_writer = conf->dt_writer;
#endif // USE_DNSTAP
if (knot_tsig_key_copy(&query->tsig_key, &conf->tsig_key) != KNOT_EOK) {
query_free(query);
return NULL;
if (conf->tsig_key.name) {
int r = knot_tsig_key_copy(&query->tsig_key, &conf->tsig_key);
if (r != KNOT_EOK) {
query_free(query);
return NULL;
}
}
}
......@@ -954,7 +958,7 @@ void query_free(query_t *query)
srv_info_free(query->local);
}
// Cleanup cryptographic content.
// Cleanup signing key.
knot_tsig_key_deinit(&query->tsig_key);
#if USE_DNSTAP
......
......@@ -30,6 +30,7 @@
#include "utils/common/params.h"
#include "utils/common/exec.h"
#include "utils/common/sign.h"
#include "libknot/libknot.h"
#include "libknot/internal/sockaddr.h"
......@@ -133,7 +134,7 @@ struct query {
bool nsid;
/*!< EDNS version (8unsigned + -1 uninitialized). */
int16_t edns;
/*!< TSIG key. */
/*!< Transaction signature. */
knot_tsig_key_t tsig_key;
/*!< EDNS client subnet. */
subnet_t *subnet;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment