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 bincode::config::BigEndian;
9use ring::{
10    aead::{self, CHACHA20_POLY1305},
11    agreement::{EphemeralPrivateKey, PublicKey},
12    hkdf::{self, HKDF_SHA256},
13};
14use secrecy::SecretBox;
15
16use crate::protocol::{Challenge, ExchangePublicKey};
17
18/// A helper type for errors.
19pub type Err = anyhow::Error;
20/// A helper type for results.
21pub type Res<T> = anyhow::Result<T, Err>;
22/// A helper type for void results.
23pub type Void = Res<()>;
24/// A struct for constants.
25pub struct Constant;
26
27impl Constant {
28    /// The AEAD algorithm used for encryption.
29    pub const AEAD: &'static aead::Algorithm = &CHACHA20_POLY1305;
30    /// The alrgorithm used for key agreement.
31    pub const AGREEMENT: &'static ring::agreement::Algorithm = &ring::agreement::X25519;
32    /// Thedefault base4 engine used for encoding and decoding keys.
33    pub const BASE64_ENGINE: GeneralPurpose = BASE64_URL_SAFE_NO_PAD;
34    /// The default bincode engine used for encoding and decoding data across data streams.
35    pub const BINCODE_CONFIG: bincode::config::Configuration<BigEndian> = bincode::config::standard().with_big_endian();
36    /// The default buffer size (defaulting to extra large for now).
37    pub const BUFFER_SIZE: usize = 128 * 1024 - Constant::ENCRYPTION_OVERHEAD;
38    /// The size of a signature challenge.
39    pub const CHALLENGE_SIZE: usize = 32;
40    /// The size of the encryption overhead.
41    pub const ENCRYPTION_OVERHEAD: usize = 256;
42    /// The size of a key exchange public key.
43    pub const EXCHANGE_PUBLIC_KEY_SIZE: usize = 32;
44    /// The base64 encoded size of a key exchange private key.
45    pub const IDENTITY_PRIVATE_KEY_LENGTH: usize = 111;
46    /// The base64 encoded size of a key exchange public key.
47    pub const IDENTITY_PUBLIC_KEY_LENGTH: usize = 43;
48    /// The algorithm used to produce the shared secret of the key exchange.
49    pub const KDF: hkdf::Algorithm = HKDF_SHA256;
50    /// The size of the shared secret nonce.
51    pub const SHARED_SECRET_NONCE_SIZE: usize = 12;
52    /// The size of the shared secret.
53    pub const SHARED_SECRET_SIZE: usize = 32;
54    /// The size of the shared secret encryption tag.
55    pub const SHARED_SECRET_TAG_SIZE: usize = 16;
56    /// The type of signature used for the handshake.
57    pub const SIGNATURE: &'static ring::signature::EdDSAParameters = &ring::signature::ED25519;
58    /// The size of the signature used for the handshake.
59    pub const SIGNATURE_SIZE: usize = 64;
60    /// The default timeout for the stale connections.
61    pub const TIMEOUT: Duration = Duration::from_secs(120);
62}
63
64/// A helper for the Shape of the shared secret.
65pub type SharedSecretShape = [u8; Constant::SHARED_SECRET_SIZE];
66
67/// A helper type for a shared secret.
68///
69/// These are the secrets that each end of the connection will use to encrypt and decrypt data.
70/// They are derived from the ephemeral keys, and DH key exchange.
71pub type SharedSecret = SecretBox<SharedSecretShape>;
72
73/// A helper type for a shared secret nonce.
74///
75/// These are the nonces that each end of the connection will use to encrypt and decrypt data.
76/// They are generated randomly, and are used to ensure that the same data encrypted multiple times will
77/// produce different ciphertexts.
78pub type SharedSecretNonce = [u8; Constant::SHARED_SECRET_NONCE_SIZE];
79
80/// The bind address and host address for the client.
81///
82/// This is used to determine where to bind the socket, and where to connect to on the server side.
83/// Essentially, this is the tunnel.
84#[derive(Clone, Debug)]
85pub struct TunnelDefinition {
86    pub bind_address: String,
87    pub remote_address: String,
88}
89
90/// A public-private key pair.
91///
92/// This is used to sign and verify data, primarily during the handshake phase.
93#[derive(Clone, Debug)]
94pub struct Base64KeyPair {
95    pub public_key: String,
96    pub private_key: String,
97}
98
99/// A public-private key pair for ephemeral key exchange.
100///
101/// This is used to derive a shared secret, which is used to encrypt and decrypt data.
102/// This is used during the handshake phase.
103pub struct ExchangeKeyPair {
104    pub public_key: PublicKey,
105    pub private_key: EphemeralPrivateKey,
106}
107
108/// A wrapper for a local ephemeral key pair, and a peer public key.
109///
110/// This is used to derive a shared secret, which is used to encrypt and decrypt data.
111/// Essentially, it holds the instances _local_ public/private key pair, and the _remote_ peer public key.
112/// The _local_ private key, couples with the _peer_ public key and challenge is used to derive the shared secret.
113#[derive(Debug)]
114pub struct ClientKeyExchangeData {
115    pub server_exchange_public_key: ExchangePublicKey,
116    pub server_challenge: Challenge,
117    pub local_exchange_private_key: EphemeralPrivateKey,
118    pub local_challenge: Challenge,
119}
120
121/// A wrapper for the Preamble, and the EphemeralKeyPair.
122///
123/// This is mostly used as a convenience type, to hold the preamble and the ephemeral key pair together.
124pub struct ServerKeyExchangeData {
125    pub client_exchange_public_key: ExchangePublicKey,
126    pub client_challenge: Challenge,
127    pub local_exchange_private_key: EphemeralPrivateKey,
128    pub local_challenge: Challenge,
129    pub requested_remote_address: String,
130    pub requested_should_encrypt: bool,
131    pub requested_is_udp: bool,
132}
133
134/// A wrapper for the Challenge, and the PeerPublicKey.
135///
136/// This is mostly used as a convenience type, to hold the challenge and the peer public key together.
137#[derive(Clone, Debug)]
138pub struct ClientHandshakeData {
139    pub server_challenge: Challenge,
140    pub server_exchange_public_key: ExchangePublicKey,
141}
142
143/// A wrapper for encrypted data, and its nonce.
144///
145/// This is used to encrypt and decrypt data, using the shared secret.
146/// The nonce is used to ensure that the same data encrypted multiple times will produce different ciphertexts.
147/// The data and nonce, together, are required to decrypt the data.
148pub struct EncryptedData {
149    pub nonce: SharedSecretNonce,
150    pub data: Vec<u8>,
151}