Skip to content

Commit

Permalink
draft-fregly-dnsop-slh-dsa-mtl-dnssec support
Browse files Browse the repository at this point in the history
  • Loading branch information
wtoorop committed Oct 25, 2024
1 parent 31c0fa0 commit 24bf39d
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 1 deletion.
18 changes: 18 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,24 @@ case "$enable_log_role" in
;;
esac

AC_ARG_ENABLE(draft-slh-dsa-mtl, AS_HELP_STRING([--enable-draft-slh-dsa-mtl[=optcode]],[Enables responding with SLH-DSA-MTL signatures as described in draft-fregly-dnsop-slh-dsa-mtl-dnssec. Opcode defaults to 65050]))
mtl_mode_full_code=""
case "$enable_draft_slh_dsa_mtl" in
""|no)
;;
yes)
AC_DEFINE_UNQUOTED([MTL_MODE_FULL_CODE], [65050], [Define this to enable answering with the full SLH-DSA-MTL signatures when queried with this EDNS opcode])
;;
*)
AC_DEFINE_UNQUOTED([MTL_MODE_FULL_CODE], [$enable_draft_slh_dsa_mtl], [Define this to enable answering with the full SLH-DSA-MTL signatures when queried with this EDNS opcode])
;;
esac
mtl_dnssec_alg=50
AC_ARG_WITH([slh-dsa-mtl-dnssec-alg],
AS_HELP_STRING([--with-slh-dsa-mtl-dnssec-alg=alg],[The algorithm used for SLH-DSA-MTL keys and signatures. Only relevant with draft-slh-dsa-mtl enabled. Defaults to 50.]),
[mtl_dnssec_alg=$withval])
AC_SUBST(mtl_dnssec_alg)
AC_DEFINE_UNQUOTED(MTL_DNSSEC_ALG, [$mtl_dnssec_alg], [The algorithm used for SLH-DSA-MTL keys and signatures. Default 50.])

AC_ARG_ENABLE(memclean, AS_HELP_STRING([--enable-memclean],[Cleanup memory (at exit) for eg. valgrind, memcheck]))
if test "$enable_memclean" = "yes"; then AC_DEFINE_UNQUOTED([MEMCLEAN], [1], [Define this to cleanup memory at exit (eg. for valgrind, etc.)])
Expand Down
8 changes: 8 additions & 0 deletions edns.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ edns_init_record(edns_record_type *edns)
edns->opt_reserved_space = 0;
edns->dnssec_ok = 0;
edns->nsid = 0;
#ifdef MTL_MODE_FULL_CODE
edns->mtl_mode_full = 0;
#endif
edns->cookie_status = COOKIE_NOT_PRESENT;
edns->cookie_len = 0;
edns->ede = -1; /* -1 means no Extended DNS Error */
Expand Down Expand Up @@ -116,6 +119,11 @@ edns_handle_option(uint16_t optcode, uint16_t optlen, buffer_type* packet,
buffer_skip(packet, optlen);
}
break;
#ifdef MTL_MODE_FULL_CODE
case MTL_MODE_FULL_CODE:
edns->mtl_mode_full = 1;
break;
#endif
default:
buffer_skip(packet, optlen);
break;
Expand Down
3 changes: 3 additions & 0 deletions edns.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ struct edns_record
int ede; /* RFC 8914 - Extended DNS Errors */
char* ede_text; /* RFC 8914 - Extended DNS Errors text*/
uint16_t ede_text_len;
#ifdef MTL_MODE_FULL_CODE
int mtl_mode_full;
#endif
};
typedef struct edns_record edns_record_type;

Expand Down
22 changes: 22 additions & 0 deletions namedb.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,28 @@ rr_rrsig_type_covered(rr_type* rr)
return ntohs(* (uint16_t *) rdata_atom_data(rr->rdatas[0]));
}

#ifdef MTL_MODE_FULL_CODE
uint8_t
rr_rrsig_algorithm(rr_type* rr)
{
assert(rr->type == TYPE_RRSIG);
assert(rr->rdata_count > 1);
assert(rdata_atom_size(rr->rdatas[1]) == sizeof(uint8_t));

return *(uint8_t*)rdata_atom_data(rr->rdatas[1]);
}

