hickory_proto/dnssec/verifier.rs
1// Copyright 2015-2023 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! Verifier is a structure for performing many of the signing processes of the DNSSEC specification
9
10use alloc::sync::Arc;
11
12use super::{
13 Algorithm, PublicKey,
14 rdata::{RRSIG, SIG},
15 tbs::{self, TBS},
16};
17use crate::{
18 error::ProtoResult,
19 rr::{DNSClass, Name, Record},
20 serialize::binary::BinEncodable,
21};
22
23/// Types which are able to verify DNS based signatures
24pub trait Verifier {
25 /// Return the algorithm which this Verifier covers
26 fn algorithm(&self) -> Algorithm;
27
28 /// Return the public key associated with this verifier
29 fn key(&self) -> ProtoResult<Arc<dyn PublicKey + '_>>;
30
31 /// Verifies the hash matches the signature with the current `key`.
32 ///
33 /// # Arguments
34 ///
35 /// * `hash` - the hash to be validated, see `rrset_tbs`
36 /// * `signature` - the signature to use to verify the hash, extracted from an `RData::RRSIG`
37 /// for example.
38 ///
39 /// # Return value
40 ///
41 /// True if and only if the signature is valid for the hash.
42 /// false if the `key`.
43 fn verify(&self, hash: &[u8], signature: &[u8]) -> ProtoResult<()> {
44 self.key()?.verify(hash, signature)
45 }
46
47 /// Verifies a message with the against the given signature, i.e. SIG0
48 ///
49 /// # Arguments
50 ///
51 /// * `message` - the message to verify
52 /// * `signature` - the signature to use for validation
53 ///
54 /// # Return value
55 ///
56 /// `true` if the message could be validated against the signature, `false` otherwise
57 fn verify_message<M: BinEncodable>(
58 &self,
59 message: &M,
60 signature: &[u8],
61 sig0: &SIG,
62 ) -> ProtoResult<()> {
63 tbs::message_tbs(message, sig0).and_then(|tbs| self.verify(tbs.as_ref(), signature))
64 }
65
66 /// Verifies an RRSig with the associated key, e.g. DNSKEY
67 ///
68 /// # Arguments
69 ///
70 /// * `name` - name associated with the rrsig being validated
71 /// * `dns_class` - DNSClass of the records, generally IN
72 /// * `sig` - signature record being validated
73 /// * `records` - Records covered by SIG
74 fn verify_rrsig<'a>(
75 &self,
76 name: &Name,
77 dns_class: DNSClass,
78 sig: &RRSIG,
79 records: impl Iterator<Item = &'a Record>,
80 ) -> ProtoResult<()> {
81 let rrset_tbs = TBS::from_sig(name, dns_class, sig, records)?;
82 self.verify(rrset_tbs.as_ref(), sig.sig())
83 }
84}