///|
pub struct Dnskey {
priv flags : Int32
priv algorithm : Int32
priv data : Bytes
} derive(Eq, Debug)
///|
pub extend Dnskey with Eq::{equal, not_equal}
///|
pub extend Dnskey with @debug.Debug::{to_repr}
///|
pub fn Dnskey::parse(data : Bytes) -> Result[Dnskey, DnsError] {
if data.length() < 5 || data.length() > 8192 {
return Err(Malformed("DNSKEY requires header and bounded public key"))
}
if data[2] != 3 {
return Err(Malformed("DNSKEY protocol must be three"))
}
let flags = u16_at(data, 0)
if (flags & 0x0100) == 0 {
return Err(Bogus("DNSKEY is not a zone key"))
}
if (flags & 0x0080) != 0 {
return Err(Bogus("revoked DNSKEY is not accepted"))
}
Ok({ flags, algorithm: data[3].to_int(), data, })
}
///|
pub fn Dnskey::rdata(self : Dnskey) -> Bytes {
self.data
}
///|
pub fn Dnskey::algorithm(self : Dnskey) -> Int32 {
self.algorithm
}
///|
pub fn Dnskey::is_sep(self : Dnskey) -> Bool {
(self.flags & 1) != 0
}
///|
pub struct Ds {
priv key_tag : Int32
priv algorithm : Int32
priv digest_type : Int32
priv digest : Bytes
} derive(Eq, Debug)
///|
pub extend Ds with Eq::{equal, not_equal}
///|
pub extend Ds with @debug.Debug::{to_repr}
///|
pub fn Ds::parse(data : Bytes) -> Result[Ds, DnsError] {
if data.length() < 5 {
return Err(Malformed("short DS record"))
}
let kind = data[3].to_int()
let expected = match kind {
1 => 20
2 => 32
4 => 48
_ => 0
}
if expected != 0 && data.length() != expected + 4 {
return Err(Malformed("DS digest length mismatch"))
}
if data.length() > 260 {
return Err(ResourceLimit("DS digest too large"))
}
Ok({
key_tag: u16_at(data, 0),
algorithm: data[2].to_int(),
digest_type: kind,
digest: data[4:].to_owned(),
})
}
///|
pub fn Ds::digest_type(self : Ds) -> Int32 {
self.digest_type
}
///|
fn u16_at(data : Bytes, p : Int32) -> Int32 {
(data[p].to_int() << 8) | data[p + 1].to_int()
}
///|
fn append16(out : Array[Byte], n : Int32) -> Unit {
out.push((n >> 8).to_byte())
out.push(n.to_byte())
}
///|
fn append_bytes(out : Array[Byte], data : Bytes) -> Unit {
for b in data {
out.push(b)
}
}
///|
pub fn Ds::rdata(self : Ds) -> Bytes {
let out : Array[Byte] = []
append16(out, self.key_tag)
out.push(self.algorithm.to_byte())
out.push(self.digest_type.to_byte())
append_bytes(out, self.digest)
Bytes::from_array(out)
}
///|
/// Explicitly supported signing algorithms; legacy RSA/SHA1 is not enabled.
pub fn supported_algorithm(algorithm : Int32) -> Bool {
algorithm == 8 ||
algorithm == 10 ||
algorithm == 13 ||
algorithm == 14 ||
algorithm == 15
}