Skip to main content

domain/new/rdata/dnssec/
ds.rs

1//! The DS record data type.
2
3use core::hash::{Hash, Hasher};
4use core::{cmp::Ordering, fmt};
5
6use domain_macros::*;
7
8use crate::new::base::CanonicalRecordData;
9use crate::new::base::build::{
10    BuildInMessage, NameCompressor, TruncationError,
11};
12use crate::new::base::wire::{AsBytes, U16};
13
14use super::SecAlg;
15
16//----------- Ds -------------------------------------------------------------
17
18/// The signing key for a delegated zone.
19#[derive(Debug, AsBytes, BuildBytes, ParseBytesZC, UnsizedCopy)]
20#[repr(C)]
21pub struct Ds {
22    /// The key tag of the signing key.
23    pub keytag: U16,
24
25    /// The cryptographic algorithm used by the signing key.
26    pub algorithm: SecAlg,
27
28    /// The algorithm used to calculate the key digest.
29    pub digest_type: DigestType,
30
31    /// A serialized digest of the signing key.
32    pub digest: [u8],
33}
34
35//--- Canonical operations
36
37impl CanonicalRecordData for Ds {
38    fn cmp_canonical(&self, other: &Self) -> Ordering {
39        self.as_bytes().cmp(other.as_bytes())
40    }
41}
42
43//--- Building in DNS messages
44
45impl BuildInMessage for Ds {
46    fn build_in_message(
47        &self,
48        contents: &mut [u8],
49        start: usize,
50        _compressor: &mut NameCompressor,
51    ) -> Result<usize, TruncationError> {
52        let bytes = self.as_bytes();
53        let end = start + bytes.len();
54        contents
55            .get_mut(start..end)
56            .ok_or(TruncationError)?
57            .copy_from_slice(bytes);
58        Ok(end)
59    }
60}
61
62//--- Equality
63
64impl PartialEq for Ds {
65    fn eq(&self, other: &Self) -> bool {
66        // All elements are compared bytewise.
67        self.as_bytes() == other.as_bytes()
68    }
69}
70
71impl Eq for Ds {}
72
73//--- Hashing
74
75impl Hash for Ds {
76    fn hash<H: Hasher>(&self, state: &mut H) {
77        state.write(self.as_bytes())
78    }
79}
80
81//----------- DigestType -----------------------------------------------------
82
83/// A cryptographic digest algorithm.
84#[derive(
85    Copy,
86    Clone,
87    PartialEq,
88    Eq,
89    PartialOrd,
90    Ord,
91    Hash,
92    AsBytes,
93    BuildBytes,
94    ParseBytes,
95    ParseBytesZC,
96    SplitBytes,
97    SplitBytesZC,
98    UnsizedCopy,
99)]
100#[repr(transparent)]
101pub struct DigestType {
102    /// The algorithm code.
103    pub code: u8,
104}
105
106//--- Associated Constants
107
108impl DigestType {
109    /// The SHA-1 algorithm.
110    pub const SHA1: Self = Self { code: 1 };
111}
112
113//--- Formatting
114
115impl fmt::Debug for DigestType {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        f.write_str(match *self {
118            Self::SHA1 => "DigestType::SHA1",
119            _ => return write!(f, "DigestType({})", self.code),
120        })
121    }
122}