Keep the shared secret around

pull/5/head
Frank Denis 5 years ago
parent 337eb4924d
commit 65c2bba989

@ -4,17 +4,26 @@ use crate::dnscrypt_certs::*;
use crate::errors::*; use crate::errors::*;
use libsodium_sys::*; use libsodium_sys::*;
use rand::prelude::*;
use std::ffi::CStr; use std::ffi::CStr;
use std::ptr; use std::ptr;
pub const DNSCRYPT_CLIENT_MAGIC_SIZE: usize = 8; pub const DNSCRYPT_CLIENT_MAGIC_SIZE: usize = 8;
pub const DNSCRYPT_CLIENT_PK_SIZE: usize = 32; pub const DNSCRYPT_CLIENT_PK_SIZE: usize = 32;
pub const DNSCRYPT_CLIENT_NONCE_SIZE: usize = 12; pub const DNSCRYPT_CLIENT_NONCE_SIZE: usize =
crypto_box_curve25519xchacha20poly1305_HALFNONCEBYTES as usize;
pub fn decrypt( pub fn decrypt(
wrapped_packet: &[u8], wrapped_packet: &[u8],
dnscrypt_encryption_params_set: &[DNSCryptEncryptionParams], dnscrypt_encryption_params_set: &[DNSCryptEncryptionParams],
) -> Result<Vec<u8>, Error> { ) -> Result<
(
SharedKey,
[u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize],
Vec<u8>,
),
Error,
> {
ensure!( ensure!(
wrapped_packet.len() wrapped_packet.len()
>= DNSCRYPT_CLIENT_MAGIC_SIZE >= DNSCRYPT_CLIENT_MAGIC_SIZE
@ -37,11 +46,20 @@ pub fn decrypt(
.find(|p| p.client_magic() == client_magic) .find(|p| p.client_magic() == client_magic)
.ok_or_else(|| format_err!("Client magic not found"))?; .ok_or_else(|| format_err!("Client magic not found"))?;
let mut nonce = vec![0u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize]; let mut nonce = [0u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize];
&mut nonce[..crypto_box_curve25519xchacha20poly1305_HALFNONCEBYTES] &mut nonce[..DNSCRYPT_CLIENT_NONCE_SIZE].copy_from_slice(client_nonce);
.copy_from_slice(client_nonce);
let resolver_kp = dnscrypt_encryption_params.resolver_kp(); let resolver_kp = dnscrypt_encryption_params.resolver_kp();
let shared_secret = resolver_kp.compute_shared_key(client_pk)?; let shared_key = resolver_kp.compute_shared_key(client_pk)?;
let packet = shared_secret.decrypt(&nonce, encrypted_packet)?; let packet = shared_key.decrypt(&nonce, encrypted_packet)?;
Ok(packet) rand::thread_rng().fill_bytes(&mut nonce[DNSCRYPT_CLIENT_NONCE_SIZE..]);
Ok((shared_key, nonce, packet))
}
pub fn encrypt(
packet: &[u8],
shared_key: &SharedKey,
nonce: &[u8; crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize],
) {
//
} }

@ -72,7 +72,11 @@ enum ClientCtx {
Tcp(TcpClientCtx), Tcp(TcpClientCtx),
} }
async fn respond_to_query(client_ctx: ClientCtx, packet: Vec<u8>) -> Result<(), Error> { async fn respond_to_query(
client_ctx: ClientCtx,
packet: Vec<u8>,
shared_key: Option<SharedKey>,
) -> Result<(), Error> {
ensure!(dns::is_response(&packet), "Packet is not a response"); ensure!(dns::is_response(&packet), "Packet is not a response");
match client_ctx { match client_ctx {
ClientCtx::Udp(client_ctx) => { ClientCtx::Udp(client_ctx) => {
@ -98,21 +102,21 @@ async fn handle_client_query(
client_ctx: ClientCtx, client_ctx: ClientCtx,
encrypted_packet: Vec<u8>, encrypted_packet: Vec<u8>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let packet = dnscrypt::decrypt(&encrypted_packet, &globals.dnscrypt_encryption_params_set); let (shared_key, nonce, mut packet) =
let mut packet = match packet { match dnscrypt::decrypt(&encrypted_packet, &globals.dnscrypt_encryption_params_set) {
Ok(packet) => packet, Ok(x) => x,
Err(_) => { Err(_) => {
let packet = encrypted_packet; let packet = encrypted_packet;
if let Some(synth_packet) = serve_certificates( if let Some(synth_packet) = serve_certificates(
&packet, &packet,
&globals.provider_name, &globals.provider_name,
&globals.dnscrypt_encryption_params_set, &globals.dnscrypt_encryption_params_set,
)? { )? {
return respond_to_query(client_ctx, synth_packet).await; return respond_to_query(client_ctx, synth_packet, None).await;
}
bail!("Unencrypted query");
} }
bail!("Unencrypted query"); };
}
};
ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet"); ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet");
ensure!(qdcount(&packet) == 1, "No question"); ensure!(qdcount(&packet) == 1, "No question");
ensure!( ensure!(
@ -171,7 +175,7 @@ async fn handle_client_query(
); );
} }
dns::set_tid(&mut response, original_tid); dns::set_tid(&mut response, original_tid);
respond_to_query(client_ctx, response).await respond_to_query(client_ctx, response, Some(shared_key)).await
} }
async fn tcp_acceptor(globals: Arc<Globals>, tcp_listener: TcpListener) -> Result<(), Error> { async fn tcp_acceptor(globals: Arc<Globals>, tcp_listener: TcpListener) -> Result<(), Error> {

Loading…
Cancel
Save