Compare commits

..

1 Commits

Author SHA1 Message Date
Karolin Varner
6401ed6cfb Revert "chore: Format all Cargo.toml files"
This reverts commit b0706354d3.
2024-10-01 12:22:49 +02:00
31 changed files with 719 additions and 1324 deletions

View File

@@ -6,11 +6,6 @@ on:
push: push:
branches: branches:
- main - main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
i686-linux---default: i686-linux---default:
name: Build i686-linux.default name: Build i686-linux.default
@@ -246,30 +241,30 @@ jobs:
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Build - name: Build
run: nix build .#packages.x86_64-linux.release-package --print-build-logs run: nix build .#packages.x86_64-linux.release-package --print-build-logs
# aarch64-linux---release-package: aarch64-linux---release-package:
# name: Build aarch64-linux.release-package name: Build aarch64-linux.release-package
# runs-on: runs-on:
# - ubuntu-latest - ubuntu-latest
# needs: needs:
# - aarch64-linux---rosenpass-oci-image - aarch64-linux---rosenpass-oci-image
# - aarch64-linux---rosenpass - aarch64-linux---rosenpass
# - aarch64-linux---rp - aarch64-linux---rp
# steps: steps:
# - run: | - run: |
# DEBIAN_FRONTEND=noninteractive DEBIAN_FRONTEND=noninteractive
# sudo apt-get update -q -y && sudo apt-get install -q -y qemu-system-aarch64 qemu-efi binfmt-support qemu-user-static sudo apt-get update -q -y && sudo apt-get install -q -y qemu-system-aarch64 qemu-efi binfmt-support qemu-user-static
# - uses: actions/checkout@v3 - uses: actions/checkout@v3
# - uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@v22
# with: with:
# nix_path: nixpkgs=channel:nixos-unstable nix_path: nixpkgs=channel:nixos-unstable
# extra_nix_config: | extra_nix_config: |
# system = aarch64-linux system = aarch64-linux
# - uses: cachix/cachix-action@v12 - uses: cachix/cachix-action@v12
# with: with:
# name: rosenpass name: rosenpass
# authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
# - name: Build - name: Build
# run: nix build .#packages.aarch64-linux.release-package --print-build-logs run: nix build .#packages.aarch64-linux.release-package --print-build-logs
x86_64-linux---rosenpass: x86_64-linux---rosenpass:
name: Build x86_64-linux.rosenpass name: Build x86_64-linux.rosenpass
runs-on: runs-on:

View File

@@ -4,10 +4,6 @@ on:
push: push:
branches: [main] branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: permissions:
checks: write checks: write
contents: read contents: read

View File

@@ -1,13 +1,9 @@
name: Regressions name: QC
on: on:
pull_request: pull_request:
push: push:
branches: [main] branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: permissions:
checks: write checks: write
contents: read contents: read

View File

@@ -1,5 +1,4 @@
.direnv/ .direnv/
flake.lock
papers/whitepaper.md papers/whitepaper.md
src/usage.md
target/ target/
src/usage.md

570
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ rosenpass-secret-memory = { path = "secret-memory" }
rosenpass-oqs = { path = "oqs" } rosenpass-oqs = { path = "oqs" }
rosenpass-wireguard-broker = { path = "wireguard-broker" } rosenpass-wireguard-broker = { path = "wireguard-broker" }
doc-comment = "0.3.3" doc-comment = "0.3.3"
base64ct = { version = "1.6.0", default-features = false } base64ct = {version = "1.6.0", default-features=false}
zeroize = "1.8.1" zeroize = "1.8.1"
memoffset = "0.9.1" memoffset = "0.9.1"
thiserror = "1.0.64" thiserror = "1.0.64"
@@ -41,35 +41,33 @@ env_logger = "0.10.2"
toml = "0.7.8" toml = "0.7.8"
static_assertions = "1.1.0" static_assertions = "1.1.0"
allocator-api2 = "0.2.14" allocator-api2 = "0.2.14"
memsec = { git = "https://github.com/rosenpass/memsec.git", rev = "aceb9baee8aec6844125bd6612f92e9a281373df", features = [ memsec = { git="https://github.com/rosenpass/memsec.git" ,rev="aceb9baee8aec6844125bd6612f92e9a281373df", features = [ "alloc_ext", ] }
"alloc_ext",
] }
rand = "0.8.5" rand = "0.8.5"
typenum = "1.17.0" typenum = "1.17.0"
log = { version = "0.4.22" } log = { version = "0.4.22" }
clap = { version = "4.5.20", features = ["derive"] } clap = { version = "4.5.18", features = ["derive"] }
serde = { version = "1.0.210", features = ["derive"] } serde = { version = "1.0.210", features = ["derive"] }
arbitrary = { version = "1.3.2", features = ["derive"] } arbitrary = { version = "1.3.2", features = ["derive"] }
anyhow = { version = "1.0.89", features = ["backtrace", "std"] } anyhow = { version = "1.0.89", features = ["backtrace", "std"] }
mio = { version = "1.0.2", features = ["net", "os-poll"] } mio = { version = "1.0.2", features = ["net", "os-poll"] }
oqs-sys = { version = "0.9.1", default-features = false, features = [ oqs-sys = { version = "0.9.1", default-features = false, features = [
'classic_mceliece', 'classic_mceliece',
'kyber', 'kyber',
] } ] }
blake2 = "0.10.6" blake2 = "0.10.6"
chacha20poly1305 = { version = "0.10.1", default-features = false, features = [ chacha20poly1305 = { version = "0.10.1", default-features = false, features = [
"std", "std",
"heapless", "heapless",
] } ] }
zerocopy = { version = "0.7.35", features = ["derive"] } zerocopy = { version = "0.7.35", features = ["derive"] }
home = "0.5.9" home = "0.5.9"
derive_builder = "0.20.1" derive_builder = "0.20.1"
tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }
postcard = { version = "1.0.10", features = ["alloc"] } postcard= {version = "1.0.10", features = ["alloc"]}
libcrux = { version = "0.0.2-pre.2" } libcrux = { version = "0.0.2-pre.2" }
hex-literal = { version = "0.4.1" } hex-literal = { version = "0.4.1" }
hex = { version = "0.4.3" } hex = { version = "0.4.3" }
heck = { version = "0.5.0" } heck = { version = "0.5.0" }
libc = { version = "0.2" } libc = { version = "0.2" }
uds = { git = "https://github.com/rosenpass/uds" } uds = { git = "https://github.com/rosenpass/uds" }
@@ -81,7 +79,7 @@ libfuzzer-sys = "0.4"
test_bin = "0.4.0" test_bin = "0.4.0"
criterion = "0.4.0" criterion = "0.4.0"
allocator-api2-tests = "0.2.15" allocator-api2-tests = "0.2.15"
procspawn = { version = "1.0.1", features = ["test-support"] } procspawn = {version = "1.0.1", features= ["test-support"]}
#Broker dependencies (might need cleanup or changes) #Broker dependencies (might need cleanup or changes)

View File

@@ -23,4 +23,4 @@ static_assertions = { workspace = true }
zeroize = { workspace = true } zeroize = { workspace = true }
chacha20poly1305 = { workspace = true } chacha20poly1305 = { workspace = true }
blake2 = { workspace = true } blake2 = { workspace = true }
libcrux = { workspace = true, optional = true } libcrux = { workspace = true, optional = true }

View File

