Skip to content

Commit

Permalink
add tsig to message
Browse files Browse the repository at this point in the history
  • Loading branch information
Litr0 committed Aug 6, 2024
1 parent 7c9e0bd commit 1096f87
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 22 deletions.
48 changes: 48 additions & 0 deletions src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ use crate::message::question::Question;
use crate::message::resource_record::ResourceRecord;
use crate::message::rdata::Rdata;
use crate::message::rdata::opt_rdata::OptRdata;
use crate::tsig;
use crate::tsig::tsig_algorithm::TsigAlgorithm;
use crate::message::rdata::opt_rdata::option_code::OptionCode;
use rand::thread_rng;
use rand::Rng;
use resource_record::ToBytes;
use core::fmt;
use std::vec::Vec;
use std::time::SystemTime;

#[derive(Clone)]
/// Structs that represents a DNS message.
Expand Down Expand Up @@ -286,6 +289,51 @@ impl DnsMessage {
self.update_header_counters();
}

/// Adds Tsig to the message.
///
/// # Example
/// ```
/// let dns_query_message = new_query_message(DomainName::new_from_str("example.com".to_string()), Rrtype::A, Rclass:IN, 0, false);
/// let key = vec![1, 2, 3, 4, 5, 6, 7, 8];
/// let alg_name = TsigAlgorithm::HmacSha1;
/// let fudge = 300;
/// let key_name = "key".to_string();
/// let mac_request = vec![];
/// dns_query_message.add_tsig(key, alg_name, fudge, key_name, mac_request);
/// ```
pub fn add_tsig(&mut self, key: Vec<u8>, alg_name: TsigAlgorithm,
fudge: u16, key_name: String, mac_request: Vec<u8>) {
let message = self;
let time_signed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
tsig::sign_tsig(message, &key, alg_name,
fudge, time_signed, key_name, mac_request);
}

/// Gets the MAC from the TSIG RR.
///
/// # Example
/// ```
/// let dns_query_message = new_query_message(DomainName::new_from_str("example.com".to_string()), Rrtype::A, Rclass:IN, 0, false);
/// let key = vec![1, 2, 3, 4, 5, 6, 7, 8];
/// let alg_name = TsigAlgorithm::HmacSha1;
/// let fudge = 300;
/// let key_name = "key".to_string();
/// let mac_request = vec![];
/// dns_query_message.add_tsig(key, alg_name, fudge, key_name, mac_request);
/// let mac = dns_query_message.get_mac();
/// ```
pub fn get_mac(&self) -> Vec<u8> {
let mut mac = Vec::new();
let additional = self.get_additional();

for rr in additional {
if let Rdata::TSIG(tsig_rdata) = rr.get_rdata() {
mac = tsig_rdata.get_mac();
}
}

mac
}

/// Creates a new axfr query message.
///
Expand Down
34 changes: 17 additions & 17 deletions src/message/resource_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,135 +86,135 @@ impl ResourceRecord {
rtype: Rrtype::A,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::A(val),
},
Rdata::NS(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::NS,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::NS(val),
},
Rdata::CNAME(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::CNAME,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::CNAME(val),
},
Rdata::SOA(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::SOA,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::SOA(val),
},
Rdata::PTR(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::PTR,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::PTR(val),
},
Rdata::HINFO(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::HINFO,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::HINFO(val),
},
Rdata::MX(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::MX,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::MX(val),
},
Rdata::TXT(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::TXT,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::TXT(val),
},
Rdata::AAAA(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::AAAA,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::AAAA(val),
},
Rdata::OPT(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::OPT,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::OPT(val),
},
Rdata::DS(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::DS,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::DS(val),
},
Rdata::RRSIG(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::RRSIG,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::RRSIG(val),
},
Rdata::NSEC(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::NSEC,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::NSEC(val),
},
Rdata::DNSKEY(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::DNSKEY,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::DNSKEY(val),
},
Rdata::NSEC3(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::NSEC3,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::NSEC3(val),
},
Rdata::NSEC3PARAM(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::NSEC3PARAM,
rclass: Rclass::IN,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::NSEC3PARAM(val),
},
Rdata::TSIG(val) => ResourceRecord {
name: DomainName::new(),
rtype: Rrtype::TSIG,
rclass: Rclass::ANY,
ttl: 0 as u32,
rdlength: 0 as u16,
rdlength: val.to_bytes().len() as u16,
rdata: Rdata::TSIG(val),
},
_ => ResourceRecord {
Expand Down
7 changes: 3 additions & 4 deletions src/tsig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fn digest(bytes: Vec<u8>, tsig_algorithm: TsigAlgorithm, key: Vec<u8>) -> Vec<u8
//RFC 8945, section 5.1
#[doc = r"This function creates the signature of a DnsMessage with a key in bytes and the algName that will be used to encrypt the key."]
pub fn sign_tsig(query_msg: &mut DnsMessage, key: &[u8], alg_name: TsigAlgorithm,
fudge: u16, time_signed: u64, key_name: String, mac_request: Vec<u8>) -> Vec<u8> {
fudge: u16, time_signed: u64, key_name: String, mac_request: Vec<u8>) {
let tsig_rd: TSigRdata;
let new_query_message = query_msg.clone();
let original_id = query_msg.get_query_id();
Expand Down Expand Up @@ -184,14 +184,12 @@ pub fn sign_tsig(query_msg: &mut DnsMessage, key: &[u8], alg_name: TsigAlgorithm
}
}
let rr_len = tsig_rd.to_bytes().len() as u16;
let signature = tsig_rd.get_mac();
let mut new_rr: ResourceRecord = ResourceRecord::new(Rdata::TSIG(tsig_rd));
new_rr.set_name(DomainName::new_from_string(key_name));
new_rr.set_rdlength(rr_len);
let mut vec: Vec<ResourceRecord> = vec![];
vec.push(new_rr);
query_msg.add_additionals(vec);
return signature;
}

//Revisa si el nombre de la llave es correcto
Expand Down Expand Up @@ -596,7 +594,8 @@ mod tsig_test {
let tsig_rr = set_tsig_vars(String::from(alg_name.clone()).as_str(), &name, time_signed, fudge);
let q_for_mac = q.clone();
//creation of the signature to compare
let firma_a_comparar = sign_tsig(&mut q, key, alg_name, fudge, time_signed, name, vec![]);
sign_tsig(&mut q, key, alg_name, fudge, time_signed, name, vec![]);
let firma_a_comparar = q.get_mac();
// creation of the signature digest
let dig_for_mac = get_digest_request(vec![],q_for_mac.to_bytes(), tsig_rr);
let mut hasher = crypto_hmac::new(Sha1::new(), key);
Expand Down
3 changes: 2 additions & 1 deletion tests/tsig_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ async fn tsig_signature() {
// se instancia un socket cliente que enviará y mensajes
let client_sock = UdpSocket::bind("127.0.0.1:8001").expect("Nothing");
// El cliente firma el mensaje para enviar al servidor. Se guarda el mac de la firma
let mac = sign_tsig(&mut dns_query_message, key, alg_name, fudge, time_signed, name.to_string(), vec![]);
sign_tsig(&mut dns_query_message, key, alg_name, fudge, time_signed, name.to_string(), vec![]);
let mac = dns_query_message.get_mac();
let buf = dns_query_message.to_bytes();
client_sock.send_to(&buf,"127.0.0.1:8002").unwrap();
println!("Mensaje enviado");
Expand Down

0 comments on commit 1096f87

Please sign in to comment.