const TYPE: u16;
fn name(&self) -> &Name;
fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>);
- fn read_from_data(name: Name, data: &[u8]) -> Result<Self, ()>;
+ fn read_from_data(name: Name, data: &[u8], wire_packet: &[u8]) -> Result<Self, ()>;
}
/// A trait describing a resource record (including the [`RR`] enum).
pub trait Record : Ord {
impl StaticRecord for Txt {
const TYPE: u16 = 16;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
let mut parsed_data = Vec::with_capacity(data.len() - 1);
while !data.is_empty() {
let len = read_u8(&mut data)? as usize;
impl StaticRecord for TLSA {
const TYPE: u16 = 52;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
Ok(TLSA {
name, cert_usage: read_u8(&mut data)?, selector: read_u8(&mut data)?,
data_ty: read_u8(&mut data)?, data: data.to_vec(),
impl StaticRecord for CName {
const TYPE: u16 = 5;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
- Ok(CName { name, canonical_name: read_name(&mut data)? })
+ fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
+ Ok(CName { name, canonical_name: read_wire_packet_name(&mut data, wire_packet)? })
}
fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
let len: u16 = name_len(&self.canonical_name);
impl StaticRecord for DnsKey {
const TYPE: u16 = 48;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
Ok(DnsKey {
name, flags: read_u16(&mut data)?, protocol: read_u8(&mut data)?,
alg: read_u8(&mut data)?, pubkey: data.to_vec(),
impl StaticRecord for DS {
const TYPE: u16 = 43;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, mut data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
Ok(DS {
name, key_tag: read_u16(&mut data)?, alg: read_u8(&mut data)?,
digest_type: read_u8(&mut data)?, digest: data.to_vec(),
impl StaticRecord for RRSig {
const TYPE: u16 = 46;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
Ok(RRSig {
name, ty: read_u16(&mut data)?, alg: read_u8(&mut data)?,
labels: read_u8(&mut data)?, orig_ttl: read_u32(&mut data)?,
expiration: read_u32(&mut data)?, inception: read_u32(&mut data)?,
- key_tag: read_u16(&mut data)?, key_name: read_name(&mut data)?,
+ key_tag: read_u16(&mut data)?,
+ key_name: read_wire_packet_name(&mut data, wire_packet)?,
signature: data.to_vec(),
})
}
impl StaticRecord for A {
const TYPE: u16 = 1;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
if data.len() != 4 { return Err(()); }
let mut address = [0; 4];
address.copy_from_slice(&data);
impl StaticRecord for AAAA {
const TYPE: u16 = 28;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, data: &[u8]) -> Result<Self, ()> {
+ fn read_from_data(name: Name, data: &[u8], _wire_packet: &[u8]) -> Result<Self, ()> {
if data.len() != 16 { return Err(()); }
let mut address = [0; 16];
address.copy_from_slice(&data);
impl StaticRecord for NS {
const TYPE: u16 = 2;
fn name(&self) -> &Name { &self.name }
- fn read_from_data(name: Name, mut data: &[u8]) -> Result<Self, ()> {
- Ok(NS { name, name_server: read_name(&mut data)? })
+ fn read_from_data(name: Name, mut data: &[u8], wire_packet: &[u8]) -> Result<Self, ()> {
+ Ok(NS { name, name_server: read_wire_packet_name(&mut data, wire_packet)? })
}
fn write_u16_len_prefixed_data(&self, out: &mut Vec<u8>) {
out.extend_from_slice(&name_len(&self.name_server).to_be_bytes());
Ok(u32::from_be_bytes(bytes))
}
-pub(crate) fn read_name(inp: &mut &[u8]) -> Result<Name, ()> {
- let mut name = String::with_capacity(1024);
+fn read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut String) -> Result<(), ()> {
loop {
let len = read_u8(inp)? as usize;
if len == 0 {
- if name.is_empty() { name += "."; }
+ if name.is_empty() { *name += "."; }
+ break;
+ } else if len >= 0xc0 {
+ let offs = ((len & !0xc0) << 8) | read_u8(inp)? as usize;
+ if offs >= wire_packet.len() { return Err(()); }
+ read_wire_packet_labels(&mut &wire_packet[offs..], wire_packet, name)?;
break;
}
if inp.len() <= len { return Err(()); }
- name += core::str::from_utf8(&inp[..len]).map_err(|_| ())?;
- name += ".";
+ *name += core::str::from_utf8(&inp[..len]).map_err(|_| ())?;
+ *name += ".";
*inp = &inp[len..];
- if name.len() > 1024 { return Err(()); }
+ if name.len() > 255 { return Err(()); }
}
+ Ok(())
+}
+
+pub(crate) fn read_wire_packet_name(inp: &mut &[u8], wire_packet: &[u8]) -> Result<Name, ()> {
+ let mut name = String::with_capacity(1024);
+ read_wire_packet_labels(inp, wire_packet, &mut name)?;
Ok(name.try_into()?)
}
}
}
-pub(crate) fn parse_rr(inp: &mut &[u8]) -> Result<RR, ()> {
- let name = read_name(inp)?;
+pub(crate) fn parse_wire_packet_rr(inp: &mut &[u8], wire_packet: &[u8]) -> Result<RR, ()> {
+ let name = read_wire_packet_name(inp, wire_packet)?;
let ty = read_u16(inp)?;
let class = read_u16(inp)?;
if class != 1 { return Err(()); } // We only support the INternet
*inp = &inp[data_len..];
match ty {
- A::TYPE => Ok(RR::A(A::read_from_data(name, data)?)),
- AAAA::TYPE => Ok(RR::AAAA(AAAA::read_from_data(name, data)?)),
- NS::TYPE => Ok(RR::NS(NS::read_from_data(name, data)?)),
- Txt::TYPE => {
- Ok(RR::Txt(Txt::read_from_data(name, data)?))
- }
- CName::TYPE => {
- Ok(RR::CName(CName::read_from_data(name, data)?))
- }
- TLSA::TYPE => {
- Ok(RR::TLSA(TLSA::read_from_data(name, data)?))
- },
- DnsKey::TYPE => {
- Ok(RR::DnsKey(DnsKey::read_from_data(name, data)?))
- },
- DS::TYPE => {
- Ok(RR::DS(DS::read_from_data(name, data)?))
- },
- RRSig::TYPE => {
- Ok(RR::RRSig(RRSig::read_from_data(name, data)?))
- },
+ A::TYPE => Ok(RR::A(A::read_from_data(name, data, wire_packet)?)),
+ AAAA::TYPE => Ok(RR::AAAA(AAAA::read_from_data(name, data, wire_packet)?)),
+ NS::TYPE => Ok(RR::NS(NS::read_from_data(name, data, wire_packet)?)),
+ Txt::TYPE => Ok(RR::Txt(Txt::read_from_data(name, data, wire_packet)?)),
+ CName::TYPE => Ok(RR::CName(CName::read_from_data(name, data, wire_packet)?)),
+ TLSA::TYPE => Ok(RR::TLSA(TLSA::read_from_data(name, data, wire_packet)?)),
+ DnsKey::TYPE => Ok(RR::DnsKey(DnsKey::read_from_data(name, data, wire_packet)?)),
+ DS::TYPE => Ok(RR::DS(DS::read_from_data(name, data, wire_packet)?)),
+ RRSig::TYPE => Ok(RR::RRSig(RRSig::read_from_data(name, data, wire_packet)?)),
_ => Err(()),
}
}
+pub(crate) fn parse_rr(inp: &mut &[u8]) -> Result<RR, ()> {
+ parse_wire_packet_rr(inp, &[])
+}
+
pub(crate) fn bytes_to_rsa_pk<'a>(pubkey: &'a [u8])
-> Result<signature::RsaPublicKeyComponents<&'a [u8]>, ()> {
if pubkey.len() <= 3 { return Err(()); }