Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft-fregly-dnsop-slh-dsa-mtl-dnssec support #397

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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