summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--talpid-tunnel-config-client/src/lib.rs4
-rw-r--r--talpid-types/Cargo.toml1
-rw-r--r--talpid-types/src/net/wireguard.rs37
4 files changed, 18 insertions, 25 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 572e38f197..17e28e5b65 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3232,6 +3232,7 @@ dependencies = [
"rand 0.8.5",
"serde",
"x25519-dalek",
+ "zeroize",
]
[[package]]
diff --git a/talpid-tunnel-config-client/src/lib.rs b/talpid-tunnel-config-client/src/lib.rs
index e3080741f9..de7db33c26 100644
--- a/talpid-tunnel-config-client/src/lib.rs
+++ b/talpid-tunnel-config-client/src/lib.rs
@@ -84,7 +84,9 @@ pub async fn push_pq_key(
}
})?;
- let mut psk_data = [0u8; 32];
+ // Store the PSK data on the heap. So it can be passed around and then zeroized on drop without
+ // being stored in a bunch of places on the stack.
+ let mut psk_data = Box::new([0u8; 32]);
// Decapsulate Classic McEliece and mix into PSK
{
let ciphertext_array =
diff --git a/talpid-types/Cargo.toml b/talpid-types/Cargo.toml
index ff007b74ab..4db8315c99 100644
--- a/talpid-types/Cargo.toml
+++ b/talpid-types/Cargo.toml
@@ -14,6 +14,7 @@ base64 = "0.13"
x25519-dalek = { version = "2.0.0-pre.1" }
rand = "0.8.5"
err-derive = "0.3.1"
+zeroize = "1.5.7"
[target.'cfg(target_os = "android")'.dependencies]
jnix = { version = "0.5", features = ["derive"] }
diff --git a/talpid-types/src/net/wireguard.rs b/talpid-types/src/net/wireguard.rs
index 8306c773a1..b5c3268af5 100644
--- a/talpid-types/src/net/wireguard.rs
+++ b/talpid-types/src/net/wireguard.rs
@@ -9,6 +9,7 @@ use std::{
hash::{Hash, Hasher},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
};
+use zeroize::{Zeroize, ZeroizeOnDrop};
/// Tunnel parameters required to start a `WireguardMonitor`.
/// See [`crate::net::TunnelParameters`].
@@ -55,7 +56,10 @@ pub struct PeerConfig {
pub allowed_ips: Vec<IpNetwork>,
/// IP address of the WireGuard server.
pub endpoint: SocketAddr,
- /// Preshared key.
+ /// Preshared key (PSK). The PSK should never be persisted, so it does not serialize
+ /// or deserialize. A PSK is only used with quantum-resistant tunnels and are then
+ /// ephemeral and living in memory only.
+ #[serde(skip)]
pub psk: Option<PresharedKey>,
}
@@ -260,40 +264,25 @@ impl fmt::Display for PublicKey {
}
}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PresharedKey([u8; 32]);
+/// A WireGuard preshared key (PSK). Used to make the tunnel quantum-resistant.
+#[derive(Debug, Clone, PartialEq, Eq, Hash, Zeroize, ZeroizeOnDrop)]
+pub struct PresharedKey(Box<[u8; 32]>);
impl PresharedKey {
- /// Get the PSK as bytes
+ /// Get the PSK as bytes. Try to move or dereference this data as little as possible,
+ /// since copying it to more memory locations potentially leaves the secret in more memory
+ /// locations.
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
-impl From<[u8; 32]> for PresharedKey {
- fn from(key: [u8; 32]) -> PresharedKey {
+impl From<Box<[u8; 32]>> for PresharedKey {
+ fn from(key: Box<[u8; 32]>) -> PresharedKey {
PresharedKey(key)
}
}
-impl Serialize for PresharedKey {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer,
- {
- serialize_key(&self.0, serializer)
- }
-}
-
-impl<'de> Deserialize<'de> for PresharedKey {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- deserialize_key(deserializer)
- }
-}
-
fn serialize_key<S>(key: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,