use core::fmt;
use thiserror::Error;
use crate::{
error::NetError,
proto::{
ProtoError,
dnssec::{Algorithm, Proof},
op::Query,
rr::{Name, RecordType},
},
};
#[allow(unreachable_pub)]
#[derive(Debug, Error, Clone)]
#[non_exhaustive]
pub enum ProofErrorKind {
#[error("{0}")]
Msg(String),
#[error("algorithm mismatch rrsig: {rrsig} dnskey: {dnskey}")]
AlgorithmMismatch {
rrsig: Algorithm,
dnskey: Algorithm,
},
#[error("dnskey and rrset failed to verify: {name} key_tag: {key_tag}")]
DnsKeyVerifyRrsig {
name: Name,
key_tag: u16,
error: ProtoError,
},
#[error("no dnskey was found: {name}")]
DnskeyNotFound {
name: Name,
},
#[error("dnskey revoked: {name}, key_tag: {key_tag}")]
DnsKeyRevoked {
name: Name,
key_tag: u16,
},
#[error("dnskey has no ds: {name}")]
DnsKeyHasNoDs {
name: Name,
},
#[error("ds record exists, but no dnskey: {name}")]
DsRecordsButNoDnskey {
name: Name,
},
#[error("ds record should exist: {name}")]
DsRecordShouldExist {
name: Name,
},
#[error("ds record does not exist: {name}")]
DsResponseInsecure {
name: Name,
},
#[error("internal error computing the key tag for: {name}")]
ErrorComputingKeyTag {
name: Name,
},
#[error("dnskey insecure: {name}, key_tag: {key_tag}")]
InsecureDnsKey {
name: Name,
key_tag: u16,
},
#[error("not a zone signing key: {name} key_tag: {key_tag}")]
NotZoneDnsKey {
name: Name,
key_tag: u16,
},
#[error("communication failure for query: {query}: {net}")]
Net {
query: Query,
net: NetError,
},
#[error("rrsigs are not present for: {name} record_type: {record_type}")]
RrsigsNotPresent {
name: Name,
record_type: RecordType,
},
#[error("rrsigs were not able to be verified: {name}, type: {record_type}")]
RrsigsUnverified {
name: Name,
record_type: RecordType,
},
#[error("unknown or reserved key algorithm")]
UnknownKeyAlgorithm,
#[error("unsupported key algorithms")]
UnsupportedKeyAlgorithm,
}
#[non_exhaustive]
#[derive(Debug, Clone, Error)]
pub struct ProofError {
pub proof: Proof,
pub kind: Box<ProofErrorKind>,
}
impl ProofError {
pub fn new(proof: Proof, kind: ProofErrorKind) -> Self {
Self {
proof,
kind: Box::new(kind),
}
}
pub fn kind(&self) -> &ProofErrorKind {
&self.kind
}
pub fn ds_should_exist(name: Name) -> Self {
Self {
proof: Proof::Bogus,
kind: Box::new(ProofErrorKind::DsRecordShouldExist { name }),
}
}
}
impl fmt::Display for ProofError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.proof, self.kind)
}
}