10
0
Fork 0
mirror of https://github.com/ZeusWPI/ZNS.git synced 2024-11-24 22:11:10 +01:00

Sig(0) verification finally works

This commit is contained in:
Xander Bil 2024-05-08 17:18:30 +02:00
parent 77698525d4
commit f5a1e21e86
No known key found for this signature in database
GPG key ID: EC9706B54A278598
3 changed files with 46 additions and 59 deletions

View file

@ -1,39 +1,15 @@
use std::{ use std::fs::read_to_string;
fs::{read_to_string, File},
io::{Read, Write},
};
use base64::prelude::*; use base64::prelude::*;
use ring::signature::Ed25519KeyPair;
pub fn verify(user: String, signature: &[u8], message: &[u8]) -> bool { pub fn verify(signature: &[u8], message: &[u8]) -> bool {
let str = read_to_string("/home/xander/Desktop/dnsclient/dns.pub").unwrap();
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 key_split: Vec<&str> = str.split_ascii_whitespace().collect();
let blob = BASE64_STANDARD.decode(key_split[1]).unwrap(); 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]; let key = ring::signature::UnparsedPublicKey::new(&ring::signature::ED25519, &blob.as_slice()[19..]);
prev.extend_from_slice(&blob.as_slice()[19..]);
let s = prev.as_slice();
println!("{:#?}", &blob.as_slice()[19..]);
return key.verify(&message, signature.as_ref()).is_ok();
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::<u8>::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::<u8>::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;
} }

View file

@ -173,7 +173,6 @@ impl FromBytes for LabelString {
} }
if bytes[*i] & 0b11000000 != 0 { if bytes[*i] & 0b11000000 != 0 {
println!("YOOW");
let offset = u16::from_be_bytes(bytes[*i..*i + 2].try_into().unwrap()) & 0b0011111111111111; let offset = u16::from_be_bytes(bytes[*i..*i + 2].try_into().unwrap()) & 0b0011111111111111;
if *i <= offset as usize { if *i <= offset as usize {
return Err(ParseError { return Err(ParseError {
@ -301,8 +300,6 @@ impl FromBytes for Message {
for _ in 0..header.qdcount { for _ in 0..header.qdcount {
question.push(Question::from_bytes(&bytes, i)?); question.push(Question::from_bytes(&bytes, i)?);
} }
println!("{:#?}", question);
println!("{:#?}", header);
let mut answer = vec![]; let mut answer = vec![];
for _ in 0..header.ancount { for _ in 0..header.ancount {
@ -313,7 +310,6 @@ impl FromBytes for Message {
for _ in 0..header.nscount { for _ in 0..header.nscount {
authority.push(RR::from_bytes(&bytes, i)?); authority.push(RR::from_bytes(&bytes, i)?);
} }
println!("{:#?}", authority);
let mut additional = vec![]; let mut additional = vec![];
for _ in 0..header.arcount { for _ in 0..header.arcount {

View file

@ -44,11 +44,13 @@ async fn handle_query(message: Message) -> Message {
response response
} }
async fn handle_update(message: Message) -> Message { async fn handle_update(message: Message, bytes: &[u8]) -> Message {
let mut response = message.clone(); let mut response = message.clone();
// Zone section (question) processing // 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); response.header.flags = set_response_flags(response.header.flags, RCODE::FORMERR);
return response; return response;
} }
@ -62,23 +64,27 @@ async fn handle_update(message: Message) -> Message {
} }
// Check Prerequisite TODO: implement this // 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 //TODO: this code is ugly
for rr in &message.additional { let last = message.additional.last();
if rr._type == Type::Type(RRType::KEY) { if last.is_some() && last.unwrap()._type == Type::Type(RRType::KEY) {
let mut data = message.clone(); let rr = last.unwrap();
data.header.arcount -= 1; let mut request = bytes[0..bytes.len() - 11 - rr.rdlength as usize].to_vec();
data.additional = vec![data.additional[0].clone()]; request[11] -= 1; // Decrease arcount
let mut i = 0;
let key = KeyRData::from_bytes(&rr.rdata, &mut i).unwrap(); let mut i = 0;
let mut bytes = rr.rdata[0..i].to_vec(); let key = KeyRData::from_bytes(&rr.rdata, &mut i).unwrap();
bytes.extend(Message::to_bytes(data).to_vec());
let _ = verify(String::from("xander"), &key.signature, &bytes.as_slice()); 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 // 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)) if (rr.class == Class::Class(RRClass::ANY) && (rr.ttl != 0 || rr.rdlength != 0))
|| (rr.class == Class::Class(RRClass::NONE) && rr.ttl != 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); response.header.flags = set_response_flags(response.header.flags, RCODE::FORMERR);
return response; return response;
} }
} }
//FIX: with nsupdate delete, I get `dns_request_getresponse: unexpected end of input`
for rr in message.authority { for rr in message.authority {
if rr.class == zone.qclass { if rr.class == zone.qclass {
let _ = insert_into_database(rr).await; 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; delete_from_database(rr.name, None, Class::Class(RRClass::IN), None).await;
} }
} else { } 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) { } else if rr.class == Class::Class(RRClass::NONE) {
if rr._type == Type::Type(RRType::SOA) { if rr._type == Type::Type(RRType::SOA) {
continue; 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(message) => match get_opcode(&message.header.flags) {
Ok(opcode) => match opcode { Ok(opcode) => match opcode {
Opcode::QUERY => handle_query(message).await, Opcode::QUERY => handle_query(message).await,
Opcode::UPDATE => handle_update(message).await, Opcode::UPDATE => handle_update(message, bytes).await,
}, },
Err(_) => todo!(), Err(_) => todo!(),
}, },
@ -176,8 +193,6 @@ pub async fn resolver_listener_loop(addr: SocketAddr) -> Result<(), Box<dyn Erro
let socket = socket_shared.clone(); let socket = socket_shared.clone();
tokio::spawn(async move { tokio::spawn(async move {
let response = get_response(&data[..len]).await; let response = get_response(&data[..len]).await;
println!("{:?}",Message::to_bytes(Message::from_bytes(&data[..len], &mut 0).unwrap()));
println!("{:?}",&data[..len]);
let _ = socket let _ = socket
.send_to(Message::to_bytes(response).as_slice(), addr) .send_to(Message::to_bytes(response).as_slice(), addr)
.await; .await;