1use std::{fmt, ptr};
8use bytes::{BufMut, Bytes, BytesMut};
9use ::bits::compose::{Compose, Compress, Compressor};
10use ::bits::name::{Dname, DnameError, DnameBytesError, DnameParseError};
11use ::bits::parse::{Parse, ParseAll, ParseAllError, Parser, ShortBuf};
12use ::bits::rdata::RtypeRecordData;
13use ::bits::serial::Serial;
14use ::iana::{DigestAlg, Rtype, SecAlg};
15use ::master::scan::{CharSource, ScanError, Scan, Scanner};
16use ::utils::base64;
17
18
19#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
22pub struct Dnskey {
23 flags: u16,
24 protocol: u8,
25 algorithm: SecAlg,
26 public_key: Bytes,
27}
28
29impl Dnskey {
30 pub fn new(
31 flags: u16,
32 protocol: u8,
33 algorithm: SecAlg,
34 public_key: Bytes)
35 -> Self {
36 Dnskey {
37 flags,
38 protocol,
39 algorithm,
40 public_key,
41 }
42 }
43
44 pub fn flags(&self) -> u16 {
45 self.flags
46 }
47
48 pub fn protocol(&self) -> u8 {
49 self.protocol
50 }
51
52 pub fn algorithm(&self) -> SecAlg {
53 self.algorithm
54 }
55
56 pub fn public_key(&self) -> &Bytes {
57 &self.public_key
58 }
59}
60
61
62impl ParseAll for Dnskey {
65 type Err = ParseAllError;
66
67 fn parse_all(
68 parser: &mut Parser,
69 len: usize,
70 ) -> Result<Self, Self::Err> {
71 if len < 4 {
72 return Err(ParseAllError::ShortField);
73 }
74 Ok(Self::new(
75 u16::parse(parser)?,
76 u8::parse(parser)?,
77 SecAlg::parse(parser)?,
78 Bytes::parse_all(parser, len - 4)?
79 ))
80 }
81}
82
83impl Compose for Dnskey {
84 fn compose_len(&self) -> usize {
85 4 + self.public_key.len()
86 }
87
88 fn compose<B: BufMut>(&self, buf: &mut B) {
89 self.flags.compose(buf);
90 self.protocol.compose(buf);
91 self.algorithm.compose(buf);
92 self.public_key.compose(buf);
93 }
94}
95
96impl Compress for Dnskey {
97 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
98 buf.compose(self)
99 }
100}
101
102
103impl Scan for Dnskey {
106 fn scan<C: CharSource>(
107 scanner: &mut Scanner<C>
108 ) -> Result<Self, ScanError> {
109 Ok(Self::new(
110 u16::scan(scanner)?,
111 u8::scan(scanner)?,
112 SecAlg::scan(scanner)?,
113 scanner.scan_base64_phrases(Ok)?
114 ))
115 }
116}
117
118impl fmt::Display for Dnskey {
119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120 write!(f, "{} {} {} ", self.flags, self.protocol, self.algorithm)?;
121 base64::display(&self.public_key, f)
122 }
123}
124
125
126impl RtypeRecordData for Dnskey {
129 const RTYPE: Rtype = Rtype::Dnskey;
130}
131
132
133#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd)]
136pub struct Rrsig {
137 type_covered: Rtype,
138 algorithm: SecAlg,
139 labels: u8,
140 original_ttl: u32,
141 expiration: Serial,
142 inception: Serial,
143 key_tag: u16,
144 signer_name: Dname,
145 signature: Bytes,
146}
147
148impl Rrsig {
149 #[allow(too_many_arguments)] pub fn new(
151 type_covered: Rtype,
152 algorithm: SecAlg,
153 labels: u8,
154 original_ttl: u32,
155 expiration: Serial,
156 inception: Serial,
157 key_tag: u16,
158 signer_name: Dname,
159 signature: Bytes
160 ) -> Self {
161 Rrsig {
162 type_covered,
163 algorithm,
164 labels,
165 original_ttl,
166 expiration,
167 inception,
168 key_tag,
169 signer_name,
170 signature
171 }
172 }
173
174 pub fn type_covered(&self) -> Rtype {
175 self.type_covered
176 }
177
178 pub fn algorithm(&self) -> SecAlg {
179 self.algorithm
180 }
181
182 pub fn labels(&self) -> u8 {
183 self.labels
184 }
185
186 pub fn original_ttl(&self) -> u32 {
187 self.original_ttl
188 }
189
190 pub fn expiration(&self) -> Serial {
191 self.expiration
192 }
193
194 pub fn inception(&self) -> Serial {
195 self.inception
196 }
197
198 pub fn key_tag(&self) -> u16 {
199 self.key_tag
200 }
201
202 pub fn signer_name(&self) -> &Dname {
203 &self.signer_name
204 }
205
206 pub fn signature(&self) -> &Bytes {
207 &self.signature
208 }
209}
210
211
212impl ParseAll for Rrsig {
215 type Err = DnameBytesError;
216
217 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
218 let start = parser.pos();
219 let type_covered = Rtype::parse(parser)?;
220 let algorithm = SecAlg::parse(parser)?;
221 let labels = u8::parse(parser)?;
222 let original_ttl = u32::parse(parser)?;
223 let expiration = Serial::parse(parser)?;
224 let inception = Serial::parse(parser)?;
225 let key_tag = u16::parse(parser)?;
226 let signer_name = Dname::parse(parser)?;
227 let len = if parser.pos() > start + len {
228 return Err(ShortBuf.into())
229 }
230 else {
231 len - (parser.pos() - start)
232 };
233 let signature = Bytes::parse_all(parser, len)?;
234 Ok(Self::new(
235 type_covered, algorithm, labels, original_ttl, expiration,
236 inception, key_tag, signer_name, signature
237 ))
238 }
239}
240
241impl Compose for Rrsig {
242 fn compose_len(&self) -> usize {
243 18 + self.signer_name.compose_len() + self.signature.len()
244 }
245
246 fn compose<B: BufMut>(&self, buf: &mut B) {
247 self.type_covered.compose(buf);
248 self.algorithm.compose(buf);
249 self.labels.compose(buf);
250 self.original_ttl.compose(buf);
251 self.expiration.compose(buf);
252 self.inception.compose(buf);
253 self.key_tag.compose(buf);
254 self.signer_name.compose(buf);
255 self.signature.compose(buf);
256 }
257}
258
259impl Compress for Rrsig {
260 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
261 buf.compose(self)
262 }
263}
264
265
266impl Scan for Rrsig {
269 fn scan<C: CharSource>(
270 scanner: &mut Scanner<C>
271 ) -> Result<Self, ScanError> {
272 Ok(Self::new(
273 Rtype::scan(scanner)?,
274 SecAlg::scan(scanner)?,
275 u8::scan(scanner)?,
276 u32::scan(scanner)?,
277 Serial::scan_rrsig(scanner)?,
278 Serial::scan_rrsig(scanner)?,
279 u16::scan(scanner)?,
280 Dname::scan(scanner)?,
281 scanner.scan_base64_phrases(Ok)?
282 ))
283 }
284}
285
286impl fmt::Display for Rrsig {
287 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 write!(f, "{} {} {} {} {} {} {} {} ",
289 self.type_covered, self.algorithm, self.labels,
290 self.original_ttl, self.expiration, self.inception,
291 self.key_tag, self.signer_name)?;
292 base64::display(&self.signature, f)
293 }
294}
295
296
297impl RtypeRecordData for Rrsig {
300 const RTYPE: Rtype = Rtype::Rrsig;
301}
302
303
304#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
307pub struct Nsec {
308 next_name: Dname,
309 types: RtypeBitmap,
310}
311
312impl Nsec {
313 pub fn new(next_name: Dname, types: RtypeBitmap) -> Self {
314 Nsec { next_name, types }
315 }
316
317 pub fn next_name(&self) -> &Dname {
318 &self.next_name
319 }
320
321 pub fn types(&self) -> &RtypeBitmap {
322 &self.types
323 }
324}
325
326
327impl ParseAll for Nsec {
330 type Err = ParseNsecError;
331
332 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
333 let start = parser.pos();
334 let next_name = Dname::parse(parser)?;
335 let len = if parser.pos() > start + len {
336 return Err(ShortBuf.into())
337 }
338 else {
339 len - (parser.pos() - start)
340 };
341 let types = RtypeBitmap::parse_all(parser, len)?;
342 Ok(Nsec::new(next_name, types))
343 }
344}
345
346impl Compose for Nsec {
347 fn compose_len(&self) -> usize {
348 self.next_name.compose_len() + self.types.compose_len()
349 }
350
351 fn compose<B: BufMut>(&self, buf: &mut B) {
352 self.next_name.compose(buf);
353 self.types.compose(buf);
354 }
355}
356
357impl Compress for Nsec {
358 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
359 buf.compose(self)
360 }
361}
362
363
364impl Scan for Nsec {
367 fn scan<C: CharSource>(
368 scanner: &mut Scanner<C>
369 ) -> Result<Self, ScanError> {
370 Ok(Self::new(
371 Dname::scan(scanner)?,
372 RtypeBitmap::scan(scanner)?,
373 ))
374 }
375}
376
377impl fmt::Display for Nsec {
378 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
379 write!(f, "{} {}", self.next_name, self.types)
380 }
381}
382
383
384impl RtypeRecordData for Nsec {
387 const RTYPE: Rtype = Rtype::Nsec;
388}
389
390
391#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
394pub struct Ds {
395 key_tag: u16,
396 algorithm: SecAlg,
397 digest_type: DigestAlg,
398 digest: Bytes,
399}
400
401impl Ds {
402 pub fn new(
403 key_tag: u16,
404 algorithm: SecAlg,
405 digest_type: DigestAlg,
406 digest: Bytes
407 ) -> Self {
408 Ds { key_tag, algorithm, digest_type, digest }
409 }
410
411 pub fn key_tag(&self) -> u16 {
412 self.key_tag
413 }
414
415 pub fn algorithm(&self) -> SecAlg {
416 self.algorithm
417 }
418
419 pub fn digest_type(&self) -> DigestAlg {
420 self.digest_type
421 }
422
423 pub fn digest(&self) -> &Bytes {
424 &self.digest
425 }
426}
427
428
429impl ParseAll for Ds {
432 type Err = ShortBuf;
433
434 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
435 if len < 4 {
436 return Err(ShortBuf)
437 }
438 Ok(Self::new(
439 u16::parse(parser)?,
440 SecAlg::parse(parser)?,
441 DigestAlg::parse(parser)?,
442 Bytes::parse_all(parser, len - 4)?
443 ))
444 }
445}
446
447impl Compose for Ds {
448 fn compose_len(&self) -> usize {
449 self.digest.len() + 4
450 }
451
452 fn compose<B: BufMut>(&self, buf: &mut B) {
453 self.key_tag.compose(buf);
454 self.algorithm.compose(buf);
455 self.digest_type.compose(buf);
456 self.digest.compose(buf);
457 }
458}
459
460impl Compress for Ds {
461 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
462 buf.compose(self)
463 }
464}
465
466
467impl Scan for Ds {
470 fn scan<C: CharSource>(
471 scanner: &mut Scanner<C>
472 ) -> Result<Self, ScanError> {
473 Ok(Self::new(
474 u16::scan(scanner)?,
475 SecAlg::scan(scanner)?,
476 DigestAlg::scan(scanner)?,
477 scanner.scan_hex_words(Ok)?,
478 ))
479 }
480}
481
482impl fmt::Display for Ds {
483 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
484 write!(f, "{} {} {} ", self.key_tag, self.algorithm,
485 self.digest_type)?;
486 for ch in self.digest() {
487 write!(f, "{:02x}", ch)?
488 }
489 Ok(())
490 }
491}
492
493
494impl RtypeRecordData for Ds {
497 const RTYPE: Rtype = Rtype::Ds;
498}
499
500
501#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
504pub struct RtypeBitmap(Bytes);
505
506impl RtypeBitmap {
507 pub fn from_bytes(bytes: Bytes) -> Result<Self, RtypeBitmapError> {
508 {
509 let mut data = bytes.as_ref();
510 while !data.is_empty() {
511 let len = (data[1] as usize) + 2;
512 if len > 34 {
513 return Err(RtypeBitmapError::BadRtypeBitmap)
514 }
515 if data.len() < len {
516 return Err(RtypeBitmapError::ShortBuf)
517 }
518 data = &data[len..];
519 }
520 }
521 Ok(RtypeBitmap(bytes))
522 }
523
524 pub fn as_bytes(&self) -> &Bytes {
525 &self.0
526 }
527
528 pub fn as_slice(&self) -> &[u8] {
529 self.0.as_ref()
530 }
531
532 pub fn iter(&self) -> RtypeBitmapIter {
533 RtypeBitmapIter::new(self.0.as_ref())
534 }
535
536 pub fn contains(&self, rtype: Rtype) -> bool {
537 let (block, octet, mask) = split_rtype(rtype);
538 let octet = octet + 2;
539 let mut data = self.0.as_ref();
540 while !data.is_empty() {
541 if data[0] == block {
542 return !((data[1] as usize) < octet || data[octet] & mask == 0)
543 }
544 data = &data[data[1] as usize..]
545 }
546 false
547 }
548}
549
550impl AsRef<Bytes> for RtypeBitmap {
551 fn as_ref(&self) -> &Bytes {
552 self.as_bytes()
553 }
554}
555
556impl AsRef<[u8]> for RtypeBitmap {
557 fn as_ref(&self) -> &[u8] {
558 self.as_slice()
559 }
560}
561
562
563impl<'a> IntoIterator for &'a RtypeBitmap {
566 type Item = Rtype;
567 type IntoIter = RtypeBitmapIter<'a>;
568
569 fn into_iter(self) -> Self::IntoIter {
570 self.iter()
571 }
572}
573
574
575impl ParseAll for RtypeBitmap {
578 type Err = RtypeBitmapError;
579
580 fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
581 let bytes = parser.parse_bytes(len)?;
582 RtypeBitmap::from_bytes(bytes)
583 }
584}
585
586impl Compose for RtypeBitmap {
587 fn compose_len(&self) -> usize {
588 self.0.len()
589 }
590
591 fn compose<B: BufMut>(&self, buf: &mut B) {
592 self.0.compose(buf)
593 }
594}
595
596impl Compress for RtypeBitmap {
597 fn compress(&self, buf: &mut Compressor) -> Result<(), ShortBuf> {
598 buf.compose(self)
599 }
600}
601
602
603impl Scan for RtypeBitmap {
606 fn scan<C: CharSource>(
607 scanner: &mut Scanner<C>
608 ) -> Result<Self, ScanError> {
609 let mut builder = RtypeBitmapBuilder::new();
610 while let Ok(rtype) = Rtype::scan(scanner) {
611 builder.add(rtype)
612 }
613 Ok(builder.finalize())
614 }
615}
616
617impl fmt::Display for RtypeBitmap {
618 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
619 let first = true;
620 for rtype in self {
621 if first {
622 rtype.fmt(f)?
623 }
624 else {
625 write!(f, " {}", rtype)?
626 }
627 }
628 Ok(())
629 }
630}
631
632
633#[derive(Clone, Debug)]
645pub struct RtypeBitmapBuilder {
646 buf: BytesMut,
647}
648
649impl RtypeBitmapBuilder {
650 pub fn new() -> Self {
651 RtypeBitmapBuilder {
652 buf: BytesMut::with_capacity(34)
654 }
655 }
656
657 pub fn add(&mut self, rtype: Rtype) {
658 let (block, octet, bit) = split_rtype(rtype);
659 let block = self.get_block(block);
660 if (block[1] as usize) < (octet + 1) {
661 block[1] = (octet + 1) as u8
662 }
663 block[octet + 2] |= bit;
664 }
665
666 fn get_block(&mut self, block: u8) -> &mut [u8] {
667 let mut pos = 0;
668 while pos < self.buf.len() {
669 if self.buf[pos] == block {
670 return &mut self.buf[pos..pos + 34]
671 }
672 else if self.buf[pos] > block {
673 let len = self.buf.len() - pos;
674 self.buf.extend_from_slice(&[0; 34]);
675 unsafe {
676 ptr::copy(
677 self.buf.as_ptr().offset(pos as isize),
678 self.buf.as_mut_ptr().offset(pos as isize + 34),
679 len
680 );
681 ptr::write_bytes(
682 self.buf.as_mut_ptr().offset(pos as isize),
683 0,
684 34
685 );
686 }
687 self.buf[pos] = block;
688 return &mut self.buf[pos..pos + 34]
689 }
690 else {
691 pos += 34
692 }
693 }
694
695 self.buf.extend_from_slice(&[0; 34]);
696 self.buf[pos] = block;
697 &mut self.buf[pos..pos + 34]
698 }
699
700 pub fn finalize(mut self) -> RtypeBitmap {
701 let mut src_pos = 0;
702 let mut dst_pos = 0;
703 while src_pos < self.buf.len() {
704 let len = (self.buf[src_pos + 1] as usize) + 2;
705 if src_pos != dst_pos {
706 unsafe {
707 ptr::copy(
708 self.buf.as_ptr().offset(src_pos as isize),
709 self.buf.as_mut_ptr().offset(dst_pos as isize),
710 len
711 )
712 }
713 }
714 dst_pos += len;
715 src_pos += 34;
716 }
717 self.buf.truncate(dst_pos);
718 RtypeBitmap(self.buf.freeze())
719 }
720}
721
722
723impl Default for RtypeBitmapBuilder {
726 fn default() -> Self {
727 Self::new()
728 }
729}
730
731
732pub struct RtypeBitmapIter<'a> {
735 data: &'a [u8],
736 block: u16,
737 len: usize,
738
739 octet: usize,
740 bit: u16
741}
742
743impl<'a> RtypeBitmapIter<'a> {
744 fn new(data: &'a [u8]) -> Self {
745 if data.is_empty() {
746 RtypeBitmapIter {
747 data,
748 block: 0, len: 0, octet: 0, bit: 0
749 }
750 }
751 else {
752 let mut res = RtypeBitmapIter {
753 data: &data[2..],
754 block: u16::from(data[0]) << 8,
755 len: usize::from(data[1]),
756 octet: 0,
757 bit: 0
758 };
759 if res.data[0] & 0x80 == 0 {
760 res.advance()
761 }
762 res
763 }
764 }
765
766 fn advance(&mut self) {
767 loop {
768 self.bit += 1;
769 if self.bit == 7 {
770 self.bit = 0;
771 self.octet += 1;
772 if self.octet == self.len {
773 self.data = &self.data[self.len..];
774 if self.data.is_empty() {
775 return;
776 }
777 self.block = u16::from(self.data[0]) << 8;
778 self.len = self.data[1] as usize;
779 self.octet = 0;
780 }
781 }
782 if self.data[self.octet] & (0x80 >> self.bit) != 0 {
783 return
784 }
785 }
786 }
787}
788
789impl<'a> Iterator for RtypeBitmapIter<'a> {
790 type Item = Rtype;
791
792 fn next(&mut self) -> Option<Self::Item> {
793 if self.data.is_empty() {
794 return None
795 }
796 let res = Rtype::from_int(
797 u16::from(self.data[0]) << 8 | (self.octet as u16) << 3 | self.bit
798 );
799 self.advance();
800 Some(res)
801 }
802}
803
804
805#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
808pub enum ParseNsecError {
809 #[fail(display="short field")]
810 ShortField,
811
812 #[fail(display="{}", _0)]
813 BadNextName(DnameError),
814
815 #[fail(display="invalid record type bitmap")]
816 BadRtypeBitmap,
817}
818
819impl From<ShortBuf> for ParseNsecError {
820 fn from(_: ShortBuf) -> Self {
821 ParseNsecError::ShortField
822 }
823}
824
825impl From<RtypeBitmapError> for ParseNsecError {
826 fn from(err: RtypeBitmapError) -> Self {
827 match err {
828 RtypeBitmapError::ShortBuf => ParseNsecError::ShortField,
829 RtypeBitmapError::BadRtypeBitmap => ParseNsecError::BadRtypeBitmap
830 }
831 }
832}
833
834impl From<DnameParseError> for ParseNsecError {
835 fn from(err: DnameParseError) -> Self {
836 match err {
837 DnameParseError::BadName(err)
838 => ParseNsecError::BadNextName(err),
839 DnameParseError::ShortBuf => ParseNsecError::ShortField,
840 }
841 }
842}
843
844
845#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
848pub enum RtypeBitmapError {
849 #[fail(display="short field")]
850 ShortBuf,
851
852 #[fail(display="invalid record type bitmap")]
853 BadRtypeBitmap,
854}
855
856impl From<ShortBuf> for RtypeBitmapError {
857 fn from(_: ShortBuf) -> Self {
858 RtypeBitmapError::ShortBuf
859 }
860}
861
862pub mod parsed {
865 pub use super::{Dnskey, Rrsig, Nsec, Ds};
866}
867
868
869fn split_rtype(rtype: Rtype) -> (u8, usize, u8) {
873 let rtype = rtype.to_int();
874 (
875 (rtype >> 8) as u8,
876 ((rtype & 0xFF) >> 3) as usize,
877 0x80u8 >> (rtype & 0x07)
878 )
879}
880
881#[cfg(test)]
884mod test {
885 use super::*;
886 use ::iana::Rtype;
887
888 #[test]
889 fn rtype_bitmap_builder() {
890 let mut builder = RtypeBitmapBuilder::new();
891 builder.add(Rtype::Int(1234)); builder.add(Rtype::A); builder.add(Rtype::Mx); builder.add(Rtype::Rrsig); builder.add(Rtype::Nsec); assert_eq!(builder.finalize().as_slice(),
897 &b"\x00\x06\x40\x01\x00\x00\x00\x03\
898 \x04\x1b\x00\x00\x00\x00\x00\x00\
899 \x00\x00\x00\x00\x00\x00\x00\x00\
900 \x00\x00\x00\x00\x00\x00\x00\x00\
901 \x00\x00\x00\x00\x20"[..]);
902 }
903}