Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement FromStr for zonemd Scheme and Algorithm #444

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/base/iana/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub use self::rcode::{OptRcode, Rcode, TsigRcode};
pub use self::rtype::Rtype;
pub use self::secalg::SecAlg;
pub use self::svcb::SvcParamKey;
pub use self::zonemd::{ZonemdAlg, ZonemdScheme};

#[macro_use]
mod macros;
Expand All @@ -49,3 +50,4 @@ pub mod rcode;
pub mod rtype;
pub mod secalg;
pub mod svcb;
pub mod zonemd;
50 changes: 50 additions & 0 deletions src/base/iana/zonemd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! ZONEMD IANA parameters.

//------------ ZonemdScheme --------------------------------------------------

int_enum! {
/// ZONEMD schemes.
///
/// This type selects the method by which data is collated and presented
/// as input to the hashing function for use with [ZONEMD].
///
/// For the currently registered values see the [IANA registration]. This
/// type is complete as of 2024-11-29.
///
/// [ZONEMD]: ../../../rdata/zonemd/index.html
/// [IANA registration]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#zonemd-schemes
=>
ZonemdScheme, u8;

/// Specifies that the SIMPLE scheme is used.
(SIMPLE => 1, "SIMPLE")
}

int_enum_str_decimal!(ZonemdScheme, u8);
int_enum_zonefile_fmt_decimal!(ZonemdScheme, "scheme");

//------------ ZonemdAlg -----------------------------------------------------