uint16_t
rr_rrsig_keytag(rr_type* rr)
{
assert(rr->type == TYPE_RRSIG);
assert(rr->rdata_count > 6);
assert(rdata_atom_size(rr->rdatas[6]) == sizeof(uint16_t));

return *(uint16_t*)rdata_atom_data(rr->rdatas[6]);
}
#endif

zone_type *
namedb_find_zone(namedb_type* db, const dname_type* dname)
{
Expand Down
12 changes: 12 additions & 0 deletions namedb.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,18 @@ static inline const char* domain_to_string_buf(domain_type* domain, char *buf)
*/
uint16_t rr_rrsig_type_covered(rr_type* rr);

#ifdef MTL_MODE_FULL_CODE
/*
* The algorithm field of the specified RRSIG RR
*/
uint8_t rr_rrsig_algorithm(rr_type* rr);

/*
* The keytag field of the specified RRSIG RR
*/
uint16_t rr_rrsig_keytag(rr_type* rr);
#endif

struct namedb
{
region_type* region;
Expand Down
60 changes: 60 additions & 0 deletions packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,66 @@ packet_encode_rr(query_type *q, domain_type *owner, rr_type *rr, uint32_t ttl)
buffer_skip(q->packet, sizeof(rdlength));

for (j = 0; j < rr->rdata_count; ++j) {
#ifdef MTL_MODE_FULL_CODE
rrset_type *apex_rrsigs;

if(rr->type == TYPE_RRSIG
&& j == 8 /* The signature data */
&& q->edns.mtl_mode_full
&& rr_rrsig_type_covered(rr) != TYPE_SOA
&& rr_rrsig_algorithm(rr) == MTL_DNSSEC_ALG
&& (apex_rrsigs = domain_find_rrset(
q->zone->apex, q->zone, TYPE_RRSIG))) {
size_t k;

buffer_write_u8(q->packet, 1); /* Full signature */
/* First the condensed signature */
buffer_write(q->packet,
rdata_atom_data(rr->rdatas[j])+1,
rdata_atom_size(rr->rdatas[j])-1);

for(k = 0; k < apex_rrsigs->rr_count; k++) {
rr_type* rrsig = &apex_rrsigs->rrs[k];
uint16_t sibling_count;

if(rrsig->rdata_count < 9
|| rr_rrsig_type_covered(rrsig) != TYPE_SOA
|| rr_rrsig_algorithm(rrsig) != MTL_DNSSEC_ALG
|| rr_rrsig_keytag(rrsig)!=rr_rrsig_keytag(rr))
continue;
/* MTL-Type = 1
* Randomizer = 16
* Flags = 2
* Series Identifier = 8
* Leaf Index = 4
* Target Rung Left Index = 4
* Target Rung Right Index = 4
* 1 + 16 + 2 + 8 + 4 + 4 + 4 = 39
* Next 2 (uint16_t) is Sibling Count
*/
if(rdata_atom_size(rrsig->rdatas[8]) < 41)
continue;
sibling_count = ntohs(*(uint16_t *)(
rdata_atom_data(rrsig->rdatas[8]) + 39));
/* Each sibling is 16 bytes, skipping them
* skips the complete Authentication Path
* and takes us to the remainder that needs
* to be appended to the RRSIG signature data.
*/
if(rdata_atom_size(rrsig->rdatas[8]) < 41 +
16 * sibling_count)
continue;
buffer_write(q->packet,
rdata_atom_data(rrsig->rdatas[8]) +
41 + 16 * sibling_count,
rdata_atom_size(rrsig->rdatas[8]) -
41 - 16 * sibling_count);
break;
}
if(k == apex_rrsigs->rr_count) {
}
} else
#endif
switch (rdata_atom_wireformat_type(rr->type, j)) {
case RDATA_WF_COMPRESSED_DNAME:
encode_dname(q, rdata_atom_domain(rr->rdatas[j]));
Expand Down
7 changes: 6 additions & 1 deletion zonec.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,12 @@ apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
zone->ns_rrset = rrset;
} else if (rrset_rrtype(rrset) == TYPE_RRSIG) {
for (i = 0; i < rrset->rr_count; ++i) {
if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY){
if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY
#ifdef MTL_MODE_FULL_CODE
|| (rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_SOA &&
rr_rrsig_algorithm(&rrset->rrs[i])==MTL_DNSSEC_ALG)
#endif
){
zone->is_secure = 1;
break;
}
Expand Down

0 comments on commit 24bf39d

Please sign in to comment.