X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fser.rs;fp=src%2Fser.rs;h=e88c9ba63a5b5700ed06ae6c2a0cac1bcb341c23;hb=821d8fdb9880a306ff870c45a9268c0dfff1056e;hp=c0566c3e2c4835585322a2f3ea9fbaa887709a98;hpb=a9d8b7ddf6609f2621428e42f40a6060246e1776;p=dnssec-prover diff --git a/src/ser.rs b/src/ser.rs index c0566c3..e88c9ba 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -27,20 +27,30 @@ pub(crate) fn read_u32(inp: &mut &[u8]) -> Result { Ok(u32::from_be_bytes(bytes)) } -pub(crate) fn read_name(inp: &mut &[u8]) -> Result { - 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 { + let mut name = String::with_capacity(1024); + read_wire_packet_labels(inp, wire_packet, &mut name)?; Ok(name.try_into()?) } @@ -70,8 +80,8 @@ pub(crate) fn name_len(name: &Name) -> u16 { } } -pub(crate) fn parse_rr(inp: &mut &[u8]) -> Result { - let name = read_name(inp)?; +pub(crate) fn parse_wire_packet_rr(inp: &mut &[u8], wire_packet: &[u8]) -> Result { + 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 @@ -82,31 +92,23 @@ pub(crate) fn parse_rr(inp: &mut &[u8]) -> Result { *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 { + parse_wire_packet_rr(inp, &[]) +} + pub(crate) fn bytes_to_rsa_pk<'a>(pubkey: &'a [u8]) -> Result, ()> { if pubkey.len() <= 3 { return Err(()); }