run formatters

This commit is contained in:
Ilka Schulz
2026-06-05 07:35:21 +02:00
parent 9949957afe
commit f16b2e1b03
60 changed files with 408 additions and 362 deletions
+6 -6
View File
@@ -1,4 +1,4 @@
use rosenpass_to::{ops::copy_slice, To as _};
use rosenpass_to::{To as _, ops::copy_slice};
use thiserror::Error;
/// Models authenticated encryption with assiciated data (AEAD) functionality.
@@ -148,11 +148,11 @@ pub trait AeadWithNonceInCiphertext<
}
impl<
const KEY_LEN: usize,
const NONCE_LEN: usize,
const TAG_LEN: usize,
T: Aead<KEY_LEN, NONCE_LEN, TAG_LEN>,
> AeadWithNonceInCiphertext<KEY_LEN, NONCE_LEN, TAG_LEN> for T
const KEY_LEN: usize,
const NONCE_LEN: usize,
const TAG_LEN: usize,
T: Aead<KEY_LEN, NONCE_LEN, TAG_LEN>,
> AeadWithNonceInCiphertext<KEY_LEN, NONCE_LEN, TAG_LEN> for T
{
}
+1 -1
View File
@@ -121,7 +121,7 @@ where
{
}
use rosenpass_to::{with_destination, To};
use rosenpass_to::{To, with_destination};
/// Extends the [`KeyedHash`] trait with a [`To`]-flavoured function.
pub trait KeyedHashTo<const KEY_LEN: usize, const HASH_LEN: usize>:
+3 -3
View File
@@ -79,7 +79,7 @@ mod kem {
impl_name: &str,
scheme: T,
) {
use super::{benchid, KvPair, KvPairs};
use super::{KvPair, KvPairs, benchid};
let base = [
KvPair("primitive", "kem"),
@@ -176,7 +176,7 @@ mod aead {
impl_name: &str,
scheme: T,
) {
use crate::{benchid, KvPair, KvPairs};
use crate::{KvPair, KvPairs, benchid};
let base = [
KvPair("primitive", "aead"),
@@ -326,7 +326,7 @@ mod keyed_hash {
) where
H::Error: std::fmt::Debug,
{
use crate::{benchid, KvPair, KvPairs};
use crate::{KvPair, KvPairs, benchid};
let key = [12u8; KEY_LEN];
let mut out = [0u8; HASH_LEN];
+1 -1
View File
@@ -31,7 +31,7 @@ use anyhow::Result;
use rosenpass_secret_memory::Secret;
use rosenpass_to::To as _;
pub use crate::{KeyedHash, KEY_LEN};
pub use crate::{KEY_LEN, KeyedHash};
use rosenpass_cipher_traits::primitives::KeyedHashInstanceTo;
@@ -3,7 +3,7 @@ use rosenpass_cipher_traits::{
primitives::{InferKeyedHash, KeyedHash, KeyedHashTo},
};
use rosenpass_constant_time::xor;
use rosenpass_to::{ops::copy_slice, To};
use rosenpass_to::{To, ops::copy_slice};
use zeroize::Zeroizing;
#[cfg(not(feature = "experiment_libcrux_blake2"))]
@@ -161,8 +161,8 @@ mod equivalence_tests {
// The functions below are from the old libcrux backend. I am keeping them around so we can
// check if they behave the same.
use rosenpass_to::ops::copy_slice;
use rosenpass_to::To;
use rosenpass_to::ops::copy_slice;
use zeroize::Zeroize;
/// Encrypts using ChaCha20Poly1305 as implemented in [libcrux](https://github.com/cryspen/libcrux).
+2 -2
View File
@@ -1,12 +1,12 @@
use zeroize::Zeroizing;
use blake2::Blake2bMac;
use blake2::digest::crypto_common::generic_array::GenericArray;
use blake2::digest::crypto_common::typenum::U32;
use blake2::digest::{FixedOutput, Mac};
use blake2::Blake2bMac;
use rosenpass_cipher_traits::primitives::KeyedHash;
use rosenpass_to::{ops::copy_slice, To};
use rosenpass_to::{To, ops::copy_slice};
pub use rosenpass_cipher_traits::algorithms::keyed_hash_blake2b::{HASH_LEN, KEY_LEN};
@@ -1,11 +1,11 @@
use rosenpass_to::ops::copy_slice;
use rosenpass_to::To;
use rosenpass_to::ops::copy_slice;
use rosenpass_cipher_traits::algorithms::AeadChaCha20Poly1305;
use rosenpass_cipher_traits::primitives::{Aead, AeadError};
use chacha20poly1305::aead::generic_array::GenericArray;
use chacha20poly1305::ChaCha20Poly1305 as AeadImpl;
use chacha20poly1305::aead::generic_array::GenericArray;
use chacha20poly1305::{AeadInPlace, KeyInit};
pub use rosenpass_cipher_traits::algorithms::aead_chacha20poly1305::{KEY_LEN, NONCE_LEN, TAG_LEN};
@@ -1,7 +1,7 @@
use anyhow::ensure;
use rosenpass_cipher_traits::primitives::{InferKeyedHash, KeyedHash};
use sha3::digest::{ExtendableOutput, Update, XofReader};
use sha3::Shake256;
use sha3::digest::{ExtendableOutput, Update, XofReader};
pub use rosenpass_cipher_traits::algorithms::keyed_hash_shake256::{HASH_LEN, KEY_LEN};
@@ -1,11 +1,11 @@
use rosenpass_to::ops::copy_slice;
use rosenpass_to::To;
use rosenpass_to::ops::copy_slice;
use rosenpass_cipher_traits::algorithms::aead_xchacha20poly1305::AeadXChaCha20Poly1305;
use rosenpass_cipher_traits::primitives::{Aead, AeadError, AeadWithNonceInCiphertext};
use chacha20poly1305::aead::generic_array::GenericArray;
use chacha20poly1305::XChaCha20Poly1305 as AeadImpl;
use chacha20poly1305::aead::generic_array::GenericArray;
use chacha20poly1305::{AeadInPlace, KeyInit};
pub use rosenpass_cipher_traits::algorithms::aead_xchacha20poly1305::{
+1 -1
View File
@@ -1,7 +1,7 @@
//! xor
use core::hint::black_box;
use rosenpass_to::{with_destination, To};
use rosenpass_to::{To, with_destination};
/// Xors the source into the destination
///
+11 -12
View File
@@ -63,20 +63,19 @@
};
in
{
packages =
{
default = pkgs.rosenpass;
rosenpass = pkgs.rosenpass;
rosenpass-oci-image = pkgs.rosenpass-oci-image;
rp = pkgs.rp;
packages = {
default = pkgs.rosenpass;
rosenpass = pkgs.rosenpass;
rosenpass-oci-image = pkgs.rosenpass-oci-image;
rp = pkgs.rp;
release-package = pkgs.release-package;
release-package = pkgs.release-package;
# for good measure, we also offer to cross compile to Linux on Arm
aarch64-linux-rosenpass-static = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rosenpass;
aarch64-linux-rp-static = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rp;
}
//
# for good measure, we also offer to cross compile to Linux on Arm
aarch64-linux-rosenpass-static = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rosenpass;
aarch64-linux-rp-static = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rp;
}
//
# We only offer static builds for linux, as this is not supported on OS X
(nixpkgs.lib.attrsets.optionalAttrs pkgs.stdenv.isLinux {
rosenpass-static = pkgs.pkgsStatic.rosenpass;
+1 -1
View File
@@ -1,7 +1,7 @@
use std::ops::DerefMut;
use anyhow::Result;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use rosenpass_cipher_traits::primitives::Kem;
use rosenpass_ciphers::StaticKem;
+3 -3
View File
@@ -4,10 +4,10 @@
use std::{borrow::BorrowMut, collections::VecDeque, os::fd::OwnedFd};
use anyhow::Context;
use rosenpass_to::{ops::copy_slice, To};
use rosenpass_to::{To, ops::copy_slice};
use rosenpass_util::{
fd::FdIo,
functional::{run, ApplyExt},
functional::{ApplyExt, run},
io::ReadExt,
mem::DiscardResultExt,
mio::UnixStreamExt,
@@ -21,7 +21,7 @@ use crate::{
protocol::BuildCryptoServer,
};
use super::{supply_keypair_response_status, Server as ApiServer};
use super::{Server as ApiServer, supply_keypair_response_status};
/// Stores the state of the API handler.
///
+4 -2
View File
@@ -246,9 +246,11 @@ pub trait MioConnectionContext {
// Message does not fit in buffer
Err((e @ E::MessageTooLargeError { .. }, _)) => {
log::warn!("Received message on API that was too big to fit in our buffers; \
log::warn!(
"Received message on API that was too big to fit in our buffers; \
looks like the client is broken. Stopping to process messages of the client.\n\
Error: {e:?}");
Error: {e:?}"
);
conn.invalid_read = true; // Closed mio_manager
break Ok(None);
}
+12 -7
View File
@@ -2,7 +2,7 @@
//! the actual cryptographic code lives in the [crate::protocol] module
use std::collections::{HashMap, VecDeque};
use std::io::{stdout, ErrorKind, Write};
use std::io::{ErrorKind, Write, stdout};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
use std::time::{Duration, Instant};
use std::{cell::Cell, fmt::Debug, io, path::PathBuf, slice};
@@ -10,21 +10,21 @@ use std::{cell::Cell, fmt::Debug, io, path::PathBuf, slice};
use mio::{Interest, Token};
use signal_hook_mio::v1_0 as signal_hook_mio;
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use derive_builder::Builder;
use log::{error, info, warn};
use zerocopy::AsBytes;
use rosenpass_util::attempt;
use rosenpass_util::fmt::debug::NullDebug;
use rosenpass_util::functional::{run, ApplyExt};
use rosenpass_util::functional::{ApplyExt, run};
use rosenpass_util::io::{IoResultKindHintExt, SubstituteForIoErrorKindExt};
use rosenpass_util::{
b64::B64Display, build::ConstructionSite, file::StoreValueB64, result::OkExt,
};
use rosenpass_secret_memory::{Public, Secret};
use rosenpass_wireguard_broker::{WireguardBrokerCfg, WireguardBrokerMio, WG_KEY_LEN};
use rosenpass_wireguard_broker::{WG_KEY_LEN, WireguardBrokerCfg, WireguardBrokerMio};
use crate::config::{ProtocolVersion, Verbosity};
@@ -886,7 +886,10 @@ impl AppServer {
Some(Ok(v)) => v,
None => true,
Some(Err(e)) => {
warn!("Unable to detect whether the IPv6 socket supports dual-stack operation: {}", e);
warn!(
"Unable to detect whether the IPv6 socket supports dual-stack operation: {}",
e
);
true
}
};
@@ -1325,7 +1328,7 @@ impl AppServer {
Some(C::DeleteKey(PeerPtr(no))) => break A::DeleteKey(AppPeerPtr(no)),
Some(C::SendInitiation(PeerPtr(no))) => break A::SendInitiation(AppPeerPtr(no)),
Some(C::SendRetransmission(PeerPtr(no))) => {
break A::SendRetransmission(AppPeerPtr(no))
break A::SendRetransmission(AppPeerPtr(no));
}
Some(C::Sleep(timeout)) => timeout, // No event from crypto-server, do IO
None => crate::protocol::timing::UNENDING, // Crypto server is uninitialized, do IO
@@ -1555,7 +1558,9 @@ impl AppServer {
let io_source = match self.io_source_index.get(&token) {
Some(io_source) => *io_source,
None => {
log::warn!("No IO source assiociated with mio token ({token:?}). Polling using mio tokens directly is an experimental feature and IO handler should recover when all available io sources are polled. This is a developer error. Please report it.");
log::warn!(
"No IO source assiociated with mio token ({token:?}). Polling using mio tokens directly is an experimental feature and IO handler should recover when all available io sources are polled. This is a developer error. Please report it."
);
return Ok(AppServerTryRecvResult::None);
}
};
+5 -3
View File
@@ -2,7 +2,7 @@ use anyhow::{Context, Result};
use heck::ToShoutySnakeCase;
use rosenpass_ciphers::subtle::keyed_hash::KeyedHash;
use rosenpass_ciphers::{hash_domain::HashDomain, KEY_LEN};
use rosenpass_ciphers::{KEY_LEN, hash_domain::HashDomain};
/// Recursively calculate a concrete hash value for an API message type
fn calculate_hash_value(hd: HashDomain, values: &[&str]) -> Result<[u8; KEY_LEN]> {
@@ -30,8 +30,10 @@ fn print_literal(path: &[&str], shake_or_blake: KeyedHash) -> Result<()> {
.chunks_exact(4)
.map(|chunk| chunk.iter().collect::<String>())
.collect::<Vec<_>>();
println!("const {var_name} : RawMsgType = RawMsgType::from_le_bytes(hex!(\"{} {} {} {} {} {} {} {}\"));",
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
println!(
"const {var_name} : RawMsgType = RawMsgType::from_le_bytes(hex!(\"{} {} {} {} {} {} {} {}\"));",
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]
);
Ok(())
}
+9 -5
View File
@@ -3,7 +3,7 @@
//! [CliArgs::run] is called by the rosenpass main function and contains the
//! bulk of our boostrapping code while the main function just sets up the basic environment
use anyhow::{bail, ensure, Context};
use anyhow::{Context, bail, ensure};
use clap::{Parser, Subcommand};
use rosenpass_cipher_traits::primitives::Kem;
use rosenpass_ciphers::StaticKem;
@@ -27,9 +27,9 @@ use {
log::{error, info},
mio::net::UnixStream,
rosenpass_util::fd::claim_fd,
rosenpass_wireguard_broker::brokers::mio_client::MioBrokerClient,
rosenpass_wireguard_broker::WireguardBrokerMio,
rustix::net::{socketpair, AddressFamily, SocketFlags, SocketType},
rosenpass_wireguard_broker::brokers::mio_client::MioBrokerClient,
rustix::net::{AddressFamily, SocketFlags, SocketType, socketpair},
std::os::fd::AsRawFd,
std::os::unix::net,
std::process::Command,
@@ -291,7 +291,9 @@ impl CliArgs {
// Deprecated - use gen-keys instead
Some(Keygen { args }) => {
log::warn!("The 'keygen' command is deprecated. Please use the 'gen-keys' command instead.");
log::warn!(
"The 'keygen' command is deprecated. Please use the 'gen-keys' command instead."
);
let mut public_key: Option<PathBuf> = None;
let mut secret_key: Option<PathBuf> = None;
@@ -346,7 +348,9 @@ impl CliArgs {
}
(_, Some(pkf), Some(skf)) => (pkf.clone(), skf.clone()),
_ => {
bail!("either a config-file or both public-key and secret-key file are required")
bail!(
"either a config-file or both public-key and secret-key file are required"
)
}
};
+7 -3
View File
@@ -15,7 +15,7 @@ use anyhow::{bail, ensure};
use serde::{Deserialize, Serialize};
use rosenpass_util::file::{fopen_w, LoadValue, Visibility};
use rosenpass_util::file::{LoadValue, Visibility, fopen_w};
use crate::protocol::basic_types::{SPk, SSk};
use crate::protocol::osk_domain_separator::OskDomainSeparator;
@@ -201,8 +201,12 @@ impl RosenpassPeerOskDomainSeparator {
match (&self.osk_organization, &self.osk_label) {
(None, None) => Ok(None),
(Some(org), Some(label)) => Ok(Some((org, label))),
(Some(_), None) => bail!("Specified osk_organization but not osk_label in config file. You need to specify both, or none."),
(None, Some(_)) => bail!("Specified osk_label but not osk_organization in config file. You need to specify both, or none."),
(Some(_), None) => bail!(
"Specified osk_organization but not osk_label in config file. You need to specify both, or none."
),
(None, Some(_)) => bail!(
"Specified osk_label but not osk_organization in config file. You need to specify both, or none."
),
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
use clap::CommandFactory;
use clap::Parser;
use clap_mangen::roff::{roman, Roff};
use clap_mangen::roff::{Roff, roman};
use log::error;
use rosenpass::cli::CliArgs;
use std::process::exit;
+2 -2
View File
@@ -13,7 +13,7 @@ use zerocopy::{AsBytes, FromBytes, FromZeroes};
use super::RosenpassError;
use rosenpass_cipher_traits::primitives::{Aead as _, Kem};
use rosenpass_ciphers::{Aead, XAead, KEY_LEN};
use rosenpass_ciphers::{Aead, KEY_LEN, XAead};
use rosenpass_ciphers::{EphemeralKem, StaticKem};
/// Length of a session ID such as [InitHello::sidi]
@@ -437,7 +437,7 @@ impl From<MsgType> for u8 {
mod test_constants {
use crate::msgs::{BISCUIT_CT_LEN, BISCUIT_PT_LEN};
use rosenpass_cipher_traits::primitives::Aead as _;
use rosenpass_ciphers::{XAead, KEY_LEN};
use rosenpass_ciphers::{KEY_LEN, XAead};
#[test]
fn sodium_keysize() {
+1 -1
View File
@@ -1,7 +1,7 @@
//! Key types and other fundamental types used in the Rosenpass protocol
use rosenpass_cipher_traits::primitives::{Aead, Kem};
use rosenpass_ciphers::{EphemeralKem, StaticKem, XAead, KEY_LEN};
use rosenpass_ciphers::{EphemeralKem, KEY_LEN, StaticKem, XAead};
use rosenpass_secret_memory::{Public, PublicBox, Secret};
use crate::msgs::{BISCUIT_ID_LEN, MAX_MESSAGE_LEN, SESSION_ID_LEN};
@@ -206,7 +206,10 @@ impl Build<CryptoServer> for BuildCryptoServer {
let PeerPtr(idx2) =
srv.add_peer(psk, pk, protocol_version.into(), osk_domain_separator)?;
assert!(idx == idx2, "Peer id changed during CryptoServer construction from {idx} to {idx2}. This is a developer error.")
assert!(
idx == idx2,
"Peer id changed during CryptoServer construction from {idx} to {idx2}. This is a developer error."
)
}
Ok(srv)
+1 -1
View File
@@ -2,8 +2,8 @@
use std::collections::HashMap;
use super::basic_types::{PeerId, PeerNo, SessionId};
use super::KnownResponseHash;
use super::basic_types::{PeerId, PeerNo, SessionId};
/// Maps various keys to peer (numbers).
///
+8 -20
View File
@@ -14,7 +14,7 @@ use std::{
ops::Deref,
};
use anyhow::{bail, ensure, Context, Result};
use anyhow::{Context, Result, bail, ensure};
use assert_tv::{TestVector, TestVectorNOP};
use memoffset::span_of;
use zerocopy::{AsBytes, FromBytes, Ref};
@@ -26,11 +26,11 @@ use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace
use rosenpass_ciphers::{Aead, EphemeralKem, KeyedHash, StaticKem, XAead};
use rosenpass_constant_time as constant_time;
use rosenpass_secret_memory::{Public, Secret};
use rosenpass_to::{ops::copy_slice, To};
use rosenpass_to::{To, ops::copy_slice};
use rosenpass_util::{
cat,
functional::ApplyExt,
mem::{cpy_min, DiscardResultExt},
mem::{DiscardResultExt, cpy_min},
time::Timebase,
};
@@ -38,7 +38,7 @@ use crate::protocol::test_vector_sets::{
CycledBiscuitSecretKeyTestValues, EncapsAndMixTestValues, HandleInitHelloTestValues,
HandleInitiationTestValues, StoreBiscuitTestValues,
};
use crate::{hash_domains, msgs::*, RosenpassError};
use crate::{RosenpassError, hash_domains, msgs::*};
use super::basic_types::{
BiscuitId, EPk, ESk, MsgBuf, PeerId, PeerNo, PublicSymKey, SPk, SSk, SessionId, SymKey,
@@ -53,7 +53,7 @@ use super::constants::{
use super::cookies::{BiscuitKey, CookieSecret, CookieStore};
use super::index::{PeerIndex, PeerIndexKey};
use super::osk_domain_separator::OskDomainSeparator;
use super::timing::{has_happened, Timing, BCE, UNENDING};
use super::timing::{BCE, Timing, UNENDING, has_happened};
use super::zerocopy::{truncating_cast_into, truncating_cast_into_nomut};
#[cfg(feature = "trace_bench")]
@@ -1657,11 +1657,7 @@ impl Mortal for BiscuitKeyPtr {
/// At [BiscuitKey::created_at]
fn created_at(&self, srv: &CryptoServer) -> Option<Timing> {
let t = self.get(srv).created_at;
if t < 0.0 {
None
} else {
Some(t)
}
if t < 0.0 { None } else { Some(t) }
}
/// At [Self::created_at] plus [BISCUIT_EPOCH]
@@ -1679,11 +1675,7 @@ impl Mortal for ServerCookieSecretPtr {
/// At [CookieSecret::created_at]
fn created_at(&self, srv: &CryptoServer) -> Option<Timing> {
let t = self.get(srv).created_at;
if t < 0.0 {
None
} else {
Some(t)
}
if t < 0.0 { None } else { Some(t) }
}
/// At [Self::created_at] plus [COOKIE_SECRET_EPOCH]
@@ -1725,11 +1717,7 @@ impl Mortal for KnownInitConfResponsePtr {
/// At [KnownInitConfResponse::received_at]
fn created_at(&self, srv: &CryptoServer) -> Option<Timing> {
let t = self.get(srv)?.received_at;
if t < 0.0 {
None
} else {
Some(t)
}
if t < 0.0 { None } else { Some(t) }
}
/// No retirement phase, so this is the same as [Self::die_at]
+5 -4
View File
@@ -9,7 +9,7 @@ use rosenpass_ciphers::StaticKem;
use rosenpass_secret_memory::Public;
use rosenpass_util::mem::DiscardResultExt;
use crate::msgs::{EmptyData, Envelope, InitConf, InitHello, MsgType, RespHello, MAX_MESSAGE_LEN};
use crate::msgs::{EmptyData, Envelope, InitConf, InitHello, MAX_MESSAGE_LEN, MsgType, RespHello};
use super::basic_types::{MsgBuf, SPk, SSk, SymKey};
use super::constants::REKEY_AFTER_TIME_RESPONDER;
@@ -502,13 +502,14 @@ fn cookie_reply_mechanism_initiator_bails_on_message_under_load(protocol_version
ip_addr_port_b[..ip_addr_port_b_len].to_vec().into();
//A handles RespHello message under load, should not send cookie reply
assert!(a
.handle_msg_under_load(
assert!(
a.handle_msg_under_load(
&b_to_a_buf[..resp_hello_len],
&mut *a_to_b_buf,
&ip_addr_port_b
)
.is_err());
.is_err()
);
});
}
+1 -1
View File
@@ -16,7 +16,7 @@ use assert_tv::TestValue;
use assert_tv::TestVectorSet;
use base64::Engine;
use rosenpass_cipher_traits::primitives::{Aead, Kem};
use rosenpass_ciphers::{EphemeralKem, XAead, KEY_LEN};
use rosenpass_ciphers::{EphemeralKem, KEY_LEN, XAead};
use rosenpass_secret_memory::{Public, PublicBox, Secret};
use serde_json::Value;
+1 -1
View File
@@ -6,9 +6,9 @@ use rosenpass_cipher_traits::primitives::Kem;
use rosenpass_ciphers::StaticKem;
use super::{
CryptoServer, PeerPtr, ProtocolVersion,
basic_types::{SPk, SSk},
osk_domain_separator::OskDomainSeparator,
CryptoServer, PeerPtr, ProtocolVersion,
};
/// Helper for tests and examples
@@ -7,7 +7,7 @@ use std::{
time::Duration,
};
use anyhow::{bail, Context};
use anyhow::{Context, bail};
use command_fds::{CommandFdExt, FdMapping};
use hex_literal::hex;
use rosenpass::api::{
@@ -33,7 +33,7 @@ struct KillChild(std::process::Child);
impl Drop for KillChild {
fn drop(&mut self) {
use rustix::process::{kill_process, Pid, Signal::Term};
use rustix::process::{Pid, Signal::Term, kill_process};
let pid = Pid::from_child(&self.0);
// We seriously need to start handling signals with signalfd, our current signal handling
// system is a bit broken; there is probably a few functions that just restart on EINTR
@@ -241,7 +241,7 @@ fn api_integration_api_setup(protocol_version: ProtocolVersion) -> anyhow::Resul
// Send SupplyKeypairRequest
{
use rustix::fs::{open, Mode, OFlags};
use rustix::fs::{Mode, OFlags, open};
let sk = open(peer_a_keypair.secret_key, OFlags::RDONLY, Mode::empty())?;
let pk = open(peer_a_keypair.public_key, OFlags::RDONLY, Mode::empty())?;
@@ -342,8 +342,10 @@ fn api_integration_api_setup(protocol_version: ProtocolVersion) -> anyhow::Resul
// success on consensus
match osk_a.secret() == osk_b.secret() {
true => break,
false if attempt > 10 => bail!("Peers did not produce a matching key even after ten attempts. Something is wrong with the key exchange!"),
false => {},
false if attempt > 10 => bail!(
"Peers did not produce a matching key even after ten attempts. Something is wrong with the key exchange!"
),
false => {}
};
attempt += 1;
+7 -5
View File
@@ -5,9 +5,9 @@ use std::{
process::Stdio,
};
use anyhow::{bail, Context};
use anyhow::{Context, bail};
use rosenpass::api;
use rosenpass_to::{ops::copy_slice_least_src, To};
use rosenpass_to::{To, ops::copy_slice_least_src};
use rosenpass_util::{
file::LoadValueB64,
length_prefix_encoding::{decoder::LengthPrefixDecoder, encoder::LengthPrefixEncoder},
@@ -23,7 +23,7 @@ struct KillChild(std::process::Child);
impl Drop for KillChild {
fn drop(&mut self) {
use rustix::process::{kill_process, Pid, Signal::Term};
use rustix::process::{Pid, Signal::Term, kill_process};
let pid = Pid::from_child(&self.0);
// We seriously need to start handling signals with signalfd, our current signal handling
// system is a bit broken; there is probably a few functions that just restart on EINTR
@@ -188,8 +188,10 @@ fn api_integration_test(protocol_version: ProtocolVersion) -> anyhow::Result<()>
let osk_b = SymKey::load_b64::<64, _>(peer_b_osk.clone())?;
match osk_a.secret() == osk_b.secret() {
true => break,
false if attempt > 10 => bail!("Peers did not produce a matching key even after ten attempts. Something is wrong with the key exchange!"),
false => {},
false if attempt > 10 => bail!(
"Peers did not produce a matching key even after ten attempts. Something is wrong with the key exchange!"
),
false => {}
};
attempt += 1;
+1 -1
View File
@@ -11,7 +11,7 @@ use tempfile::tempdir;
use clap::Parser;
use rosenpass::{app_server::AppServerTestBuilder, cli::CliArgs, config::EXAMPLE_CONFIG};
use rosenpass_secret_memory::{Public, Secret};
use rosenpass_wireguard_broker::{WireguardBrokerMio, WG_KEY_LEN, WG_PEER_LEN};
use rosenpass_wireguard_broker::{WG_KEY_LEN, WG_PEER_LEN, WireguardBrokerMio};
use serial_test::serial;
use std::io::Write;
+14 -6
View File
@@ -102,11 +102,14 @@ fn test_successful_exchange_with_poll(
"
);
#[cfg(not(coverage))]
assert!((110.0..175.0).contains(&(_completions[2].0 - _completions[1].0)), "\
assert!(
(110.0..175.0).contains(&(_completions[2].0 - _completions[1].0)),
"\
First renegotiation should happen in between two and three minutes after the first renegotiation!\n\
Transcript: {transcript:?}\n\
Completions: {_completions:?}\
");
"
);
Ok(())
}
@@ -198,11 +201,14 @@ fn test_successful_exchange_under_packet_loss(
"
);
#[cfg(not(coverage))]
assert!((110.0..175.0).contains(&(_completions[2].0 - _completions[1].0)), "\
assert!(
(110.0..175.0).contains(&(_completions[2].0 - _completions[1].0)),
"\
First renegotiation should happen in between two and three minutes after the first renegotiation!\n\
Transcript: {transcript:?}\n\
Completions: {_completions:?}\
");
"
);
Ok(())
}
@@ -232,8 +238,10 @@ fn test_osk_label_mismatch() -> anyhow::Result<()> {
for _ in 0..300 {
let ev = sim.poll()?;
assert!(!matches!(ev, TranscriptEvent::CompletedExchange(_)),
"We deliberately provoked a mismatch in OSK domain separator, but still saw a successfully completed key exchange");
assert!(
!matches!(ev, TranscriptEvent::CompletedExchange(_)),
"We deliberately provoked a mismatch in OSK domain separator, but still saw a successfully completed key exchange"
);
// Wait for a key exchange that failed with a KeyMismatch event
let (osk_a_custom1, osk_b_custom2) = match ev {
+1 -1
View File
@@ -15,7 +15,7 @@
//! TEST_MODE=init cargo test crypto_server_test_vector_1
//! ```
use assert_tv::{test_vec_case, TestValue, TestVector, TestVectorActive, TestVectorSet};
use assert_tv::{TestValue, TestVector, TestVectorActive, TestVectorSet, test_vec_case};
use rosenpass::protocol::basic_types::{MsgBuf, SPk, SSk, SymKey};
use rosenpass::protocol::osk_domain_separator::OskDomainSeparator;
use rosenpass::protocol::test_vector_sets::deserialize_byte_vec;
+17 -6
View File
@@ -56,11 +56,22 @@ fn fatal<T>(note: &str, command: Option<CommandType>) -> Result<T, String> {
match command {
Some(command) => match command {
CommandType::GenKey => Err(format!("{}\nUsage: rp genkey PRIVATE_KEYS_DIR", note)),
CommandType::PubKey => Err(format!("{}\nUsage: rp pubkey PRIVATE_KEYS_DIR PUBLIC_KEYS_DIR", note)),
CommandType::Exchange => Err(format!("{}\nUsage: rp exchange PRIVATE_KEYS_DIR [dev <device>] [ip <ip1>/<cidr1>] [listen <ip>:<port>] [peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...", note)),
CommandType::ExchangeConfig => Err(format!("{}\nUsage: rp exchange-config <CONFIG_FILE>", note)),
CommandType::PubKey => Err(format!(
"{}\nUsage: rp pubkey PRIVATE_KEYS_DIR PUBLIC_KEYS_DIR",
note
)),
CommandType::Exchange => Err(format!(
"{}\nUsage: rp exchange PRIVATE_KEYS_DIR [dev <device>] [ip <ip1>/<cidr1>] [listen <ip>:<port>] [peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...",
note
)),
CommandType::ExchangeConfig => {
Err(format!("{}\nUsage: rp exchange-config <CONFIG_FILE>", note))
}
},
None => Err(format!("{}\nUsage: rp [verbose] genkey|pubkey|exchange|exchange-config [ARGS]...", note)),
None => Err(format!(
"{}\nUsage: rp [verbose] genkey|pubkey|exchange|exchange-config [ARGS]...",
note
)),
}
}
@@ -140,7 +151,7 @@ impl ExchangePeer {
return fatal(
&format!("Unknown option {}", x),
Some(CommandType::Exchange),
)
);
}
}
}
@@ -208,7 +219,7 @@ impl ExchangeOptions {
return fatal(
&format!("Unknown option {}", x),
Some(CommandType::Exchange),
)
);
}
}
}
+2 -2
View File
@@ -3,7 +3,7 @@ use std::{borrow::Borrow, net::SocketAddr, path::PathBuf};
use tokio::process::Command;
use anyhow::{bail, ensure, Context, Result};
use anyhow::{Context, Result, bail, ensure};
use futures_util::TryStreamExt as _;
use serde::Deserialize;
@@ -33,7 +33,7 @@ use crate::key::WG_B64_LEN;
mod netlink {
/// Re-exports from [::netlink_packet_core]
pub mod core {
pub use ::netlink_packet_core::{NetlinkMessage, NLM_F_ACK, NLM_F_REQUEST};
pub use ::netlink_packet_core::{NLM_F_ACK, NLM_F_REQUEST, NetlinkMessage};
}
/// Re-exports from [::rtnetlink]
+4 -4
View File
@@ -5,14 +5,14 @@ use std::{
path::Path,
};
use anyhow::{anyhow, Result};
use anyhow::{Result, anyhow};
use rosenpass_util::file::{LoadValueB64, StoreValue, StoreValueB64};
use zeroize::Zeroize;
use rosenpass::protocol::basic_types::{SPk, SSk};
use rosenpass_cipher_traits::primitives::Kem;
use rosenpass_ciphers::StaticKem;
use rosenpass_secret_memory::{file::StoreSecret as _, Public, Secret};
use rosenpass_secret_memory::{Public, Secret, file::StoreSecret as _};
/// The length of wireguard keys as a length in base 64 encoding.
pub const WG_B64_LEN: usize = 32 * 5 / 3;
@@ -119,13 +119,13 @@ mod tests {
use std::fs;
use rosenpass::protocol::basic_types::{SPk, SSk};
use rosenpass_secret_memory::secret_policy_try_use_memfd_secrets;
use rosenpass_secret_memory::Secret;
use rosenpass_secret_memory::secret_policy_try_use_memfd_secrets;
use rosenpass_util::file::LoadValue;
use rosenpass_util::file::LoadValueB64;
use tempfile::tempdir;
use crate::key::{genkey, pubkey, WG_B64_LEN};
use crate::key::{WG_B64_LEN, genkey, pubkey};
#[test]
#[cfg_attr(miri, ignore)] // Miri does not support calls to mmap with protections other than PROT_READ|PROT_WRITE
+3 -1
View File
@@ -15,5 +15,7 @@ fn main() -> anyhow::Result<()> {
#[cfg(not(any(target_os = "linux", target_os = "freebsd")))]
fn main() {
panic!("Unfortunately, the rp command is currently not supported on your platform. See https://github.com/rosenpass/rosenpass/issues/689 for more information and discussion.")
panic!(
"Unfortunately, the rp command is currently not supported on your platform. See https://github.com/rosenpass/rosenpass/issues/689 for more information and discussion."
)
}
+1 -1
View File
@@ -5,7 +5,7 @@ use rosenpass_util::tokio::janitor::ensure_janitor;
use rosenpass_secret_memory::policy;
use crate::cli::{Cli, Command};
use crate::exchange::{exchange, ExchangeOptions};
use crate::exchange::{ExchangeOptions, exchange};
use crate::key::{genkey, pubkey};
#[tokio::main]
+4 -2
View File
@@ -105,10 +105,12 @@ unsafe impl Allocator for MallocAllocator {
// Ensure the right alignment is used
let off = (mem.as_ptr() as *const u8).align_offset(layout.align());
if off != 0 {
log::error!("Allocation {layout:?} was requested but malloc-based memsec returned allocation \
log::error!(
"Allocation {layout:?} was requested but malloc-based memsec returned allocation \
with offset {off} from the requested alignment. Malloc always allocates values \
at the end of a memory page for security reasons, custom alignments are not supported. \
You could try allocating an oversized value.");
You could try allocating an oversized value."
);
unsafe { memsec::free(mem) };
return Err(AllocError);
};
+7 -3
View File
@@ -99,17 +99,21 @@ unsafe impl Allocator for MemfdSecAllocator {
// Unwrap the option
let Some(mem) = mem else {
log::error!("Allocation {layout:?} was requested but memfd-based memsec returned a null pointer");
log::error!(
"Allocation {layout:?} was requested but memfd-based memsec returned a null pointer"
);
return Err(AllocError);
};
// Ensure the right alignment is used
let off = (mem.as_ptr() as *const u8).align_offset(layout.align());
if off != 0 {
log::error!("Allocation {layout:?} was requested but memfd-based memsec returned allocation \
log::error!(
"Allocation {layout:?} was requested but memfd-based memsec returned allocation \
with offset {off} from the requested alignment. Memfd always allocates values \
at the end of a memory page for security reasons, custom alignments are not supported. \
You could try allocating an oversized value.");
You could try allocating an oversized value."
);
unsafe { memsec::free_memfd_secret(mem) };
return Err(AllocError);
};
+5 -5
View File
@@ -1,11 +1,11 @@
use crate::debug::debug_crypto_array;
use anyhow::Context;
use rand::{Fill as Randomize, Rng};
use rosenpass_to::{ops::copy_slice, To};
use rosenpass_to::{To, ops::copy_slice};
use rosenpass_util::b64::{b64_decode, b64_encode};
use rosenpass_util::file::{
fopen_r, fopen_w, LoadValue, LoadValueB64, ReadExactToEnd, ReadSliceToEnd, StoreValue,
StoreValueB64, StoreValueB64Writer, Visibility,
LoadValue, LoadValueB64, ReadExactToEnd, ReadSliceToEnd, StoreValue, StoreValueB64,
StoreValueB64Writer, Visibility, fopen_r, fopen_w,
};
use rosenpass_util::functional::mutating;
use std::borrow::{Borrow, BorrowMut};
@@ -390,8 +390,8 @@ mod tests {
use rosenpass_util::{
b64::b64_encode,
file::{
fopen_w, LoadValue, LoadValueB64, StoreValue, StoreValueB64, StoreValueB64Writer,
Visibility,
LoadValue, LoadValueB64, StoreValue, StoreValueB64, StoreValueB64Writer,
Visibility, fopen_w,
},
};
use std::{fs, ops::Deref, os::unix::fs::PermissionsExt};
+4 -4
View File
@@ -10,15 +10,15 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
use rosenpass_util::b64::{b64_decode, b64_encode};
use rosenpass_util::file::{
fopen_r, LoadValue, LoadValueB64, ReadExactToEnd, ReadSliceToEnd, StoreValueB64,
StoreValueB64Writer,
LoadValue, LoadValueB64, ReadExactToEnd, ReadSliceToEnd, StoreValueB64, StoreValueB64Writer,
fopen_r,
};
use rosenpass_util::functional::mutating;
use crate::alloc::{secret_box, SecretBox, SecretVec};
use crate::alloc::{SecretBox, SecretVec, secret_box};
use crate::file::StoreSecret;
use rosenpass_util::file::{fopen_w, Visibility};
use rosenpass_util::file::{Visibility, fopen_w};
use std::io::Write;
// This might become a problem in library usage; it's effectively a memory
// leak which probably isn't a problem right now because most memory will
+1 -1
View File
@@ -101,7 +101,7 @@ impl<'de, const N: usize> Deserialize<'de> for PublicBox<N> {
mod tests {
use super::*;
use crate::secret_policy_use_only_malloc_secrets;
use serde::{de::DeserializeOwned, Serialize};
use serde::{Serialize, de::DeserializeOwned};
use serde_json;
// Generic helper: serialize to JSON, then deserialize back.
+187 -191
View File
@@ -33,79 +33,78 @@ let
peerBConfigFileVersion = getConfigFileVersion pkgs.rosenpass-peer-b;
peerCConfigFileVersion = if multiPeer then getConfigFileVersion pkgs.rosenpass-peer-c else null;
staticConfig =
{
peerA = {
innerIp = "10.100.0.1";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerA.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerA.pk";
rosenpassConfig = builtins.toFile "peer-a.toml" (
''
public_key = "${rosenpassKeyFolder}/self.pk"
secret_key = "${rosenpassKeyFolder}/self.sk"
listen = ["[::]:${builtins.toString rpPort}"]
verbosity = "Verbose"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-b.pk"
endpoint = "peerbkeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathAB}"
''
+ (lib.optionalString multiPeer ''
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-c.pk"
endpoint = "peerckeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathAC}"
'')
);
};
peerB = {
innerIp = "10.100.0.2";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerB.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerB.pk";
rosenpassConfig = builtins.toFile "peer-b.toml" (
''
public_key = "${rosenpassKeyFolder}/self.pk"
secret_key = "${rosenpassKeyFolder}/self.sk"
listen = ["[::]:${builtins.toString rpPort}"]
verbosity = "Verbose"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-a.pk"
endpoint = "peerakeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathBA}"
''
+ (lib.optionalString multiPeer ''
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-c.pk"
endpoint = "peerckeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathBC}"
'')
);
};
}
// lib.optionalAttrs multiPeer {
# peerC is only defined if we are in a multiPeer context.
peerC = {
innerIp = "10.100.0.3";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerC.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerC.pk";
rosenpassConfig = builtins.toFile "peer-c.toml" ''
staticConfig = {
peerA = {
innerIp = "10.100.0.1";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerA.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerA.pk";
rosenpassConfig = builtins.toFile "peer-a.toml" (
''
public_key = "${rosenpassKeyFolder}/self.pk"
secret_key = "${rosenpassKeyFolder}/self.sk"
listen = ["[::]:${builtins.toString rpPort}"]
verbosity = "Verbose"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-b.pk"
endpoint = "peerbkeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathAB}"
''
+ (lib.optionalString multiPeer ''
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-c.pk"
endpoint = "peerckeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathAC}"
'')
);
};
peerB = {
innerIp = "10.100.0.2";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerB.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerB.pk";
rosenpassConfig = builtins.toFile "peer-b.toml" (
''
public_key = "${rosenpassKeyFolder}/self.pk"
secret_key = "${rosenpassKeyFolder}/self.sk"
listen = ["[::]:${builtins.toString rpPort}"]
verbosity = "Verbose"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-a.pk"
endpoint = "peerakeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathCA}"
key_out = "${keyExchangePathBA}"
''
+ (lib.optionalString multiPeer ''
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-b.pk"
public_key = "${rosenpassKeyFolder}/peer-c.pk"
endpoint = "peerckeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathCB}"
'';
};
key_out = "${keyExchangePathBC}"
'')
);
};
}
// lib.optionalAttrs multiPeer {
# peerC is only defined if we are in a multiPeer context.
peerC = {
innerIp = "10.100.0.3";
wgPrivateKeyFile = "${wireguardKeyFolder}/peerC.sk";
wgPublicKeyFile = "${wireguardKeyFolder}/peerC.pk";
rosenpassConfig = builtins.toFile "peer-c.toml" ''
public_key = "${rosenpassKeyFolder}/self.pk"
secret_key = "${rosenpassKeyFolder}/self.sk"
listen = ["[::]:${builtins.toString rpPort}"]
verbosity = "Verbose"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-a.pk"
endpoint = "peerakeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathCA}"
[[peers]]
public_key = "${rosenpassKeyFolder}/peer-b.pk"
endpoint = "peerckeyexchanger:${builtins.toString rpPort}"
key_out = "${keyExchangePathCB}"
'';
};
};
inherit (import (pkgs.path + "/nixos/tests/ssh-keys.nix") pkgs)
snakeOilPublicKey
@@ -133,143 +132,140 @@ in
systemd.tmpfiles.rules = [ "d ${rosenpassKeyFolder} 0400 root root - -" ];
};
nodes =
{
# peerA and peerB are the only neccessary peers unless we are in the multiPeer test.
peerA = {
networking.firewall.allowedUDPPorts = [ wgPort ];
nodes = {
# peerA and peerB are the only neccessary peers unless we are in the multiPeer test.
peerA = {
networking.firewall.allowedUDPPorts = [ wgPort ];
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances =
{
AB = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerakeyexchanger";
peerPubkeyFile = staticConfig.peerB.wgPublicKeyFile;
remoteKeyPath = keyExchangePathAB;
endpoint = "peerB:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerB.innerIp}/32";
};
}
// lib.optionalAttrs multiPeer {
AC = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerakeyexchanger";
peerPubkeyFile = staticConfig.peerC.wgPublicKeyFile;
remoteKeyPath = keyExchangePathAC;
endpoint = "peerC:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerC.innerIp}/32";
};
};
};
peerB = {
networking.firewall.allowedUDPPorts = [ wgPort ];
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances =
{
BA = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerbkeyexchanger";
peerPubkeyFile = staticConfig.peerA.wgPublicKeyFile;
remoteKeyPath = keyExchangePathBA;
endpoint = "peerA:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerA.innerIp}/32";
};
}
// lib.optionalAttrs multiPeer {
BC = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerbkeyexchanger";
peerPubkeyFile = staticConfig.peerC.wgPublicKeyFile;
remoteKeyPath = keyExchangePathBC;
endpoint = "peerC:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerC.innerIp}/32";
};
};
};
# The key exchanger node for peerA is the node that actually runs rosenpass. It takes the rosenpass confguration for peerA and runs it.
# The key sync services of peerA will ssh into this node and download the exchanged keys from here.
peerakeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
networking.firewall.allowedUDPPorts = [ rpPort ];
services.rosenpassKeyExchange = {
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances = {
AB = {
create = true;
enable = false;
config = staticConfig.peerA.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-a;
inherit wgInterface;
rpHost = "peerakeyexchanger";
peerPubkeyFile = staticConfig.peerB.wgPublicKeyFile;
remoteKeyPath = keyExchangePathAB;
endpoint = "peerB:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerB.innerIp}/32";
};
};
# The key exchanger node for peerB is the node that actually runs rosenpass. It takes the rosenpass confguration for peerB and runs it.
# The key sync services of peerB will ssh into this node and download the exchanged keys from here.
peerbkeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
services.rosenpassKeyExchange = {
}
// lib.optionalAttrs multiPeer {
AC = {
create = true;
enable = false;
config = staticConfig.peerB.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-b;
};
};
}
// lib.optionalAttrs multiPeer {
peerC = {
networking.firewall.allowedUDPPorts = [ wgPort ];
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances = {
CA = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerckeyexchanger";
peerPubkeyFile = staticConfig.peerA.wgPublicKeyFile;
remoteKeyPath = keyExchangePathCA;
endpoint = "peerA:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerA.innerIp}/32";
};
CB = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerckeyexchanger";
peerPubkeyFile = staticConfig.peerB.wgPublicKeyFile;
remoteKeyPath = keyExchangePathCB;
endpoint = "peerB:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerB.innerIp}/32";
};
};
};
# The key exchanger node for peerC is the node that actually runs rosenpass. It takes the rosenpass confguration for peerC and runs it.
# The key sync services of peerC will ssh into this node and download the exchanged keys from here.
peerckeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
networking.firewall.allowedUDPPorts = [ rpPort ];
services.rosenpassKeyExchange = {
create = true;
enable = false;
config = staticConfig.peerC.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-c;
inherit wgInterface;
rpHost = "peerakeyexchanger";
peerPubkeyFile = staticConfig.peerC.wgPublicKeyFile;
remoteKeyPath = keyExchangePathAC;
endpoint = "peerC:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerC.innerIp}/32";
};
};
};
peerB = {
networking.firewall.allowedUDPPorts = [ wgPort ];
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances = {
BA = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerbkeyexchanger";
peerPubkeyFile = staticConfig.peerA.wgPublicKeyFile;
remoteKeyPath = keyExchangePathBA;
endpoint = "peerA:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerA.innerIp}/32";
};
}
// lib.optionalAttrs multiPeer {
BC = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerbkeyexchanger";
peerPubkeyFile = staticConfig.peerC.wgPublicKeyFile;
remoteKeyPath = keyExchangePathBC;
endpoint = "peerC:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerC.innerIp}/32";
};
};
};
# The key exchanger node for peerA is the node that actually runs rosenpass. It takes the rosenpass confguration for peerA and runs it.
# The key sync services of peerA will ssh into this node and download the exchanged keys from here.
peerakeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
networking.firewall.allowedUDPPorts = [ rpPort ];
services.rosenpassKeyExchange = {
create = true;
enable = false;
config = staticConfig.peerA.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-a;
};
};
# The key exchanger node for peerB is the node that actually runs rosenpass. It takes the rosenpass confguration for peerB and runs it.
# The key sync services of peerB will ssh into this node and download the exchanged keys from here.
peerbkeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
services.rosenpassKeyExchange = {
create = true;
enable = false;
config = staticConfig.peerB.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-b;
};
};
}
// lib.optionalAttrs multiPeer {
peerC = {
networking.firewall.allowedUDPPorts = [ wgPort ];
# Each instance of the key sync service loads a symmetric key from a rosenpass keyexchanger node and sets it as the preshared key for the appropriate wireguard tunnel.
services.rosenpassKeySync.instances = {
CA = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerckeyexchanger";
peerPubkeyFile = staticConfig.peerA.wgPublicKeyFile;
remoteKeyPath = keyExchangePathCA;
endpoint = "peerA:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerA.innerIp}/32";
};
CB = {
create = true;
enable = false;
inherit wgInterface;
rpHost = "peerckeyexchanger";
peerPubkeyFile = staticConfig.peerB.wgPublicKeyFile;
remoteKeyPath = keyExchangePathCB;
endpoint = "peerB:${builtins.toString wgPort}";
allowedIps = "${staticConfig.peerB.innerIp}/32";
};
};
};
# The key exchanger node for peerC is the node that actually runs rosenpass. It takes the rosenpass confguration for peerC and runs it.
# The key sync services of peerC will ssh into this node and download the exchanged keys from here.
peerckeyexchanger = {
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
networking.firewall.allowedUDPPorts = [ rpPort ];
services.rosenpassKeyExchange = {
create = true;
enable = false;
config = staticConfig.peerC.rosenpassConfig;
rosenpassVersion = pkgs.rosenpass-peer-c;
};
};
};
interactive = {
defaults = {
+1 -1
View File
@@ -1,7 +1,7 @@
//! Functions that make it easy to copy data between arrays and slices using functions with
//! destinations. See the specific functions for examples and more explanations.
use crate::{with_destination, To};
use crate::{To, with_destination};
/// Function with destination that copies data from
/// origin into the destination.
+1 -1
View File
@@ -459,7 +459,7 @@ where
let builder = match site {
site @ Self::Void => return (site, Err(ConstructionSiteErectError::IsVoid)),
site @ Self::Product(_) => {
return (site, Err(ConstructionSiteErectError::AlreadyBuilt))
return (site, Err(ConstructionSiteErectError::AlreadyBuilt));
}
Self::Builder(builder) => builder,
};
+3 -3
View File
@@ -133,7 +133,7 @@ pub fn clone_fd_cloexec<Fd: AsFd>(fd: Fd) -> rustix::io::Result<OwnedFd> {
/// explicit destination file descriptor.
#[cfg(target_os = "linux")]
pub fn clone_fd_to_cloexec<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> rustix::io::Result<()> {
use rustix::io::{dup3, DupFlags};
use rustix::io::{DupFlags, dup3};
dup3(fd, new, DupFlags::CLOEXEC)
}
@@ -143,7 +143,7 @@ pub fn clone_fd_to_cloexec<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> rustix::io::R
/// This is slightly different from [clone_fd_cloexec], as this function supports specifying an
/// explicit destination file descriptor.
pub fn clone_fd_to_cloexec<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> rustix::io::Result<()> {
use rustix::io::{dup2, fcntl_setfd, FdFlags};
use rustix::io::{FdFlags, dup2, fcntl_setfd};
dup2(&fd, new)?;
fcntl_setfd(&new, FdFlags::CLOEXEC)
}
@@ -165,7 +165,7 @@ pub fn clone_fd_to_cloexec<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> rustix::io::R
/// let nullfd = open_nullfd().unwrap();
/// ```
pub fn open_nullfd() -> rustix::io::Result<OwnedFd> {
use rustix::fs::{open, Mode, OFlags};
use rustix::fs::{Mode, OFlags, open};
// TODO: Add tests showing that this will throw errors on use
open("/dev/null", OFlags::CLOEXEC, Mode::empty())
}
+1 -1
View File
@@ -271,7 +271,7 @@ impl<Buf: BorrowMut<[u8]>> LengthPrefixDecoder<Buf> {
break Err(ReadFromIoError::IoError(io::Error::new(
K::UnexpectedEof,
"",
)))
)));
}
// Retry
+1 -1
View File
@@ -283,9 +283,9 @@ impl<T: Sized> MoveExt for T {
#[cfg(test)]
mod test_forgetting {
use crate::mem::Forgetting;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::Arc;
#[test]
fn test_forgetting() {
+1 -1
View File
@@ -7,7 +7,7 @@ use std::{
};
use uds::UnixStreamExt as FdPassingExt;
use crate::fd::{claim_fd_inplace, IntoStdioErr};
use crate::fd::{IntoStdioErr, claim_fd_inplace};
/// A wrapper around a socket that combines reading from the socket with tracking
/// received file descriptors. Limits the maximum number of file descriptors that
+18 -12
View File
@@ -50,7 +50,7 @@
use std::any::type_name;
use std::future::Future;
use anyhow::{bail, Context};
use anyhow::{Context, bail};
use tokio::task::{AbortHandle, JoinError, JoinHandle, JoinSet};
use tokio::task_local;
@@ -214,13 +214,14 @@ impl JanitorAgent {
}),
// JoinError produced by the user task: The user task was cancelled.
(Some(Ok(E::CleanupJobJoinError(err))), _) if err.is_cancelled() => Err(err).with_context(|| {
format!(
"Error in cleanup job handled by {me}; the cleanup task was cancelled.
(Some(Ok(E::CleanupJobJoinError(err))), _) if err.is_cancelled() => Err(err)
.with_context(|| {
format!(
"Error in cleanup job handled by {me}; the cleanup task was cancelled.
This should not happend and likely indicates a developer error in {me}.",
me = type_name::<Self>()
)
}),
me = type_name::<Self>()
)
}),
// JoinError produced by the user task: The user task panicked
(Some(Ok(E::CleanupJobJoinError(err))), _) => Err(err).with_context(|| {
@@ -250,17 +251,18 @@ impl JanitorAgent {
)
}),
// Internal errors: State machine failure
// No tasks left, but ticket queue was not drained
(Option::None, false) => bail!("Internal error in {me}::handle_one_event(); \
(Option::None, false) => bail!(
"Internal error in {me}::handle_one_event(); \
there are no more internal tasks active, but the ticket queue was not drained. \
The {me}::handle_one_event() code is deliberately designed to never leave the internal task set empty; \
instead, there should always be one task to receive new cleanup jobs from the task queue unless the task \
queue has been closed. \
This is probably a developer error.",
me = type_name::<Self>())
me = type_name::<Self>()
),
}
}
@@ -562,10 +564,14 @@ where
#[derive(thiserror::Error, Debug)]
pub enum TrySpawnCleanupJobError {
/// No active janitor exists
#[error("No janitor registered. Did the developer forget to call enter_janitor(…) or ensure_janitor(…)?")]
#[error(
"No janitor registered. Did the developer forget to call enter_janitor(…) or ensure_janitor(…)?"
)]
NoActiveJanitor,
/// The currently active janitor is in the process of terminating
#[error("There is a registered janitor, but it is currently in the process of terminating and won't accept new tasks.")]
#[error(
"There is a registered janitor, but it is currently in the process of terminating and won't accept new tasks."
)]
ActiveJanitorTerminating,
}
+1 -1
View File
@@ -1,7 +1,7 @@
//! A module providing the [`RefMaker`] type and its associated methods for constructing
//! [`zerocopy::Ref`] references from byte buffers.
use anyhow::{ensure, Context};
use anyhow::{Context, ensure};
use std::marker::PhantomData;
use zerocopy::{ByteSlice, ByteSliceMut, Ref};
use zeroize::Zeroize;
+1 -1
View File
@@ -1,7 +1,7 @@
#![cfg(feature = "tokio")]
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
use tokio::time::sleep;
+1 -1
View File
@@ -39,11 +39,11 @@
use std::{borrow::BorrowMut, fmt::Debug};
use crate::{
SerializedBrokerConfig, WireGuardBroker,
api::{
config::NetworkBrokerConfig,
msgs::{self, REQUEST_MSG_BUFFER_SIZE},
},
SerializedBrokerConfig, WireGuardBroker,
};
use super::{
+1 -1
View File
@@ -1,7 +1,7 @@
//! This module defines message formats for messages in the Wireguard Broker protocol as well as
//! helper structures like errors and conversion functions.
use std::str::{from_utf8, Utf8Error};
use std::str::{Utf8Error, from_utf8};
use zerocopy::{AsBytes, FromBytes, FromZeroes};
+2 -2
View File
@@ -9,8 +9,8 @@ use std::borrow::BorrowMut;
use rosenpass_secret_memory::{Public, Secret};
use crate::api::msgs::{self, Envelope, SetPskRequest, SetPskResponse};
use crate::WireGuardBroker;
use crate::api::msgs::{self, Envelope, SetPskRequest, SetPskResponse};
use super::config::{NetworkBrokerConfigBuilder, NetworkBrokerConfigErr};
@@ -137,7 +137,7 @@ mod tests {
use crate::api::server::BrokerServer;
use crate::brokers::netlink::SetPskError;
use crate::{SerializedBrokerConfig, WireGuardBroker};
use rosenpass_secret_memory::{secret_policy_use_only_malloc_secrets, Secret};
use rosenpass_secret_memory::{Secret, secret_policy_use_only_malloc_secrets};
use zerocopy::AsBytes;
#[derive(Debug, Clone)]
+1 -1
View File
@@ -19,7 +19,7 @@ fn main() {
pub mod linux {
//! Linux-specific implementation for the broker that communicates with the WireGuard broker.
use std::io::{stdin, stdout, Read, Write};
use std::io::{Read, Write, stdin, stdout};
use rosenpass_wireguard_broker::api::msgs;
use rosenpass_wireguard_broker::api::server::BrokerServer;
+1 -1
View File
@@ -9,7 +9,7 @@ use tokio::process::Command;
use tokio::sync::{mpsc, oneshot};
use tokio::task;
use anyhow::{bail, ensure, Result};
use anyhow::{Result, bail, ensure};
use clap::{ArgGroup, Parser};
use rosenpass_util::fd::claim_fd;
+10 -5
View File
@@ -47,10 +47,10 @@
//! # }
//! ```
use anyhow::{bail, Context};
use anyhow::{Context, bail};
use mio::Interest;
use rosenpass_secret_memory::Secret;
use rosenpass_to::{ops::copy_slice_least_src, To};
use rosenpass_to::{To, ops::copy_slice_least_src};
use rosenpass_util::io::{IoResultKindHintExt, TryIoResultKindHintExt};
use rosenpass_util::length_prefix_encoding::decoder::LengthPrefixDecoder;
use rosenpass_util::length_prefix_encoding::encoder::LengthPrefixEncoder;
@@ -233,7 +233,10 @@ impl BrokerClientIo for MioBrokerClientIo {
fn send_msg(&mut self, buf: &[u8]) -> Result<(), Self::SendError> {
// Clear write buffer (blocking write)
self.flush_blocking()?;
assert!(self.write_buffer.exhausted(), "flush_blocking() should have put the write buffer in exhausted state. Developer error!");
assert!(
self.write_buffer.exhausted(),
"flush_blocking() should have put the write buffer in exhausted state. Developer error!"
);
// Emplace new message in write buffer
copy_slice_least_src(buf).to(self.write_buffer.buffer_bytes_mut());
@@ -273,8 +276,10 @@ impl MioBrokerClientIo {
return Ok(());
}
log::warn!("Could not flush PSK broker write buffer in non-blocking mode. Flushing in blocking mode!");
use rustix::io::{fcntl_getfd, fcntl_setfd, FdFlags};
log::warn!(
"Could not flush PSK broker write buffer in non-blocking mode. Flushing in blocking mode!"
);
use rustix::io::{FdFlags, fcntl_getfd, fcntl_setfd};
// Build O_NONBLOCK
let o_nonblock = {
+2 -2
View File
@@ -90,6 +90,7 @@ impl From<wg::err::GetDeviceError> for SetPskError {
}
}
use SetPskError as SetPskNetlinkError;
/// # Example
/// ```
/// use rosenpass_wireguard_broker::api::msgs::SetPskError as SetPskMsgsError;
@@ -98,7 +99,6 @@ impl From<wg::err::GetDeviceError> for SetPskError {
/// let set_psk_msgs_error = SetPskMsgsError::from(set_psk_nlink_error);
/// ```
use msgs::SetPskError as SetPskMsgsError;
use SetPskError as SetPskNetlinkError;
impl From<SetPskNetlinkError> for SetPskMsgsError {
fn from(err: SetPskError) -> Self {
match err {
@@ -191,7 +191,7 @@ impl WireGuardBroker for NetlinkWireGuardBroker {
#[cfg(test)]
mod tests {
use super::*;
use rosenpass_secret_memory::{secret_policy_use_only_malloc_secrets, Public, Secret};
use rosenpass_secret_memory::{Public, Secret, secret_policy_use_only_malloc_secrets};
#[test]
fn smoke_test() -> Result<(), Box<dyn std::error::Error>> {
secret_policy_use_only_malloc_secrets();