hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 284ec9f97be8b56acaa46effcfbd2438179e1f67
parent 92736948b8e09bc346946fbb2bdf7e2655f847f2
Author: Conrad Hoffmann <ch@bitfehler.net>
Date:   Thu, 10 Aug 2023 17:30:54 +0200

net::dns: support for basic DNSSEC RR types

This does not do any DNSSEC whatsoever, it only makes the RRs used by
DNSSEC available to an application that might want to use them.

Signed-off-by: Conrad Hoffmann <ch@bitfehler.net>

Diffstat:
Mnet/dns/decode.ha | 42++++++++++++++++++++++++++++++++++++++++++
Mnet/dns/types.ha | 43+++++++++++++++++++++++++++++++++++++++++--
2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/net/dns/decode.ha b/net/dns/decode.ha @@ -208,14 +208,20 @@ fn decode_rdata(dec: *decoder, rtype: rtype, rlen: size) (rdata | format) = { return decode_caa(&sub); case rtype::CNAME => return decode_cname(&sub); + case rtype::DNSKEY => + return decode_dnskey(&sub); case rtype::MX => return decode_mx(&sub); case rtype::NS => return decode_ns(&sub); case rtype::OPT => return decode_opt(&sub); + case rtype::NSEC => + return decode_nsec(&sub); case rtype::PTR => return decode_ptr(&sub); + case rtype::RRSIG => + return decode_rrsig(&sub); case rtype::SOA => return decode_soa(&sub); case rtype::SRV => @@ -284,6 +290,17 @@ fn decode_cname(dec: *decoder) (rdata | format) = { }; }; +fn decode_dnskey(dec: *decoder) (rdata | format) = { + let r = dnskey { + flags = decode_u16(dec)?, + protocol = decode_u8(dec)?, + algorithm = decode_u8(dec)?, + key = [], + }; + append(r.key, dec.cur[..]...); + return r; +}; + fn decode_mx(dec: *decoder) (rdata | format) = { return mx { priority = decode_u16(dec)?, @@ -325,12 +342,37 @@ fn decode_opt(dec: *decoder) (rdata | format) = { return r; }; +fn decode_nsec(dec: *decoder) (rdata | format) = { + let r = nsec { + next_domain = decode_name(dec)?, + type_bitmaps = [], + }; + append(r.type_bitmaps, dec.cur[..]...); + return r; +}; + fn decode_ptr(dec: *decoder) (rdata | format) = { return ptr { name = decode_name(dec)?, }; }; +fn decode_rrsig(dec: *decoder) (rdata | format) = { + let r = rrsig { + type_covered = decode_u16(dec)?, + algorithm = decode_u8(dec)?, + labels = decode_u8(dec)?, + orig_ttl = decode_u32(dec)?, + sig_expiration = decode_u32(dec)?, + sig_inception = decode_u32(dec)?, + key_tag = decode_u16(dec)?, + signer_name = decode_name(dec)?, + signature = [], + }; + append(r.signature, dec.cur[..]...); + return r; +}; + fn decode_soa(dec: *decoder) (rdata | format) = { return soa { mname = decode_name(dec)?, diff --git a/net/dns/types.ha b/net/dns/types.ha @@ -19,6 +19,8 @@ export type rtype = enum u16 { SRV = 33, OPT = 41, SSHFP = 44, + RRSIG = 46, + NSEC = 47, DNSKEY = 48, TSIG = 250, CAA = 257, @@ -37,6 +39,8 @@ export type qtype = enum u16 { SRV = 33, OPT = 41, SSHFP = 44, + RRSIG = 46, + NSEC = 47, DNSKEY = 48, // ... AXFR = 252, @@ -170,6 +174,14 @@ export type cname = struct { name: []str, }; +// A DNSKEY record. +export type dnskey = struct { + flags: u16, + protocol: u8, + algorithm: u8, + key: []u8, +}; + // An MX record. export type mx = struct { priority: u16, @@ -186,11 +198,30 @@ export type opt = struct { options: []edns_opt, }; +// An NSEC record. +export type nsec = struct { + next_domain: []str, + type_bitmaps: []u8, +}; + // A PTR record. export type ptr = struct { name: []str, }; +// An RRSIG record. +export type rrsig = struct { + type_covered: u16, + algorithm: u8, + labels: u8, + orig_ttl: u32, + sig_expiration: u32, + sig_inception: u32, + key_tag: u16, + signer_name: []str, + signature: []u8, +}; + // An SOA record. export type soa = struct { mname: []str, @@ -236,8 +267,8 @@ export type txt = [][]u8; export type unknown_rdata = []u8; // Tagged union of supported rdata types. -export type rdata = (a | aaaa | caa | cname | mx | ns | opt | ptr | soa | srv - | sshfp | tsig | txt | unknown_rdata); +export type rdata = (a | aaaa | caa | cname | dnskey | mx | ns | nsec | opt + | ptr | rrsig | soa | srv | sshfp | tsig | txt | unknown_rdata); // A DNS message, Hare representation. See [[encode]] and [[decode]] for the DNS // representation. @@ -285,6 +316,8 @@ fn rrecord_finish(rr: *rrecord) void = { case let ca: caa => free(ca.tag); free(ca.value); + case let dk: dnskey => + free(dk.key); case let mx: mx => strings::freeall(mx.name); case let ns: ns => @@ -294,8 +327,14 @@ fn rrecord_finish(rr: *rrecord) void = { free(opt.options[i].data); }; free(opt.options); + case let nsec: nsec => + strings::freeall(nsec.next_domain); + free(nsec.type_bitmaps); case let ptr: ptr => strings::freeall(ptr.name); + case let rrsig: rrsig => + strings::freeall(rrsig.signer_name); + free(rrsig.signature); case let so: soa => strings::freeall(so.mname); strings::freeall(so.rname);