@@ -1,15 +1,7 @@
//! Constant-time comparison
use core::ptr; use core::ptr;
/// Little endian memcmp version of quinier/memsec /// Little endian memcmp version of quinier/memsec
/// https://github.com/quininer/memsec/blob/bbc647967ff6d20d6dccf1c85f5d9037fcadd3b0/src/lib.rs#L30 /// https://github.com/quininer/memsec/blob/bbc647967ff6d20d6dccf1c85f5d9037fcadd3b0/src/lib.rs#L30
///
/// # Panic & Safety
///
/// Both input arrays must be at least of the indicated length.
///
/// See [std::ptr::read_volatile] on safety.
#[inline(never)] #[inline(never)]
pub unsafe fn memcmp_le(b1: *const u8, b2: *const u8, len: usize) -> i32 { pub unsafe fn memcmp_le(b1: *const u8, b2: *const u8, len: usize) -> i32 {
let mut res = 0; let mut res = 0;
@@ -21,16 +13,6 @@ pub unsafe fn memcmp_le(b1: *const u8, b2: *const u8, len: usize) -> i32 {
((res - 1) >> 8) + (res >> 8) + 1 ((res - 1) >> 8) + (res >> 8) + 1
} }
#[test]
pub fn memcmp_le_test() {
// use rosenpass_constant_time::memcmp_le;
let a = [0, 1, 0, 0];
let b = [0, 0, 0, 1];
assert_eq!(-1, unsafe { memcmp_le(a.as_ptr(), b.as_ptr(), 4) });
assert_eq!(0, unsafe { memcmp_le(a.as_ptr(), a.as_ptr(), 4) });
assert_eq!(1, unsafe { memcmp_le(b.as_ptr(), a.as_ptr(), 4) });
}
/// compares two slices of memory content and returns an integer indicating the relationship between /// compares two slices of memory content and returns an integer indicating the relationship between
/// the slices /// the slices
/// ///
@@ -50,28 +32,6 @@ pub fn memcmp_le_test() {
/// ## Tests /// ## Tests
/// For discussion on how to ensure the constant-time execution of this function, see /// For discussion on how to ensure the constant-time execution of this function, see
/// <https://github.com/rosenpass/rosenpass/issues/232> /// <https://github.com/rosenpass/rosenpass/issues/232>
///
/// # Examples
///
/// ```rust
/// use rosenpass_constant_time::compare;
/// let a = [0, 1, 0, 0];
/// let b = [0, 0, 0, 1];
/// assert_eq!(-1, compare(&a, &b));
/// assert_eq!(0, compare(&a, &a));
/// assert_eq!(1, compare(&b, &a));
/// ```
///
/// # Panic
///
/// This function will panic if the input arrays are of different lengths.
///
/// ```should_panic
/// use rosenpass_constant_time::compare;
/// let a = [0, 1, 0];
/// let b = [0, 0, 0, 1];
/// compare(&a, &b);
/// ```
#[inline] #[inline]
pub fn compare(a: &[u8], b: &[u8]) -> i32 { pub fn compare(a: &[u8], b: &[u8]) -> i32 {
assert!(a.len() == b.len()); assert!(a.len() == b.len());

View File

@@ -1,5 +1,3 @@
//! Incrementing numbers
use core::hint::black_box; use core::hint::black_box;
/// Interpret the given slice as a little-endian unsigned integer /// Interpret the given slice as a little-endian unsigned integer

View File

@@ -1,5 +1,3 @@
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
//! constant-time implementations of some primitives //! constant-time implementations of some primitives
//! //!
//! Rosenpass internal library providing basic constant-time operations. //! Rosenpass internal library providing basic constant-time operations.

View File

@@ -1,5 +1,3 @@
//! memcmp
/// compares two sclices of memory content and returns whether they are equal /// compares two sclices of memory content and returns whether they are equal
/// ///
/// ## Leaks /// ## Leaks
@@ -9,18 +7,6 @@
/// ///
/// The execution time of the function grows approx. linear with the length of the input. This is /// The execution time of the function grows approx. linear with the length of the input. This is
/// considered safe. /// considered safe.
///
/// ## Examples
///
/// ```rust
/// use rosenpass_constant_time::memcmp;
/// let a = [0, 0, 0, 0];
/// let b = [0, 0, 0, 1];
/// let c = [0, 0, 0];
/// assert!(memcmp(&a, &a));
/// assert!(!memcmp(&a, &b));
/// assert!(!memcmp(&a, &c));
/// ```
#[inline] #[inline]
pub fn memcmp(a: &[u8], b: &[u8]) -> bool { pub fn memcmp(a: &[u8], b: &[u8]) -> bool {
a.len() == b.len() && unsafe { memsec::memeq(a.as_ptr(), b.as_ptr(), a.len()) } a.len() == b.len() && unsafe { memsec::memeq(a.as_ptr(), b.as_ptr(), a.len()) }

View File

@@ -1,5 +1,3 @@
//! xor
use core::hint::black_box; use core::hint::black_box;
use rosenpass_to::{with_destination, To}; use rosenpass_to::{with_destination, To};

49
flake.lock generated
View File

@@ -2,17 +2,15 @@
"nodes": { "nodes": {
"fenix": { "fenix": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": ["nixpkgs"],
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src" "rust-analyzer-src": "rust-analyzer-src"
}, },
"locked": { "locked": {
"lastModified": 1728282832, "lastModified": 1712298178,
"narHash": "sha256-I7AbcwGggf+CHqpyd/9PiAjpIBGTGx5woYHqtwxaV7I=", "narHash": "sha256-590fpCPXYAkaAeBz/V91GX4/KGzPObdYtqsTWzT6AhI=",
"owner": "nix-community", "owner": "nix-community",
"repo": "fenix", "repo": "fenix",
"rev": "1ec71be1f4b8f3105c5d38da339cb061fefc43f4", "rev": "569b5b5781395da08e7064e825953c548c26af76",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -26,11 +24,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1726560853, "lastModified": 1710146030,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -39,18 +37,36 @@
"type": "github" "type": "github"
} }
}, },
"naersk": {
"inputs": {
"nixpkgs": ["nixpkgs"]
},
"locked": {
"lastModified": 1698420672,
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
"owner": "nix-community",
"repo": "naersk",
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "naersk",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1728193676, "lastModified": 1712168706,
"narHash": "sha256-PbDWAIjKJdlVg+qQRhzdSor04bAPApDqIv2DofTyynk=", "narHash": "sha256-XP24tOobf6GGElMd0ux90FEBalUtw6NkBSVh/RlA6ik=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "ecbc1ca8ffd6aea8372ad16be9ebbb39889e55b6", "rev": "1487bdea619e4a7a53a4590c475deabb5a9d1bfb",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.05", "ref": "nixos-23.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -59,17 +75,18 @@
"inputs": { "inputs": {
"fenix": "fenix", "fenix": "fenix",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"naersk": "naersk",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
} }
}, },
"rust-analyzer-src": { "rust-analyzer-src": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1728249780, "lastModified": 1712156296,
"narHash": "sha256-J269DvCI5dzBmPrXhAAtj566qt0b22TJtF3TIK+tMsI=", "narHash": "sha256-St7ZQrkrr5lmQX9wC1ZJAFxL8W7alswnyZk9d1se3Us=",
"owner": "rust-lang", "owner": "rust-lang",
"repo": "rust-analyzer", "repo": "rust-analyzer",
"rev": "2b750da1a1a2c1d2c70896108d7096089842d877", "rev": "8e581ac348e223488622f4d3003cb2bd412bf27e",
"type": "github" "type": "github"
}, },
"original": { "original": {

410
flake.nix
View File

@@ -1,8 +1,12 @@
{ {
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
# for quicker rust builds
naersk.url = "github:nix-community/naersk";
naersk.inputs.nixpkgs.follows = "nixpkgs";
# for rust nightly with llvm-tools-preview # for rust nightly with llvm-tools-preview
fenix.url = "github:nix-community/fenix"; fenix.url = "github:nix-community/fenix";
fenix.inputs.nixpkgs.follows = "nixpkgs"; fenix.inputs.nixpkgs.follows = "nixpkgs";
@@ -11,15 +15,6 @@
outputs = { self, nixpkgs, flake-utils, ... }@inputs: outputs = { self, nixpkgs, flake-utils, ... }@inputs:
nixpkgs.lib.foldl (a: b: nixpkgs.lib.recursiveUpdate a b) { } [ nixpkgs.lib.foldl (a: b: nixpkgs.lib.recursiveUpdate a b) { } [
#
### Export the overlay.nix from this flake ###
#
{
overlays.default = import ./overlay.nix;
}
# #
### Actual Rosenpass Package and Docker Container Images ### ### Actual Rosenpass Package and Docker Container Images ###
# #
@@ -35,39 +30,310 @@
] ]
(system: (system:
let let
scoped = (scope: scope.result);
lib = nixpkgs.lib;
# normal nixpkgs # normal nixpkgs
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
};
# apply our own overlay, overriding/inserting our packages as defined in ./pkgs # parsed Cargo.toml
overlays = [ self.overlays.default ]; cargoToml = builtins.fromTOML (builtins.readFile ./rosenpass/Cargo.toml);
# source files relevant for rust
src = scoped rec {
# File suffices to include
extensions = [
"lock"
"rs"
"toml"
];
# Files to explicitly include
files = [
"to/README.md"
];
src = ./.;
filter = (path: type: scoped rec {
inherit (lib) any id removePrefix hasSuffix;
anyof = (any id);
basename = baseNameOf (toString path);
relative = removePrefix (toString src + "/") (toString path);
result = anyof [
(type == "directory")
(any (ext: hasSuffix ".${ext}" basename) extensions)
(any (file: file == relative) files)
];
});
result = pkgs.lib.sources.cleanSourceWith { inherit src filter; };
};
# a function to generate a nix derivation for rosenpass against any
# given set of nixpkgs
rosenpassDerivation = p:
let
# whether we want to build a statically linked binary
isStatic = p.targetPlatform.isStatic;
# the rust target of `p`
target = p.rust.toRustTargetSpec p.targetPlatform;
# convert a string to shout case
shout = string: builtins.replaceStrings [ "-" ] [ "_" ] (pkgs.lib.toUpper string);
# suitable Rust toolchain
toolchain = with inputs.fenix.packages.${system}; combine [
stable.cargo
stable.rustc
targets.${target}.stable.rust-std
];
# naersk with a custom toolchain
naersk = pkgs.callPackage inputs.naersk {
cargo = toolchain;
rustc = toolchain;
};
# used to trick the build.rs into believing that CMake was ran **again**
fakecmake = pkgs.writeScriptBin "cmake" ''
#! ${pkgs.stdenv.shell} -e
true
'';
in
naersk.buildPackage
{
# metadata and source
name = cargoToml.package.name;
version = cargoToml.package.version;
inherit src;
cargoBuildOptions = x: x ++ [ "-p" "rosenpass" ];
cargoTestOptions = x: x ++ [ "-p" "rosenpass" ];
doCheck = true;
nativeBuildInputs = with pkgs; [
p.stdenv.cc
cmake # for oqs build in the oqs-sys crate
mandoc # for the built-in manual
removeReferencesTo
rustPlatform.bindgenHook # for C-bindings in the crypto libs
];
buildInputs = with p; [ bash ];
override = x: {
preBuild =
# nix defaults to building for aarch64 _without_ the armv8-a crypto
# extensions, but liboqs depens on these
(lib.optionalString (system == "aarch64-linux") ''
NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"
''
);
# fortify is only compatible with dynamic linking
hardeningDisable = lib.optional isStatic "fortify";
};
overrideMain = x: {
# CMake detects that it was served a _foreign_ target dir, and CMake
# would be executed again upon the second build step of naersk.
# By adding our specially optimized CMake version, we reduce the cost
# of recompilation by 99 % while, while avoiding any CMake errors.
nativeBuildInputs = [ (lib.hiPrio fakecmake) ] ++ x.nativeBuildInputs;
# make sure that libc is linked, under musl this is not the case per
# default
preBuild = (lib.optionalString isStatic ''
NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -lc"
'');
};
# We want to build for a specific target...
CARGO_BUILD_TARGET = target;
# ... which might require a non-default linker:
"CARGO_TARGET_${shout target}_LINKER" =
let
inherit (p.stdenv) cc;
in
"${cc}/bin/${cc.targetPrefix}cc";
meta = with pkgs.lib;
{
inherit (cargoToml.package) description homepage;
license = with licenses; [ mit asl20 ];
maintainers = [ maintainers.wucke13 ];
platforms = platforms.all;
};
} // (lib.mkIf isStatic {
# otherwise pkg-config tries to link non-existent dynamic libs
# documented here: https://docs.rs/pkg-config/latest/pkg_config/
PKG_CONFIG_ALL_STATIC = true;
# tell rust to build everything statically linked
CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static";
});
# a function to generate a nix derivation for the rp helper against any
# given set of nixpkgs
rpDerivation = p:
let
# whether we want to build a statically linked binary
isStatic = p.targetPlatform.isStatic;
# the rust target of `p`
target = p.rust.toRustTargetSpec p.targetPlatform;
# convert a string to shout case
shout = string: builtins.replaceStrings [ "-" ] [ "_" ] (pkgs.lib.toUpper string);
# suitable Rust toolchain
toolchain = with inputs.fenix.packages.${system}; combine [
stable.cargo
stable.rustc
targets.${target}.stable.rust-std
];
# naersk with a custom toolchain
naersk = pkgs.callPackage inputs.naersk {
cargo = toolchain;
rustc = toolchain;
};
# used to trick the build.rs into believing that CMake was ran **again**
fakecmake = pkgs.writeScriptBin "cmake" ''
#! ${pkgs.stdenv.shell} -e
true
'';
in
naersk.buildPackage
{
# metadata and source
name = cargoToml.package.name;
version = cargoToml.package.version;
inherit src;
cargoBuildOptions = x: x ++ [ "-p" "rp" ];
cargoTestOptions = x: x ++ [ "-p" "rp" ];
doCheck = true;
nativeBuildInputs = with pkgs; [
p.stdenv.cc
cmake # for oqs build in the oqs-sys crate
mandoc # for the built-in manual
removeReferencesTo
rustPlatform.bindgenHook # for C-bindings in the crypto libs
];
buildInputs = with p; [ bash ];
override = x: {
preBuild =
# nix defaults to building for aarch64 _without_ the armv8-a crypto
# extensions, but liboqs depens on these
(lib.optionalString (system == "aarch64-linux") ''
NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -march=armv8-a+crypto"
''
);
# fortify is only compatible with dynamic linking
hardeningDisable = lib.optional isStatic "fortify";
};
overrideMain = x: {
# CMake detects that it was served a _foreign_ target dir, and CMake
# would be executed again upon the second build step of naersk.
# By adding our specially optimized CMake version, we reduce the cost
# of recompilation by 99 % while, while avoiding any CMake errors.
nativeBuildInputs = [ (lib.hiPrio fakecmake) ] ++ x.nativeBuildInputs;
# make sure that libc is linked, under musl this is not the case per
# default
preBuild = (lib.optionalString isStatic ''
NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -lc"
'');
};
# We want to build for a specific target...
CARGO_BUILD_TARGET = target;
# ... which might require a non-default linker:
"CARGO_TARGET_${shout target}_LINKER" =
let
inherit (p.stdenv) cc;
in
"${cc}/bin/${cc.targetPrefix}cc";
meta = with pkgs.lib;
{
inherit (cargoToml.package) description homepage;
license = with licenses; [ mit asl20 ];
maintainers = [ maintainers.wucke13 ];
platforms = platforms.all;
};
} // (lib.mkIf isStatic {
# otherwise pkg-config tries to link non-existent dynamic libs
# documented here: https://docs.rs/pkg-config/latest/pkg_config/
PKG_CONFIG_ALL_STATIC = true;
# tell rust to build everything statically linked
CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static";
});
# a function to generate a docker image based of rosenpass
rosenpassOCI = name: pkgs.dockerTools.buildImage rec {
inherit name;
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [ self.packages.${system}.${name} ];
pathsToLink = [ "/bin" ];
};
config.Cmd = [ "/bin/rosenpass" ];
}; };
in in
{ rec {
packages = { packages = rec {
default = pkgs.rosenpass; default = rosenpass;
rosenpass = pkgs.rosenpass; rosenpass = rosenpassDerivation pkgs;
rosenpass-oci-image = pkgs.rosenpass-oci-image; rp = rpDerivation pkgs;
rp = pkgs.rp; rosenpass-oci-image = rosenpassOCI "rosenpass";
release-package = pkgs.release-package; # derivation for the release
release-package =
# for good measure, we also offer to cross compile to Linux on Arm let
aarch64-linux-rosenpass-static = version = cargoToml.package.version;
pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rosenpass; package =
aarch64-linux-rp-static = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic.rp; if pkgs.hostPlatform.isLinux then
} packages.rosenpass-static
// else packages.rosenpass;
# We only offer static builds for linux, as this is not supported on OS X rp =
(nixpkgs.lib.attrsets.optionalAttrs pkgs.stdenv.isLinux { if pkgs.hostPlatform.isLinux then
rosenpass-static = pkgs.pkgsStatic.rosenpass; packages.rp-static
rosenpass-static-oci-image = pkgs.pkgsStatic.rosenpass-oci-image; else packages.rp;
rp-static = pkgs.pkgsStatic.rp; oci-image =
}); if pkgs.hostPlatform.isLinux then
packages.rosenpass-static-oci-image
else packages.rosenpass-oci-image;
in
pkgs.runCommandNoCC "lace-result" { }
''
mkdir {bin,$out}
tar -cvf $out/rosenpass-${system}-${version}.tar \
-C ${package} bin/rosenpass \
-C ${rp} bin/rp
cp ${oci-image} \
$out/rosenpass-oci-image-${system}-${version}.tar.gz
'';
} // (if pkgs.stdenv.isLinux then rec {
rosenpass-static = rosenpassDerivation pkgs.pkgsStatic;
rp-static = rpDerivation pkgs.pkgsStatic;
rosenpass-static-oci-image = rosenpassOCI "rosenpass-static";
} else { });
} }
)) ))
# #
### Linux specifics ### ### Linux specifics ###
# #
@@ -75,46 +341,88 @@
let let
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
# apply our own overlay, overriding/inserting our packages as defined in ./pkgs
overlays = [ self.overlays.default ];
}; };
packages = self.packages.${system};
in in
{ {
#
### Whitepaper ###
#
packages.whitepaper =
let
tlsetup = (pkgs.texlive.combine {
inherit (pkgs.texlive) scheme-basic acmart amsfonts ccicons
csquotes csvsimple doclicense fancyvrb fontspec gobble
koma-script ifmtarg latexmk lm markdown mathtools minted noto
nunito pgf soul unicode-math lualatex-math paralist
gitinfo2 eso-pic biblatex biblatex-trad biblatex-software
xkeyval xurl xifthen biber;
});
in
pkgs.stdenvNoCC.mkDerivation {
name = "whitepaper";
src = ./papers;
nativeBuildInputs = with pkgs; [
ncurses # tput
python3Packages.pygments
tlsetup # custom tex live scheme
which
];
buildPhase = ''
export HOME=$(mktemp -d)
latexmk -r tex/CI.rc
'';
installPhase = ''
mkdir -p $out
mv *.pdf readme.md $out/
'';
};
#
### Reading materials ###
#
packages.whitepaper = pkgs.whitepaper;
# #
### Proof and Proof Tools ### ### Proof and Proof Tools ###
# #
packages.proverif-patched = pkgs.proverif-patched; packages.proverif-patched = pkgs.proverif.overrideAttrs (old: {
packages.proof-proverif = pkgs.proof-proverif; postInstall = ''
install -D -t $out/lib cryptoverif.pvl
'';
});
packages.proof-proverif = pkgs.stdenv.mkDerivation {
name = "rosenpass-proverif-proof";
version = "unstable";
src = pkgs.lib.sources.sourceByRegex ./. [
"analyze.sh"
"marzipan(/marzipan.awk)?"
"analysis(/.*)?"
];
nativeBuildInputs = [ pkgs.proverif pkgs.graphviz ];
CRYPTOVERIF_LIB = packages.proverif-patched + "/lib/cryptoverif.pvl";
installPhase = ''
mkdir -p $out
bash analyze.sh -color -html $out
'';
};
# #
### Devshells ### ### Devshells ###
# #
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
inherit (pkgs.proof-proverif) CRYPTOVERIF_LIB; inherit (packages.proof-proverif) CRYPTOVERIF_LIB;
inputsFrom = [ pkgs.rosenpass ]; inputsFrom = [ packages.default ];
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
inputs.fenix.packages.${system}.complete.toolchain
cmake # override the fakecmake from the main step above
cargo-release cargo-release
clippy clippy
rustfmt
nodePackages.prettier nodePackages.prettier
nushell # for the .ci/gen-workflow-files.nu script nushell # for the .ci/gen-workflow-files.nu script
proverif-patched packages.proverif-patched
]; ];
}; };
devShells.coverage = pkgs.mkShell { devShells.coverage = pkgs.mkShell {
inputsFrom = [ pkgs.rosenpass ]; inputsFrom = [ packages.default ];
nativeBuildInputs = [ nativeBuildInputs = with pkgs; [ inputs.fenix.packages.${system}.complete.toolchain cargo-llvm-cov ];
inputs.fenix.packages.${system}.complete.toolchain
pkgs.cargo-llvm-cov
];
}; };

