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}