Skip to content

Commit

Permalink
fix: dnssec module
Browse files Browse the repository at this point in the history
  • Loading branch information
joalopez1206 committed Jul 14, 2024
1 parent 1a42a35 commit 67c42d3
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 99 deletions.
94 changes: 4 additions & 90 deletions src/dnssec.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,4 @@
pub mod dnssec;



use std::str::FromStr;
use crate::domain_name::DomainName;
use crate::message::rclass::Rclass;
use crate::message::DnsMessage;
use crate::message::rdata::opt_rdata::OptRdata;
use crate::message::rdata::Rdata;
use crate::message::resource_record::{FromBytes, ResourceRecord, ToBytes};
use crate::message::rcode;
use crate::message::rcode::Rcode;
use crate::message::rrtype::Rrtype;

const EDNS_VERSION: u8 = 0;
const REQUESTED_UDP_LEN: u16 = 4096;
/*
The mechanism chosen for the explicit notification of the ability of
the client to accept (if not understand) DNSSEC security RRs is using
the most significant bit of the Z field on the EDNS0 OPT header in
the query. This bit is referred to as the "DNSSEC OK" (DO) bit. In
the context of the EDNS0 OPT meta-RR, the DO bit is the first bit of
the third and fourth bytes of the "extended RCODE and flags" portion
of the EDNS0 OPT meta-RR, structured as follows:
+0 (MSB) +1 (LSB)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
0: | EXTENDED-RCODE | VERSION |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
2: |DO| Z |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
fn create_opt_rr(capacity: u16 ,e_rcode :u8, version: u8, do_bit: bool) -> ResourceRecord {
let opt_rdata = OptRdata::new();
let rdata = Rdata::OPT(opt_rdata);
let mut rr = ResourceRecord::new(rdata);

let do_val: u16 = if do_bit {0x8000} else {0x0};
let ttl: u32 = (e_rcode as u32) << 24 | (version as u32) << 16| (do_val as u32);
rr.set_ttl(ttl);
rr.set_rclass(Rclass::UNKNOWN(capacity));
println!("EL ttl es: {:#05x?}", ttl);
rr
}

fn read_opt_rr(opt_rr: ResourceRecord) -> String {
let requested_udp_len = Rclass::from_rclass_to_int(opt_rr.get_rclass());
let data = opt_rr.get_ttl().to_be_bytes();
let (e_rcode, version) = (data[0], data[1]);
let z = u16::from_be_bytes([data[2], data[3]]);

let do_bit = ((z & 0x8000) > 0) as u8 ;
format!("OPT PSEUDO-RR\n\trequested_udp_len: {requested_udp_len}\n\terror code: {e_rcode}\n\tversion: EDNS{version}\n\tuse dnssec: {do_bit}")
}

/*
A security-aware resolver MUST include an EDNS ([RFC2671]) OPT
pseudo-RR with the DO ([RFC3225]) bit set when sending queries.
*/
fn create_dns_message_with_dnssec(mut msg: DnsMessage) -> DnsMessage {
// We create a opt rr with the do bit set to 1
// with NOERR as rcode and EDNS0
let rr = create_opt_rr(REQUESTED_UDP_LEN,
rcode::Rcode::from_rcode_to_int(Rcode::NOERROR),
EDNS_VERSION,
true);

let vec = vec![rr];
msg.add_additionals(vec);
msg
}

#[test]
fn see_dnssec_message() {
let query = DnsMessage::new_query_message(
DomainName::new_from_str("example.com"),
Rrtype::A,
Rclass::UNKNOWN(4096),
1,
true,
2000
);
let query= create_dns_message_with_dnssec(query);
assert_eq!(String::from_str
("OPT PSEUDO-RR\n\trequested_udp_len: 4096\n\terror code: 0\n\tversion: EDNS0\n\tuse dnssec: 1")
.expect("Not a utf8 str"),
read_opt_rr(query.get_additional().pop().expect("No OPT Record!"))
)
}
pub mod dnssec_message;
pub mod dnssec_message_processing;
pub mod dnssec_fetch;
pub mod rrset_signature;
4 changes: 2 additions & 2 deletions src/dnssec/dnssec.rs → src/dnssec/dnssec_fetch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::message::{DnsMessage, Rdata, ResourceRecord};
use crate::dnssec_message_processing::extract_dnssec_records;
use crate::rrset_signature::{verify_rrsig, verify_ds};
use crate::dnssec::dnssec_message_processing::extract_dnssec_records;
use crate::dnssec::rrset_signature::{verify_rrsig, verify_ds};
use crate::message::rdata::DnskeyRdata;
use crate::client::client_error::ClientError;

Expand Down
87 changes: 87 additions & 0 deletions src/dnssec/dnssec_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

use std::str::FromStr;
use crate::domain_name::DomainName;
use crate::message::rclass::Rclass;
use crate::message::DnsMessage;
use crate::message::rdata::opt_rdata::OptRdata;
use crate::message::rdata::Rdata;
use crate::message::resource_record::{FromBytes, ResourceRecord, ToBytes};
use crate::message::rcode;
use crate::message::rcode::Rcode;
use crate::message::rrtype::Rrtype;

