use core::convert::From;
use core::fmt::{Debug, Display};
use core::iter::Extend;
use core::marker::Send;
use core::ops::Deref;
use std::boxed::Box;
use std::hash::Hash;
use std::vec::Vec;
use octseq::builder::{EmptyBuilder, FromBuilder, OctetsBuilder, Truncate};
use octseq::OctetsFrom;
use crate::base::cmp::CanonicalOrd;
use crate::base::name::ToName;
use crate::base::record::Record;
use crate::base::Name;
use crate::crypto::sign::SignRaw;
use crate::dnssec::sign::error::SigningError;
use crate::dnssec::sign::keys::SigningKey;
use crate::dnssec::sign::records::{
DefaultSorter, RecordsIter, Rrset, SortedRecords, Sorter,
};
use crate::dnssec::sign::sign_zone;
use crate::dnssec::sign::signatures::rrsigs::sign_sorted_zone_records;
use crate::dnssec::sign::signatures::rrsigs::GenerateRrsigConfig;
use crate::dnssec::sign::SignableZoneInOut;
use crate::dnssec::sign::SigningConfig;
use crate::rdata::dnssec::Timestamp;
use crate::rdata::{Rrsig, ZoneRecordData};
pub trait SortedExtend<N, Octs, Sort>
where
Sort: Sorter,
{
fn sorted_extend<
T: IntoIterator<Item = Record<N, ZoneRecordData<Octs, N>>>,
>(
&mut self,
iter: T,
);
}
impl<N, Octs, Sort> SortedExtend<N, Octs, Sort>
for SortedRecords<N, ZoneRecordData<Octs, N>, Sort>
where
N: Send + PartialEq + ToName,
Octs: Send,
Sort: Sorter,
ZoneRecordData<Octs, N>: CanonicalOrd + PartialEq,
{
fn sorted_extend<
T: IntoIterator<Item = Record<N, ZoneRecordData<Octs, N>>>,
>(
&mut self,
iter: T,
) {
self.extend(iter);
}
}
impl<N, Octs, Sort> SortedExtend<N, Octs, Sort>
for Vec<Record<N, ZoneRecordData<Octs, N>>>
where
N: Send + PartialEq + ToName,
Octs: Send,
Sort: Sorter,
ZoneRecordData<Octs, N>: CanonicalOrd + PartialEq,
{
fn sorted_extend<
T: IntoIterator<Item = Record<N, ZoneRecordData<Octs, N>>>,
>(
&mut self,
iter: T,
) {
self.extend(iter);
Sort::sort_by(self, CanonicalOrd::canonical_cmp);
self.dedup();
}
}
pub trait SignableZone<N, Octs, Sort>:
Deref<Target = [Record<N, ZoneRecordData<Octs, N>>]>
where
N: Clone + Debug + ToName + From<Name<Octs>> + PartialEq + Ord + Hash,
Octs: Clone
+ Debug
+ FromBuilder
+ From<&'static [u8]>
+ Send
+ OctetsFrom<Vec<u8>>
+ From<Box<[u8]>>
+ Default,
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
Sort: Sorter,
{
fn sign_zone<Inner, T>(
&self,
apex_owner: &N,
signing_config: &SigningConfig<Octs, Sort>,
signing_keys: &[&SigningKey<Octs, Inner>],
out: &mut T,
) -> Result<(), SigningError>
where
Inner: Debug + SignRaw,
N: Display + Send + CanonicalOrd,
<Octs as FromBuilder>::Builder: Truncate,
<<Octs as FromBuilder>::Builder as OctetsBuilder>::AppendError: Debug,
T: Deref<Target = [Record<N, ZoneRecordData<Octs, N>>]>
+ SortedExtend<N, Octs, Sort>
+ ?Sized,
Self: Sized,
{
let in_out = SignableZoneInOut::new_into(self, out);
sign_zone::<N, Octs, _, Inner, Sort, T>(
apex_owner,
in_out,
signing_config,
signing_keys,
)
}
}
impl<N, Octs, Sort, T> SignableZone<N, Octs, Sort> for T
where
N: Clone
+ Debug
+ ToName
+ From<Name<Octs>>
+ PartialEq
+ Send
+ CanonicalOrd
+ Ord
+ Hash,
Octs: Clone
+ Debug
+ FromBuilder
+ From<&'static [u8]>
+ Send
+ OctetsFrom<Vec<u8>>
+ From<Box<[u8]>>
+ Default,
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
Sort: Sorter,
T: Deref<Target = [Record<N, ZoneRecordData<Octs, N>>]>,
{
}
pub trait SignableZoneInPlace<N, Octs, Sort>:
SignableZone<N, Octs, Sort> + SortedExtend<N, Octs, Sort>
where
N: Clone + Debug + ToName + From<Name<Octs>> + PartialEq + Ord + Hash,
Octs: Clone
+ Debug
+ FromBuilder
+ From<&'static [u8]>
+ Send
+ OctetsFrom<Vec<u8>>
+ From<Box<[u8]>>
+ Default,
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
Self: SortedExtend<N, Octs, Sort> + Sized,
Sort: Sorter,
{
fn sign_zone<Inner>(
&mut self,
apex_owner: &N,
signing_config: &SigningConfig<Octs, Sort>,
signing_keys: &[&SigningKey<Octs, Inner>],
) -> Result<(), SigningError>
where
Inner: Debug + SignRaw,
N: Display + Send + CanonicalOrd,
<Octs as FromBuilder>::Builder: Truncate,
<<Octs as FromBuilder>::Builder as OctetsBuilder>::AppendError: Debug,
{
let in_out =
SignableZoneInOut::<_, _, Self, _, _>::new_in_place(self);
sign_zone::<N, Octs, _, Inner, Sort, _>(
apex_owner,
in_out,
signing_config,
signing_keys,
)
}
}
impl<N, Octs, Sort, T> SignableZoneInPlace<N, Octs, Sort> for T
where
N: Clone
+ Debug
+ ToName
+ From<Name<Octs>>
+ PartialEq
+ Send
+ CanonicalOrd
+ Hash
+ Ord,
Octs: Clone
+ Debug
+ FromBuilder
+ From<&'static [u8]>
+ Send
+ OctetsFrom<Vec<u8>>
+ From<Box<[u8]>>
+ Default,
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
Sort: Sorter,
T: Deref<Target = [Record<N, ZoneRecordData<Octs, N>>]>,
T: SortedExtend<N, Octs, Sort> + Sized,
{
}
pub trait Signable<N, Octs, Inner, Sort = DefaultSorter>
where
N: ToName
+ CanonicalOrd
+ Send
+ Debug
+ Display
+ Clone
+ PartialEq
+ From<Name<Octs>>,
Inner: Debug + SignRaw,
Octs: From<Box<[u8]>>
+ From<&'static [u8]>
+ FromBuilder
+ Clone
+ Debug
+ OctetsFrom<std::vec::Vec<u8>>
+ Send,
<Octs as FromBuilder>::Builder: EmptyBuilder + AsRef<[u8]> + AsMut<[u8]>,
Sort: Sorter,
{
fn owner_rrs(&self) -> RecordsIter<'_, N, ZoneRecordData<Octs, N>>;
#[allow(clippy::type_complexity)]
fn sign(
&self,
apex_owner: &N,
keys: &[&SigningKey<Octs, Inner>],
inception: Timestamp,
expiration: Timestamp,
) -> Result<Vec<Record<N, Rrsig<Octs, N>>>, SigningError> {
let rrsig_config = GenerateRrsigConfig::new(inception, expiration);
sign_sorted_zone_records(
apex_owner,
self.owner_rrs(),
keys,
&rrsig_config,
)
}
}
impl<N, Octs, Inner> Signable<N, Octs, Inner>
for Rrset<'_, N, ZoneRecordData<Octs, N>>
where
Inner: Debug + SignRaw,
N: From<Name<Octs>>
+ PartialEq
+ Clone
+ Debug
+ Display
+ Send
+ CanonicalOrd
+ ToName,
Octs: octseq::FromBuilder
+ Send
+ OctetsFrom<Vec<u8>>
+ Clone
+ Debug
+ From<&'static [u8]>
+ From<Box<[u8]>>,
<Octs as FromBuilder>::Builder: AsRef<[u8]> + AsMut<[u8]> + EmptyBuilder,
{
fn owner_rrs(&self) -> RecordsIter<'_, N, ZoneRecordData<Octs, N>> {
RecordsIter::new(self.clone().into_inner())
}
}