mirror of
https://github.com/DNSCrypt/encrypted-dns-server.git
synced 2024-06-10 23:06:08 +02:00
Refactor a bit, remove question padding
This commit is contained in:
parent
5f0bb6daf5
commit
337eb4924d
|
@ -142,29 +142,45 @@ impl CryptKeyPair {
|
|||
kp
|
||||
}
|
||||
|
||||
pub fn decrypt(
|
||||
&self,
|
||||
client_pk: &[u8],
|
||||
nonce: &[u8],
|
||||
encrypted: &[u8],
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
pub fn compute_shared_key(&self, pk: &[u8]) -> Result<SharedKey, Error> {
|
||||
let mut shared_key = SharedKey::default();
|
||||
let res = unsafe {
|
||||
crypto_box_curve25519xchacha20poly1305_beforenm(
|
||||
shared_key.0.as_mut_ptr(),
|
||||
pk.as_ptr(),
|
||||
self.sk.0.as_ptr(),
|
||||
)
|
||||
};
|
||||
ensure!(res == 0, "Weak public key");
|
||||
Ok(shared_key)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SharedKey([u8; crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES as usize]);
|
||||
|
||||
impl SharedKey {
|
||||
pub fn decrypt(&self, nonce: &[u8], encrypted: &[u8]) -> Result<Vec<u8>, Error> {
|
||||
let encrypted_len = encrypted.len();
|
||||
let mut decrypted =
|
||||
vec![0u8; encrypted_len - crypto_box_curve25519xchacha20poly1305_MACBYTES as usize];
|
||||
let res = unsafe {
|
||||
libsodium_sys::crypto_box_curve25519xchacha20poly1305_open_easy(
|
||||
libsodium_sys::crypto_box_curve25519xchacha20poly1305_open_easy_afternm(
|
||||
decrypted.as_mut_ptr(),
|
||||
encrypted.as_ptr(),
|
||||
encrypted_len as _,
|
||||
nonce.as_ptr(),
|
||||
client_pk.as_ptr(),
|
||||
self.sk.as_bytes().as_ptr(),
|
||||
self.0.as_ptr(),
|
||||
)
|
||||
};
|
||||
match res {
|
||||
0 => Ok(decrypted),
|
||||
_ => bail!("Unable to decrypt"),
|
||||
}
|
||||
ensure!(res == 0, "Unable to decrypt");
|
||||
let idx = decrypted
|
||||
.iter()
|
||||
.rposition(|x| *x != 0x00)
|
||||
.ok_or_else(|| format_err!("Padding error"))?;
|
||||
ensure!(decrypted[idx] == 0x80, "Padding error");
|
||||
decrypted.truncate(idx);
|
||||
Ok(decrypted)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -295,6 +295,12 @@ pub fn serve_certificates<'t>(
|
|||
expected_qname: &str,
|
||||
dnscrypt_encryption_params_set: impl IntoIterator<Item = &'t DNSCryptEncryptionParams>,
|
||||
) -> Result<Option<Vec<u8>>, Error> {
|
||||
ensure!(client_packet.len() >= DNS_HEADER_SIZE, "Short packet");
|
||||
ensure!(qdcount(&client_packet) == 1, "No question");
|
||||
ensure!(
|
||||
!is_response(&client_packet),
|
||||
"Question expected, but got a response instead"
|
||||
);
|
||||
let offset = skip_name(client_packet, DNS_HEADER_SIZE)?;
|
||||
ensure!(client_packet.len() - offset >= 4, "Short packet");
|
||||
let qtype = BigEndian::read_u16(&client_packet[offset..]);
|
||||
|
|
|
@ -11,61 +11,37 @@ pub const DNSCRYPT_CLIENT_MAGIC_SIZE: usize = 8;
|
|||
pub const DNSCRYPT_CLIENT_PK_SIZE: usize = 32;
|
||||
pub const DNSCRYPT_CLIENT_NONCE_SIZE: usize = 12;
|
||||
|
||||
pub struct DNSCryptQuery<'t> {
|
||||
wrapped_packet: &'t [u8],
|
||||
}
|
||||
|
||||
impl<'t> DNSCryptQuery<'t> {
|
||||
pub fn new(
|
||||
wrapped_packet: &'t [u8],
|
||||
dnscrypt_encryption_params_set: &[DNSCryptEncryptionParams],
|
||||
) -> Result<Self, Error> {
|
||||
ensure!(
|
||||
wrapped_packet.len()
|
||||
>= DNSCRYPT_CLIENT_MAGIC_SIZE
|
||||
+ DNSCRYPT_CLIENT_PK_SIZE
|
||||
+ DNSCRYPT_CLIENT_NONCE_SIZE
|
||||
+ DNS_HEADER_SIZE,
|
||||
"Short packet"
|
||||
);
|
||||
let dnscrypt_query = DNSCryptQuery { wrapped_packet };
|
||||
let client_magic = dnscrypt_query.client_magic();
|
||||
let dnscrypt_encryption_params = dnscrypt_encryption_params_set
|
||||
.iter()
|
||||
.find(|p| p.client_magic() == client_magic)
|
||||
.ok_or_else(|| format_err!("Client magic not found"))?;
|
||||
|
||||
let encrypted_packet = dnscrypt_query.encrypted_packet();
|
||||
let encrypted_packet_len = encrypted_packet.len();
|
||||
let mut nonce = vec![0u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize];
|
||||
&mut nonce[..crypto_box_curve25519xchacha20poly1305_HALFNONCEBYTES]
|
||||
.copy_from_slice(dnscrypt_query.client_nonce());
|
||||
let resolver_kp = dnscrypt_encryption_params.resolver_kp();
|
||||
resolver_kp.decrypt(dnscrypt_query.client_pk(), &nonce, encrypted_packet)?;
|
||||
dbg!("ok");
|
||||
Ok(dnscrypt_query)
|
||||
}
|
||||
|
||||
pub fn client_magic(&self) -> &[u8] {
|
||||
&self.wrapped_packet[..DNSCRYPT_CLIENT_MAGIC_SIZE]
|
||||
}
|
||||
|
||||
pub fn client_pk(&self) -> &[u8] {
|
||||
&self.wrapped_packet
|
||||
[DNSCRYPT_CLIENT_MAGIC_SIZE..DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE]
|
||||
}
|
||||
|
||||
pub fn client_nonce(&self) -> &[u8] {
|
||||
&self.wrapped_packet[DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE
|
||||
..DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE + DNSCRYPT_CLIENT_NONCE_SIZE]
|
||||
}
|
||||
|
||||
pub fn encrypted_packet(&self) -> &[u8] {
|
||||
&self.wrapped_packet
|
||||
[DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE + DNSCRYPT_CLIENT_NONCE_SIZE..]
|
||||
}
|
||||
|
||||
pub fn into_packet(self) -> Vec<u8> {
|
||||
self.encrypted_packet().to_vec()
|
||||
}
|
||||
pub fn decrypt(
|
||||
wrapped_packet: &[u8],
|
||||
dnscrypt_encryption_params_set: &[DNSCryptEncryptionParams],
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
ensure!(
|
||||
wrapped_packet.len()
|
||||
>= DNSCRYPT_CLIENT_MAGIC_SIZE
|
||||
+ DNSCRYPT_CLIENT_PK_SIZE
|
||||
+ DNSCRYPT_CLIENT_NONCE_SIZE
|
||||
+ DNS_HEADER_SIZE,
|
||||
"Short packet"
|
||||
);
|
||||
let client_magic = &wrapped_packet[..DNSCRYPT_CLIENT_MAGIC_SIZE];
|
||||
let client_pk = &wrapped_packet
|
||||
[DNSCRYPT_CLIENT_MAGIC_SIZE..DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE];
|
||||
let client_nonce = &wrapped_packet[DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE
|
||||
..DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE + DNSCRYPT_CLIENT_NONCE_SIZE];
|
||||
let encrypted_packet = &wrapped_packet
|
||||
[DNSCRYPT_CLIENT_MAGIC_SIZE + DNSCRYPT_CLIENT_PK_SIZE + DNSCRYPT_CLIENT_NONCE_SIZE..];
|
||||
let encrypted_packet_len = encrypted_packet.len();
|
||||
|
||||
let dnscrypt_encryption_params = dnscrypt_encryption_params_set
|
||||
.iter()
|
||||
.find(|p| p.client_magic() == client_magic)
|
||||
.ok_or_else(|| format_err!("Client magic not found"))?;
|
||||
|
||||
let mut nonce = vec![0u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize];
|
||||
&mut nonce[..crypto_box_curve25519xchacha20poly1305_HALFNONCEBYTES]
|
||||
.copy_from_slice(client_nonce);
|
||||
let resolver_kp = dnscrypt_encryption_params.resolver_kp();
|
||||
let shared_secret = resolver_kp.compute_shared_key(client_pk)?;
|
||||
let packet = shared_secret.decrypt(&nonce, encrypted_packet)?;
|
||||
Ok(packet)
|
||||
}
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -98,16 +98,11 @@ async fn handle_client_query(
|
|||
client_ctx: ClientCtx,
|
||||
encrypted_packet: Vec<u8>,
|
||||
) -> Result<(), Error> {
|
||||
let packet = DNSCryptQuery::new(&encrypted_packet, &globals.dnscrypt_encryption_params_set);
|
||||
let packet = dnscrypt::decrypt(&encrypted_packet, &globals.dnscrypt_encryption_params_set);
|
||||
let mut packet = match packet {
|
||||
Ok(packet) => packet,
|
||||
Err(_) => {
|
||||
let packet = encrypted_packet;
|
||||
ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet");
|
||||
ensure!(dns::qdcount(&packet) == 1, "No question");
|
||||
ensure!(
|
||||
!dns::is_response(&packet),
|
||||
"Question expected, but got a response instead"
|
||||
);
|
||||
if let Some(synth_packet) = serve_certificates(
|
||||
&packet,
|
||||
&globals.provider_name,
|
||||
|
@ -117,8 +112,13 @@ async fn handle_client_query(
|
|||
}
|
||||
bail!("Unencrypted query");
|
||||
}
|
||||
Ok(packet) => packet.into_packet(),
|
||||
};
|
||||
ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet");
|
||||
ensure!(qdcount(&packet) == 1, "No question");
|
||||
ensure!(
|
||||
!dns::is_response(&packet),
|
||||
"Question expected, but got a response instead"
|
||||
);
|
||||
|
||||
let original_tid = dns::tid(&packet);
|
||||
let tid = random();
|
||||
|
|
Loading…
Reference in New Issue