mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-18 21:34:37 +03:00
Compare commits
1 Commits
dev/rustif
...
dev/wucke1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4722d7eeb |
82
Cargo.lock
generated
82
Cargo.lock
generated
@@ -186,7 +186,7 @@ checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap_lex 0.2.4",
|
"clap_lex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
@@ -194,34 +194,6 @@ dependencies = [
|
|||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "4.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"clap_derive",
|
|
||||||
"clap_lex 0.3.2",
|
|
||||||
"is-terminal",
|
|
||||||
"once_cell",
|
|
||||||
"strsim",
|
|
||||||
"termcolor",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_derive"
|
|
||||||
version = "4.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0"
|
|
||||||
dependencies = [
|
|
||||||
"heck",
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -231,15 +203,6 @@ dependencies = [
|
|||||||
"os_str_bytes",
|
"os_str_bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_lex"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
|
|
||||||
dependencies = [
|
|
||||||
"os_str_bytes",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cmake"
|
name = "cmake"
|
||||||
version = "0.1.49"
|
version = "0.1.49"
|
||||||
@@ -466,12 +429,6 @@ version = "0.12.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "heck"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
@@ -819,30 +776,6 @@ dependencies = [
|
|||||||
"plotters-backend",
|
"plotters-backend",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error-attr",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error-attr"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.51"
|
version = "1.0.51"
|
||||||
@@ -950,13 +883,6 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rp"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"clap 4.1.8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.21"
|
version = "0.1.21"
|
||||||
@@ -1250,12 +1176,6 @@ version = "0.2.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.3.2"
|
version = "2.3.2"
|
||||||
|
|||||||
39
Cargo.toml
39
Cargo.toml
@@ -1,6 +1,35 @@
|
|||||||
[workspace]
|
[package]
|
||||||
|
name = "rosenpass"
|
||||||
|
version = "0.1.1"
|
||||||
|
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
description = "Build post-quantum-secure VPNs with WireGuard!"
|
||||||
|
homepage = "https://rosenpass.eu/"
|
||||||
|
repository = "https://github.com/rosenpass/rosenpass"
|
||||||
|
readme = "readme.md"
|
||||||
|
|
||||||
members = [
|
[[bench]]
|
||||||
"rosenpass",
|
name = "handshake"
|
||||||
"rp",
|
harness = false
|
||||||
]
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = { version = "1.0.52", features = ["backtrace"] }
|
||||||
|
base64 = "0.13.0"
|
||||||
|
clap = { version = "3.0.0", features = ["yaml"] }
|
||||||
|
static_assertions = "1.1.0"
|
||||||
|
memoffset = "0.6.5"
|
||||||
|
libsodium-sys-stable = { version = "1.19.26", features = ["use-pkg-config"] }
|
||||||
|
oqs-sys = { version = "0.7.1", default-features = false, features = ['classic_mceliece', 'kyber'] }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
thiserror = "1.0.38"
|
||||||
|
paste = "1.0.11"
|
||||||
|
log = { version = "0.4.17", optional = true }
|
||||||
|
env_logger = { version = "0.10.0", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3.5"
|
||||||
|
test_bin = "0.4.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["log", "env_logger"]
|
||||||
|
|||||||
27
flake.nix
27
flake.nix
@@ -66,9 +66,27 @@
|
|||||||
# given set of nixpkgs
|
# given set of nixpkgs
|
||||||
rpDerivation = p:
|
rpDerivation = p:
|
||||||
let
|
let
|
||||||
isStatic = p.stdenv.hostPlatform.isStatic;
|
# 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
|
||||||
|
];
|
||||||
|
myRustPlatform = p.makeRustPlatform {
|
||||||
|
cargo = toolchain;
|
||||||
|
rustc = toolchain;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
p.rustPlatform.buildRustPackage {
|
myRustPlatform.buildRustPackage {
|
||||||
# metadata and source
|
# metadata and source
|
||||||
pname = cargoToml.package.name;
|
pname = cargoToml.package.name;
|
||||||
version = cargoToml.package.version;
|
version = cargoToml.package.version;
|
||||||
@@ -83,12 +101,17 @@
|
|||||||
pkg-config # let libsodium-sys-stable find libsodium
|
pkg-config # let libsodium-sys-stable find libsodium
|
||||||
removeReferencesTo
|
removeReferencesTo
|
||||||
rustPlatform.bindgenHook # for C-bindings in the crypto libs
|
rustPlatform.bindgenHook # for C-bindings in the crypto libs
|
||||||
|
pkgs.stdenv.cc # for Rust proc macro linking we need a non-cross compiler
|
||||||
];
|
];
|
||||||
buildInputs = with p; [ bash libsodium ];
|
buildInputs = with p; [ bash libsodium ];
|
||||||
|
|
||||||
# otherwise pkg-config tries to link non-existent dynamic libs
|
# otherwise pkg-config tries to link non-existent dynamic libs
|
||||||
PKG_CONFIG_ALL_STATIC = true;
|
PKG_CONFIG_ALL_STATIC = true;
|
||||||
|
|
||||||
|
CARGO_BUILD_TARGET = target;
|
||||||
|
# for final linking, a cross compiler needs to be used
|
||||||
|
"CARGO_TARGET_${shout target}_LINKER" = "${pkgs.stdenv.cc.targetPrefix}ld";
|
||||||
|
|
||||||
# nix defaults to building for aarch64 _without_ the armv8-a
|
# nix defaults to building for aarch64 _without_ the armv8-a
|
||||||
# crypto extensions, but liboqs depens on these
|
# crypto extensions, but liboqs depens on these
|
||||||
preBuild =
|
preBuild =
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ abstract: |
|
|||||||
Rosenpass inherits most security properties from Post-Quantum WireGuard (PQWG). The security properties mentioned here are covered by the symbolic analysis in the Rosenpass repository.
|
Rosenpass inherits most security properties from Post-Quantum WireGuard (PQWG). The security properties mentioned here are covered by the symbolic analysis in the Rosenpass repository.
|
||||||
|
|
||||||
## Secrecy
|
## Secrecy
|
||||||
Three key encapsulations using the keypairs `sski`/`spki`, `sskr`/`spkr`, and `eski`/`epki` provide secrecy (see Section \ref{variables} for an introduction of the variables). Their respective ciphertexts are called `scti`, `sctr`, and `ectr` and the resulting keys are called `spti`, `sptr`, `epti`. A single secure encapsulation is sufficient to provide secrecy. We use two different KEMs (Key Encapsulation Mechanisms; see section \ref{skem}): Kyber and Classic McEliece.
|
Three key encapsulations using the keypairs `sski`/`spki`, `sskr`/`spkr`, and `eski`/`epki` provide secrecy (see Section \ref{variables} for an introduction of the variables). Their respective ciphertexts are called `scti`, `sctr`, and `ectr` and the resulting keys are called `spti`, `sptr`, `epti`. A single secure encapsulation is sufficient to provide secrecy. We use two different KEMs (Key Encapsulation Methods; see section \ref{skem}): Kyber and Classic McEliece.
|
||||||
|
|
||||||
## Authenticity
|
## Authenticity
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "rosenpass"
|
|
||||||
version = "0.1.1"
|
|
||||||
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
|
||||||
edition = "2021"
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "Build post-quantum-secure VPNs with WireGuard!"
|
|
||||||
homepage = "https://rosenpass.eu/"
|
|
||||||
repository = "https://github.com/rosenpass/rosenpass"
|
|
||||||
readme = "../readme.md"
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "handshake"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow = { version = "1.0.52", features = ["backtrace"] }
|
|
||||||
base64 = "0.13.0"
|
|
||||||
clap = { version = "3.0.0", features = ["yaml"] }
|
|
||||||
static_assertions = "1.1.0"
|
|
||||||
memoffset = "0.6.5"
|
|
||||||
libsodium-sys-stable = { version = "1.19.26", features = ["use-pkg-config"] }
|
|
||||||
oqs-sys = { version = "0.7.1", default-features = false, features = ['classic_mceliece', 'kyber'] }
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
thiserror = "1.0.38"
|
|
||||||
paste = "1.0.11"
|
|
||||||
log = { version = "0.4.17", optional = true }
|
|
||||||
env_logger = { version = "0.10.0", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
criterion = "0.3.5"
|
|
||||||
test_bin = "0.4.0"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["log", "env_logger"]
|
|
||||||
352
rp
Executable file
352
rp
Executable file
@@ -0,0 +1,352 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# String formatting subsystem
|
||||||
|
|
||||||
|
formatting_init() {
|
||||||
|
endl=$'\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
enquote() {
|
||||||
|
while (( $# > 1 )); do
|
||||||
|
printf "%q " "${1}"; shift
|
||||||
|
done
|
||||||
|
if (( $# == 1 )); then
|
||||||
|
printf "%q" "${1}"; shift
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
multiline() {
|
||||||
|
# shellcheck disable=SC1004
|
||||||
|
echo "${1} " | awk '
|
||||||
|
function pm(a, b, l) {
|
||||||
|
return length(a) > l \
|
||||||
|
&& length(b) > l \
|
||||||
|
&& substr(a, 1, l+1) == substr(b, 1, l+1) \
|
||||||
|
? pm(a, b, l+1) : l;
|
||||||
|
}
|
||||||
|
|
||||||
|
!started && $0 !~ /^[ \t]*$/ {
|
||||||
|
started=1
|
||||||
|
match($0, /^[ \t]*/)
|
||||||
|
prefix=substr($0, 1, RLENGTH)
|
||||||
|
}
|
||||||
|
|
||||||
|
started {
|
||||||
|
print(substr($0, 1 + pm($0, prefix)));
|
||||||
|
}
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg() {
|
||||||
|
echo >&2 "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cleanup subsystem (sigterm)
|
||||||
|
|
||||||
|
cleanup_init() {
|
||||||
|
cleanup_actions=()
|
||||||
|
trap cleanup_apply exit
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_apply() {
|
||||||
|
local f
|
||||||
|
for f in "${cleanup_actions[@]}"; do
|
||||||
|
eval "${f}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
cleanup_actions+=("$(multiline "${1}")")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Transactional execution subsystem
|
||||||
|
|
||||||
|
frag_init() {
|
||||||
|
explain=0
|
||||||
|
frag_transaction=()
|
||||||
|
frag "
|
||||||
|
#! /bin/bash
|
||||||
|
set -e"
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_apply() {
|
||||||
|
local f
|
||||||
|
for f in "${frag_transaction[@]}"; do
|
||||||
|
if (( explain == 1 )); then
|
||||||
|
dbg "${f}"
|
||||||
|
fi
|
||||||
|
eval "${f}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
frag() {
|
||||||
|
frag_transaction+=("$(multiline "${1}")")
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_append() {
|
||||||
|
local len; len="${#frag_transaction[@]}"
|
||||||
|
frag_transaction=("${frag_transaction[@]:0:len-1}" "${frag_transaction[len-1]}${1}")
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_append_esc() {
|
||||||
|
frag_append " \\${endl}${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage documentation subsystem
|
||||||
|
usage_init() {
|
||||||
|
usagestack=("${script}")
|
||||||
|
}
|
||||||
|
|
||||||
|
usage_snap() {
|
||||||
|
echo "${#usagestack}"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage_restore() {
|
||||||
|
local n; n="${1}"
|
||||||
|
dbg REST "${1}"
|
||||||
|
usagestack=("${usagestack[@]:0:n-2}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
dbg "Usage: ${usagestack[*]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal() {
|
||||||
|
dbg "FATAL: $*"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
genkey() {
|
||||||
|
usagestack+=("PRIVATE_KEYS_DIR")
|
||||||
|
local skdir
|
||||||
|
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
local arg; arg="$1"; shift
|
||||||
|
case "${arg}" in
|
||||||
|
-h | -help | --help | help) usage; return 0 ;;
|
||||||
|
*) fatal "Unknown option ${arg}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -e "${skdir}"; then
|
||||||
|
fatal "PRIVATE_KEYS_DIR \"${skdir}\" already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag "
|
||||||
|
umask 077
|
||||||
|
mkdir -p $(enquote "${skdir}")
|
||||||
|
wg genkey > $(enquote "${skdir}"/wgsk)
|
||||||
|
$(enquote "${binary}") keygen \\
|
||||||
|
private-key $(enquote "${skdir}"/pqsk) \\
|
||||||
|
public-key $(enquote "${skdir}"/pqpk)"
|
||||||
|
}
|
||||||
|
|
||||||
|
pubkey() {
|
||||||
|
usagestack+=("PRIVATE_KEYS_DIR" "PUBLIC_KEYS_DIR")
|
||||||
|
local skdir pkdir
|
||||||
|
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||||
|
pkdir="${1%/}"; shift || fatal "Required positional argument: PUBLIC_KEYS_DIR"
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
local arg; arg="$1"; shift
|
||||||
|
case "${arg}" in
|
||||||
|
-h | -help | --help | help) usage; exit 0;;
|
||||||
|
*) fatal "Unknown option ${arg}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -e "${pkdir}"; then
|
||||||
|
fatal "PUBLIC_KEYS_DIR \"${pkdir}\" already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag "
|
||||||
|
mkdir -p $(enquote "${pkdir}")
|
||||||
|
wg pubkey < $(enquote "${skdir}"/wgsk) > $(enquote "${pkdir}/wgpk")
|
||||||
|
cp $(enquote "${skdir}"/pqpk) $(enquote "${pkdir}/pqpk")"
|
||||||
|
}
|
||||||
|
|
||||||
|
exchange() {
|
||||||
|
usagestack+=("PRIVATE_KEYS_DIR" "[dev <device>]" "[listen <ip>:<port>]" "[peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...")
|
||||||
|
local skdir dev lport
|
||||||
|
dev="${project_name}0"
|
||||||
|
skdir="${1%/}"; shift || fatal "Required positional argument: PRIVATE_KEYS_DIR"
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
local arg; arg="$1"; shift
|
||||||
|
case "${arg}" in
|
||||||
|
dev) dev="${1}"; shift || fatal "dev option requires parameter";;
|
||||||
|
peer) set -- "peer" "$@"; break;; # Parsed down below
|
||||||
|
listen)
|
||||||
|
local listen; listen="${1}";
|
||||||
|
lip="${listen%:*}";
|
||||||
|
lport="${listen/*:/}";
|
||||||
|
if [[ "$lip" = "$lport" ]]; then
|
||||||
|
lip="[0::0]"
|
||||||
|
fi
|
||||||
|
shift;;
|
||||||
|
-h | -help | --help | help) usage; return 0;;
|
||||||
|
*) fatal "Unknown option ${arg}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( $# == 0 )); then
|
||||||
|
fatal "Needs at least one peer specified"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag "
|
||||||
|
# Create the Wireguard interface
|
||||||
|
ip link add dev $(enquote "${dev}") type wireguard || true"
|
||||||
|
|
||||||
|
cleanup "
|
||||||
|
ip link del dev $(enquote "${dev}") || true"
|
||||||
|
|
||||||
|
frag "
|
||||||
|
ip link set dev $(enquote "${dev}") up"
|
||||||
|
|
||||||
|
frag "
|
||||||
|
# Deploy the classic wireguard private key
|
||||||
|
wg set $(enquote "${dev}") private-key $(enquote "${skdir}/wgsk")"
|
||||||
|
|
||||||
|
|
||||||
|
if test -n "${lport}"; then
|
||||||
|
frag_append "listen-port $(enquote "$(( lport + 1 ))")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag "
|
||||||
|
# Launch the post quantum wireguard exchange daemon
|
||||||
|
$(enquote "${binary}") exchange"
|
||||||
|
|
||||||
|
if (( verbose == 1 )); then
|
||||||
|
frag_append "verbose"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag_append_esc " private-key $(enquote "${skdir}/pqsk")"
|
||||||
|
frag_append_esc " public-key $(enquote "${skdir}/pqpk")"
|
||||||
|
|
||||||
|
if test -n "${lport}"; then
|
||||||
|
frag_append_esc " listen $(enquote "${lip}:${lport}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
usagestack+=("peer" "PUBLIC_KEYS_DIR endpoint IP:PORT")
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
shift; # Skip "peer" argument
|
||||||
|
|
||||||
|
local peerdir ip port keepalive allowedips
|
||||||
|
peerdir="${1%/}"; shift || fatal "Required peer argument: PUBLIC_KEYS_DIR"
|
||||||
|
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
local arg; arg="$1"; shift
|
||||||
|
case "${arg}" in
|
||||||
|
peer) set -- "peer" "$@"; break;; # Next peer
|
||||||
|
endpoint) ip="${1%:*}"; port="${1/*:/}"; shift;;
|
||||||
|
persistent-keepalive) keepalive="${1}"; shift;;
|
||||||
|
allowed-ips) allowedips="${1}"; shift;;
|
||||||
|
-h | -help | --help | help) usage; return 0;;
|
||||||
|
*) fatal "Unknown option ${arg}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Public key
|
||||||
|
frag_append_esc " peer public-key $(enquote "${peerdir}/pqpk")"
|
||||||
|
|
||||||
|
# PSK
|
||||||
|
local pskfile; pskfile="${peerdir}/psk"
|
||||||
|
if test -f "${pskfile}"; then
|
||||||
|
frag_append_esc " preshared-key $(enquote "${pskfile}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test -n "${ip}"; then
|
||||||
|
frag_append_esc " endpoint $(enquote "${ip}:${port}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
frag_append_esc " wireguard $(enquote "${dev}") $(enquote "$(cat "${peerdir}/wgpk")")"
|
||||||
|
|
||||||
|
if test -n "${ip}"; then
|
||||||
|
frag_append_esc " endpoint $(enquote "${ip}:$(( port + 1 ))")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "${keepalive}"; then
|
||||||
|
frag_append_esc " persistent-keepalive $(enquote "${keepalive}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "${allowedips}"; then
|
||||||
|
frag_append_esc " allowed-ips $(enquote "${allowedips}")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
find_rosenpass_binary() {
|
||||||
|
local binary; binary=""
|
||||||
|
if [[ -n "${gitdir}" ]]; then
|
||||||
|
# If rp is run from the git repo, use the newest build artifact
|
||||||
|
binary=$(
|
||||||
|
find "${gitdir}/result/bin/${project_name}" \
|
||||||
|
"${gitdir}"/target/{release,debug}/"${project_name}" \
|
||||||
|
-printf "%T@ %p\n" 2>/dev/null \
|
||||||
|
| sort -nr \
|
||||||
|
| awk 'NR==1 { print($2) }'
|
||||||
|
)
|
||||||
|
elif [[ -n "${nixdir}" ]]; then
|
||||||
|
# If rp is run from nix, use the nix-installed rosenpass version
|
||||||
|
binary="${nixdir}/bin/${project_name}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${binary}" ]]; then
|
||||||
|
binary="${project_name}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${binary}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
formatting_init
|
||||||
|
cleanup_init
|
||||||
|
usage_init
|
||||||
|
frag_init
|
||||||
|
|
||||||
|
project_name="rosenpass"
|
||||||
|
verbose=0
|
||||||
|
scriptdir="$(dirname "${script}")"
|
||||||
|
gitdir="$(git -C "${scriptdir}" rev-parse --show-toplevel 2>/dev/null)" || true
|
||||||
|
nixdir="$(readlink -f result/bin/rp | grep -Pio '^/nix/store/[^/]+(?=/bin/[^/]+)')" || true
|
||||||
|
binary="$(find_rosenpass_binary)"
|
||||||
|
|
||||||
|
# Parse command
|
||||||
|
|
||||||
|
usagestack+=("[explain]" "[verbose]" "genkey|pubkey|exchange" "[ARGS]...")
|
||||||
|
|
||||||
|
local cmd
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
local arg; arg="$1"; shift
|
||||||
|
case "${arg}" in
|
||||||
|
genkey|pubkey|exchange) cmd="${arg}"; break;;
|
||||||
|
explain) explain=1;;
|
||||||
|
verbose) verbose=1;;
|
||||||
|
-h | -help | --help | help) usage; return 0 ;;
|
||||||
|
*) fatal "Unknown command ${arg}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
test -n "${cmd}" || fatal "No command supplied"
|
||||||
|
usagestack=("${script}")
|
||||||
|
|
||||||
|
# Execute command
|
||||||
|
|
||||||
|
usagestack+=("${cmd}")
|
||||||
|
"${cmd}" "$@"
|
||||||
|
usagestack=("${script}")
|
||||||
|
|
||||||
|
# Apply transaction
|
||||||
|
|
||||||
|
frag_apply
|
||||||
|
}
|
||||||
|
|
||||||
|
script="$0"
|
||||||
|
main "$@"
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "rp"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
authors = ["wucke13 <wucke13@gmail.com>", "Karolin Varner <karo@cupdev.net>"]
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "Build post-quantum-secure VPNs with WireGuard!"
|
|
||||||
homepage = "https://rosenpass.eu/"
|
|
||||||
repository = "https://github.com/rosenpass/rosenpass"
|
|
||||||
readme = "../readme.md"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = { version = "4.1.8", features = ["derive"] }
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
|
|
||||||
// Usage: ../rp-old [explain] [verbose] genkey|pubkey|exchange [ARGS]...
|
|
||||||
|
|
||||||
/// Simple program to greet a person
|
|
||||||
#[derive(Parser, Debug)]
|
|
||||||
#[command(author, version, about, long_about = None)]
|
|
||||||
struct Cli {
|
|
||||||
/// Explain what is done
|
|
||||||
#[arg(short, long)]
|
|
||||||
explain: bool,
|
|
||||||
|
|
||||||
/// Be verbose about what's going on
|
|
||||||
#[arg(short, long)]
|
|
||||||
verbose: bool,
|
|
||||||
|
|
||||||
#[command(subcommand)]
|
|
||||||
command: Command,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Doc comment
|
|
||||||
#[derive(Subcommand, Debug)]
|
|
||||||
// #[command(PARENT CMD ATTRIBUTE)]
|
|
||||||
enum Command {
|
|
||||||
/// Generate a keypair
|
|
||||||
// --- Requirements ---
|
|
||||||
// requires wireguard
|
|
||||||
// should not exist before
|
|
||||||
// should be dir after
|
|
||||||
// should contain three files after pqpk, pqsk, wgsk
|
|
||||||
Genkey {
|
|
||||||
private_keys_dir: PathBuf,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Generate public keys
|
|
||||||
// --- Requirements ---
|
|
||||||
// requires wireguard
|
|
||||||
// requires private_keys_dir to exist
|
|
||||||
// should create public_keys_dir
|
|
||||||
// should copy pqpk from private_ to public_keys_dir
|
|
||||||
// should generate wgpk to public_keys_dir
|
|
||||||
Pubkey {
|
|
||||||
private_keys_dir: PathBuf,
|
|
||||||
public_keys_dir: PathBuf,
|
|
||||||
},
|
|
||||||
|
|
||||||
Exchange {},
|
|
||||||
}
|
|
||||||
fn main() {
|
|
||||||
let args = Cli::parse();
|
|
||||||
|
|
||||||
println!("{args:#?}");
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,9 @@ DESCRIPTION
|
|||||||
These keys can then be passed to various services such as wireguard or other vpn services
|
These keys can then be passed to various services such as wireguard or other vpn services
|
||||||
as pre-shared-keys to achieve security against attackers with quantum computers.
|
as pre-shared-keys to achieve security against attackers with quantum computers.
|
||||||
|
|
||||||
|
This is a research project and quantum computers are not thought to become practical in less than ten years.
|
||||||
|
If you are not specifically tasked with developing post-quantum secure systems, you probably do not need this tool.
|
||||||
|
|
||||||
COMMANDS
|
COMMANDS
|
||||||
|
|
||||||
keygen private-key <file-path> public-key <file-path>
|
keygen private-key <file-path> public-key <file-path>
|
||||||
@@ -32,11 +35,11 @@ COMMANDS
|
|||||||
You must either specify the outfile or wireguard output option.
|
You must either specify the outfile or wireguard output option.
|
||||||
|
|
||||||
endpoint <ip>[:<port>]
|
endpoint <ip>[:<port>]
|
||||||
Specifies the address where the peer can be reached. This will be automatically updated after the first successful
|
Specifies the address where the peer can be reached. This will be automatically updated after the first sucessfull
|
||||||
key exchange with the peer. If this is unspecified, the peer must initiate the connection.
|
key exchange with the peer. If this is unspecified, the peer must initiate the connection.
|
||||||
|
|
||||||
preshared-key <file-path>
|
preshared-key <file-path>
|
||||||
You may specify a pre-shared key which will be mixed into the final secret.
|
You may specifie a pre-shared key which will be mixied into the final secret.
|
||||||
|
|
||||||
outfile <file-path>
|
outfile <file-path>
|
||||||
You may specify a file to write the exchanged keys to. If this option is specified, {0} will
|
You may specify a file to write the exchanged keys to. If this option is specified, {0} will
|
||||||
Reference in New Issue
Block a user