const EDNS_VERSION: u8 = 0;
const REQUESTED_UDP_LEN: u16 = 4096;
/*
The mechanism chosen for the explicit notification of the ability of
the client to accept (if not understand) DNSSEC security RRs is using
the most significant bit of the Z field on the EDNS0 OPT header in
the query. This bit is referred to as the "DNSSEC OK" (DO) bit. In
the context of the EDNS0 OPT meta-RR, the DO bit is the first bit of
the third and fourth bytes of the "extended RCODE and flags" portion
of the EDNS0 OPT meta-RR, structured as follows:
+0 (MSB) +1 (LSB)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
0: | EXTENDED-RCODE | VERSION |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
2: |DO| Z |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
fn create_opt_rr(capacity: u16 ,e_rcode :u8, version: u8, do_bit: bool) -> ResourceRecord {
let opt_rdata = OptRdata::new();
let rdata = Rdata::OPT(opt_rdata);
let mut rr = ResourceRecord::new(rdata);

let do_val: u16 = if do_bit {0x8000} else {0x0};
let ttl: u32 = (e_rcode as u32) << 24 | (version as u32) << 16| (do_val as u32);
rr.set_ttl(ttl);
rr.set_rclass(Rclass::UNKNOWN(capacity));
println!("EL ttl es: {:#05x?}", ttl);
rr
}

fn read_opt_rr(opt_rr: ResourceRecord) -> String {
let requested_udp_len = Rclass::from_rclass_to_int(opt_rr.get_rclass());
let data = opt_rr.get_ttl().to_be_bytes();
let (e_rcode, version) = (data[0], data[1]);
let z = u16::from_be_bytes([data[2], data[3]]);

let do_bit = ((z & 0x8000) > 0) as u8 ;
format!("OPT PSEUDO-RR\n\trequested_udp_len: {requested_udp_len}\n\terror code: {e_rcode}\n\tversion: EDNS{version}\n\tuse dnssec: {do_bit}")
}

/*
A security-aware resolver MUST include an EDNS ([RFC2671]) OPT
pseudo-RR with the DO ([RFC3225]) bit set when sending queries.
*/
fn create_dns_message_with_dnssec(mut msg: DnsMessage) -> DnsMessage {
// We create a opt rr with the do bit set to 1
// with NOERR as rcode and EDNS0
let rr = create_opt_rr(REQUESTED_UDP_LEN,
rcode::Rcode::from_rcode_to_int(Rcode::NOERROR),
EDNS_VERSION,
true);

let vec = vec![rr];
msg.add_additionals(vec);
msg
}

#[test]
fn see_dnssec_message() {
let query = DnsMessage::new_query_message(
DomainName::new_from_str("example.com"),
Rrtype::A,
Rclass::UNKNOWN(4096),
1,
true,
2000
);
let query= create_dns_message_with_dnssec(query);
assert_eq!(String::from_str
("OPT PSEUDO-RR\n\trequested_udp_len: 4096\n\terror code: 0\n\tversion: EDNS0\n\tuse dnssec: 1")
.expect("Not a utf8 str"),
read_opt_rr(query.get_additional().pop().expect("No OPT Record!"))
)
}
15 changes: 8 additions & 7 deletions src/dnssec/rrset_signature.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use sha2::{Sha256, Digest};
use rust_crypto::digest::Digest as RustDigest;
use rust_crypto::sha1::Sha1;
use crypto::digest::Digest as RustDigest;
use crypto::sha1::Sha1;
use base64::encode;
use crate::message::rdata::{DnskeyRdata, RrsigRdata, Rdata};
use crate::message::rdata::{DnskeyRdata, Rdata};
use crate::message::rdata::rrsig_rdata::{RRSIGRdata};
use crate::message::resource_record::ResourceRecord;
use crate::client::client_error::ClientError;

pub fn verify_rrsig(rrsig: &RrsigRdata, dnskey: &DnskeyRdata, rrset: &[ResourceRecord]) -> Result<bool, ClientError> {
pub fn verify_rrsig(rrsig: &RRSIGRdata, dnskey: &DnskeyRdata, rrset: &[ResourceRecord]) -> Result<bool, ClientError> {
let mut rrsig_data = Vec::new();
rrsig_data.extend_from_slice(&rrsig.type_covered.to_be_bytes());
rrsig_data.push(rrsig.algorithm);
rrsig_data.push(rrsig.labels);
rrsig_data.extend_from_slice(&rrsig.get_type_covered().to_be_bytes());
rrsig_data.push(rrsig.get_algorithm());
rrsig_data.push(rrsig.get_labels());
rrsig_data.extend_from_slice(&rrsig.original_ttl.to_be_bytes());
rrsig_data.extend_from_slice(&rrsig.expiration.to_be_bytes());
rrsig_data.extend_from_slice(&rrsig.inception.to_be_bytes());
Expand Down

0 comments on commit 67c42d3

Please sign in to comment.