Switch from snow to noise-protocol; Noise responder implementation
This commit is contained in:
parent
94040ae566
commit
4becf23caa
|
@ -64,6 +64,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
@ -457,14 +463,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.0.0-pre.5"
|
||||
version = "3.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67bc65846be335cb20f4e52d49a437b773a2c1fdb42b19fc84e79e6f6771536f"
|
||||
checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fiat-crypto",
|
||||
"packed_simd_2",
|
||||
"platforms",
|
||||
"byteorder",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
@ -575,12 +580,6 @@ dependencies = [
|
|||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.19"
|
||||
|
@ -757,6 +756,17 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
|
@ -1011,12 +1021,6 @@ version = "0.2.139"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
|
@ -1159,6 +1163,31 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "noise-protocol"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb474d36dfe51bb4d7e733fee2b0dfd92ee1b95c716030a70e92737dea1a52b"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "noise-rust-crypto"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e7cfeb8e6a63b4a5ccef34ed7a22d084a129b1e53a000c080bbc54c0da6f8c"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"blake2",
|
||||
"chacha20poly1305",
|
||||
"getrandom 0.2.8",
|
||||
"noise-protocol",
|
||||
"sha2 0.10.6",
|
||||
"x25519-dalek",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.17"
|
||||
|
@ -1342,16 +1371,6 @@ version = "6.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "packed_simd_2"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
|
@ -1421,12 +1440,6 @@ version = "0.3.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "platforms"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.4"
|
||||
|
@ -1564,7 +1577,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1574,7 +1587,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1583,7 +1605,7 @@ version = "0.6.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1652,15 +1674,6 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.7"
|
||||
|
@ -1734,12 +1747,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
|
@ -1860,22 +1867,6 @@ version = "1.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "snow"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "774d05a3edae07ce6d68ea6984f3c05e9bba8927e3dd591e3b479e5b03213d0d"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"blake2",
|
||||
"chacha20poly1305",
|
||||
"curve25519-dalek",
|
||||
"rand_core",
|
||||
"rustc_version",
|
||||
"sha2 0.10.6",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
|
@ -1946,7 +1937,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"criterion",
|
||||
"futures",
|
||||
"getrandom",
|
||||
"getrandom 0.2.8",
|
||||
"hmac",
|
||||
"lazy_static",
|
||||
"openssl",
|
||||
|
@ -1980,9 +1971,10 @@ dependencies = [
|
|||
"chrono",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"noise-protocol",
|
||||
"noise-rust-crypto",
|
||||
"notify",
|
||||
"preserves-schema",
|
||||
"snow",
|
||||
"structopt",
|
||||
"syndicate",
|
||||
"syndicate-macros",
|
||||
|
@ -2005,6 +1997,18 @@ dependencies = [
|
|||
"syndicate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
|
@ -2305,6 +2309,12 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.4.1"
|
||||
|
@ -2367,6 +2377,12 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
|
@ -2554,7 +2570,33 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.5.7"
|
||||
name = "x25519-dalek"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
|
||||
checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"rand_core 0.5.1",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
|
|
@ -21,8 +21,9 @@ syndicate-macros = { path = "../syndicate-macros", version = "0.20.0"}
|
|||
chrono = "0.4"
|
||||
futures = "0.3"
|
||||
lazy_static = "1.4"
|
||||
noise-protocol = "0.1"
|
||||
noise-rust-crypto = "0.5"
|
||||
notify = "4.0"
|
||||
snow = "0.9"
|
||||
structopt = "0.3"
|
||||
|
||||
tungstenite = "0.13"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
´³bundle·µ³
documentation„´³schema·³version‘³definitions·³Url´³orµµ±present´³dict·³url´³named³url´³atom³String„„„„„µ±invalid´³dict·³url´³named³url³any„„„„µ±absent´³dict·„„„„„³IOList´³orµµ±bytes´³atom³
|
||||
ByteString„„µ±string´³atom³String„„µ±nested´³seqof´³refµ„³IOList„„„„„³Metadata´³rec´³lit³metadata„´³tupleµ´³named³object³any„´³named³info´³dictof´³atom³Symbol„³any„„„„„³Description´³orµµ±present´³dict·³description´³named³description´³refµ„³IOList„„„„„µ±invalid´³dict·³description´³named³description³any„„„„µ±absent´³dict·„„„„„„³embeddedType€„„µ³
gatekeeperMux„´³schema·³version‘³definitions·³API´³orµµ±Resolve´³refµ³
|
||||
gatekeeper„³Resolve„„µ±Connect´³refµ³noise„³Connect„„„„³NoiseService´³rec´³lit³noise„´³tupleµ´³named³serviceSelector³any„´³named³responderListener´³embedded´³refµ³noise„³Connect„„„„„„„³embeddedType€„„µ³externalServices„´³schema·³version‘³definitions·³Process´³orµµ±simple´³refµ„³CommandLine„„µ±full´³refµ„³FullProcess„„„„³Service´³refµ„³
DaemonService„³ClearEnv´³orµµ±present´³dict·³clearEnv´³named³clearEnv´³atom³Boolean„„„„„µ±invalid´³dict·³clearEnv´³named³clearEnv³any„„„„µ±absent´³dict·„„„„„³EnvValue´³orµµ±set´³atom³String„„µ±remove´³lit€„„µ±invalid³any„„„³Protocol´³orµµ±none´³lit³none„„µ±binarySyndicate´³lit³application/syndicate„„µ±
textSyndicate´³lit³text/syndicate„„„„³
|
||||
gatekeeper„³Resolve„„µ±Connect´³refµ³noise„³Connect„„„„³NoiseService´³rec´³lit³noise„´³tupleµ´³named³spec´³refµ³noise„³ NoiseSpec„„´³named³service´³embedded³any„„„„„³SecretKeyField´³orµµ±present´³dict·³ secretKey´³named³ secretKey´³atom³
|
||||
ByteString„„„„„µ±invalid´³dict·³ secretKey´³named³ secretKey³any„„„„µ±absent´³dict·„„„„„³NoiseServiceSpec´³andµ´³named³base´³refµ³noise„³ NoiseSpec„„´³named³ secretKey´³refµ„³SecretKeyField„„„„„³embeddedType€„„µ³externalServices„´³schema·³version‘³definitions·³Process´³orµµ±simple´³refµ„³CommandLine„„µ±full´³refµ„³FullProcess„„„„³Service´³refµ„³
DaemonService„³ClearEnv´³orµµ±present´³dict·³clearEnv´³named³clearEnv´³atom³Boolean„„„„„µ±invalid´³dict·³clearEnv´³named³clearEnv³any„„„„µ±absent´³dict·„„„„„³EnvValue´³orµµ±set´³atom³String„„µ±remove´³lit€„„µ±invalid³any„„„³Protocol´³orµµ±none´³lit³none„„µ±binarySyndicate´³lit³application/syndicate„„µ±
textSyndicate´³lit³text/syndicate„„„„³
|
||||
ProcessDir´³orµµ±present´³dict·³dir´³named³dir´³atom³String„„„„„µ±invalid´³dict·³dir´³named³dir³any„„„„µ±absent´³dict·„„„„„³
|
||||
ProcessEnv´³orµµ±present´³dict·³env´³named³env´³dictof´³refµ„³EnvVariable„´³refµ„³EnvValue„„„„„„µ±invalid´³dict·³env´³named³env³any„„„„µ±absent´³dict·„„„„„³CommandLine´³orµµ±shell´³atom³String„„µ±full´³refµ„³FullCommandLine„„„„³EnvVariable´³orµµ±string´³atom³String„„µ±symbol´³atom³Symbol„„µ±invalid³any„„„³FullProcess´³andµ´³dict·³argv´³named³argv´³refµ„³CommandLine„„„„´³named³env´³refµ„³
|
||||
ProcessEnv„„´³named³dir´³refµ„³
|
||||
|
|
|
@ -2,4 +2,6 @@ version 1 .
|
|||
|
||||
API = gatekeeper.Resolve / noise.Connect .
|
||||
|
||||
NoiseService = <noise @serviceSelector any @responderListener #!noise.Connect> .
|
||||
NoiseService = <noise @spec noise.NoiseSpec @service #!any> .
|
||||
NoiseServiceSpec = @base noise.NoiseSpec & @secretKey SecretKeyField .
|
||||
SecretKeyField = @present { secretKey: bytes } / @invalid { secretKey: any } / @absent {} .
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
use noise_protocol::CipherState;
|
||||
use noise_protocol::U8Array;
|
||||
use noise_protocol::patterns::HandshakePattern;
|
||||
use noise_rust_crypto::Blake2s;
|
||||
use noise_rust_crypto::ChaCha20Poly1305;
|
||||
use noise_rust_crypto::X25519;
|
||||
use preserves_schema::Codec;
|
||||
use syndicate::relay::Mutex;
|
||||
use syndicate::relay::TunnelRelay;
|
||||
use syndicate::trace::TurnCause;
|
||||
use syndicate::value::NoEmbeddedDomainCodec;
|
||||
use syndicate::value::packed::PackedWriter;
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
|
||||
use syndicate::actor::*;
|
||||
use syndicate::during::DuringResult;
|
||||
use syndicate::value::NestedValue;
|
||||
use syndicate::schemas::dataspace;
|
||||
use syndicate::schemas::gatekeeper;
|
||||
use syndicate::schemas::noise;
|
||||
|
||||
use crate::language::language;
|
||||
use crate::schemas::gatekeeper_mux::{Api, NoiseService};
|
||||
use crate::schemas::gatekeeper_mux::Api;
|
||||
use crate::schemas::gatekeeper_mux::NoiseServiceSpec;
|
||||
use crate::schemas::gatekeeper_mux::SecretKeyField;
|
||||
|
||||
// pub fn bind(
|
||||
// t: &mut Activation,
|
||||
|
@ -29,7 +45,7 @@ pub fn handle_assertion(
|
|||
) -> DuringResult<Arc<Cap>> {
|
||||
match a {
|
||||
Api::Resolve(resolve_box) => handle_resolve(ds, t, *resolve_box),
|
||||
Api::Connect(_) => todo!(),
|
||||
Api::Connect(connect_box) => handle_connect(ds, t, *connect_box),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,8 +54,6 @@ fn handle_resolve(
|
|||
t: &mut Activation,
|
||||
a: gatekeeper::Resolve,
|
||||
) -> DuringResult<Arc<Cap>> {
|
||||
use syndicate::schemas::dataspace;
|
||||
|
||||
let gatekeeper::Resolve { sturdyref, observer } = a;
|
||||
let queried_oid = sturdyref.oid.clone();
|
||||
let handler = syndicate::entity(observer)
|
||||
|
@ -76,3 +90,263 @@ fn handle_resolve(
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_connect(
|
||||
ds: &mut Arc<Cap>,
|
||||
t: &mut Activation,
|
||||
a: noise::Connect<AnyValue>,
|
||||
) -> DuringResult<Arc<Cap>> {
|
||||
let noise::Connect { service_selector, initiator_session } = a;
|
||||
let handler = syndicate::entity(())
|
||||
.on_asserted_facet(move |_state, t, a: AnyValue| {
|
||||
let initiator_session = Arc::clone(&initiator_session);
|
||||
t.spawn_link(None, move |t| {
|
||||
let bindings = a.value().to_sequence()?;
|
||||
let spec: NoiseServiceSpec<AnyValue> = language().parse(&bindings[0])?;
|
||||
let protocol = match spec.base.protocol {
|
||||
noise::NoiseProtocol::Present { protocol } =>
|
||||
protocol,
|
||||
noise::NoiseProtocol::Invalid { protocol } =>
|
||||
Err(format!("Invalid noise protocol {:?}", protocol))?,
|
||||
noise::NoiseProtocol::Absent =>
|
||||
language().unparse(&noise::DefaultProtocol).value().to_string()?.clone(),
|
||||
};
|
||||
let psks = match spec.base.pre_shared_keys {
|
||||
noise::NoisePreSharedKeys::Present { pre_shared_keys } =>
|
||||
pre_shared_keys,
|
||||
noise::NoisePreSharedKeys::Invalid { pre_shared_keys } =>
|
||||
Err(format!("Invalid pre-shared-keys {:?}", pre_shared_keys))?,
|
||||
noise::NoisePreSharedKeys::Absent =>
|
||||
vec![],
|
||||
};
|
||||
let secret_key = match spec.secret_key {
|
||||
SecretKeyField::Present { secret_key } =>
|
||||
Some(secret_key),
|
||||
SecretKeyField::Invalid { secret_key } =>
|
||||
Err(format!("Invalid secret key {:?}", secret_key))?,
|
||||
SecretKeyField::Absent =>
|
||||
None,
|
||||
};
|
||||
let service = bindings[1].value().to_embedded()?;
|
||||
run_noise_responder(t,
|
||||
spec.base.service,
|
||||
protocol,
|
||||
psks,
|
||||
secret_key,
|
||||
initiator_session,
|
||||
Arc::clone(service))
|
||||
});
|
||||
Ok(())
|
||||
})
|
||||
.create_cap(t);
|
||||
if let Some(oh) = ds.assert(t, language(), &dataspace::Observe {
|
||||
// TODO: codegen plugin to generate pattern constructors
|
||||
pattern: syndicate_macros::pattern!{
|
||||
<noise $spec:NoiseServiceSpec{ { service: #(&service_selector) } } $service >
|
||||
},
|
||||
observer: handler,
|
||||
}) {
|
||||
Ok(Some(Box::new(move |_ds, t| Ok(t.retract(oh)))))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
struct ResponderDetails {
|
||||
initiator_session: Arc<Cap>,
|
||||
service: Arc<Cap>,
|
||||
}
|
||||
|
||||
struct ResponderTransport {
|
||||
relay_input: Arc<Mutex<Option<TunnelRelay>>>,
|
||||
c_recv: CipherState<ChaCha20Poly1305>
|
||||
}
|
||||
|
||||
enum ResponderState {
|
||||
Handshake(ResponderDetails, noise_protocol::HandshakeState<X25519, ChaCha20Poly1305, Blake2s>),
|
||||
Transport(ResponderTransport),
|
||||
}
|
||||
|
||||
impl Entity<noise::Packet> for ResponderState {
|
||||
fn message(&mut self, t: &mut Activation, p: noise::Packet) -> ActorResult {
|
||||
match self {
|
||||
ResponderState::Handshake(details, hs) => match p {
|
||||
noise::Packet::Complete(bs) => {
|
||||
if bs.len() < hs.get_next_message_overhead() {
|
||||
Err("Invalid handshake message for pattern")?;
|
||||
}
|
||||
if bs.len() > hs.get_next_message_overhead() {
|
||||
Err("Cannot accept payload during handshake")?;
|
||||
}
|
||||
hs.read_message(&bs, &mut [])?;
|
||||
let mut reply = vec![0u8; hs.get_next_message_overhead()];
|
||||
hs.write_message(&[], &mut reply[..])?;
|
||||
details.initiator_session.message(t, language(), &noise::Packet::Complete(reply.into()));
|
||||
if hs.completed() {
|
||||
let (c_recv, mut c_send) = hs.get_ciphers();
|
||||
let (_, relay_input, mut relay_output) =
|
||||
TunnelRelay::_run(t, Some(Arc::clone(&details.service)), None, false);
|
||||
let trace_collector = t.trace_collector();
|
||||
let transport = ResponderTransport { relay_input, c_recv };
|
||||
let initiator_session = Arc::clone(&details.initiator_session);
|
||||
let relay_output_name = Some(AnyValue::symbol("relay_output"));
|
||||
let transport_facet = t.facet.clone();
|
||||
t.linked_task(relay_output_name.clone(), async move {
|
||||
let account = Account::new(relay_output_name, trace_collector);
|
||||
let cause = TurnCause::external("relay_output");
|
||||
loop {
|
||||
match relay_output.recv().await {
|
||||
None => return Ok(LinkedTaskTermination::KeepFacet),
|
||||
Some(loaned_item) => {
|
||||
const MAXSIZE: usize = 65535 - 16; /* Noise tag length is 16 */
|
||||
let p = if loaned_item.item.len() > MAXSIZE {
|
||||
noise::Packet::Fragmented(
|
||||
loaned_item.item
|
||||
.chunks(MAXSIZE)
|
||||
.map(|c| c_send.encrypt_vec(c))
|
||||
.collect())
|
||||
} else {
|
||||
noise::Packet::Complete(c_send.encrypt_vec(&loaned_item.item))
|
||||
};
|
||||
if !transport_facet.activate(&account, Some(cause.clone()), |t| {
|
||||
initiator_session.message(t, language(), &p);
|
||||
Ok(())
|
||||
}) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(LinkedTaskTermination::Normal)
|
||||
});
|
||||
*self = ResponderState::Transport(transport);
|
||||
}
|
||||
}
|
||||
_ => Err("Fragmented handshake is not allowed")?,
|
||||
},
|
||||
ResponderState::Transport(transport) => {
|
||||
let bs = match p {
|
||||
noise::Packet::Complete(bs) =>
|
||||
transport.c_recv.decrypt_vec(&bs[..]).map_err(|_| "Cannot decrypt packet")?,
|
||||
noise::Packet::Fragmented(pieces) => {
|
||||
let mut result = Vec::with_capacity(1024);
|
||||
for piece in pieces {
|
||||
result.extend(transport.c_recv.decrypt_vec(&piece[..])
|
||||
.map_err(|_| "Cannot decrypt packet fragment")?);
|
||||
}
|
||||
result
|
||||
}
|
||||
};
|
||||
let mut g = transport.relay_input.lock();
|
||||
let tr = g.as_mut().expect("initialized");
|
||||
tr.handle_inbound_datagram(t, &bs[..])?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_pattern(name: &str) -> Option<HandshakePattern> {
|
||||
use noise_protocol::patterns::*;
|
||||
Some(match name {
|
||||
"N" => noise_n(),
|
||||
"K" => noise_k(),
|
||||
"X" => noise_x(),
|
||||
"NN" => noise_nn(),
|
||||
"NK" => noise_nk(),
|
||||
"NX" => noise_nx(),
|
||||
"XN" => noise_xn(),
|
||||
"XK" => noise_xk(),
|
||||
"XX" => noise_xx(),
|
||||
"KN" => noise_kn(),
|
||||
"KK" => noise_kk(),
|
||||
"KX" => noise_kx(),
|
||||
"IN" => noise_in(),
|
||||
"IK" => noise_ik(),
|
||||
"IX" => noise_ix(),
|
||||
"Npsk0" => noise_n_psk0(),
|
||||
"Kpsk0" => noise_k_psk0(),
|
||||
"Xpsk1" => noise_x_psk1(),
|
||||
"NNpsk0" => noise_nn_psk0(),
|
||||
"NNpsk2" => noise_nn_psk2(),
|
||||
"NKpsk0" => noise_nk_psk0(),
|
||||
"NKpsk2" => noise_nk_psk2(),
|
||||
"NXpsk2" => noise_nx_psk2(),
|
||||
"XNpsk3" => noise_xn_psk3(),
|
||||
"XKpsk3" => noise_xk_psk3(),
|
||||
"XXpsk3" => noise_xx_psk3(),
|
||||
"KNpsk0" => noise_kn_psk0(),
|
||||
"KNpsk2" => noise_kn_psk2(),
|
||||
"KKpsk0" => noise_kk_psk0(),
|
||||
"KKpsk2" => noise_kk_psk2(),
|
||||
"KXpsk2" => noise_kx_psk2(),
|
||||
"INpsk1" => noise_in_psk1(),
|
||||
"INpsk2" => noise_in_psk2(),
|
||||
"IKpsk1" => noise_ik_psk1(),
|
||||
"IKpsk2" => noise_ik_psk2(),
|
||||
"IXpsk2" => noise_ix_psk2(),
|
||||
"NNpsk0+psk2" => noise_nn_psk0_psk2(),
|
||||
"NXpsk0+psk1+psk2" => noise_nx_psk0_psk1_psk2(),
|
||||
"XNpsk1+psk3" => noise_xn_psk1_psk3(),
|
||||
"XKpsk0+psk3" => noise_xk_psk0_psk3(),
|
||||
"KNpsk1+psk2" => noise_kn_psk1_psk2(),
|
||||
"KKpsk0+psk2" => noise_kk_psk0_psk2(),
|
||||
"INpsk1+psk2" => noise_in_psk1_psk2(),
|
||||
"IKpsk0+psk2" => noise_ik_psk0_psk2(),
|
||||
"IXpsk0+psk2" => noise_ix_psk0_psk2(),
|
||||
"XXpsk0+psk1" => noise_xx_psk0_psk1(),
|
||||
"XXpsk0+psk2" => noise_xx_psk0_psk2(),
|
||||
"XXpsk0+psk3" => noise_xx_psk0_psk3(),
|
||||
"XXpsk0+psk1+psk2+psk3" => noise_xx_psk0_psk1_psk2_psk3(),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
fn run_noise_responder(
|
||||
t: &mut Activation,
|
||||
service_selector: AnyValue,
|
||||
protocol: String,
|
||||
psks: Vec<Vec<u8>>,
|
||||
secret_key: Option<Vec<u8>>,
|
||||
initiator_session: Arc<Cap>,
|
||||
service: Arc<Cap>,
|
||||
) -> ActorResult {
|
||||
const PREFIX: &'static str = "Noise_";
|
||||
const SUFFIX: &'static str = "_25519_ChaChaPoly_BLAKE2s";
|
||||
if !protocol.starts_with(PREFIX) || !protocol.ends_with(SUFFIX) {
|
||||
Err(format!("Unsupported protocol {:?}", protocol))?;
|
||||
}
|
||||
let pattern_name = &protocol[PREFIX.len()..(protocol.len()-SUFFIX.len())];
|
||||
let pattern = lookup_pattern(pattern_name).ok_or_else::<ActorError, _>(
|
||||
|| format!("Unsupported handshake pattern {:?}", pattern_name).into())?;
|
||||
|
||||
let hs = {
|
||||
let mut builder = noise_protocol::HandshakeStateBuilder::new();
|
||||
builder.set_pattern(pattern);
|
||||
builder.set_is_initiator(false);
|
||||
let prologue = PackedWriter::encode(&mut NoEmbeddedDomainCodec, &service_selector)?;
|
||||
builder.set_prologue(&prologue);
|
||||
match secret_key {
|
||||
None => (),
|
||||
Some(sk) => {
|
||||
let sk: [u8; 32] = sk.try_into().map_err(|_| "Bad secret key length")?;
|
||||
builder.set_s(U8Array::from_slice(&sk));
|
||||
},
|
||||
}
|
||||
let mut hs = builder.build_handshake_state();
|
||||
for psk in psks.into_iter() {
|
||||
hs.push_psk(&psk);
|
||||
}
|
||||
hs
|
||||
};
|
||||
|
||||
let details = ResponderDetails {
|
||||
initiator_session: initiator_session.clone(),
|
||||
service,
|
||||
};
|
||||
|
||||
let responder_session =
|
||||
Cap::guard(crate::Language::arc(), t.create(ResponderState::Handshake(details, hs)));
|
||||
initiator_session.assert(t, language(), &noise::Accept { responder_session });
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue