mirror of https://github.com/getdnsapi/getdns.git
Track updating TA's with root DNSKEY rrset
This commit is contained in:
parent
e2ffaf3e07
commit
34d35f9e79
305
src/anchor.c
305
src/anchor.c
|
@ -45,9 +45,10 @@
|
|||
#include "gldns/parseutil.h"
|
||||
#include "gldns/gbuffer.h"
|
||||
#include "gldns/str2wire.h"
|
||||
#include "gldns/wire2str.h"
|
||||
#include "gldns/pkthdr.h"
|
||||
#include "gldns/keyraw.h"
|
||||
#include "general.h"
|
||||
#include "rr-iter.h"
|
||||
#include "util-internal.h"
|
||||
|
||||
/* get key usage out of its extension, returns 0 if no key_usage extension */
|
||||
|
@ -741,7 +742,6 @@ void _getdns_context_equip_with_anchor(
|
|||
else if (!verify_CA || !*verify_CA)
|
||||
DEBUG_ANCHOR("NOTICE: Trust anchor verification explicitely "
|
||||
"disabled by empty verify CA\n");
|
||||
return;
|
||||
|
||||
else if ((r = getdns_context_get_trust_anchor_verify_email(
|
||||
context, ".", &verify_email)))
|
||||
|
@ -1612,4 +1612,305 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
|
|||
context->trust_anchors_source = GETDNS_TASRC_FETCHING;
|
||||
}
|
||||
|
||||
|
||||
static int _uint16_cmp(const void *a, const void *b)
|
||||
{ return (int)*(uint16_t *)a - (int)*(uint16_t *)b; }
|
||||
|
||||
static int _uint8x16_cmp(const void *a, const void *b)
|
||||
{ return memcmp(a, b, RRSIG_RDATA_LEN); }
|
||||
|
||||
static void
|
||||
_getdns_init_ksks(_getdns_ksks *ksks, _getdns_rrset *dnskey_set)
|
||||
{
|
||||
_getdns_rrtype_iter *rr, rr_space;
|
||||
_getdns_rrsig_iter *rrsig, rrsig_space;
|
||||
|
||||
assert(ksks);
|
||||
assert(dnskey_set);
|
||||
assert(dnskey_set->rr_type == GETDNS_RRTYPE_DNSKEY);
|
||||
|
||||
ksks->n = 0;
|
||||
for ( rr = _getdns_rrtype_iter_init(&rr_space, dnskey_set)
|
||||
; rr && ksks->n < MAX_KSKS
|
||||
; rr = _getdns_rrtype_iter_next(rr)) {
|
||||
|
||||
if (rr->rr_i.nxt - rr->rr_i.rr_type < 12
|
||||
|| !(rr->rr_i.rr_type[11] & 1))
|
||||
continue; /* Not a KSK */
|
||||
|
||||
ksks->ids[ksks->n++] = gldns_calc_keytag_raw(
|
||||
rr->rr_i.rr_type + 10,
|
||||
rr->rr_i.nxt - rr->rr_i.rr_type - 10);
|
||||
}
|
||||
qsort(ksks->ids, ksks->n, sizeof(uint16_t), _uint16_cmp);
|
||||
|
||||
ksks->n_rrsigs = 0;
|
||||
for ( rrsig = _getdns_rrsig_iter_init(&rrsig_space, dnskey_set)
|
||||
; rrsig && ksks->n_rrsigs < MAX_KSKS
|
||||
; rrsig = _getdns_rrsig_iter_next(rrsig)) {
|
||||
|
||||
if (rrsig->rr_i.nxt - rrsig->rr_i.rr_type < 28)
|
||||
continue;
|
||||
|
||||
(void) memcpy(ksks->rrsigs[ksks->n_rrsigs++],
|
||||
rrsig->rr_i.rr_type + 12, RRSIG_RDATA_LEN);
|
||||
}
|
||||
qsort(ksks->rrsigs, ksks->n_rrsigs, RRSIG_RDATA_LEN, _uint8x16_cmp);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_getdns_ksks_equal(_getdns_ksks *a, _getdns_ksks *b)
|
||||
{
|
||||
return a == b
|
||||
|| ( a != NULL && b != NULL
|
||||
&& a->n == b->n
|
||||
&& memcmp(a->ids, b->ids, a->n * sizeof(uint16_t)) == 0
|
||||
&& a->n_rrsigs == b->n_rrsigs
|
||||
&& memcmp(a->rrsigs, b->rrsigs, a->n_rrsigs * RRSIG_RDATA_LEN) == 0);
|
||||
}
|
||||
|
||||
static void _getdns_context_read_root_ksk(getdns_context *context)
|
||||
{
|
||||
FILE *fp;
|
||||
struct gldns_file_parse_state pst;
|
||||
size_t len, dname_len;
|
||||
uint8_t buf_spc[4096], *buf = buf_spc, *ptr = buf_spc;
|
||||
size_t buf_sz = sizeof(buf_spc);
|
||||
_getdns_rrset root_dnskey;
|
||||
uint8_t *root_dname = (uint8_t *)"\00";
|
||||
|
||||
|
||||
if (!(fp = _getdns_context_get_priv_fp(context, "root.key")))
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
size_t n_rrs = 0;
|
||||
|
||||
*pst.origin = 0;
|
||||
pst.origin_len = 1;
|
||||
*pst.prev_rr = 0;
|
||||
pst.prev_rr_len = 1;
|
||||
pst.default_ttl = 0;
|
||||
pst.lineno = 1;
|
||||
|
||||
(void) memset(buf, 0, 12);
|
||||
ptr += 12;
|
||||
|
||||
while (!feof(fp)) {
|
||||
len = buf + buf_sz - ptr;
|
||||
dname_len = 0;
|
||||
if (gldns_fp2wire_rr_buf(fp, ptr, &len, &dname_len, &pst))
|
||||
break;
|
||||
if ((ptr += len) > buf + buf_sz)
|
||||
break;
|
||||
if (len)
|
||||
n_rrs += 1;
|
||||
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
|
||||
memcpy(pst.prev_rr, ptr, dname_len);
|
||||
pst.prev_rr_len = dname_len;
|
||||
}
|
||||
}
|
||||
if (ptr <= buf + buf_sz) {
|
||||
gldns_write_uint16(buf + GLDNS_ANCOUNT_OFF, n_rrs);
|
||||
break;
|
||||
}
|
||||
rewind(fp);
|
||||
if (buf == buf_spc)
|
||||
buf_sz = 65536;
|
||||
else {
|
||||
GETDNS_FREE(context->mf, buf);
|
||||
buf_sz *= 2;
|
||||
}
|
||||
if (!(buf = GETDNS_XMALLOC(context->mf, uint8_t, buf_sz))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__);
|
||||
break;;
|
||||
}
|
||||
ptr = buf;
|
||||
};
|
||||
fclose(fp);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
root_dnskey.name = root_dname;
|
||||
root_dnskey.rr_class = GETDNS_RRCLASS_IN;
|
||||
root_dnskey.rr_type = GETDNS_RRTYPE_DNSKEY;
|
||||
root_dnskey.pkt = buf;
|
||||
root_dnskey.pkt_len = ptr - buf;
|
||||
root_dnskey.sections = SECTION_ANSWER;
|
||||
|
||||
_getdns_init_ksks(&context->root_ksk, &root_dnskey);
|
||||
|
||||
if (buf && buf != buf_spc)
|
||||
GETDNS_FREE(context->mf, buf);
|
||||
}
|
||||
|
||||
void
|
||||
_getdns_context_update_root_ksk(
|
||||
getdns_context *context, _getdns_rrset *dnskey_set)
|
||||
{
|
||||
_getdns_ksks root_ksk_seen;
|
||||
_getdns_rrtype_iter *rr, rr_space;
|
||||
_getdns_rrsig_iter *rrsig, rrsig_space;
|
||||
char str_spc[4096], *str_buf, *str_pos;
|
||||
int sz_needed;
|
||||
int remaining;
|
||||
size_t str_sz = 0;
|
||||
getdns_bindata root_key_bd;
|
||||
|
||||
_getdns_init_ksks(&root_ksk_seen, dnskey_set);
|
||||
if (_getdns_ksks_equal(&context->root_ksk, &root_ksk_seen))
|
||||
return; /* root DNSKEY rrset already known */
|
||||
|
||||
/* Try to read root DNSKEY rrset from root.key */
|
||||
_getdns_context_read_root_ksk(context);
|
||||
if (_getdns_ksks_equal(&context->root_ksk, &root_ksk_seen))
|
||||
return; /* root DNSKEY rrset same as the safed one */
|
||||
|
||||
/* Different root DNSKEY rrset. Perhaps because of failure to read
|
||||
* from disk. If we cannot write to our appdata directory, bail out
|
||||
*/
|
||||
if (context->can_write_appdata == PROP_UNABLE)
|
||||
return;
|
||||
|
||||
/* We might be able to write or we do not know whether we can write
|
||||
* to the appdata directory. In the latter we'll try to write to
|
||||
* find out. The section below converts the wireformat DNSKEY rrset
|
||||
* to presentationformat.
|
||||
*/
|
||||
str_pos = str_buf = str_spc;
|
||||
remaining = sizeof(str_spc);
|
||||
for (;;) {
|
||||
for ( rr = _getdns_rrtype_iter_init(&rr_space, dnskey_set)
|
||||
; rr ; rr = _getdns_rrtype_iter_next(rr)) {
|
||||
|
||||
sz_needed = gldns_wire2str_rr_buf((uint8_t *)rr->rr_i.pos,
|
||||
rr->rr_i.nxt - rr->rr_i.pos, str_pos,
|
||||
(size_t)(remaining > 0 ? remaining : 0));
|
||||
|
||||
str_pos += sz_needed;
|
||||
remaining -= sz_needed;
|
||||
}
|
||||
for ( rrsig = _getdns_rrsig_iter_init(&rrsig_space, dnskey_set)
|
||||
; rrsig
|
||||
; rrsig = _getdns_rrsig_iter_next(rrsig)) {
|
||||
sz_needed = gldns_wire2str_rr_buf((uint8_t *)rrsig->rr_i.pos,
|
||||
rrsig->rr_i.nxt - rrsig->rr_i.pos, str_pos,
|
||||
(size_t)(remaining > 0 ? remaining : 0));
|
||||
|
||||
str_pos += sz_needed;
|
||||
remaining -= sz_needed;
|
||||
}
|
||||
if (remaining > 0) {
|
||||
*str_pos = 0;
|
||||
if (str_buf == str_spc)
|
||||
str_sz = sizeof(str_spc) - remaining;
|
||||
break;
|
||||
}
|
||||
if (str_buf != str_spc) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Buffer size determination "
|
||||
"error\n", __FUNC__);
|
||||
if (str_buf)
|
||||
GETDNS_FREE(context->mf, str_buf);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!(str_pos = str_buf = GETDNS_XMALLOC( context->mf, char,
|
||||
(str_sz = sizeof(str_spc) - remaining) + 1))) {
|
||||
DEBUG_ANCHOR("ERROR %s(): Memory error\n", __FUNC__);
|
||||
return;
|
||||
}
|
||||
remaining = str_sz + 1;
|
||||
DEBUG_ANCHOR("Retrying with buf size: %d\n", remaining);
|
||||
};
|
||||
|
||||
/* Write presentation format DNSKEY rrset to "root.key" file */
|
||||
root_key_bd.size = str_sz;
|
||||
root_key_bd.data = (void *)str_buf;
|
||||
if (_getdns_context_write_priv_file(
|
||||
context, "root.key", &root_key_bd)) {
|
||||
size_t i;
|
||||
|
||||
/* A new "root.key" file was written. When they contain
|
||||
* key_id's which are not in "root-anchors.xml", then update
|
||||
* "root-anchors.xml".
|
||||
*/
|
||||
|
||||
for (i = 0; i < context->root_ksk.n; i++) {
|
||||
_getdns_rrset_iter tas_iter_spc, *ta;
|
||||
|
||||
for ( ta = _getdns_rrset_iter_init(&tas_iter_spc
|
||||
, context->trust_anchors
|
||||
, context->trust_anchors_len
|
||||
, SECTION_ANSWER)
|
||||
; ta ; ta = _getdns_rrset_iter_next(ta)) {
|
||||
_getdns_rrtype_iter *rr, rr_space;
|
||||
_getdns_rrset *rrset;
|
||||
|
||||
if (!(rrset = _getdns_rrset_iter_value(ta)))
|
||||
continue;
|
||||
|
||||
if (*rrset->name != '\0')
|
||||
continue; /* Not a root anchor */
|
||||
|
||||
if (rrset->rr_type == GETDNS_RRTYPE_DS) {
|
||||
for ( rr = _getdns_rrtype_iter_init(
|
||||
&rr_space, rrset)
|
||||
; rr
|
||||
; rr = _getdns_rrtype_iter_next(rr)
|
||||
) {
|
||||
if (rr->rr_i.nxt -
|
||||
rr->rr_i.rr_type < 12)
|
||||
continue;
|
||||
|
||||
DEBUG_ANCHOR("DS with id: %d\n"
|
||||
, (int)gldns_read_uint16(rr->rr_i.rr_type + 10));
|
||||
if (gldns_read_uint16(
|
||||
rr->rr_i.rr_type + 10) ==
|
||||
context->root_ksk.ids[i])
|
||||
break;
|
||||
}
|
||||
if (rr)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (rrset->rr_type != GETDNS_RRTYPE_DNSKEY)
|
||||
continue;
|
||||
|
||||
for ( rr = _getdns_rrtype_iter_init(&rr_space
|
||||
, rrset)
|
||||
; rr ; rr = _getdns_rrtype_iter_next(rr)) {
|
||||
|
||||
|
||||
if (rr->rr_i.nxt-rr->rr_i.rr_type < 12
|
||||
|| !(rr->rr_i.rr_type[11] & 1))
|
||||
continue; /* Not a KSK */
|
||||
|
||||
if (gldns_calc_keytag_raw(
|
||||
rr->rr_i.rr_type + 10,
|
||||
rr->rr_i.nxt-rr->rr_i.rr_type - 10)
|
||||
== context->root_ksk.ids[i])
|
||||
break;
|
||||
}
|
||||
if (rr)
|
||||
break;
|
||||
}
|
||||
if (!ta) {
|
||||
DEBUG_ANCHOR("NOTICE %s(): Key with id %d "
|
||||
"*not* found in TA.\n"
|
||||
"\"root-anchors.xml\" need "
|
||||
"updating.\n", __FUNC__
|
||||
, context->root_ksk.ids[i]);
|
||||
context->trust_anchors_source =
|
||||
GETDNS_TASRC_XML_UPDATE;
|
||||
break;
|
||||
}
|
||||
DEBUG_ANCHOR("DEBUG %s(): Key with id %d found in TA\n"
|
||||
, __FUNC__, context->root_ksk.ids[i]);
|
||||
}
|
||||
}
|
||||
if (str_buf && str_buf != str_spc)
|
||||
GETDNS_FREE(context->mf, str_buf);
|
||||
}
|
||||
|
||||
/* anchor.c */
|
||||
|
|
13
src/anchor.h
13
src/anchor.h
|
@ -37,10 +37,23 @@
|
|||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include <time.h>
|
||||
#include "rr-iter.h"
|
||||
|
||||
void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms);
|
||||
|
||||
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop);
|
||||
|
||||
#define MAX_KSKS 16
|
||||
#define RRSIG_RDATA_LEN 16
|
||||
typedef struct _getdns_ksks {
|
||||
size_t n;
|
||||
uint16_t ids[MAX_KSKS];
|
||||
size_t n_rrsigs;
|
||||
uint8_t rrsigs[MAX_KSKS][RRSIG_RDATA_LEN];
|
||||
} _getdns_ksks;
|
||||
|
||||
void _getdns_context_update_root_ksk(
|
||||
getdns_context *context, _getdns_rrset *dnskey_set);
|
||||
|
||||
#endif
|
||||
/* anchor.h */
|
||||
|
|
|
@ -1500,6 +1500,8 @@ getdns_context_create_with_extended_memory_functions(
|
|||
= _getdns_default_root_anchor_verify_email;
|
||||
result->root_anchor_verify_CA = _getdns_default_root_anchor_verify_CA;
|
||||
|
||||
(void) memset(&result->root_ksk, 0, sizeof(result->root_ksk));
|
||||
|
||||
(void) memset(&result->a, 0, sizeof(result->a));
|
||||
(void) memset(&result->aaaa, 0, sizeof(result->aaaa));
|
||||
result->a.fd = -1;
|
||||
|
@ -4654,13 +4656,13 @@ static size_t _getdns_get_appdata(char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz)
|
||||
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
FILE *f = NULL;
|
||||
size_t len;
|
||||
|
||||
(void) context;
|
||||
if (!(len = _getdns_get_appdata(path)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||
, __FUNC__);
|
||||
|
@ -4675,6 +4677,17 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
|||
DEBUG_ANCHOR("ERROR %s(): Opening \"%s\": %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
|
||||
if (!(f = _getdns_context_get_priv_fp(context, fn)))
|
||||
; /* pass */
|
||||
|
||||
else if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) {
|
||||
buf[*file_sz] = 0;
|
||||
(void) fclose(f);
|
||||
|
@ -4682,19 +4695,19 @@ uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
|||
}
|
||||
else if (fseek(f, 0, SEEK_END) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
, __FUNC__, fn, strerror(errno));
|
||||
|
||||
else if (!(buf = GETDNS_XMALLOC(
|
||||
context->mf, uint8_t, (buf_len = ftell(f) + 1))))
|
||||
DEBUG_ANCHOR("ERROR %s(): Allocating %d memory for \"%s\"\n"
|
||||
, __FUNC__, (int)buf_len, path);
|
||||
, __FUNC__, (int)buf_len, fn);
|
||||
|
||||
else {
|
||||
rewind(f);
|
||||
if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) {
|
||||
GETDNS_FREE(context->mf, buf);
|
||||
DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
, __FUNC__, fn, strerror(errno));
|
||||
}
|
||||
else {
|
||||
buf[*file_sz] = 0;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "util/lruhash.h"
|
||||
#endif
|
||||
#include "rr-iter.h"
|
||||
#include "anchor.h"
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct ub_ctx;
|
||||
|
@ -99,6 +100,7 @@ typedef enum getdns_tasrc {
|
|||
GETDNS_TASRC_APP,
|
||||
GETDNS_TASRC_FETCHING,
|
||||
GETDNS_TASRC_XML,
|
||||
GETDNS_TASRC_XML_UPDATE,
|
||||
GETDNS_TASRC_FAILED
|
||||
} getdns_tasrc;
|
||||
|
||||
|
@ -341,6 +343,8 @@ struct getdns_context {
|
|||
const char *root_anchor_verify_CA;
|
||||
const char *root_anchor_verify_email;
|
||||
|
||||
_getdns_ksks root_ksk;
|
||||
|
||||
getdns_upstreams *upstreams;
|
||||
uint16_t limit_outstanding_queries;
|
||||
uint32_t dnssec_allowed_skew;
|
||||
|
@ -545,6 +549,7 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
|||
|
||||
void _getdns_upstream_shutdown(getdns_upstream *upstream);
|
||||
|
||||
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn);
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
|
||||
|
||||
|
|
15
src/dnssec.c
15
src/dnssec.c
|
@ -2998,6 +2998,11 @@ static void append_empty_ds2val_chain_list(
|
|||
if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
||||
getdns_dict_destroy(rr_dict);
|
||||
}
|
||||
static inline chain_node *_to_the_root(chain_node *node)
|
||||
{
|
||||
while (node->parent) node = node->parent;
|
||||
return node;
|
||||
}
|
||||
|
||||
static void check_chain_complete(chain_head *chain)
|
||||
{
|
||||
|
@ -3063,6 +3068,16 @@ static void check_chain_complete(chain_head *chain)
|
|||
, context->trust_anchors_len
|
||||
, SECTION_ANSWER));
|
||||
#endif
|
||||
if (context->trust_anchors_source != GETDNS_TASRC_XML)
|
||||
; /* pass */
|
||||
|
||||
/* Find root key or query for it in full recursion... */
|
||||
else if (!(head = chain) || !(node = _to_the_root(head->parent)))
|
||||
; /* pass */
|
||||
|
||||
else if (node->dnskey.name && *node->dnskey.name == 0)
|
||||
_getdns_context_update_root_ksk(context, &node->dnskey);
|
||||
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
if ( dnsreq->dnssec_roadblock_avoidance
|
||||
&& !dnsreq->avoid_dnssec_roadblocks
|
||||
|
|
|
@ -581,11 +581,15 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
req->internal_cb = internal_cb;
|
||||
req->is_sync_request = loop == &context->sync_eventloop.loop;
|
||||
|
||||
if (req->dnssec_return_status &&
|
||||
context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_context_equip_with_anchor(context, &now_ms);
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_NONE)
|
||||
if (req->dnssec_return_status) {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_XML_UPDATE)
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
|
||||
else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_context_equip_with_anchor(context, &now_ms);
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_NONE)
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
}
|
||||
}
|
||||
/* Set up the context assuming we won't use the specified namespaces.
|
||||
This is (currently) identical to setting up a pure DNS namespace */
|
||||
|
|
|
@ -95,7 +95,7 @@ gldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize)
|
||||
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize)
|
||||
{
|
||||
if(keysize < 4) {
|
||||
return 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ size_t gldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
|
|||
* \param[in] keysize length of key data.
|
||||
* \return the keytag
|
||||
*/
|
||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize);
|
||||
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize);
|
||||
|
||||
#if GLDNS_BUILD_CONFIG_HAVE_SSL
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue