X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fser.rs;h=dfd89932e6afd15e46591504dd3f098c7885697a;hb=d7bf25b7d6335f250a96036c792ce997a4a7b05d;hp=8829725dc139f0d0dca485e622e8afb21648b2e5;hpb=82e51554f05ba47826f1ee9afdce3add1e8b1457;p=dnssec-prover diff --git a/src/ser.rs b/src/ser.rs index 8829725..dfd8993 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -4,6 +4,7 @@ use alloc::vec::Vec; use alloc::string::String; use crate::rr::*; +use crate::query::QueryBuf; pub(crate) fn read_u8(inp: &mut &[u8]) -> Result { let res = *inp.get(0).ok_or(())?; @@ -25,6 +26,54 @@ pub(crate) fn read_u32(inp: &mut &[u8]) -> Result { Ok(u32::from_be_bytes(bytes)) } +pub(crate) fn read_u8_len_prefixed_bytes(inp: &mut &[u8]) -> Result, ()> { + let len = *inp.get(0).ok_or(())?; + *inp = &inp[1..]; + if inp.len() < len.into() { return Err(()); } + let mut res = Vec::with_capacity(len.into()); + res.extend_from_slice(&inp[..len.into()]); + *inp = &inp[len.into()..]; + Ok(res) +} + +pub(crate) fn write_nsec_types_bitmap(out: &mut W, types: &[u8; 8192]) { + for (idx, flags) in types.chunks(32).enumerate() { + debug_assert_eq!(flags.len(), 32); + if flags != &[0; 32] { + let last_nonzero_idx = flags.iter().rposition(|flag| *flag != 0) + .unwrap_or_else(|| { debug_assert!(false); 0 }); + out.write(&(idx as u8).to_be_bytes()); + out.write(&(last_nonzero_idx as u8 + 1).to_be_bytes()); + out.write(&flags[..last_nonzero_idx + 1]); + } + } +} +pub(crate) fn nsec_types_bitmap_len(types: &[u8; 8192]) -> u16 { + let mut total_len = 0; + for flags in types.chunks(32) { + debug_assert_eq!(flags.len(), 32); + if flags != &[0; 32] { + total_len += 3 + flags.iter().rposition(|flag| *flag != 0) + .unwrap_or_else(|| { debug_assert!(false); 0 }) as u16; + } + } + total_len +} + +pub(crate) fn read_nsec_types_bitmap(inp: &mut &[u8]) -> Result<[u8; 8192], ()> { + let mut res = [0; 8192]; + while !inp.is_empty() { + let block = *inp.get(0).ok_or(())?; + let len = *inp.get(1).ok_or(())?; + *inp = &inp[2..]; + if inp.len() < len as usize { return Err(()); } + res[block as usize * 32..block as usize * 32 + len as usize] + .copy_from_slice(&inp[..len as usize]); + *inp = &inp[len as usize..]; + } + Ok(res) +} + fn do_read_wire_packet_labels(inp: &mut &[u8], wire_packet: &[u8], name: &mut String, recursion_limit: usize) -> Result<(), ()> { loop { let len = read_u8(inp)? as usize; @@ -58,8 +107,9 @@ pub(crate) fn read_wire_packet_name(inp: &mut &[u8], wire_packet: &[u8]) -> Resu pub(crate) trait Writer { fn write(&mut self, buf: &[u8]); } impl Writer for Vec { fn write(&mut self, buf: &[u8]) { self.extend_from_slice(buf); } } +impl Writer for QueryBuf { fn write(&mut self, buf: &[u8]) { self.extend_from_slice(buf); } } #[cfg(feature = "validation")] -impl Writer for ring::digest::Context { fn write(&mut self, buf: &[u8]) { self.update(buf); } } +impl Writer for crate::crypto::hash::Hasher { fn write(&mut self, buf: &[u8]) { self.update(buf); } } pub(crate) fn write_name(out: &mut W, name: &str) { let canonical_name = name.to_ascii_lowercase(); if canonical_name == "." { @@ -100,10 +150,13 @@ pub(crate) fn parse_wire_packet_rr(inp: &mut &[u8], wire_packet: &[u8]) -> Resul NS::TYPE => RR::NS(NS::read_from_data(name, data, wire_packet)?), Txt::TYPE => RR::Txt(Txt::read_from_data(name, data, wire_packet)?), CName::TYPE => RR::CName(CName::read_from_data(name, data, wire_packet)?), + DName::TYPE => RR::DName(DName::read_from_data(name, data, wire_packet)?), TLSA::TYPE => RR::TLSA(TLSA::read_from_data(name, data, wire_packet)?), DnsKey::TYPE => RR::DnsKey(DnsKey::read_from_data(name, data, wire_packet)?), DS::TYPE => RR::DS(DS::read_from_data(name, data, wire_packet)?), RRSig::TYPE => RR::RRSig(RRSig::read_from_data(name, data, wire_packet)?), + NSec::TYPE => RR::NSec(NSec::read_from_data(name, data, wire_packet)?), + NSec3::TYPE => RR::NSec3(NSec3::read_from_data(name, data, wire_packet)?), _ => return Err(()), }; Ok((rr, ttl))