From f5a1e21e8649f6014a8b56e2c4b2a602c64cd10a Mon Sep 17 00:00:00 2001 From: Xander Bil Date: Wed, 8 May 2024 17:18:30 +0200 Subject: [PATCH] Sig(0) verification finally works --- src/auth.rs | 38 ++++++----------------------- src/parser.rs | 4 ---- src/resolver.rs | 63 ++++++++++++++++++++++++++++++------------------- 3 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index c3b5f7c..73036f6 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,39 +1,15 @@ -use std::{ - fs::{read_to_string, File}, - io::{Read, Write}, -}; +use std::fs::read_to_string; use base64::prelude::*; -use ring::signature::Ed25519KeyPair; -pub fn verify(user: String, signature: &[u8], message: &[u8]) -> bool { - let str = read_to_string("/home/xander/Desktop/dnsclient/dns.pub").unwrap(); +pub fn verify(signature: &[u8], message: &[u8]) -> bool { + + let str = read_to_string("dns.pub").unwrap(); //TODO: pub ssh key use zauth + let key_split: Vec<&str> = str.split_ascii_whitespace().collect(); let blob = BASE64_STANDARD.decode(key_split[1]).unwrap(); - let mut prev = vec![ 0x30, 0x2a, 0x30,0x05, 0x06,0x03,0x2b,0x65, 0x70, 0x03, 0x21, 0x00]; - prev.extend_from_slice(&blob.as_slice()[19..]); - let s = prev.as_slice(); - println!("{:#?}", &blob.as_slice()[19..]); + let key = ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, &blob.as_slice()[19..]); - - let mut file = File::create("foo.txt").unwrap(); - file.write_all(s); - - let mut pem = File::open("/home/xander/Desktop/dnsclient/cert.der").unwrap(); - let mut pem_buf = Vec::::new(); - pem.read_to_end(&mut pem_buf).unwrap(); - let key = Ed25519KeyPair::from_pkcs8_maybe_unchecked(&pem_buf).unwrap(); - let mut pem = File::open("/home/xander/Desktop/dnsclient/der").unwrap(); - let mut pem_buf = Vec::::new(); - pem.read_to_end(&mut pem_buf).unwrap(); - - // let rng = rand::SystemRandom::new(); - // let mut signature = vec![]; - // key.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature); - let k = ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, &blob.as_slice()[19..]); - println!("{:#?}",k.verify(message, signature.as_ref())); - - - return false; + return key.verify(&message, signature.as_ref()).is_ok(); } diff --git a/src/parser.rs b/src/parser.rs index 834813a..c44be64 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -173,7 +173,6 @@ impl FromBytes for LabelString { } if bytes[*i] & 0b11000000 != 0 { - println!("YOOW"); let offset = u16::from_be_bytes(bytes[*i..*i + 2].try_into().unwrap()) & 0b0011111111111111; if *i <= offset as usize { return Err(ParseError { @@ -301,8 +300,6 @@ impl FromBytes for Message { for _ in 0..header.qdcount { question.push(Question::from_bytes(&bytes, i)?); } - println!("{:#?}", question); - println!("{:#?}", header); let mut answer = vec![]; for _ in 0..header.ancount { @@ -313,7 +310,6 @@ impl FromBytes for Message { for _ in 0..header.nscount { authority.push(RR::from_bytes(&bytes, i)?); } - println!("{:#?}", authority); let mut additional = vec![]; for _ in 0..header.arcount { diff --git a/src/resolver.rs b/src/resolver.rs index 64b57ab..7970b19 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -44,11 +44,13 @@ async fn handle_query(message: Message) -> Message { response } -async fn handle_update(message: Message) -> Message { +async fn handle_update(message: Message, bytes: &[u8]) -> Message { let mut response = message.clone(); // Zone section (question) processing - if (message.header.qdcount != 1) || !matches!(message.question[0].qtype, Type::Type(RRType::SOA)) { + if (message.header.qdcount != 1) + || !matches!(message.question[0].qtype, Type::Type(RRType::SOA)) + { response.header.flags = set_response_flags(response.header.flags, RCODE::FORMERR); return response; } @@ -62,23 +64,27 @@ async fn handle_update(message: Message) -> Message { } // Check Prerequisite TODO: implement this - // if message.header.ancount > 0 { - // response.header.flags = set_response_flags(response.header.flags, RCODE::NOTIMP); - // return response; - // } - // Check Requestor Permission - for rr in &message.additional { - if rr._type == Type::Type(RRType::KEY) { - let mut data = message.clone(); - data.header.arcount -= 1; - data.additional = vec![data.additional[0].clone()]; - let mut i = 0; - let key = KeyRData::from_bytes(&rr.rdata, &mut i).unwrap(); - let mut bytes = rr.rdata[0..i].to_vec(); - bytes.extend(Message::to_bytes(data).to_vec()); - let _ = verify(String::from("xander"), &key.signature, &bytes.as_slice()); + //TODO: this code is ugly + let last = message.additional.last(); + if last.is_some() && last.unwrap()._type == Type::Type(RRType::KEY) { + let rr = last.unwrap(); + let mut request = bytes[0..bytes.len() - 11 - rr.rdlength as usize].to_vec(); + request[11] -= 1; // Decrease arcount + + let mut i = 0; + let key = KeyRData::from_bytes(&rr.rdata, &mut i).unwrap(); + + let mut data = rr.rdata[0..i].to_vec(); + data.extend(request); + + if !verify(&key.signature, &data.as_slice()) { + response.header.flags = set_response_flags(response.header.flags, RCODE::NOTAUTH); + return response; } + } else { + response.header.flags = set_response_flags(response.header.flags, RCODE::NOTAUTH); + return response; } // Update Section Prescan @@ -93,14 +99,18 @@ async fn handle_update(message: Message) -> Message { if (rr.class == Class::Class(RRClass::ANY) && (rr.ttl != 0 || rr.rdlength != 0)) || (rr.class == Class::Class(RRClass::NONE) && rr.ttl != 0) - || ![Class::Class(RRClass::NONE), Class::Class(RRClass::ANY), zone.qclass.clone()].contains(&rr.class) + || ![ + Class::Class(RRClass::NONE), + Class::Class(RRClass::ANY), + zone.qclass.clone(), + ] + .contains(&rr.class) { response.header.flags = set_response_flags(response.header.flags, RCODE::FORMERR); return response; } } - //FIX: with nsupdate delete, I get `dns_request_getresponse: unexpected end of input` for rr in message.authority { if rr.class == zone.qclass { let _ = insert_into_database(rr).await; @@ -114,13 +124,20 @@ async fn handle_update(message: Message) -> Message { delete_from_database(rr.name, None, Class::Class(RRClass::IN), None).await; } } else { - delete_from_database(rr.name, Some(rr._type), Class::Class(RRClass::IN), None).await; + delete_from_database(rr.name, Some(rr._type), Class::Class(RRClass::IN), None) + .await; } } else if rr.class == Class::Class(RRClass::NONE) { if rr._type == Type::Type(RRType::SOA) { continue; } - delete_from_database(rr.name, Some(rr._type), Class::Class(RRClass::IN), Some(rr.rdata)).await; + delete_from_database( + rr.name, + Some(rr._type), + Class::Class(RRClass::IN), + Some(rr.rdata), + ) + .await; } } @@ -160,7 +177,7 @@ async fn get_response(bytes: &[u8]) -> Message { Ok(message) => match get_opcode(&message.header.flags) { Ok(opcode) => match opcode { Opcode::QUERY => handle_query(message).await, - Opcode::UPDATE => handle_update(message).await, + Opcode::UPDATE => handle_update(message, bytes).await, }, Err(_) => todo!(), }, @@ -176,8 +193,6 @@ pub async fn resolver_listener_loop(addr: SocketAddr) -> Result<(), Box