int_enum! {
/// ZONEMD algorithms.
///
/// This type selects the algorithm used to hash domain names for use with
/// the [ZONEMD].
///
/// For the currently registered values see the [IANA registration]. This
/// type is complete as of 2024-11-29.
///
/// [ZONEMD]: ../../../rdata/zonemd/index.html
/// [IANA registration]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#zonemd-hash-algorithms
=>
ZonemdAlg, u8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be ZonemdAlgorithm?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was for consistency with the other algorithm type names (SecAlg, DigestAlg, Nsec3HashAlg, ...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we avoid abbreviation unless something is frequently used. In wonder what is different in this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean why the other type names are abbreviated in the first place?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a PR that renames them all. So we can leave it as is for the moment.


/// Specifies that the SHA-384 algorithm is used.
(SHA384 => 1, "SHA384")

/// Specifies that the SHA-512 algorithm is used.
(SHA512 => 2, "SHA512")
}

int_enum_str_decimal!(ZonemdAlg, u8);
int_enum_zonefile_fmt_decimal!(ZonemdAlg, "hash algorithm");
120 changes: 11 additions & 109 deletions src/rdata/zonemd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#![allow(clippy::needless_maybe_sized)]

use crate::base::cmp::CanonicalOrd;
use crate::base::iana::Rtype;
use crate::base::iana::{Rtype, ZonemdAlg, ZonemdScheme};
use crate::base::rdata::{ComposeRecordData, RecordData};
use crate::base::scan::{Scan, Scanner};
use crate::base::serial::Serial;
use crate::base::zonefile_fmt::{self, Formatter, ZonefileFmt};
use crate::base::wire::{Composer, ParseError};
use crate::base::zonefile_fmt::{self, Formatter, ZonefileFmt};
use crate::utils::base16;
use core::cmp::Ordering;
use core::{fmt, hash};
Expand All @@ -29,8 +29,8 @@ const DIGEST_MIN_LEN: usize = 12;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Zonemd<Octs: ?Sized> {
serial: Serial,
scheme: Scheme,
algo: Algorithm,
scheme: ZonemdScheme,
algo: ZonemdAlg,
#[cfg_attr(
feature = "serde",
serde(
Expand All @@ -54,8 +54,8 @@ impl<Octs> Zonemd<Octs> {
/// Create a Zonemd record data from provided parameters.
pub fn new(
serial: Serial,
scheme: Scheme,
algo: Algorithm,
scheme: ZonemdScheme,
algo: ZonemdAlg,
digest: Octs,
) -> Self {
Self {
Expand All @@ -72,12 +72,12 @@ impl<Octs> Zonemd<Octs> {
}

/// Get the scheme field.
pub fn scheme(&self) -> Scheme {
pub fn scheme(&self) -> ZonemdScheme {
self.scheme
}

/// Get the hash algorithm field.
pub fn algorithm(&self) -> Algorithm {
pub fn algorithm(&self) -> ZonemdAlg {
self.algo
}

Expand Down Expand Up @@ -233,20 +233,7 @@ impl<Octs: AsRef<[u8]>> ZonefileFmt for Zonemd<Octs> {
p.block(|p| {
p.write_token(self.serial)?;
p.write_show(self.scheme)?;
p.write_comment(format_args!("scheme ({})", match self.scheme {
Scheme::Reserved => "reserved",
Scheme::Simple => "simple",
Scheme::Unassigned(_) => "unassigned",
Scheme::Private(_) => "private",
}))?;
p.write_show(self.algo)?;
p.write_comment(format_args!("algorithm ({})", match self.algo {
Algorithm::Reserved => "reserved",
Algorithm::Sha384 => "SHA384",
Algorithm::Sha512 => "SHA512",
Algorithm::Unassigned(_) => "unassigned",
Algorithm::Private(_) => "private",
}))?;
p.write_token(base16::encode_display(&self.digest))
})
}
Expand Down Expand Up @@ -314,92 +301,6 @@ impl<Octs: AsRef<[u8]>> Ord for Zonemd<Octs> {
}
}

/// The data collation scheme.
///
/// This enumeration wraps an 8-bit unsigned integer that identifies the
/// methods by which data is collated and presented as input to the
/// hashing function.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Scheme {
Reserved,
Simple,
Unassigned(u8),
Private(u8),
}

impl From<Scheme> for u8 {
fn from(s: Scheme) -> u8 {
match s {
Scheme::Reserved => 0,
Scheme::Simple => 1,
Scheme::Unassigned(n) => n,
Scheme::Private(n) => n,
}
}
}

impl From<u8> for Scheme {
fn from(n: u8) -> Self {
match n {
0 | 255 => Self::Reserved,
1 => Self::Simple,
2..=239 => Self::Unassigned(n),
240..=254 => Self::Private(n),
}
}
}

impl ZonefileFmt for Scheme {
fn fmt(&self, p: &mut impl Formatter) -> zonefile_fmt::Result {
p.write_token(u8::from(*self))
}
}

/// The Hash Algorithm used to construct the digest.
///
/// This enumeration wraps an 8-bit unsigned integer that identifies
/// the cryptographic hash algorithm.
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Algorithm {
Reserved,
Sha384,
Sha512,
Unassigned(u8),
Private(u8),
}

impl From<Algorithm> for u8 {
fn from(algo: Algorithm) -> u8 {
match algo {
Algorithm::Reserved => 0,
Algorithm::Sha384 => 1,
Algorithm::Sha512 => 2,
Algorithm::Unassigned(n) => n,
Algorithm::Private(n) => n,
}
}
}

impl From<u8> for Algorithm {
fn from(n: u8) -> Self {
match n {
0 | 255 => Self::Reserved,
1 => Self::Sha384,
2 => Self::Sha512,
3..=239 => Self::Unassigned(n),
240..=254 => Self::Private(n),
}
}
}

impl ZonefileFmt for Algorithm {
fn fmt(&self, p: &mut impl Formatter) -> zonefile_fmt::Result {
p.write_token(u8::from(*self))
}
}

#[cfg(test)]
#[cfg(all(feature = "std", feature = "bytes"))]
mod test {
Expand Down Expand Up @@ -437,6 +338,7 @@ mod test {
#[cfg(feature = "zonefile")]
#[test]
fn zonemd_parse_zonefile() {
use crate::base::iana::ZonemdAlg;
use crate::base::Name;
use crate::rdata::ZoneRecordData;
use crate::zonefile::inplace::{Entry, Zonefile};
Expand Down Expand Up @@ -469,8 +371,8 @@ ns2 3600 IN AAAA 2001:db8::63
match record.into_data() {
ZoneRecordData::Zonemd(rd) => {
assert_eq!(2018031900, rd.serial().into_int());
assert_eq!(Scheme::Simple, rd.scheme());
assert_eq!(Algorithm::Sha384, rd.algorithm());
assert_eq!(ZonemdScheme::SIMPLE, rd.scheme());
assert_eq!(ZonemdAlg::SHA384, rd.algorithm());
}
_ => panic!(),
}
Expand Down