View File

@@ -14,7 +14,3 @@ rosenpass-cipher-traits = { workspace = true }
rosenpass-util = { workspace = true } rosenpass-util = { workspace = true }
oqs-sys = { workspace = true } oqs-sys = { workspace = true }
paste = { workspace = true } paste = { workspace = true }
[dev-dependencies]
rosenpass-secret-memory = { workspace = true }
rosenpass-constant-time = { workspace = true }

View File

@@ -1,42 +1,9 @@
//! Generic helpers for declaring bindings to liboqs kems
/// Generate bindings to a liboqs-provided KEM
macro_rules! oqs_kem { macro_rules! oqs_kem {
($name:ident) => { ::paste::paste!{ ($name:ident) => { ::paste::paste!{
#[doc = "Bindings for ::oqs_sys::kem::" [<"OQS_KEM" _ $name:snake>] "_*"]
mod [< $name:snake >] { mod [< $name:snake >] {
use rosenpass_cipher_traits::Kem; use rosenpass_cipher_traits::Kem;
use rosenpass_util::result::Guaranteed; use rosenpass_util::result::Guaranteed;
#[doc = "Bindings for ::oqs_sys::kem::" [<"OQS_KEM" _ $name:snake>] "_*"]
#[doc = ""]
#[doc = "# Examples"]
#[doc = ""]
#[doc = "```rust"]
#[doc = "use std::borrow::{Borrow, BorrowMut};"]
#[doc = "use rosenpass_cipher_traits::Kem;"]
#[doc = "use rosenpass_oqs::" $name:camel " as MyKem;"]
#[doc = "use rosenpass_secret_memory::{Secret, Public};"]
#[doc = ""]
#[doc = "rosenpass_secret_memory::secret_policy_try_use_memfd_secrets();"]
#[doc = ""]
#[doc = "// Recipient generates secret key, transfers pk to sender"]
#[doc = "let mut sk = Secret::<{ MyKem::SK_LEN }>::zero();"]
#[doc = "let mut pk = Public::<{ MyKem::PK_LEN }>::zero();"]
#[doc = "MyKem::keygen(sk.secret_mut(), pk.borrow_mut());"]
#[doc = ""]
#[doc = "// Sender generates ciphertext and local shared key, sends ciphertext to recipient"]
#[doc = "let mut shk_enc = Secret::<{ MyKem::SHK_LEN }>::zero();"]
#[doc = "let mut ct = Public::<{ MyKem::CT_LEN }>::zero();"]
#[doc = "MyKem::encaps(shk_enc.secret_mut(), ct.borrow_mut(), pk.borrow());"]
#[doc = ""]
#[doc = "// Recipient decapsulates ciphertext"]
#[doc = "let mut shk_dec = Secret::<{ MyKem::SHK_LEN }>::zero();"]
#[doc = "MyKem::decaps(shk_dec.secret_mut(), sk.secret(), ct.borrow());"]
#[doc = ""]
#[doc = "// Both parties end up with the same shared key"]
#[doc = "assert!(rosenpass_constant_time::compare(shk_enc.secret_mut(), shk_dec.secret_mut()) == 0);"]
#[doc = "```"]
pub enum [< $name:camel >] {} pub enum [< $name:camel >] {}
/// # Panic & Safety /// # Panic & Safety

View File

@@ -1,8 +1,3 @@
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
//! Bindings for liboqs used in Rosenpass
/// Call into a libOQS function
macro_rules! oqs_call { macro_rules! oqs_call {
($name:path, $($args:expr),*) => {{ ($name:path, $($args:expr),*) => {{
use oqs_sys::common::OQS_STATUS::*; use oqs_sys::common::OQS_STATUS::*;

View File

@@ -1,39 +0,0 @@
final: prev: {
#
### Actual rosenpass software ###
#
rosenpass = final.callPackage ./pkgs/rosenpass.nix { };
rosenpass-oci-image = final.callPackage ./pkgs/rosenpass-oci-image.nix { };
rp = final.callPackage ./pkgs/rosenpass.nix { package = "rp"; };
release-package = final.callPackage ./pkgs/release-package.nix { };
#
### Appendix ###
#
proverif-patched = prev.proverif.overrideAttrs (old: {
postInstall = ''
install -D -t $out/lib cryptoverif.pvl
'';
});
proof-proverif = final.stdenv.mkDerivation {
name = "rosenpass-proverif-proof";
version = "unstable";
src = final.lib.sources.sourceByRegex ./. [
"analyze.sh"
"marzipan(/marzipan.awk)?"
"analysis(/.*)?"
];
nativeBuildInputs = [ final.proverif final.graphviz ];
CRYPTOVERIF_LIB = final.proverif-patched + "/lib/cryptoverif.pvl";
installPhase = ''
mkdir -p $out
bash analyze.sh -color -html $out
'';
};
whitepaper = final.callPackage ./pkgs/whitepaper.nix { };
}

View File

@@ -1,27 +0,0 @@
{ lib, stdenvNoCC, runCommandNoCC, pkgsStatic, rosenpass, rosenpass-oci-image, rp } @ args:
let
version = rosenpass.version;
# select static packages on Linux, default packages otherwise
package =
if stdenvNoCC.hostPlatform.isLinux then
pkgsStatic.rosenpass
else args.rosenpass;
rp =
if stdenvNoCC.hostPlatform.isLinux then
pkgsStatic.rp
else args.rp;
oci-image =
if stdenvNoCC.hostPlatform.isLinux then
pkgsStatic.rosenpass-oci-image
else args.rosenpass-oci-image;
in
runCommandNoCC "lace-result" { } ''
mkdir {bin,$out}
tar -cvf $out/rosenpass-${stdenvNoCC.hostPlatform.system}-${version}.tar \
-C ${package} bin/rosenpass \
-C ${rp} bin/rp
cp ${oci-image} \
$out/rosenpass-oci-image-${stdenvNoCC.hostPlatform.system}-${version}.tar.gz
''

View File

@@ -1,11 +0,0 @@
{ dockerTools, buildEnv, rosenpass }:
dockerTools.buildImage {
name = rosenpass.name + "-oci";
copyToRoot = buildEnv {
name = "image-root";
paths = [ rosenpass ];
pathsToLink = [ "/bin" ];
};
config.Cmd = [ "/bin/rosenpass" ];
}

View File

@@ -1,78 +0,0 @@
{ lib, stdenv, rustPlatform, cmake, mandoc, removeReferencesTo, bash, package ? "rosenpass" }:
let
# whether we want to build a statically linked binary
isStatic = stdenv.targetPlatform.isStatic;
scoped = (scope: scope.result);
# source files relevant for rust
src = scoped rec {
# File suffices to include
extensions = [
"lock"
"rs"
"toml"
];
# Files to explicitly include
files = [
"to/README.md"
];
src = ../.;
filter = (path: type: scoped rec {
inherit (lib) any id removePrefix hasSuffix;
anyof = (any id);
basename = baseNameOf (toString path);
relative = removePrefix (toString src + "/") (toString path);
result = anyof [
(type == "directory")
(any (ext: hasSuffix ".${ext}" basename) extensions)
(any (file: file == relative) files)
];
});
result = lib.sources.cleanSourceWith { inherit src filter; };
};
# parsed Cargo.toml
cargoToml = builtins.fromTOML (builtins.readFile (src + "/rosenpass/Cargo.toml"));
in
rustPlatform.buildRustPackage {
name = cargoToml.package.name;
version = cargoToml.package.version;
inherit src;
cargoBuildOptions = [ "--package" package ];
cargoTestOptions = [ "--package" package ];
doCheck = true;
cargoLock = {
lockFile = src + "/Cargo.lock";
outputHashes = {
"memsec-0.6.3" = "sha256-4ri+IEqLd77cLcul3lZrmpDKj4cwuYJ8oPRAiQNGeLw=";
"uds-0.4.2" = "sha256-qlxr/iJt2AV4WryePIvqm/8/MK/iqtzegztNliR93W8=";
};
};
nativeBuildInputs = [
stdenv.cc
cmake # for oqs build in the oqs-sys crate
mandoc # for the built-in manual
removeReferencesTo
rustPlatform.bindgenHook # for C-bindings in the crypto libs
];
buildInputs = [ bash ];
hardeningDisable = lib.optional isStatic "fortify";
meta = {
inherit (cargoToml.package) description homepage;
license = with lib.licenses; [ mit asl20 ];
maintainers = [ lib.maintainers.wucke13 ];
platforms = lib.platforms.all;
};
}

View File

@@ -1,29 +0,0 @@
{ stdenvNoCC, texlive, ncurses, python3Packages, which }:
let
customTexLiveSetup = (texlive.combine {
inherit (texlive) acmart amsfonts biber biblatex biblatex-software
biblatex-trad ccicons csquotes csvsimple doclicense eso-pic fancyvrb
fontspec gitinfo2 gobble ifmtarg koma-script latexmk lm lualatex-math
markdown mathtools minted noto nunito paralist pgf scheme-basic soul
unicode-math upquote xifthen xkeyval xurl;
});
in
stdenvNoCC.mkDerivation {
name = "whitepaper";
src = ../papers;
nativeBuildInputs = [
ncurses # tput
python3Packages.pygments
customTexLiveSetup # custom tex live scheme
which
];
buildPhase = ''
export HOME=$(mktemp -d)
latexmk -r tex/CI.rc
'';
installPhase = ''
mkdir -p $out
mv *.pdf readme.md $out/
'';
}

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "rosenpass" name = "rosenpass"
version = "0.3.0-dev" version = "0.2.1"
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"] authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
@@ -51,8 +51,8 @@ mio = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
zerocopy = { workspace = true } zerocopy = { workspace = true }
home = { workspace = true } home = { workspace = true }
derive_builder = { workspace = true } derive_builder = {workspace = true}
rosenpass-wireguard-broker = { workspace = true } rosenpass-wireguard-broker = {workspace = true}
zeroize = { workspace = true } zeroize = { workspace = true }
hex-literal = { workspace = true, optional = true } hex-literal = { workspace = true, optional = true }
hex = { workspace = true, optional = true } hex = { workspace = true, optional = true }
@@ -68,21 +68,15 @@ anyhow = { workspace = true }
criterion = { workspace = true } criterion = { workspace = true }
test_bin = { workspace = true } test_bin = { workspace = true }
stacker = { workspace = true } stacker = { workspace = true }
serial_test = { workspace = true } serial_test = {workspace = true}
procspawn = { workspace = true } procspawn = {workspace = true}
tempfile = { workspace = true } tempfile = { workspace = true }
rustix = { workspace = true } rustix = {workspace = true}
[features] [features]
default = ["experiment_api"] default = ["experiment_api"]
experiment_memfd_secret = ["rosenpass-wireguard-broker/experiment_memfd_secret"] experiment_memfd_secret = ["rosenpass-wireguard-broker/experiment_memfd_secret"]
experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"] experiment_libcrux = ["rosenpass-ciphers/experiment_libcrux"]
experiment_api = [ experiment_api = ["hex-literal", "uds", "command-fds", "rosenpass-util/experiment_file_descriptor_passing", "rosenpass-wireguard-broker/experiment_api"]
"hex-literal", internal_testing = []
"uds",
"command-fds",
"rosenpass-util/experiment_file_descriptor_passing",
"rosenpass-wireguard-broker/experiment_api",
]
internal_testing = []
internal_bin_gen_ipc_msg_types = ["hex", "heck"] internal_bin_gen_ipc_msg_types = ["hex", "heck"]

View File

@@ -154,6 +154,7 @@ pub struct AppServerTest {
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum AppServerIoSource { pub enum AppServerIoSource {
Socket(usize), Socket(usize),
#[cfg(feature = "experiment_api")]
PskBroker(Public<BROKER_ID_BYTES>), PskBroker(Public<BROKER_ID_BYTES>),
#[cfg(feature = "experiment_api")] #[cfg(feature = "experiment_api")]
MioManager(crate::api::mio::MioManagerIoSource), MioManager(crate::api::mio::MioManagerIoSource),
@@ -1208,12 +1209,15 @@ impl AppServer {
buf: &mut [u8], buf: &mut [u8],
io_source: AppServerIoSource, io_source: AppServerIoSource,
) -> anyhow::Result<Option<(usize, Endpoint)>> { ) -> anyhow::Result<Option<(usize, Endpoint)>> {
use crate::api::mio::MioManagerContext;
match io_source { match io_source {
AppServerIoSource::Socket(idx) => self AppServerIoSource::Socket(idx) => self
.try_recv_from_listen_socket(buf, idx) .try_recv_from_listen_socket(buf, idx)
.substitute_for_ioerr_wouldblock(None)? .substitute_for_ioerr_wouldblock(None)?
.ok(), .ok(),
#[cfg(feature = "experiment_api")]
AppServerIoSource::PskBroker(key) => self AppServerIoSource::PskBroker(key) => self
.brokers .brokers
.store .store
@@ -1223,13 +1227,9 @@ impl AppServer {
.map(|_| None), .map(|_| None),
#[cfg(feature = "experiment_api")] #[cfg(feature = "experiment_api")]
AppServerIoSource::MioManager(mmio_src) => { AppServerIoSource::MioManager(mmio_src) => MioManagerFocus(self)
use crate::api::mio::MioManagerContext; .poll_particular(mmio_src)
.map(|_| None),
MioManagerFocus(self)
.poll_particular(mmio_src)
.map(|_| None)
}
} }
} }

View File

@@ -134,10 +134,11 @@ pub const PEER_COOKIE_VALUE_EPOCH: Timing = 120.0;
// decryption for a second epoch // decryption for a second epoch
pub const BISCUIT_EPOCH: Timing = 300.0; pub const BISCUIT_EPOCH: Timing = 300.0;
// Retransmission pub constants; will retransmit for up to _ABORT seconds; // Retransmission pub constants; will retransmit for up to _ABORT ms; starting with a delay of
// starting with a delay of _DELAY_BEGIN seconds and increasing the delay // _DELAY_BEG ms and increasing the delay exponentially by a factor of
// exponentially by a factor of _DELAY_GROWTH up to _DELAY_END. // _DELAY_GROWTH up to _DELAY_END. An additional jitter factor of ±_DELAY_JITTER
// An additional jitter factor of ±_DELAY_JITTER is added. // is added.
pub const RETRANSMIT_ABORT: Timing = 120.0;
pub const RETRANSMIT_DELAY_GROWTH: Timing = 2.0; pub const RETRANSMIT_DELAY_GROWTH: Timing = 2.0;
pub const RETRANSMIT_DELAY_BEGIN: Timing = 0.5; pub const RETRANSMIT_DELAY_BEGIN: Timing = 0.5;
pub const RETRANSMIT_DELAY_END: Timing = 10.0; pub const RETRANSMIT_DELAY_END: Timing = 10.0;
@@ -1472,7 +1473,7 @@ impl IniHsPtr {
.min(ih.tx_count as f64), .min(ih.tx_count as f64),
) )
* RETRANSMIT_DELAY_JITTER * RETRANSMIT_DELAY_JITTER
* (rand::random::<f64>() + 1.0); * (rand::random::<f64>() + 1.0); // TODO: Replace with the rand crate
ih.tx_count += 1; ih.tx_count += 1;
Ok(()) Ok(())
} }

View File

@@ -20,9 +20,9 @@ rosenpass-ciphers = { workspace = true }
rosenpass-cipher-traits = { workspace = true } rosenpass-cipher-traits = { workspace = true }
rosenpass-secret-memory = { workspace = true } rosenpass-secret-memory = { workspace = true }
rosenpass-util = { workspace = true } rosenpass-util = { workspace = true }
rosenpass-wireguard-broker = { workspace = true } rosenpass-wireguard-broker = {workspace = true}
tokio = { workspace = true } tokio = {workspace = true}
[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] [target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies]
ctrlc-async = "3.2" ctrlc-async = "3.2"
@@ -35,8 +35,8 @@ netlink-packet-generic = "0.3"
netlink-packet-wireguard = "0.2" netlink-packet-wireguard = "0.2"
[dev-dependencies] [dev-dependencies]
tempfile = { workspace = true } tempfile = {workspace = true}
stacker = { workspace = true } stacker = {workspace = true}
[features] [features]
experiment_memfd_secret = [] experiment_memfd_secret = []

View File

@@ -21,6 +21,6 @@ log = { workspace = true }
[dev-dependencies] [dev-dependencies]
allocator-api2-tests = { workspace = true } allocator-api2-tests = { workspace = true }
tempfile = { workspace = true } tempfile = {workspace = true}
base64ct = { workspace = true } base64ct = {workspace = true}
procspawn = { workspace = true } procspawn = {workspace = true}

View File

@@ -1,13 +1,8 @@
//! Utilities for working with Base64
use base64ct::{Base64, Decoder as B64Reader, Encoder as B64Writer}; use base64ct::{Base64, Decoder as B64Reader, Encoder as B64Writer};
use zeroize::Zeroize; use zeroize::Zeroize;
use std::fmt::Display; use std::fmt::Display;
/// Formatter that displays its input as base64.
///
/// Use through [B64Display].
pub struct B64DisplayHelper<'a, const F: usize>(&'a [u8]); pub struct B64DisplayHelper<'a, const F: usize>(&'a [u8]);
impl<const F: usize> Display for B64DisplayHelper<'_, F> { impl<const F: usize> Display for B64DisplayHelper<'_, F> {
@@ -20,25 +15,7 @@ impl<const F: usize> Display for B64DisplayHelper<'_, F> {
} }
} }
/// Extension trait that can be used to display values as Base64
///
/// # Examples
///
/// ```
/// use rosenpass_util::b64::B64Display;
///
/// let a = vec![0,1,2,3,4,5];
/// assert_eq!(
/// format!("{}", a.fmt_b64::<10>()), // Maximum size of the encoded buffer
/// "AAECAwQF",
/// );
/// ```
pub trait B64Display { pub trait B64Display {
/// Display this value as base64
///
/// # Examples
///
/// See [B64Display].
fn fmt_b64<const F: usize>(&self) -> B64DisplayHelper<F>; fn fmt_b64<const F: usize>(&self) -> B64DisplayHelper<F>;
} }
@@ -54,11 +31,6 @@ impl<T: AsRef<[u8]>> B64Display for T {
} }
} }
/// Decode a base64-encoded value
///
/// # Examples
///
/// See [b64_encode].
pub fn b64_decode(input: &[u8], output: &mut [u8]) -> anyhow::Result<()> { pub fn b64_decode(input: &[u8], output: &mut [u8]) -> anyhow::Result<()> {
let mut reader = B64Reader::<Base64>::new(input).map_err(|e| anyhow::anyhow!(e))?; let mut reader = B64Reader::<Base64>::new(input).map_err(|e| anyhow::anyhow!(e))?;
match reader.decode(output) { match reader.decode(output) {
@@ -77,23 +49,6 @@ pub fn b64_decode(input: &[u8], output: &mut [u8]) -> anyhow::Result<()> {
} }
} }
/// Encode a value as base64.
///
/// ```
/// use rosenpass_util::b64::{b64_encode, b64_decode};
///
/// let bytes = b"Hello World";
///
/// let mut encoder_buffer = [0u8; 64];
/// let encoded = b64_encode(bytes, &mut encoder_buffer)?;
///
/// let mut bytes_decoded = [0u8; 11];
/// b64_decode(encoded.as_bytes(), &mut bytes_decoded);
/// assert_eq!(bytes, &bytes_decoded);
///
/// Ok::<(), anyhow::Error>(())
/// ```
///
pub fn b64_encode<'o>(input: &[u8], output: &'o mut [u8]) -> anyhow::Result<&'o str> { pub fn b64_encode<'o>(input: &[u8], output: &'o mut [u8]) -> anyhow::Result<&'o str> {
let mut writer = B64Writer::<Base64>::new(output).map_err(|e| anyhow::anyhow!(e))?; let mut writer = B64Writer::<Base64>::new(output).map_err(|e| anyhow::anyhow!(e))?;
writer.encode(input).map_err(|e| anyhow::anyhow!(e))?; writer.encode(input).map_err(|e| anyhow::anyhow!(e))?;

View File

@@ -1,163 +1,33 @@
//! Lazy construction of values
use crate::{ use crate::{
functional::ApplyExt, functional::ApplyExt,
mem::{SwapWithDefaultExt, SwapWithExt}, mem::{SwapWithDefaultExt, SwapWithExt},
}; };
/// Errors returned by [ConstructionSite::erect] #[derive(thiserror::Error, Debug)]
#[derive(thiserror::Error, Debug, Eq, PartialEq)]
pub enum ConstructionSiteErectError<E> { pub enum ConstructionSiteErectError<E> {
/// Attempted to erect an empty construction site
#[error("Construction site is void")] #[error("Construction site is void")]
IsVoid, IsVoid,
/// Attempted to erect a construction that is already standing
#[error("Construction is already built")] #[error("Construction is already built")]
AlreadyBuilt, AlreadyBuilt,
/// Other error
#[error("Other construction site error {0:?}")] #[error("Other construction site error {0:?}")]
Other(#[from] E), Other(#[from] E),
} }
/// A type that can build some other type
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::Build;
/// use anyhow::{Context, Result};
///
/// #[derive(Eq, PartialEq, Debug)]
/// struct Person {
/// pub fav_pokemon: String,
/// pub fav_number: u8,
/// }
///
/// #[derive(Default, Clone)]
/// struct PersonBuilder {
/// pub fav_pokemon: Option<String>,
/// pub fav_number: Option<u8>,
/// }
///
/// impl Build<Person> for &PersonBuilder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<Person, Self::Error> {
/// let fav_pokemon = self.fav_pokemon.clone().context("Missing fav pokemon")?;
/// let fav_number = self.fav_number.context("Missing fav number")?;
/// Ok(Person {
/// fav_pokemon,
/// fav_number,
/// })
/// }
/// }
///
/// let mut person_builder = PersonBuilder::default();
/// assert!(person_builder.build().is_err());
///
/// person_builder.fav_pokemon = Some("Krabby".to_owned());
/// person_builder.fav_number = Some(0);
/// assert_eq!(
/// person_builder.build().unwrap(),
/// Person {
/// fav_pokemon: "Krabby".to_owned(),
/// fav_number: 0
/// }
/// );
/// ```
pub trait Build<T>: Sized { pub trait Build<T>: Sized {
/// Error returned by the builder
type Error; type Error;
/// Build the type
///
/// # Examples
///
/// See [Self].
fn build(self) -> Result<T, Self::Error>; fn build(self) -> Result<T, Self::Error>;
} }
/// A type that can be incrementally built from a type that can [Build] it #[derive(Debug)]
///
/// This is similar to an option, where [Self::Void] is [std::Option::None],
/// [Self::Product] is [std::Option::Some], except that there is a third
/// intermediate state [Self::Builder] that represents a Some/Product value
/// in the process of being made.
///
/// # Examples
///
/// ```
/// use std::borrow::Borrow;
/// use rosenpass_util::build::{ConstructionSite, Build};
/// use anyhow::{Context, Result};
///
/// #[derive(Eq, PartialEq, Debug)]
/// struct Person {
/// pub fav_pokemon: String,
/// pub fav_number: u8,
/// }
///
/// #[derive(Eq, PartialEq, Default, Clone, Debug)]
/// struct PersonBuilder {
/// pub fav_pokemon: Option<String>,
/// pub fav_number: Option<u8>,
/// }
///
/// impl Build<Person> for &PersonBuilder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<Person, Self::Error> {
/// let fav_pokemon = self.fav_pokemon.clone().context("Missing fav pokemon")?;
/// let fav_number = self.fav_number.context("Missing fav number")?;
/// Ok(Person {
/// fav_pokemon,
/// fav_number,
/// })
/// }
/// }
///
/// impl Build<Person> for PersonBuilder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<Person, Self::Error> {
/// self.borrow().build()
/// }
/// }
///
/// // Allocate the construction site
/// let mut site = ConstructionSite::void();
///
/// // Start construction
/// site = ConstructionSite::Builder(PersonBuilder::default());
///
/// // Use the builder to build the value
/// site.builder_mut().unwrap().fav_pokemon = Some("Krabby".to_owned());
/// site.builder_mut().unwrap().fav_number = Some(0);
///
/// // Use `erect` to call Build::build
/// site.erect();
///
/// assert_eq!(
/// site,
/// ConstructionSite::Product(Person {
/// fav_pokemon: "Krabby".to_owned(),
/// fav_number: 0
/// }),
/// );
/// ```
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum ConstructionSite<Builder, T> pub enum ConstructionSite<Builder, T>
where where
Builder: Build<T>, Builder: Build<T>,
{ {
/// The site is empty
Void, Void,
/// The site is being built
Builder(Builder), Builder(Builder),
/// The site has been built and is now finished
Product(T), Product(T),
} }
/// Initializes the construction site as [ConstructionSite::Void]
impl<Builder, T> Default for ConstructionSite<Builder, T> impl<Builder, T> Default for ConstructionSite<Builder, T>
where where
Builder: Build<T>, Builder: Build<T>,
@@ -171,189 +41,22 @@ impl<Builder, T> ConstructionSite<Builder, T>
where where
Builder: Build<T>, Builder: Build<T>,
{ {
/// Initializes the construction site as [ConstructionSite::Void]
///
/// # Examples
///
/// See [Self].
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// assert_eq!(
/// ConstructionSite::<Builder, House>::void(),
/// ConstructionSite::Void,
/// );
/// ```
pub fn void() -> Self { pub fn void() -> Self {
Self::Void Self::Void
} }
/// Initialize the construction site from its builder
///
/// # Examples
///
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// assert_eq!(
/// ConstructionSite::<Builder, House>::new(Builder),
/// ConstructionSite::Builder(Builder),
/// );
/// ```
pub fn new(builder: Builder) -> Self { pub fn new(builder: Builder) -> Self {
Self::Builder(builder) Self::Builder(builder)
} }
/// Initialize the construction site from its product
///
/// # Examples
///
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// assert_eq!(
/// ConstructionSite::<Builder, House>::from_product(House),
/// ConstructionSite::Product(House),
/// );
/// ```
pub fn from_product(value: T) -> Self { pub fn from_product(value: T) -> Self {
Self::Product(value) Self::Product(value)
} }
/// Extract the construction site and replace it with [Self::Void]
///
/// # Examples
///
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// let mut a = ConstructionSite::<Builder, House>::from_product(House);
/// let a_backup = a.clone();
///
/// let b = a.take();
/// assert_eq!(a, ConstructionSite::void());
/// assert_eq!(b, ConstructionSite::Product(House));
/// ```
pub fn take(&mut self) -> Self { pub fn take(&mut self) -> Self {
self.swap_with_default() self.swap_with_default()
} }
/// Apply the given function to Self, temporarily converting
/// the mutable reference into an owned value.
///
/// This is useful if you have some function that needs to modify
/// the construction site as an owned value but all you have is a reference.
///
/// # Examples
///
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House(u32);
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder(u32);
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House(self.0))
/// }
/// }
///
/// #[derive(Debug, PartialEq, Eq)]
/// enum FancyMatchState {
/// New,
/// Built,
/// Increment,
/// };
///
/// fn fancy_match(site: &mut ConstructionSite<Builder, House>, def: u32) -> FancyMatchState {
/// site.modify_taken_with_return(|site| {
/// use ConstructionSite as C;
/// use FancyMatchState as F;
/// let (prod, state) = match site {
/// C::Void => (House(def), F::New),
/// C::Builder(b) => (b.build().unwrap(), F::Built),
/// C::Product(House(v)) => (House(v + 1), F::Increment),
/// };
/// let prod = ConstructionSite::from_product(prod);
/// (prod, state)
/// })
/// }
///
/// let mut a = ConstructionSite::void();
/// let r = fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(42)));
/// assert_eq!(r, FancyMatchState::New);
///
/// let mut a = ConstructionSite::new(Builder(13));
/// let r = fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(13)));
/// assert_eq!(r, FancyMatchState::Built);
///
/// let r = fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(14)));
/// assert_eq!(r, FancyMatchState::Increment);
/// ```
pub fn modify_taken_with_return<R, F>(&mut self, f: F) -> R pub fn modify_taken_with_return<R, F>(&mut self, f: F) -> R
where where
F: FnOnce(Self) -> (Self, R), F: FnOnce(Self) -> (Self, R),
@@ -363,53 +66,6 @@ where
res res
} }
/// Apply the given function to Self, temporarily converting
/// the mutable reference into an owned value.
///
/// This is useful if you have some function that needs to modify
/// the construction site as an owned value but all you have is a reference.
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House(u32);
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder(u32);
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House(self.0))
/// }
/// }
///
/// fn fancy_match(site: &mut ConstructionSite<Builder, House>, def: u32) {
/// site.modify_taken(|site| {
/// use ConstructionSite as C;
/// let prod = match site {
/// C::Void => House(def),
/// C::Builder(b) => b.build().unwrap(),
/// C::Product(House(v)) => House(v + 1),
/// };
/// ConstructionSite::from_product(prod)
/// })
/// }
///
/// let mut a = ConstructionSite::void();
/// fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(42)));
///
/// let mut a = ConstructionSite::new(Builder(13));
/// fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(13)));
///
/// fancy_match(&mut a, 42);
/// assert_eq!(a, ConstructionSite::Product(House(14)));
/// ```
pub fn modify_taken<F>(&mut self, f: F) pub fn modify_taken<F>(&mut self, f: F)
where where
F: FnOnce(Self) -> Self, F: FnOnce(Self) -> Self,
@@ -417,42 +73,6 @@ where
self.take().apply(f).swap_with_mut(self) self.take().apply(f).swap_with_mut(self)
} }
/// If this constructions site contains [Self::Builder], call the inner [Build]'s [Build::build]
/// and have the construction site contain a product.
///
/// # Examples
///
/// See [Self].
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build, ConstructionSiteErectError};
/// use std::convert::Infallible;
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = Infallible;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// let mut a = ConstructionSite::<Builder, House>::void();
/// assert_eq!(a.erect(), Err(ConstructionSiteErectError::IsVoid));
/// assert_eq!(a, ConstructionSite::void());
///
/// let mut a = ConstructionSite::<Builder, House>::from_product(House);
/// assert_eq!(a.erect(), Err(ConstructionSiteErectError::AlreadyBuilt));
/// assert_eq!(a, ConstructionSite::from_product(House));
///
/// let mut a = ConstructionSite::<Builder, House>::new(Builder);
/// a.erect().unwrap();
/// assert_eq!(a, ConstructionSite::from_product(House));
/// ```
#[allow(clippy::result_unit_err)] #[allow(clippy::result_unit_err)]
pub fn erect(&mut self) -> Result<(), ConstructionSiteErectError<Builder::Error>> { pub fn erect(&mut self) -> Result<(), ConstructionSiteErectError<Builder::Error>> {
self.modify_taken_with_return(|site| { self.modify_taken_with_return(|site| {
@@ -478,31 +98,6 @@ where
/// Returns `true` if the construction site is [`Void`]. /// Returns `true` if the construction site is [`Void`].
/// ///
/// [`Void`]: ConstructionSite::Void /// [`Void`]: ConstructionSite::Void
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// type Site = ConstructionSite<Builder, House>;
///
/// assert_eq!(Site::Void.is_void(), true);
/// assert_eq!(Site::Builder(Builder).is_void(), false);
/// assert_eq!(Site::Product(House).is_void(), false);
/// ```
#[must_use] #[must_use]
pub fn is_void(&self) -> bool { pub fn is_void(&self) -> bool {
matches!(self, Self::Void) matches!(self, Self::Void)
@@ -511,95 +106,19 @@ where
/// Returns `true` if the construction site is [`InProgress`]. /// Returns `true` if the construction site is [`InProgress`].
/// ///
/// [`InProgress`]: ConstructionSite::InProgress /// [`InProgress`]: ConstructionSite::InProgress
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// type Site = ConstructionSite<Builder, House>;
///
/// assert_eq!(Site::Void.in_progress(), false);
/// assert_eq!(Site::Builder(Builder).in_progress(), true);
/// assert_eq!(Site::Product(House).in_progress(), false);
/// ```
#[must_use] #[must_use]
pub fn in_progress(&self) -> bool { pub fn in_progess(&self) -> bool {
matches!(self, Self::Builder(..)) matches!(self, Self::Builder(..))
} }
/// Returns `true` if the construction site is [`Done`]. /// Returns `true` if the construction site is [`Done`].
/// ///
/// [`Done`]: ConstructionSite::Done /// [`Done`]: ConstructionSite::Done
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// type Site = ConstructionSite<Builder, House>;
///
/// assert_eq!(Site::Void.is_available(), false);
/// assert_eq!(Site::Builder(Builder).is_available(), false);
/// assert_eq!(Site::Product(House).is_available(), true);
/// ```
#[must_use] #[must_use]
pub fn is_available(&self) -> bool { pub fn is_available(&self) -> bool {
matches!(self, Self::Product(..)) matches!(self, Self::Product(..))
} }
/// Returns the value of [Self::Builder]
///
/// # Examples
///
/// ```
/// use rosenpass_util::build::{ConstructionSite, Build};
///
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct House;
/// #[derive(Debug, Eq, PartialEq, Clone, Copy)]
/// struct Builder;
///
/// impl Build<House> for Builder {
/// type Error = anyhow::Error;
///
/// fn build(self) -> Result<House, Self::Error> {
/// Ok(House)
/// }
/// }
///
/// type Site = ConstructionSite<Builder, House>;
///
/// assert_eq!(Site::Void.into_builder(), None);
/// assert_eq!(Site::Builder(Builder).into_builder(), Some(Builder));
/// assert_eq!(Site::Product(House).into_builder(), None);
/// ```
pub fn into_builder(self) -> Option<Builder> { pub fn into_builder(self) -> Option<Builder> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {
@@ -608,11 +127,6 @@ where
} }
} }
/// Returns the value of [Self::Builder] as a reference
///
/// # Examples
///
/// See [Self::into_builder].
pub fn builder_ref(&self) -> Option<&Builder> { pub fn builder_ref(&self) -> Option<&Builder> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {
@@ -621,11 +135,6 @@ where
} }
} }
/// Returns the value of [Self::Builder] as a mutable reference
///
/// # Examples
///
/// Similar to [Self::into_builder].
pub fn builder_mut(&mut self) -> Option<&mut Builder> { pub fn builder_mut(&mut self) -> Option<&mut Builder> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {
@@ -634,11 +143,6 @@ where
} }
} }
/// Returns the value of [Self::Product]
///
/// # Examples
///
/// Similar to [Self::into_builder].
pub fn into_product(self) -> Option<T> { pub fn into_product(self) -> Option<T> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {
@@ -647,11 +151,6 @@ where
} }
} }
/// Returns the value of [Self::Product] as a reference
///
/// # Examples
///
/// Similar to [Self::into_builder].
pub fn product_ref(&self) -> Option<&T> { pub fn product_ref(&self) -> Option<&T> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {
@@ -660,11 +159,6 @@ where
} }
} }
/// Returns the value of [Self::Product] as a mutable reference
///
/// # Examples
///
/// Similar to [Self::into_builder].
pub fn product_mut(&mut self) -> Option<&mut T> { pub fn product_mut(&mut self) -> Option<&mut T> {
use ConstructionSite as S; use ConstructionSite as S;
match self { match self {

View File

@@ -1,5 +1,3 @@
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
pub mod b64; pub mod b64;

View File

@@ -12,7 +12,7 @@ readme = "readme.md"
[dependencies] [dependencies]
thiserror = { workspace = true } thiserror = { workspace = true }
zerocopy = { workspace = true } zerocopy = { workspace = true }
rosenpass-secret-memory = { workspace = true } rosenpass-secret-memory = {workspace = true}
# Privileged only # Privileged only
wireguard-uapi = { workspace = true } wireguard-uapi = { workspace = true }
@@ -24,20 +24,20 @@ anyhow = { workspace = true }
clap = { workspace = true } clap = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
log = { workspace = true } log = { workspace = true }
derive_builder = { workspace = true } derive_builder = {workspace = true}
postcard = { workspace = true } postcard = {workspace = true}
# Problem in CI, unknown reasons: dependency (libc) specified without providing a local path, Git repository, version, or workspace dependency to use # Problem in CI, unknown reasons: dependency (libc) specified without providing a local path, Git repository, version, or workspace dependency to use
# Maybe something about the combination of features and optional crates? # Maybe something about the combination of features and optional crates?
rustix = { version = "0.38.37", optional = true } rustix = { version = "0.38.37", optional = true }
libc = { version = "0.2", optional = true } libc = { version = "0.2", optional = true }
# Mio broker client # Mio broker client
mio = { workspace = true } mio = { workspace = true }
rosenpass-util = { workspace = true } rosenpass-util = { workspace = true }
[dev-dependencies] [dev-dependencies]
rand = { workspace = true } rand = {workspace = true}
procspawn = { workspace = true } procspawn = {workspace = true}
[features] [features]
experiment_api = ["rustix", "libc"] experiment_api = ["rustix", "libc"]
@@ -49,7 +49,7 @@ path = "src/bin/priviledged.rs"
test = false test = false
doc = false doc = false
required-features = ["experiment_api"] required-features = ["experiment_api"]
cfg = { target_os = "linux" } cfg = { target_os = "linux" }
[[bin]] [[bin]]
name = "rosenpass-wireguard-broker-socket-handler" name = "rosenpass-wireguard-broker-socket-handler"
@@ -57,4 +57,4 @@ test = false
path = "src/bin/socket_handler.rs" path = "src/bin/socket_handler.rs"
doc = false doc = false
required-features = ["experiment_api"] required-features = ["experiment_api"]
cfg = { target_os = "linux" } cfg = { target_os = "linux" }