mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-18 21:34:37 +03:00
Compare commits
20 Commits
regression
...
dev/karo/l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99ac3c0902 | ||
|
|
010c14dadf | ||
|
|
45b6132312 | ||
|
|
77f9fd38f3 | ||
|
|
775ed86adc | ||
|
|
40377dce1f | ||
|
|
19293471e8 | ||
|
|
cc5877dd83 | ||
|
|
ebb591aa6f | ||
|
|
07146d9914 | ||
|
|
cd04dbc4eb | ||
|
|
cc22165dc4 | ||
|
|
8496571765 | ||
|
|
ee3a1f580e | ||
|
|
89584645c3 | ||
|
|
3286e49370 | ||
|
|
100d7b6e1c | ||
|
|
921b2bfc39 | ||
|
|
a18658847c | ||
|
|
bdad414c90 |
7
.github/workflows/qc.yaml
vendored
7
.github/workflows/qc.yaml
vendored
@@ -110,7 +110,12 @@ jobs:
|
||||
- run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --document-private-items
|
||||
|
||||
cargo-test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-13]
|
||||
# - ubuntu is x86-64
|
||||
# - macos-13 is also x86-64 architecture
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
|
||||
87
Cargo.lock
generated
87
Cargo.lock
generated
@@ -387,9 +387,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.7"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
|
||||
checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -397,9 +397,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.7"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
|
||||
checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -409,9 +409,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.5"
|
||||
version = "4.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
|
||||
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
@@ -984,8 +984,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1066,6 +1068,12 @@ version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
@@ -1222,6 +1230,38 @@ version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libcrux"
|
||||
version = "0.0.2-pre.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31d9dcd435758db03438089760c55a45e6bcab7e4e299ee261f75225ab29d482"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"libcrux-hacl",
|
||||
"libcrux-platform",
|
||||
"libjade-sys",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-hacl"
|
||||
version = "0.0.2-pre.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52b2581ce493c5c22700077b5552b47be69b67b8176716572b02856218db0b68"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libcrux-platform",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libcrux-platform"
|
||||
version = "0.0.2-pre.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "647e39666194b11df17c19451d1154b9be79df98b9821532560c2ecad0cf3410"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.4.7"
|
||||
@@ -1233,6 +1273,16 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libjade-sys"
|
||||
version = "0.0.2-pre.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec4d22bba476bf8f5aebe36ccfd0e56dba8707e0c3b5c76996576028f48ffb8e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libcrux-platform",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.3"
|
||||
@@ -1261,9 +1311,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@@ -1885,7 +1935,7 @@ name = "rosenpass"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.5.7",
|
||||
"clap 4.5.8",
|
||||
"criterion",
|
||||
"derive_builder 0.20.0",
|
||||
"env_logger",
|
||||
@@ -1924,6 +1974,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"blake2",
|
||||
"chacha20poly1305",
|
||||
"libcrux",
|
||||
"rosenpass-constant-time",
|
||||
"rosenpass-oqs",
|
||||
"rosenpass-secret-memory",
|
||||
@@ -2008,7 +2059,7 @@ name = "rosenpass-wireguard-broker"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.5.7",
|
||||
"clap 4.5.8",
|
||||
"derive_builder 0.20.0",
|
||||
"env_logger",
|
||||
"log",
|
||||
@@ -2325,6 +2376,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "take-until"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4e17d8598067a8c134af59cd33c1c263470e089924a11ab61cf61690919fe3b"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
@@ -2857,8 +2914,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ba4e9811befc20af3b6efb15924a7238ee5e8e8706a196576462a00b9f1af1"
|
||||
dependencies = [
|
||||
"derive_builder 0.10.2",
|
||||
"hex",
|
||||
"libc",
|
||||
"neli",
|
||||
"take-until",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -2886,9 +2945,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.34"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
@@ -2896,9 +2955,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.34"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -44,8 +44,8 @@ allocator-api2 = "0.2.14"
|
||||
memsec = { git="https://github.com/rosenpass/memsec.git" ,rev="aceb9baee8aec6844125bd6612f92e9a281373df", features = [ "alloc_ext", ] }
|
||||
rand = "0.8.5"
|
||||
typenum = "1.17.0"
|
||||
log = { version = "0.4.21" }
|
||||
clap = { version = "4.5.7", features = ["derive"] }
|
||||
log = { version = "0.4.22" }
|
||||
clap = { version = "4.5.8", features = ["derive"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
arbitrary = { version = "1.3.2", features = ["derive"] }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace", "std"] }
|
||||
@@ -59,11 +59,12 @@ chacha20poly1305 = { version = "0.10.1", default-features = false, features = [
|
||||
"std",
|
||||
"heapless",
|
||||
] }
|
||||
zerocopy = { version = "0.7.34", features = ["derive"] }
|
||||
zerocopy = { version = "0.7.35", features = ["derive"] }
|
||||
home = "0.5.9"
|
||||
derive_builder = "0.20.0"
|
||||
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] }
|
||||
postcard= {version = "1.0.8", features = ["alloc"]}
|
||||
libcrux = { version = "0.0.2-pre.2" }
|
||||
|
||||
#Dev dependencies
|
||||
serial_test = "3.1.1"
|
||||
@@ -77,6 +78,6 @@ procspawn = {version = "1.0.0", features= ["test-support"]}
|
||||
|
||||
|
||||
#Broker dependencies (might need cleanup or changes)
|
||||
wireguard-uapi = "3.0.0"
|
||||
wireguard-uapi = { version = "3.0.0", features = ["xplatform"] }
|
||||
command-fds = "0.2.3"
|
||||
rustix = { version = "0.38.27", features = ["net"] }
|
||||
|
||||
@@ -9,6 +9,9 @@ homepage = "https://rosenpass.eu/"
|
||||
repository = "https://github.com/rosenpass/rosenpass"
|
||||
readme = "readme.md"
|
||||
|
||||
[features]
|
||||
experiment_libcrux = ["dep:libcrux"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
rosenpass-to = { workspace = true }
|
||||
@@ -20,3 +23,4 @@ static_assertions = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
chacha20poly1305 = { workspace = true }
|
||||
blake2 = { workspace = true }
|
||||
libcrux = { workspace = true, optional = true }
|
||||
|
||||
@@ -9,6 +9,9 @@ const_assert!(KEY_LEN == hash_domain::KEY_LEN);
|
||||
|
||||
/// Authenticated encryption with associated data
|
||||
pub mod aead {
|
||||
#[cfg(not(feature = "libcrux"))]
|
||||
pub use crate::subtle::chacha20poly1305_ietf::{decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN};
|
||||
#[cfg(feature = "libcrux")]
|
||||
pub use crate::subtle::chacha20poly1305_ietf::{decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN};
|
||||
}
|
||||
|
||||
|
||||
60
ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs
Normal file
60
ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use rosenpass_to::ops::copy_slice;
|
||||
use rosenpass_to::To;
|
||||
|
||||
use zeroize::Zeroize;
|
||||
|
||||
pub const KEY_LEN: usize = 32; // Grrrr! Libcrux, please provide me these constants.
|
||||
pub const TAG_LEN: usize = 16;
|
||||
pub const NONCE_LEN: usize = 12;
|
||||
|
||||
#[inline]
|
||||
pub fn encrypt(
|
||||
ciphertext: &mut [u8],
|
||||
key: &[u8],
|
||||
nonce: &[u8],
|
||||
ad: &[u8],
|
||||
plaintext: &[u8],
|
||||
) -> anyhow::Result<()> {
|
||||
let (ciphertext, mac) = ciphertext.split_at_mut(ciphertext.len() - TAG_LEN);
|
||||
|
||||
use libcrux::aead as C;
|
||||
let crux_key = C::Key::Chacha20Poly1305(C::Chacha20Key(key.try_into().unwrap()));
|
||||
let crux_iv = C::Iv(nonce.try_into().unwrap());
|
||||
|
||||
copy_slice(plaintext).to(ciphertext);
|
||||
let crux_tag = libcrux::aead::encrypt(&crux_key, ciphertext, crux_iv, ad).unwrap();
|
||||
copy_slice(crux_tag.as_ref()).to(mac);
|
||||
|
||||
match crux_key {
|
||||
C::Key::Chacha20Poly1305(mut k) => k.0.zeroize(),
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decrypt(
|
||||
plaintext: &mut [u8],
|
||||
key: &[u8],
|
||||
nonce: &[u8],
|
||||
ad: &[u8],
|
||||
ciphertext: &[u8],
|
||||
) -> anyhow::Result<()> {
|
||||
let (ciphertext, mac) = ciphertext.split_at(ciphertext.len() - TAG_LEN);
|
||||
|
||||
use libcrux::aead as C;
|
||||
let crux_key = C::Key::Chacha20Poly1305(C::Chacha20Key(key.try_into().unwrap()));
|
||||
let crux_iv = C::Iv(nonce.try_into().unwrap());
|
||||
let crux_tag = C::Tag::from_slice(mac).unwrap();
|
||||
|
||||
copy_slice(ciphertext).to(plaintext);
|
||||
libcrux::aead::decrypt(&crux_key, plaintext, crux_iv, ad, &crux_tag).unwrap();
|
||||
|
||||
match crux_key {
|
||||
C::Key::Chacha20Poly1305(mut k) => k.0.zeroize(),
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
pub mod blake2b;
|
||||
#[cfg(not(feature = "libcrux"))]
|
||||
pub mod chacha20poly1305_ietf;
|
||||
#[cfg(feature = "libcrux")]
|
||||
pub mod chacha20poly1305_ietf_libcrux;
|
||||
pub mod incorrect_hmac_blake2b;
|
||||
pub mod xchacha20poly1305_ietf;
|
||||
|
||||
@@ -108,7 +108,7 @@ Rosenpass was created by Karolin Varner, Benjamin Lipp, Wanja Zaeske,
|
||||
Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Emil Engler
|
||||
.An Clara Engler
|
||||
.Sh BUGS
|
||||
The bugs are tracked at
|
||||
.Lk https://github.com/rosenpass/rosenpass/issues .
|
||||
|
||||
2
doc/rp.1
2
doc/rp.1
@@ -113,7 +113,7 @@ Rosenpass was created by Karolin Varner, Benjamin Lipp, Wanja Zaeske,
|
||||
Marei Peischl, Stephan Ajuvo, and Lisa Schmidt.
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Emil Engler
|
||||
.An Clara Engler
|
||||
.Sh BUGS
|
||||
The bugs are tracked at
|
||||
.Lk https://github.com/rosenpass/rosenpass/issues .
|
||||
|
||||
@@ -4,6 +4,9 @@ version = "0.0.1"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@ use rosenpass::protocol::CryptoServer;
|
||||
use rosenpass_cipher_traits::Kem;
|
||||
use rosenpass_ciphers::kem::StaticKem;
|
||||
use rosenpass_secret_memory::policy::*;
|
||||
use rosenpass_secret_memory::Secret;
|
||||
use rosenpass_secret_memory::{PublicBox, Secret};
|
||||
use std::sync::Once;
|
||||
|
||||
static ONCE: Once = Once::new();
|
||||
fuzz_target!(|rx_buf: &[u8]| {
|
||||
ONCE.call_once(secret_policy_use_only_malloc_secrets);
|
||||
let sk = Secret::from_slice(&[0; StaticKem::SK_LEN]);
|
||||
let pk = Secret::from_slice(&[0; StaticKem::PK_LEN]);
|
||||
let pk = PublicBox::from_slice(&[0; StaticKem::PK_LEN]);
|
||||
|
||||
let mut cs = CryptoServer::new(sk, pk);
|
||||
let mut tx_buf = [0; 10240];
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct Input {
|
||||
|
||||
fuzz_target!(|input: Input| {
|
||||
let mut ciphertext = [0u8; EphemeralKem::CT_LEN];
|
||||
let mut shared_secret = [0u8; EphemeralKem::SK_LEN];
|
||||
let mut shared_secret = [0u8; EphemeralKem::SHK_LEN];
|
||||
|
||||
EphemeralKem::encaps(&mut shared_secret, &mut ciphertext, &input.pk).unwrap();
|
||||
});
|
||||
|
||||
@@ -54,3 +54,4 @@ procspawn = {workspace = true}
|
||||
[features]
|
||||
enable_broker_api = ["rosenpass-wireguard-broker/enable_broker_api"]
|
||||
enable_memfd_alloc = []
|
||||
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use rosenpass::protocol::{CryptoServer, HandleMsgResult, MsgBuf, PeerPtr, SPk, SSk, SymKey};
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use rosenpass_cipher_traits::Kem;
|
||||
use rosenpass_ciphers::kem::StaticKem;
|
||||
@@ -40,7 +41,7 @@ fn hs(ini: &mut CryptoServer, res: &mut CryptoServer) -> Result<()> {
|
||||
|
||||
fn keygen() -> Result<(SSk, SPk)> {
|
||||
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
|
||||
StaticKem::keygen(sk.secret_mut(), pk.secret_mut())?;
|
||||
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
|
||||
Ok((sk, pk))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ use rosenpass_secret_memory::file::StoreSecret;
|
||||
use rosenpass_secret_memory::{
|
||||
secret_policy_try_use_memfd_secrets, secret_policy_use_only_malloc_secrets,
|
||||
};
|
||||
use rosenpass_util::file::{LoadValue, LoadValueB64};
|
||||
use rosenpass_util::file::{LoadValue, LoadValueB64, StoreValue};
|
||||
use rosenpass_wireguard_broker::brokers::native_unix::{
|
||||
NativeUnixBroker, NativeUnixBrokerConfigBaseBuilder, NativeUnixBrokerConfigBaseBuilderError,
|
||||
};
|
||||
use std::ops::DerefMut;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::app_server::AppServerTest;
|
||||
@@ -370,7 +371,7 @@ impl CliCommand {
|
||||
fn generate_and_save_keypair(secret_key: PathBuf, public_key: PathBuf) -> anyhow::Result<()> {
|
||||
let mut ssk = crate::protocol::SSk::random();
|
||||
let mut spk = crate::protocol::SPk::random();
|
||||
StaticKem::keygen(ssk.secret_mut(), spk.secret_mut())?;
|
||||
StaticKem::keygen(ssk.secret_mut(), spk.deref_mut())?;
|
||||
ssk.store_secret(secret_key)?;
|
||||
spk.store(public_key)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
//! [CryptoServer].
|
||||
//!
|
||||
//! ```
|
||||
//! use std::ops::DerefMut;
|
||||
//! use rosenpass_secret_memory::policy::*;
|
||||
//! use rosenpass_cipher_traits::Kem;
|
||||
//! use rosenpass_ciphers::kem::StaticKem;
|
||||
@@ -32,11 +33,11 @@
|
||||
//!
|
||||
//! // initialize secret and public key for peer a ...
|
||||
//! let (mut peer_a_sk, mut peer_a_pk) = (SSk::zero(), SPk::zero());
|
||||
//! StaticKem::keygen(peer_a_sk.secret_mut(), peer_a_pk.secret_mut())?;
|
||||
//! StaticKem::keygen(peer_a_sk.secret_mut(), peer_a_pk.deref_mut())?;
|
||||
//!
|
||||
//! // ... and for peer b
|
||||
//! let (mut peer_b_sk, mut peer_b_pk) = (SSk::zero(), SPk::zero());
|
||||
//! StaticKem::keygen(peer_b_sk.secret_mut(), peer_b_pk.secret_mut())?;
|
||||
//! StaticKem::keygen(peer_b_sk.secret_mut(), peer_b_pk.deref_mut())?;
|
||||
//!
|
||||
//! // initialize server and a pre-shared key
|
||||
//! let psk = SymKey::random();
|
||||
@@ -71,6 +72,7 @@
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::mem::size_of;
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
collections::hash_map::{
|
||||
Entry::{Occupied, Vacant},
|
||||
@@ -88,7 +90,7 @@ use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace
|
||||
use rosenpass_ciphers::kem::{EphemeralKem, StaticKem};
|
||||
use rosenpass_ciphers::{aead, xaead, KEY_LEN};
|
||||
use rosenpass_constant_time as constant_time;
|
||||
use rosenpass_secret_memory::{Public, Secret};
|
||||
use rosenpass_secret_memory::{Public, PublicBox, Secret};
|
||||
use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase};
|
||||
use zerocopy::{AsBytes, FromBytes, Ref};
|
||||
|
||||
@@ -163,7 +165,7 @@ pub fn has_happened(ev: Timing, now: Timing) -> bool {
|
||||
|
||||
// DATA STRUCTURES & BASIC TRAITS & ACCESSORS ////
|
||||
|
||||
pub type SPk = Secret<{ StaticKem::PK_LEN }>; // Just Secret<> instead of Public<> so it gets allocated on the heap
|
||||
pub type SPk = PublicBox<{ StaticKem::PK_LEN }>;
|
||||
pub type SSk = Secret<{ StaticKem::SK_LEN }>;
|
||||
pub type EPk = Public<{ EphemeralKem::PK_LEN }>;
|
||||
pub type ESk = Secret<{ EphemeralKem::SK_LEN }>;
|
||||
@@ -548,7 +550,7 @@ impl CryptoServer {
|
||||
pub fn pidm(&self) -> Result<PeerId> {
|
||||
Ok(Public::new(
|
||||
hash_domains::peerid()?
|
||||
.mix(self.spkm.secret())?
|
||||
.mix(self.spkm.deref())?
|
||||
.into_value()))
|
||||
}
|
||||
|
||||
@@ -708,7 +710,7 @@ impl Peer {
|
||||
pub fn pidt(&self) -> Result<PeerId> {
|
||||
Ok(Public::new(
|
||||
hash_domains::peerid()?
|
||||
.mix(self.spkt.secret())?
|
||||
.mix(self.spkt.deref())?
|
||||
.into_value()))
|
||||
}
|
||||
}
|
||||
@@ -1017,7 +1019,7 @@ impl CryptoServer {
|
||||
|
||||
let cookie_value = active_cookie_value.unwrap();
|
||||
let cookie_key = hash_domains::cookie_key()?
|
||||
.mix(self.spkm.secret())?
|
||||
.mix(self.spkm.deref())?
|
||||
.into_value();
|
||||
|
||||
let mut msg_out = truncating_cast_into::<CookieReply>(tx_buf)?;
|
||||
@@ -1509,7 +1511,7 @@ where
|
||||
/// Calculate the message authentication code (`mac`) and also append cookie value
|
||||
pub fn seal(&mut self, peer: PeerPtr, srv: &CryptoServer) -> Result<()> {
|
||||
let mac = hash_domains::mac()?
|
||||
.mix(peer.get(srv).spkt.secret())?
|
||||
.mix(peer.get(srv).spkt.deref())?
|
||||
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
|
||||
self.mac.copy_from_slice(mac.into_value()[..16].as_ref());
|
||||
self.seal_cookie(peer, srv)?;
|
||||
@@ -1536,7 +1538,7 @@ where
|
||||
/// Check the message authentication code
|
||||
pub fn check_seal(&self, srv: &CryptoServer) -> Result<bool> {
|
||||
let expected = hash_domains::mac()?
|
||||
.mix(srv.spkm.secret())?
|
||||
.mix(srv.spkm.deref())?
|
||||
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
|
||||
Ok(constant_time::memcmp(
|
||||
&self.mac,
|
||||
@@ -1641,7 +1643,7 @@ impl HandshakeState {
|
||||
|
||||
// calculate ad contents
|
||||
let ad = hash_domains::biscuit_ad()?
|
||||
.mix(srv.spkm.secret())?
|
||||
.mix(srv.spkm.deref())?
|
||||
.mix(self.sidi.as_slice())?
|
||||
.mix(self.sidr.as_slice())?
|
||||
.into_value();
|
||||
@@ -1676,7 +1678,7 @@ impl HandshakeState {
|
||||
|
||||
// Calculate additional data fields
|
||||
let ad = hash_domains::biscuit_ad()?
|
||||
.mix(srv.spkm.secret())?
|
||||
.mix(srv.spkm.deref())?
|
||||
.mix(sidi.as_slice())?
|
||||
.mix(sidr.as_slice())?
|
||||
.into_value();
|
||||
@@ -1763,7 +1765,7 @@ impl CryptoServer {
|
||||
let mut hs = InitiatorHandshake::zero_with_timestamp(self);
|
||||
|
||||
// IHI1
|
||||
hs.core.init(peer.get(self).spkt.secret())?;
|
||||
hs.core.init(peer.get(self).spkt.deref())?;
|
||||
|
||||
// IHI2
|
||||
hs.core.sidi.randomize();
|
||||
@@ -1780,7 +1782,7 @@ impl CryptoServer {
|
||||
hs.core
|
||||
.encaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
|
||||
ih.sctr.as_mut_slice(),
|
||||
peer.get(self).spkt.secret(),
|
||||
peer.get(self).spkt.deref(),
|
||||
)?;
|
||||
|
||||
// IHI6
|
||||
@@ -1789,7 +1791,7 @@ impl CryptoServer {
|
||||
|
||||
// IHI7
|
||||
hs.core
|
||||
.mix(self.spkm.secret())?
|
||||
.mix(self.spkm.deref())?
|
||||
.mix(peer.get(self).psk.secret())?;
|
||||
|
||||
// IHI8
|
||||
@@ -1807,7 +1809,7 @@ impl CryptoServer {
|
||||
core.sidi = SessionId::from_slice(&ih.sidi);
|
||||
|
||||
// IHR1
|
||||
core.init(self.spkm.secret())?;
|
||||
core.init(self.spkm.deref())?;
|
||||
|
||||
// IHR4
|
||||
core.mix(&ih.sidi)?.mix(&ih.epki)?;
|
||||
@@ -1815,7 +1817,7 @@ impl CryptoServer {
|
||||
// IHR5
|
||||
core.decaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
|
||||
self.sskm.secret(),
|
||||
self.spkm.secret(),
|
||||
self.spkm.deref(),
|
||||
&ih.sctr,
|
||||
)?;
|
||||
|
||||
@@ -1828,7 +1830,7 @@ impl CryptoServer {
|
||||
};
|
||||
|
||||
// IHR7
|
||||
core.mix(peer.get(self).spkt.secret())?
|
||||
core.mix(peer.get(self).spkt.deref())?
|
||||
.mix(peer.get(self).psk.secret())?;
|
||||
|
||||
// IHR8
|
||||
@@ -1848,7 +1850,7 @@ impl CryptoServer {
|
||||
// RHR5
|
||||
core.encaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
|
||||
&mut rh.scti,
|
||||
peer.get(self).spkt.secret(),
|
||||
peer.get(self).spkt.deref(),
|
||||
)?;
|
||||
|
||||
// RHR6
|
||||
@@ -1909,14 +1911,14 @@ impl CryptoServer {
|
||||
// RHI4
|
||||
core.decaps_and_mix::<EphemeralKem, { EphemeralKem::SHK_LEN }>(
|
||||
hs!().eski.secret(),
|
||||
&*hs!().epki,
|
||||
hs!().epki.deref(),
|
||||
&rh.ecti,
|
||||
)?;
|
||||
|
||||
// RHI5
|
||||
core.decaps_and_mix::<StaticKem, { StaticKem::SHK_LEN }>(
|
||||
self.sskm.secret(),
|
||||
self.spkm.secret(),
|
||||
self.spkm.deref(),
|
||||
&rh.scti,
|
||||
)?;
|
||||
|
||||
@@ -2113,7 +2115,7 @@ impl CryptoServer {
|
||||
),
|
||||
}?;
|
||||
|
||||
let spkt = peer.get(self).spkt.secret();
|
||||
let spkt = peer.get(self).spkt.deref();
|
||||
let cookie_key = hash_domains::cookie_key()?.mix(spkt)?.into_value();
|
||||
let cookie_value = peer.cv().update_mut(self).unwrap();
|
||||
|
||||
@@ -2146,7 +2148,7 @@ fn truncating_cast_into_nomut<T: FromBytes>(buf: &[u8]) -> Result<Ref<&[u8], T>,
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::{net::SocketAddrV4, thread::sleep, time::Duration};
|
||||
use std::{net::SocketAddrV4, ops::DerefMut, thread::sleep, time::Duration};
|
||||
|
||||
use super::*;
|
||||
use serial_test::serial;
|
||||
@@ -2255,7 +2257,7 @@ mod test {
|
||||
fn keygen() -> Result<(SSk, SPk)> {
|
||||
// TODO: Copied from the benchmark; deduplicate
|
||||
let (mut sk, mut pk) = (SSk::zero(), SPk::zero());
|
||||
StaticKem::keygen(sk.secret_mut(), pk.secret_mut())?;
|
||||
StaticKem::keygen(sk.secret_mut(), pk.deref_mut())?;
|
||||
Ok((sk, pk))
|
||||
}
|
||||
|
||||
|
||||
@@ -40,3 +40,4 @@ stacker = {workspace = true}
|
||||
|
||||
[features]
|
||||
enable_memfd_alloc = []
|
||||
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use std::{
|
||||
fs::{self, DirBuilder},
|
||||
ops::DerefMut,
|
||||
os::unix::fs::{DirBuilderExt, PermissionsExt},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use rosenpass_util::file::{LoadValueB64, StoreValueB64};
|
||||
use rosenpass_util::file::{LoadValueB64, StoreValue, StoreValueB64};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
use rosenpass::protocol::{SPk, SSk};
|
||||
@@ -56,8 +57,8 @@ pub fn genkey(private_keys_dir: &Path) -> Result<()> {
|
||||
if !pqsk_path.exists() && !pqpk_path.exists() {
|
||||
let mut pqsk = SSk::random();
|
||||
let mut pqpk = SPk::random();
|
||||
StaticKem::keygen(pqsk.secret_mut(), pqpk.secret_mut())?;
|
||||
pqpk.store_secret(pqpk_path)?;
|
||||
StaticKem::keygen(pqsk.secret_mut(), pqpk.deref_mut())?;
|
||||
pqpk.store(pqpk_path)?;
|
||||
pqsk.store_secret(pqsk_path)?;
|
||||
} else {
|
||||
eprintln!(
|
||||
|
||||
@@ -6,6 +6,7 @@ pub mod alloc;
|
||||
|
||||
mod public;
|
||||
pub use crate::public::Public;
|
||||
pub use crate::public::PublicBox;
|
||||
|
||||
mod secret;
|
||||
pub use crate::secret::Secret;
|
||||
|
||||
@@ -172,12 +172,153 @@ impl<const N: usize> StoreValueB64Writer for Public<N> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[repr(transparent)]
|
||||
pub struct PublicBox<const N: usize> {
|
||||
pub inner: Box<Public<N>>,
|
||||
}
|
||||
|
||||
impl<const N: usize> PublicBox<N> {
|
||||
/// Create a new [PublicBox] from a byte slice
|
||||
pub fn from_slice(value: &[u8]) -> Self {
|
||||
Self {
|
||||
inner: Box::new(Public::from_slice(value)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [PublicBox] from a byte array
|
||||
pub fn new(value: [u8; N]) -> Self {
|
||||
Self {
|
||||
inner: Box::new(Public::new(value)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a zero initialized [PublicBox]
|
||||
pub fn zero() -> Self {
|
||||
Self {
|
||||
inner: Box::new(Public::zero()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a random initialized [PublicBox]
|
||||
pub fn random() -> Self {
|
||||
Self {
|
||||
inner: Box::new(Public::random()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Randomize all bytes in an existing [PublicBox]
|
||||
pub fn randomize(&mut self) {
|
||||
self.inner.randomize()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Randomize for PublicBox<N> {
|
||||
fn try_fill<R: Rng + ?Sized>(&mut self, rng: &mut R) -> Result<(), rand::Error> {
|
||||
self.inner.try_fill(rng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> fmt::Debug for PublicBox<N> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
debug_crypto_array(&**self, fmt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Deref for PublicBox<N> {
|
||||
type Target = [u8; N];
|
||||
|
||||
fn deref(&self) -> &[u8; N] {
|
||||
self.inner.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> DerefMut for PublicBox<N> {
|
||||
fn deref_mut(&mut self) -> &mut [u8; N] {
|
||||
self.inner.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Borrow<[u8]> for PublicBox<N> {
|
||||
fn borrow(&self) -> &[u8] {
|
||||
self.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> BorrowMut<[u8]> for PublicBox<N> {
|
||||
fn borrow_mut(&mut self) -> &mut [u8] {
|
||||
self.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> LoadValue for PublicBox<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
// This is implemented separately from Public to avoid allocating too much stack memory
|
||||
fn load<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
|
||||
let mut p = Self::random();
|
||||
fopen_r(path)?.read_exact_to_end(p.deref_mut())?;
|
||||
Ok(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> StoreValue for PublicBox<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn store<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
||||
self.inner.store(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> LoadValueB64 for PublicBox<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
// This is implemented separately from Public to avoid allocating too much stack memory
|
||||
fn load_b64<const F: usize, P: AsRef<Path>>(path: P) -> Result<Self, Self::Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
// A vector is used here to ensure heap allocation without copy from stack
|
||||
let mut f = vec![0u8; F];
|
||||
let mut v = PublicBox::zero();
|
||||
let p = path.as_ref();
|
||||
|
||||
let len = fopen_r(p)?
|
||||
.read_slice_to_end(&mut f)
|
||||
.with_context(|| format!("Could not load file {p:?}"))?;
|
||||
|
||||
b64_decode(&f[0..len], v.deref_mut())
|
||||
.with_context(|| format!("Could not decode base64 file {p:?}"))?;
|
||||
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> StoreValueB64 for PublicBox<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn store_b64<const F: usize, P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
||||
self.inner.store_b64::<F, P>(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> StoreValueB64Writer for PublicBox<N> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn store_b64_writer<const F: usize, W: std::io::Write>(
|
||||
&self,
|
||||
writer: W,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.inner.store_b64_writer::<F, W>(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Public;
|
||||
use crate::{Public, PublicBox};
|
||||
use rosenpass_util::{
|
||||
b64::b64_encode,
|
||||
file::{
|
||||
@@ -185,32 +326,35 @@ mod tests {
|
||||
Visibility,
|
||||
},
|
||||
};
|
||||
use std::{fs, os::unix::fs::PermissionsExt};
|
||||
use std::{fs, ops::Deref, os::unix::fs::PermissionsExt};
|
||||
use tempfile::tempdir;
|
||||
|
||||
/// test loading a public from an example file, and then storing it again in a different file
|
||||
#[test]
|
||||
fn test_public_load_store() {
|
||||
const N: usize = 100;
|
||||
/// Number of bytes in payload for load and store tests
|
||||
const N: usize = 100;
|
||||
|
||||
/// Convenience function for running a load/store test
|
||||
fn run_load_store_test<
|
||||
T: LoadValue<Error = anyhow::Error>
|
||||
+ StoreValue<Error = anyhow::Error>
|
||||
+ Deref<Target = [u8; N]>,
|
||||
>() {
|
||||
// Generate original random bytes
|
||||
let original_bytes: [u8; N] = [rand::random(); N];
|
||||
|
||||
// Create a temporary directory
|
||||
let temp_dir = tempdir().unwrap();
|
||||
|
||||
// Store the original public to an example file in the temporary directory
|
||||
// Store the original bytes to an example file in the temporary directory
|
||||
let example_file = temp_dir.path().join("example_file");
|
||||
std::fs::write(example_file.clone(), &original_bytes).unwrap();
|
||||
|
||||
// Load the public from the example file
|
||||
// Load the value from the example file into our generic type
|
||||
let loaded_public = T::load(&example_file).unwrap();
|
||||
|
||||
let loaded_public = Public::load(&example_file).unwrap();
|
||||
// Check that the loaded value matches the original bytes
|
||||
assert_eq!(loaded_public.deref(), &original_bytes);
|
||||
|
||||
// Check that the loaded public matches the original bytes
|
||||
assert_eq!(&loaded_public.value, &original_bytes);
|
||||
|
||||
// Store the loaded public to a different file in the temporary directory
|
||||
// Store the loaded value to a different file in the temporary directory
|
||||
let new_file = temp_dir.path().join("new_file");
|
||||
loaded_public.store(&new_file).unwrap();
|
||||
|
||||
@@ -224,10 +368,13 @@ mod tests {
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
}
|
||||
|
||||
/// test loading a base64 encoded public from an example file, and then storing it again in a different file
|
||||
#[test]
|
||||
fn test_public_load_store_base64() {
|
||||
const N: usize = 100;
|
||||
/// Convenience function for running a base64 load/store test
|
||||
fn run_base64_load_store_test<
|
||||
T: LoadValueB64<Error = anyhow::Error>
|
||||
+ StoreValueB64<Error = anyhow::Error>
|
||||
+ StoreValueB64Writer<Error = anyhow::Error>
|
||||
+ Deref<Target = [u8; N]>,
|
||||
>() {
|
||||
// Generate original random bytes
|
||||
let original_bytes: [u8; N] = [rand::random(); N];
|
||||
// Create a temporary directory
|
||||
@@ -238,9 +385,9 @@ mod tests {
|
||||
std::fs::write(&example_file, encoded_public).unwrap();
|
||||
|
||||
// Load the public from the example file
|
||||
let loaded_public = Public::load_b64::<{ N * 2 }, _>(&example_file).unwrap();
|
||||
let loaded_public = T::load_b64::<{ N * 2 }, _>(&example_file).unwrap();
|
||||
// Check that the loaded public matches the original bytes
|
||||
assert_eq!(&loaded_public.value, &original_bytes);
|
||||
assert_eq!(loaded_public.deref(), &original_bytes);
|
||||
|
||||
// Store the loaded public to a different file in the temporary directory
|
||||
let new_file = temp_dir.path().join("new_file");
|
||||
@@ -253,7 +400,7 @@ mod tests {
|
||||
// Check that the contents of the new file match the original file
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
|
||||
//Check new file permissions are public
|
||||
// Check new file permissions are public
|
||||
let metadata = fs::metadata(&new_file).unwrap();
|
||||
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
|
||||
|
||||
@@ -271,9 +418,35 @@ mod tests {
|
||||
// Check that the contents of the new file match the original file
|
||||
assert_eq!(new_file_contents, original_file_contents);
|
||||
|
||||
//Check new file permissions are public
|
||||
// Check new file permissions are public
|
||||
let metadata = fs::metadata(&new_file).unwrap();
|
||||
assert_eq!(metadata.permissions().mode() & 0o000777, 0o644);
|
||||
}
|
||||
|
||||
/// Test loading a [Public] from an example file, and then storing it again in a new file
|
||||
#[test]
|
||||
fn test_public_load_store() {
|
||||
run_load_store_test::<Public<N>>();
|
||||
}
|
||||
|
||||
/// Test loading a [PublicBox] from an example file, and then storing it again in a new file
|
||||
#[test]
|
||||
fn test_public_box_load_store() {
|
||||
run_load_store_test::<PublicBox<N>>();
|
||||
}
|
||||
|
||||
/// Test loading a base64-encoded [Public] from an example file, and then storing it again
|
||||
/// in a different file
|
||||
#[test]
|
||||
fn test_public_load_store_base64() {
|
||||
run_base64_load_store_test::<Public<N>>();
|
||||
}
|
||||
|
||||
/// Test loading a base64-encoded [PublicBox] from an example file, and then storing it
|
||||
/// again in a different file
|
||||
#[test]
|
||||
fn test_public_box_load_store_base64() {
|
||||
run_base64_load_store_test::<PublicBox<N>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ path = "src/bin/priviledged.rs"
|
||||
test = false
|
||||
doc = false
|
||||
required-features=["enable_broker_api"]
|
||||
cfg = { target_os = "linux" }
|
||||
|
||||
[[bin]]
|
||||
name = "rosenpass-wireguard-broker-socket-handler"
|
||||
@@ -51,3 +52,4 @@ test = false
|
||||
path = "src/bin/socket_handler.rs"
|
||||
doc = false
|
||||
required-features=["enable_broker_api"]
|
||||
cfg = { target_os = "linux" }
|
||||
|
||||
@@ -1,56 +1,67 @@
|
||||
use std::io::{stdin, stdout, Read, Write};
|
||||
use std::result::Result;
|
||||
fn main() {
|
||||
#[cfg(target_os = "linux")]
|
||||
linux::main().unwrap();
|
||||
|
||||
use rosenpass_wireguard_broker::api::msgs;
|
||||
use rosenpass_wireguard_broker::api::server::BrokerServer;
|
||||
use rosenpass_wireguard_broker::brokers::netlink as wg;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum BrokerAppError {
|
||||
#[error(transparent)]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error(transparent)]
|
||||
WgConnectError(#[from] wg::ConnectError),
|
||||
#[error(transparent)]
|
||||
WgSetPskError(#[from] wg::SetPskError),
|
||||
#[error("Oversized message {}; something about the request is fatally wrong", .0)]
|
||||
OversizedMessage(u64),
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
panic!("This binary is only supported on Linux");
|
||||
}
|
||||
|
||||
fn main() -> Result<(), BrokerAppError> {
|
||||
let mut broker = BrokerServer::new(wg::NetlinkWireGuardBroker::new()?);
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod linux {
|
||||
use std::io::{stdin, stdout, Read, Write};
|
||||
use std::result::Result;
|
||||
|
||||
let mut stdin = stdin().lock();
|
||||
let mut stdout = stdout().lock();
|
||||
loop {
|
||||
// Read the message length
|
||||
let mut len = [0u8; 8];
|
||||
stdin.read_exact(&mut len)?;
|
||||
use rosenpass_wireguard_broker::api::msgs;
|
||||
use rosenpass_wireguard_broker::api::server::BrokerServer;
|
||||
use rosenpass_wireguard_broker::brokers::netlink as wg;
|
||||
|
||||
// Parse the message length
|
||||
let len = u64::from_le_bytes(len);
|
||||
if (len as usize) > msgs::REQUEST_MSG_BUFFER_SIZE {
|
||||
return Err(BrokerAppError::OversizedMessage(len));
|
||||
}
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum BrokerAppError {
|
||||
#[error(transparent)]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error(transparent)]
|
||||
WgConnectError(#[from] wg::ConnectError),
|
||||
#[error(transparent)]
|
||||
WgSetPskError(#[from] wg::SetPskError),
|
||||
#[error("Oversized message {}; something about the request is fatally wrong", .0)]
|
||||
OversizedMessage(u64),
|
||||
}
|
||||
|
||||
// Read the message itself
|
||||
let mut req_buf = [0u8; msgs::REQUEST_MSG_BUFFER_SIZE];
|
||||
let req_buf = &mut req_buf[..(len as usize)];
|
||||
stdin.read_exact(req_buf)?;
|
||||
pub fn main() -> Result<(), BrokerAppError> {
|
||||
let mut broker = BrokerServer::new(wg::NetlinkWireGuardBroker::new()?);
|
||||
|
||||
// Process the message
|
||||
let mut res_buf = [0u8; msgs::RESPONSE_MSG_BUFFER_SIZE];
|
||||
let res = match broker.handle_message(req_buf, &mut res_buf) {
|
||||
Ok(len) => &res_buf[..len],
|
||||
Err(e) => {
|
||||
eprintln!("Error processing message for wireguard PSK broker: {e:?}");
|
||||
continue;
|
||||
let mut stdin = stdin().lock();
|
||||
let mut stdout = stdout().lock();
|
||||
loop {
|
||||
// Read the message length
|
||||
let mut len = [0u8; 8];
|
||||
stdin.read_exact(&mut len)?;
|
||||
|
||||
// Parse the message length
|
||||
let len = u64::from_le_bytes(len);
|
||||
if (len as usize) > msgs::REQUEST_MSG_BUFFER_SIZE {
|
||||
return Err(BrokerAppError::OversizedMessage(len));
|
||||
}
|
||||
};
|
||||
|
||||
// Write the response
|
||||
stdout.write_all(&(res.len() as u64).to_le_bytes())?;
|
||||
stdout.write_all(&res)?;
|
||||
stdout.flush()?;
|
||||
// Read the message itself
|
||||
let mut req_buf = [0u8; msgs::REQUEST_MSG_BUFFER_SIZE];
|
||||
let req_buf = &mut req_buf[..(len as usize)];
|
||||
stdin.read_exact(req_buf)?;
|
||||
|
||||
// Process the message
|
||||
let mut res_buf = [0u8; msgs::RESPONSE_MSG_BUFFER_SIZE];
|
||||
let res = match broker.handle_message(req_buf, &mut res_buf) {
|
||||
Ok(len) => &res_buf[..len],
|
||||
Err(e) => {
|
||||
eprintln!("Error processing message for wireguard PSK broker: {e:?}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Write the response
|
||||
stdout.write_all(&(res.len() as u64).to_le_bytes())?;
|
||||
stdout.write_all(&res)?;
|
||||
stdout.flush()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#[cfg(feature = "enable_broker_api")]
|
||||
pub mod mio_client;
|
||||
#[cfg(feature = "enable_broker_api")]
|
||||
#[cfg(all(feature = "enable_broker_api", target_os = "linux"))]
|
||||
pub mod netlink;
|
||||
|
||||
pub mod native_unix;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![cfg(target_os = "linux")]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use wireguard_uapi::linux as wg;
|
||||
|
||||
Reference in New Issue
Block a user