use std::time::Duration;
use base64::{engine::GeneralPurpose, prelude::BASE64_URL_SAFE_NO_PAD};
use bincode::config::BigEndian;
use ring::{
aead::{self, CHACHA20_POLY1305},
agreement::{EphemeralPrivateKey, PublicKey},
hkdf::{self, HKDF_SHA256},
};
use secrecy::SecretBox;
use crate::protocol::{Challenge, ExchangePublicKey};
pub type Err = anyhow::Error;
pub type Res<T> = anyhow::Result<T, Err>;
pub type Void = Res<()>;
pub struct Constant;
impl Constant {
pub const AEAD: &'static aead::Algorithm = &CHACHA20_POLY1305;
pub const AGREEMENT: &'static ring::agreement::Algorithm = &ring::agreement::X25519;
pub const BASE64_ENGINE: GeneralPurpose = BASE64_URL_SAFE_NO_PAD;
pub const BINCODE_CONFIG: bincode::config::Configuration<BigEndian> = bincode::config::standard().with_big_endian();
pub const BUFFER_SIZE: usize = 128 * 1024 - Constant::ENCRYPTION_OVERHEAD;
pub const CHALLENGE_SIZE: usize = 32;
pub const ENCRYPTION_OVERHEAD: usize = 256;
pub const EXCHANGE_PUBLIC_KEY_SIZE: usize = 32;
pub const IDENTITY_PRIVATE_KEY_LENGTH: usize = 111;
pub const IDENTITY_PUBLIC_KEY_LENGTH: usize = 43;
pub const KDF: hkdf::Algorithm = HKDF_SHA256;
pub const SHARED_SECRET_NONCE_SIZE: usize = 12;
pub const SHARED_SECRET_SIZE: usize = 32;
pub const SHARED_SECRET_TAG_SIZE: usize = 16;
pub const SIGNATURE: &'static ring::signature::EdDSAParameters = &ring::signature::ED25519;
pub const SIGNATURE_SIZE: usize = 64;
pub const TIMEOUT: Duration = Duration::from_secs(120);
}
pub type SharedSecretShape = [u8; Constant::SHARED_SECRET_SIZE];
pub type SharedSecret = SecretBox<SharedSecretShape>;
pub type SharedSecretNonce = [u8; Constant::SHARED_SECRET_NONCE_SIZE];
#[derive(Clone, Debug)]
pub struct TunnelDefinition {
pub bind_address: String,
pub remote_address: String,
}
#[derive(Clone, Debug)]
pub struct Base64KeyPair {
pub public_key: String,
pub private_key: String,
}
pub struct ExchangeKeyPair {
pub public_key: PublicKey,
pub private_key: EphemeralPrivateKey,
}
#[derive(Debug)]
pub struct ClientKeyExchangeData {
pub server_exchange_public_key: ExchangePublicKey,
pub server_challenge: Challenge,
pub local_exchange_private_key: EphemeralPrivateKey,
pub local_challenge: Challenge,
}
pub struct ServerKeyExchangeData {
pub client_exchange_public_key: ExchangePublicKey,
pub client_challenge: Challenge,
pub local_exchange_private_key: EphemeralPrivateKey,
pub local_challenge: Challenge,
pub requested_remote_address: String,
pub requested_should_encrypt: bool,
pub requested_is_udp: bool,
}
#[derive(Clone, Debug)]
pub struct ClientHandshakeData {
pub server_challenge: Challenge,
pub server_exchange_public_key: ExchangePublicKey,
}
pub struct EncryptedData {
pub nonce: SharedSecretNonce,
pub data: Vec<u8>,
}