move existing test into RFC4035 section 3.2.2
This commit is contained in:
parent
8f414879b8
commit
b6e97bf3b6
@ -1,4 +1,5 @@
|
|||||||
//! DNSSEC functionality
|
//! DNSSEC functionality
|
||||||
|
|
||||||
|
mod fixtures;
|
||||||
mod rfc4035;
|
mod rfc4035;
|
||||||
mod scenarios;
|
mod scenarios;
|
||||||
|
50
packages/conformance-tests/src/resolver/dnssec/fixtures.rs
Normal file
50
packages/conformance-tests/src/resolver/dnssec/fixtures.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
|
use base64::prelude::*;
|
||||||
|
use dns_test::{
|
||||||
|
name_server::{Graph, NameServer, Sign},
|
||||||
|
record::Record,
|
||||||
|
Network, Resolver, Result, FQDN,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn bad_signature_in_leaf_nameserver(
|
||||||
|
leaf_fqdn: &FQDN,
|
||||||
|
leaf_ipv4_addr: Ipv4Addr,
|
||||||
|
) -> Result<(Resolver, Graph)> {
|
||||||
|
assert_eq!(Some(FQDN::NAMESERVERS), leaf_fqdn.parent());
|
||||||
|
|
||||||
|
let network = Network::new()?;
|
||||||
|
|
||||||
|
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||||
|
leaf_ns.add(Record::a(leaf_fqdn.clone(), leaf_ipv4_addr));
|
||||||
|
|
||||||
|
let graph = Graph::build(
|
||||||
|
leaf_ns,
|
||||||
|
Sign::AndAmend(&|zone, records| {
|
||||||
|
if zone == &FQDN::NAMESERVERS {
|
||||||
|
let mut modified = 0;
|
||||||
|
for record in records {
|
||||||
|
if let Record::RRSIG(rrsig) = record {
|
||||||
|
if rrsig.fqdn == *leaf_fqdn {
|
||||||
|
let mut signature = BASE64_STANDARD.decode(&rrsig.signature).unwrap();
|
||||||
|
let last = signature.last_mut().expect("empty signature");
|
||||||
|
*last = !*last;
|
||||||
|
|
||||||
|
rrsig.signature = BASE64_STANDARD.encode(&signature);
|
||||||
|
modified += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(modified, 1, "sanity check");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let trust_anchor = graph.trust_anchor.as_ref().unwrap();
|
||||||
|
let resolver = Resolver::new(&network, graph.root.clone())
|
||||||
|
.trust_anchor(trust_anchor)
|
||||||
|
.start(&dns_test::SUBJECT)?;
|
||||||
|
|
||||||
|
Ok((resolver, graph))
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use dns_test::{
|
use dns_test::{
|
||||||
client::{Client, DigSettings},
|
client::{Client, DigSettings},
|
||||||
name_server::NameServer,
|
name_server::NameServer,
|
||||||
@ -6,6 +8,8 @@ use dns_test::{
|
|||||||
Network, Resolver, Result, FQDN,
|
Network, Resolver, Result, FQDN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::resolver::dnssec::fixtures;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn copies_cd_bit_from_query_to_response() -> Result<()> {
|
fn copies_cd_bit_from_query_to_response() -> Result<()> {
|
||||||
let network = &Network::new()?;
|
let network = &Network::new()?;
|
||||||
@ -21,3 +25,33 @@ fn copies_cd_bit_from_query_to_response() -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_cd_bit_is_set_then_respond_with_data_that_fails_authentication() -> Result<()> {
|
||||||
|
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||||
|
let needle_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||||
|
|
||||||
|
let (resolver, _graph) =
|
||||||
|
fixtures::bad_signature_in_leaf_nameserver(&needle_fqdn, needle_ipv4_addr)?;
|
||||||
|
|
||||||
|
let resolver_addr = resolver.ipv4_addr();
|
||||||
|
|
||||||
|
let client = Client::new(resolver.network())?;
|
||||||
|
|
||||||
|
let settings = *DigSettings::default()
|
||||||
|
.recurse()
|
||||||
|
.authentic_data()
|
||||||
|
.checking_disabled();
|
||||||
|
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
||||||
|
|
||||||
|
assert!(output.status.is_noerror());
|
||||||
|
assert!(!output.flags.authenticated_data);
|
||||||
|
|
||||||
|
let [record] = output.answer.try_into().unwrap();
|
||||||
|
let record = record.try_into_a().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(needle_fqdn, record.fqdn);
|
||||||
|
assert_eq!(needle_ipv4_addr, record.ipv4_addr);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -1,73 +1,29 @@
|
|||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use base64::prelude::*;
|
|
||||||
use dns_test::client::{Client, DigSettings};
|
use dns_test::client::{Client, DigSettings};
|
||||||
use dns_test::name_server::{Graph, NameServer, Sign};
|
use dns_test::record::RecordType;
|
||||||
use dns_test::record::{Record, RecordType};
|
use dns_test::{Result, FQDN};
|
||||||
use dns_test::{Network, Resolver, Result, FQDN};
|
|
||||||
|
|
||||||
|
use crate::resolver::dnssec::fixtures;
|
||||||
|
|
||||||
|
// TODO find out which RFC section states this
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn bad_signature_in_leaf_nameserver() -> Result<()> {
|
fn if_cd_bit_is_clear_and_data_is_not_authentic_then_respond_with_servfail() -> Result<()> {
|
||||||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
|
||||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||||
|
let needle_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||||
|
|
||||||
let network = Network::new()?;
|
let (resolver, _graph) =
|
||||||
|
fixtures::bad_signature_in_leaf_nameserver(&needle_fqdn, needle_ipv4_addr)?;
|
||||||
|
|
||||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
|
||||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
|
||||||
|
|
||||||
let Graph {
|
|
||||||
nameservers: _nameservers,
|
|
||||||
root,
|
|
||||||
trust_anchor,
|
|
||||||
} = Graph::build(
|
|
||||||
leaf_ns,
|
|
||||||
Sign::AndAmend(&|zone, records| {
|
|
||||||
if zone == &FQDN::NAMESERVERS {
|
|
||||||
let mut modified = 0;
|
|
||||||
for record in records {
|
|
||||||
if let Record::RRSIG(rrsig) = record {
|
|
||||||
if rrsig.fqdn == needle_fqdn {
|
|
||||||
let mut signature = BASE64_STANDARD.decode(&rrsig.signature).unwrap();
|
|
||||||
let last = signature.last_mut().expect("empty signature");
|
|
||||||
*last = !*last;
|
|
||||||
|
|
||||||
rrsig.signature = BASE64_STANDARD.encode(&signature);
|
|
||||||
modified += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(modified, 1, "sanity check");
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let trust_anchor = &trust_anchor.unwrap();
|
|
||||||
let resolver = Resolver::new(&network, root)
|
|
||||||
.trust_anchor(trust_anchor)
|
|
||||||
.start(&dns_test::SUBJECT)?;
|
|
||||||
let resolver_addr = resolver.ipv4_addr();
|
let resolver_addr = resolver.ipv4_addr();
|
||||||
|
|
||||||
let client = Client::new(&network)?;
|
let client = Client::new(resolver.network())?;
|
||||||
|
|
||||||
let mut settings = *DigSettings::default().recurse().authentic_data();
|
let settings = *DigSettings::default().recurse().authentic_data();
|
||||||
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
||||||
|
|
||||||
// the resolver will try to validate the chain of trust; the validation fails so it responds
|
|
||||||
// with SERVFAIL
|
|
||||||
assert!(output.status.is_servfail());
|
assert!(output.status.is_servfail());
|
||||||
|
|
||||||
// avoids a SERVFAIL response
|
|
||||||
settings.checking_disabled();
|
|
||||||
|
|
||||||
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
|
||||||
|
|
||||||
// when the CD (Checking Disabled) bit is set the server won't respond with SERVFAIL on
|
|
||||||
// validation errors. the outcome of the validation process is reported in the AD bit
|
|
||||||
assert!(output.status.is_noerror());
|
|
||||||
assert!(!output.flags.authenticated_data);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@ impl Resolver {
|
|||||||
self.container.eavesdrop()
|
self.container.eavesdrop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn network(&self) -> &Network {
|
||||||
|
self.container.network()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn container_id(&self) -> &str {
|
pub fn container_id(&self) -> &str {
|
||||||
self.container.id()
|
self.container.id()
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ impl FromStr for ZoneFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A root (server) hint
|
/// A root (server) hint
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Root {
|
pub struct Root {
|
||||||
pub ipv4_addr: Ipv4Addr,
|
pub ipv4_addr: Ipv4Addr,
|
||||||
pub ns: FQDN,
|
pub ns: FQDN,
|
||||||
|
Loading…
Reference in New Issue
Block a user