ratrodlib/
base.rs

1//! This module contains constants and types used throughout the code.
2//!
3//! It includes constants for cryptographic algorithms, buffer sizes, and other parameters.
4
5use std::time::Duration;
6
7use base64::{engine::GeneralPurpose, prelude::BASE64_URL_SAFE_NO_PAD};
8use ring::{
9    aead::{self, CHACHA20_POLY1305},
10    agreement::{EphemeralPrivateKey, PublicKey},
11    hkdf::{self, HKDF_SHA256},
12};
13use secrecy::SecretBox;
14
15use crate::protocol::{Challenge, ExchangePublicKey};
16
17/// A helper type for errors.
18pub type Err = anyhow::Error;
19/// A helper type for results.
20pub type Res<T> = anyhow::Result<T, Err>;
21/// A helper type for void results.
22pub type Void = Res<()>;
23/// A struct for constants.
24pub struct Constant;
25
26impl Constant {
27    pub const AEAD: &'static aead::Algorithm = &CHACHA20_POLY1305;
28    pub const AGREEMENT: &'static ring::agreement::Algorithm = &ring::agreement::X25519;
29    pub const BASE64_ENGINE: GeneralPurpose = BASE64_URL_SAFE_NO_PAD;
30    pub const BUFFER_SIZE: usize = 8192;
31    pub const CHALLENGE_SIZE: usize = 32;
32    pub const DELIMITER: &[u8] = b"\xAA\xAB\xAC\xAD\xAE\xAF\xBA\xBB";
33    pub const DELIMITER_SIZE: usize = 8;
34    pub const ENCRYPTION_OVERHEAD: usize = Self::SHARED_SECRET_NONCE_SIZE + Self::SHARED_SECRET_TAG_SIZE + Self::DELIMITER_SIZE;
35    pub const IDENTITY_PRIVATE_KEY_LENGTH: usize = 111;
36    pub const IDENTITY_PUBLIC_KEY_LENGTH: usize = 43;
37    pub const KDF: hkdf::Algorithm = HKDF_SHA256;
38    pub const NULL_PEER_PUBLIC_KEY: ExchangePublicKey = [0; Self::PEER_PUBLIC_KEY_SIZE];
39    pub const PEER_PUBLIC_KEY_SIZE: usize = 32;
40    pub const SHARED_SECRET_NONCE_SIZE: usize = 12;
41    pub const SHARED_SECRET_SIZE: usize = 32;
42    pub const SHARED_SECRET_TAG_SIZE: usize = 16;
43    pub const SIGNATURE: &'static ring::signature::EdDSAParameters = &ring::signature::ED25519;
44    pub const SIGNATURE_SIZE: usize = 64;
45    pub const UDP_TIMEOUT: Duration = Duration::from_mins(2);
46}
47
48/// A helper for the Shape of the shared secret.
49pub type SharedSecretShape = [u8; Constant::SHARED_SECRET_SIZE];
50
51/// A helper type for a shared secret.
52///
53/// These are the secrets that each end of the connection will use to encrypt and decrypt data.
54/// They are derived from the ephemeral keys, and DH key exchange.
55pub type SharedSecret = SecretBox<SharedSecretShape>;
56
57/// A helper type for a shared secret nonce.
58///
59/// These are the nonces that each end of the connection will use to encrypt and decrypt data.
60/// They are generated randomly, and are used to ensure that the same data encrypted multiple times will
61/// produce different ciphertexts.
62pub type SharedSecretNonce = [u8; Constant::SHARED_SECRET_NONCE_SIZE];
63
64/// The bind address and host address for the client.
65///
66/// This is used to determine where to bind the socket, and where to connect to on the server side.
67/// Essentially, this is the tunnel.
68#[derive(Clone, Debug)]
69pub struct TunnelDefinition {
70    pub bind_address: String,
71    pub remote_address: String,
72}
73
74/// A public-private key pair.
75///
76/// This is used to sign and verify data, primarily during the handshake phase.
77#[derive(Clone, Debug)]
78pub struct Base64KeyPair {
79    pub public_key: String,
80    pub private_key: String,
81}
82
83/// A public-private key pair for ephemeral key exchange.
84///
85/// This is used to derive a shared secret, which is used to encrypt and decrypt data.
86/// This is used during the handshake phase.
87pub struct ExchangeKeyPair {
88    pub public_key: PublicKey,
89    pub private_key: EphemeralPrivateKey,
90}
91
92/// A wrapper for a local ephemeral key pair, and a peer public key.
93///
94/// This is used to derive a shared secret, which is used to encrypt and decrypt data.
95/// Essentially, it holds the instances _local_ public/private key pair, and the _remote_ peer public key.
96/// The _local_ private key, couples with the _peer_ public key and challenge is used to derive the shared secret.
97#[derive(Debug)]
98pub struct ClientKeyExchangeData {
99    pub server_exchange_public_key: ExchangePublicKey,
100    pub server_challenge: Challenge,
101    pub local_exchange_private_key: EphemeralPrivateKey,
102    pub local_challenge: Challenge,
103}
104
105/// A wrapper for the Preamble, and the EphemeralKeyPair.
106///
107/// This is mostly used as a convenience type, to hold the preamble and the ephemeral key pair together.
108pub struct ServerKeyExchangeData {
109    pub client_exchange_public_key: ExchangePublicKey,
110    pub client_challenge: Challenge,
111    pub local_exchange_private_key: EphemeralPrivateKey,
112    pub local_challenge: Challenge,
113    pub requested_remote_address: String,
114    pub requested_should_encrypt: bool,
115    pub requested_is_udp: bool,
116}
117
118/// A wrapper for the Challenge, and the PeerPublicKey.
119///
120/// This is mostly used as a convenience type, to hold the challenge and the peer public key together.
121#[derive(Clone, Debug)]
122pub struct ClientHandshakeData {
123    pub server_challenge: Challenge,
124    pub server_exchange_public_key: ExchangePublicKey,
125}
126
127/// A wrapper for encrypted data, and its nonce.
128///
129/// This is used to encrypt and decrypt data, using the shared secret.
130/// The nonce is used to ensure that the same data encrypted multiple times will produce different ciphertexts.
131/// The data and nonce, together, are required to decrypt the data.
132pub struct EncryptedData {
133    pub nonce: SharedSecretNonce,
134    pub data: Vec<u8>,
135}