diff --git a/Makefile b/Makefile index 6a4ddaab..decfcc64 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ clippy: test: $(Change_Work_Path) && RUSTFLAGS='-W warnings' RUST_BACKTRACE=full cargo test --all --features ws,unstable,tls,upnp + cargo clean + $(Change_Work_Path) && RUSTFLAGS='-W warnings' RUST_BACKTRACE=full cargo test --all --features ws,unstable,tls,upnp,secio-async-trait fuzz: cargo +nightly fuzz run secio_crypto_decrypt_cipher -- -max_total_time=60 @@ -44,7 +46,7 @@ features-check: $(Change_Work_Path) && cargo build --features async-runtime,async-timer,unstable --no-default-features # required wasm32-unknown-unknown target $(Change_Work_Path) && cargo build --features wasm-timer,unstable --no-default-features --target=wasm32-unknown-unknown - + $(Change_Work_Path) && cargo build --features wasm-timer,unstable,secio-async-trait --no-default-features --target=wasm32-unknown-unknown bench_p2p: cd bench && cargo run --release diff --git a/bench/src/main.rs b/bench/src/main.rs index 1762952c..d9f8917b 100644 --- a/bench/src/main.rs +++ b/bench/src/main.rs @@ -31,9 +31,9 @@ enum Notify { Message(bytes::Bytes), } -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default() .insert_protocol(meta) @@ -41,7 +41,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/secio/Cargo.toml b/secio/Cargo.toml index 5daf642d..944fd53e 100644 --- a/secio/Cargo.toml +++ b/secio/Cargo.toml @@ -21,6 +21,7 @@ futures = { version = "0.3.0" } tokio = { version = "1.0", features = ["io-util"] } tokio-util = { version = "0.7.0", features = ["codec"] } log = "0.4.1" +async-trait = { version = "0.1", optional = true } molecule = "0.7.0" diff --git a/secio/src/codec/hmac_compat/openssl_impl.rs b/secio/src/codec/hmac_compat/openssl_impl.rs index 9d6f900e..30b03968 100644 --- a/secio/src/codec/hmac_compat/openssl_impl.rs +++ b/secio/src/codec/hmac_compat/openssl_impl.rs @@ -1,6 +1,5 @@ use openssl::{ hash::MessageDigest, - memcmp, pkey::{PKey, Private}, sign::Signer, }; @@ -15,6 +14,7 @@ pub struct Hmac { impl Hmac { /// Returns the size of the hash in bytes. + #[cfg(test)] #[inline] pub fn num_bytes(&self) -> usize { self.digest.size() @@ -32,6 +32,7 @@ impl Hmac { } /// Signs the data. + #[cfg(test)] pub fn sign(&mut self, crypted_data: &[u8]) -> Vec { let mut sign = Signer::new(self.digest, &self.key).expect("init openssl signer ctx fail"); sign.update(crypted_data).expect("openssl hmac update fail"); @@ -39,12 +40,13 @@ impl Hmac { } /// Verifies that the data matches the expected hash. + #[cfg(test)] pub fn verify(&mut self, crypted_data: &[u8], expected_hash: &[u8]) -> bool { let n = self.sign(crypted_data); if n.len() != expected_hash.len() { return false; } - memcmp::eq(&n, expected_hash) + openssl::memcmp::eq(&n, expected_hash) } /// Return a multi-step hmac context diff --git a/secio/src/codec/hmac_compat/ring_impl.rs b/secio/src/codec/hmac_compat/ring_impl.rs index 1a50af86..12b26ddd 100644 --- a/secio/src/codec/hmac_compat/ring_impl.rs +++ b/secio/src/codec/hmac_compat/ring_impl.rs @@ -6,6 +6,7 @@ pub struct Hmac(ring::hmac::Key); impl Hmac { /// Returns the size of the hash in bytes. + #[cfg(test)] #[inline] pub fn num_bytes(&self) -> usize { self.0.algorithm().digest_algorithm().output_len @@ -20,11 +21,13 @@ impl Hmac { } /// Signs the data. + #[cfg(test)] pub fn sign(&mut self, crypted_data: &[u8]) -> ring::hmac::Tag { ring::hmac::sign(&self.0, crypted_data) } /// Verifies that the data matches the expected hash. + #[cfg(test)] pub fn verify(&mut self, crypted_data: &[u8], expected_hash: &[u8]) -> bool { ring::hmac::verify(&self.0, crypted_data, expected_hash).is_ok() } diff --git a/secio/src/codec/mod.rs b/secio/src/codec/mod.rs index 7e3c7e25..207b0da1 100644 --- a/secio/src/codec/mod.rs +++ b/secio/src/codec/mod.rs @@ -3,7 +3,4 @@ /// Encryption and decryption stream pub mod secure_stream; // hmac compatible -mod hmac_compat; - -// TODO: remove this pub use for next break version -pub use hmac_compat::Hmac; +pub(crate) mod hmac_compat; diff --git a/secio/src/error.rs b/secio/src/error.rs index 86eeead9..f74c0eb1 100644 --- a/secio/src/error.rs +++ b/secio/src/error.rs @@ -14,6 +14,9 @@ pub enum SecioError { /// Crypto error CryptoError, + /// Sign operation not supported + NotSupportKeyProvider, + /// Failed to generate ephemeral key. EphemeralKeyGenerationFailed, @@ -29,9 +32,6 @@ pub enum SecioError { /// The received frame was of invalid length. FrameTooShort, - /// The hashes of the message didn't match. - HmacNotMatching, - /// Connect yourself ConnectSelf, @@ -58,11 +58,11 @@ impl PartialEq for SecioError { | (NoSupportIntersection, NoSupportIntersection) | (NonceVerificationFailed, NonceVerificationFailed) | (FrameTooShort, FrameTooShort) - | (HmacNotMatching, HmacNotMatching) | (ConnectSelf, ConnectSelf) | (HandshakeParsingFailure, HandshakeParsingFailure) | (SignatureVerificationFailed, SignatureVerificationFailed) - | (InvalidMessage, InvalidMessage) => true, + | (InvalidMessage, InvalidMessage) + | (NotSupportKeyProvider, NotSupportKeyProvider) => true, _ => false, } } @@ -113,12 +113,12 @@ impl fmt::Display for SecioError { SecioError::NoSupportIntersection => write!(f, "No Support Intersection"), SecioError::NonceVerificationFailed => write!(f, "Nonce Verification Failed"), SecioError::FrameTooShort => write!(f, "Frame Too Short"), - SecioError::HmacNotMatching => write!(f, "Hmac Not Matching"), SecioError::ConnectSelf => write!(f, "Connect Self"), SecioError::HandshakeParsingFailure => write!(f, "Handshake Parsing Failure"), SecioError::InvalidMessage => write!(f, "Invalid Message"), SecioError::SignatureVerificationFailed => write!(f, "Signature Verification Failed"), SecioError::InvalidProposition(e) => write!(f, "Invalid Proposition: {}", e), + SecioError::NotSupportKeyProvider => write!(f, "Sign operation not supported"), } } } diff --git a/secio/src/handshake/handshake_context.rs b/secio/src/handshake/handshake_context.rs index 4fc6c35a..197de59d 100644 --- a/secio/src/handshake/handshake_context.rs +++ b/secio/src/handshake/handshake_context.rs @@ -9,7 +9,7 @@ use crate::{ handshake_struct::{Propose, PublicKey}, Config, }, - support, Digest, + support, Digest, KeyProvider, }; use bytes::{Bytes, BytesMut}; @@ -20,8 +20,8 @@ use std::cmp::Ordering; // This struct contains the whole context of a handshake, and is filled progressively // throughout the various parts of the handshake. -pub struct HandshakeContext { - pub(crate) config: Config, +pub struct HandshakeContext { + pub(crate) config: Config, pub(crate) state: T, } @@ -30,7 +30,7 @@ pub struct Local { // Locally-generated random number. The array size can be changed without any repercussion. pub(crate) nonce: [u8; 16], // Our local public key bytes: - pub(crate) public_key: Vec, + pub(crate) public_key: PublicKey, // Our local proposition's raw bytes: pub(crate) proposition_bytes: Bytes, } @@ -75,23 +75,28 @@ pub struct PubEphemeral { pub(crate) local_tmp_pub_key: Vec, } -impl HandshakeContext<()> { - pub fn new(config: Config) -> Self { +impl HandshakeContext<(), K> +where + K: KeyProvider, +{ + pub fn new(config: Config) -> Self { HandshakeContext { config, state: () } } // Setup local proposition. - pub fn with_local(self) -> HandshakeContext { + pub fn with_local(self) -> HandshakeContext { let mut nonce = [0; 16]; rand::thread_rng().fill_bytes(&mut nonce); - let public_key = self.config.key.public_key(); + let public_key = PublicKey { + key: self.config.key_provider.pubkey(), + }; // Send our proposition with our nonce, public key and supported protocols. let mut proposition = Propose::new(); proposition.rand = nonce.to_vec(); - let encode_key = public_key.clone(); - proposition.pubkey = encode_key.encode(); + let encode_key = public_key.clone().encode(); + proposition.pubkey = encode_key; proposition.exchange = self .config @@ -120,19 +125,22 @@ impl HandshakeContext<()> { config: self.config, state: Local { nonce, - public_key: public_key.inner(), + public_key, proposition_bytes, }, } } } -impl HandshakeContext { +impl HandshakeContext +where + K: KeyProvider, +{ // Process remote proposition. pub fn with_remote( self, remote_bytes: BytesMut, - ) -> Result, SecioError> { + ) -> Result, SecioError> { let propose = match Propose::decode(&remote_bytes) { Some(prop) => prop, None => { @@ -152,7 +160,7 @@ impl HandshakeContext { } }; - if public_key.inner_ref() == self.state.public_key { + if public_key == self.state.public_key { return Err(SecioError::ConnectSelf); } @@ -168,7 +176,7 @@ impl HandshakeContext { let oh2 = { let mut ctx = crate::sha256_compat::Context::new(); - ctx.update(&self.state.public_key); + ctx.update(self.state.public_key.inner_ref()); ctx.update(&nonce); ctx.finish() }; @@ -252,12 +260,15 @@ impl HandshakeContext { } } -impl HandshakeContext { +impl HandshakeContext +where + K: KeyProvider, +{ pub fn with_ephemeral( self, sk: crate::dh_compat::EphemeralPrivateKey, pk: Vec, - ) -> HandshakeContext { + ) -> HandshakeContext { HandshakeContext { config: self.config, state: Ephemeral { @@ -269,11 +280,14 @@ impl HandshakeContext { } } -impl HandshakeContext { +impl HandshakeContext +where + K: KeyProvider, +{ pub fn take_private_key( self, ) -> ( - HandshakeContext, + HandshakeContext, crate::dh_compat::EphemeralPrivateKey, ) { let context = HandshakeContext { diff --git a/secio/src/handshake/handshake_struct.rs b/secio/src/handshake/handshake_struct.rs index 4a81a5a9..9aa6460c 100644 --- a/secio/src/handshake/handshake_struct.rs +++ b/secio/src/handshake/handshake_struct.rs @@ -119,34 +119,19 @@ impl Exchange { /// Public Key #[derive(Clone, PartialEq, Ord, PartialOrd, Eq, Hash)] -pub enum PublicKey { - /// Secp256k1 - Secp256k1(Vec), +pub struct PublicKey { + pub(crate) key: Vec, } impl PublicKey { /// Get inner data pub fn inner_ref(&self) -> &[u8] { - match self { - PublicKey::Secp256k1(ref key) => key, - } + &self.key } /// Get inner data pub fn inner(self) -> Vec { - match self { - PublicKey::Secp256k1(key) => key, - } - } - - /// Creates a public key directly from a slice - pub fn secp256k1_raw_key(key: K) -> Result - where - K: AsRef<[u8]>, - { - crate::secp256k1_compat::pubkey_from_slice(key.as_ref()) - .map(|key| PublicKey::Secp256k1(crate::secp256k1_compat::serialize_pubkey(&key))) - .map_err(|_| crate::error::SecioError::SecretGenerationFailed) + self.key } /// Encode with molecule @@ -164,10 +149,11 @@ impl PublicKey { pub fn decode(data: &[u8]) -> Option { let reader = handshake_mol::PublicKeyReader::from_compatible_slice(data).ok()?; let union = reader.to_enum(); + match union { - handshake_mol::PublicKeyUnionReader::Secp256k1(reader) => { - Some(PublicKey::Secp256k1(reader.raw_data().to_owned())) - } + handshake_mol::PublicKeyUnionReader::Secp256k1(reader) => Some(PublicKey { + key: reader.raw_data().to_owned(), + }), } } @@ -223,20 +209,4 @@ mod tests { assert_eq!(raw, Exchange::decode(&byte.encode()).unwrap()) } - - #[test] - fn test_pubkey_from_slice() { - let privkey = SecioKeyPair::secp256k1_generated(); - let raw = privkey.public_key(); - let inner = raw.inner_ref(); - - let other = PublicKey::secp256k1_raw_key(inner).unwrap(); - assert_eq!(raw, other); - let uncompressed = crate::secp256k1_compat::pubkey_from_slice(inner) - .map(|key| key.serialize_uncompressed().to_vec()) - .unwrap(); - - let other_1 = PublicKey::secp256k1_raw_key(uncompressed).unwrap(); - assert_eq!(raw, other_1); - } } diff --git a/secio/src/handshake/mod.rs b/secio/src/handshake/mod.rs index 8c4ec05c..a7ab8e55 100644 --- a/secio/src/handshake/mod.rs +++ b/secio/src/handshake/mod.rs @@ -1,7 +1,7 @@ /// Most of the code for this module comes from `rust-libp2p`, but modified some logic(struct). use crate::{ crypto::cipher::CipherType, dh_compat::KeyAgreement, error::SecioError, - handshake::procedure::handshake, support, Digest, EphemeralPublicKey, PublicKey, SecioKeyPair, + handshake::procedure::handshake, support, Digest, EphemeralPublicKey, PublicKey, }; use crate::codec::secure_stream::SecureStream; @@ -20,19 +20,22 @@ const MAX_FRAME_SIZE: usize = 1024 * 1024 * 8; /// Config for Secio #[derive(Debug, Clone)] -pub struct Config { - pub(crate) key: SecioKeyPair, +pub struct Config { + pub(crate) key_provider: K, pub(crate) agreements_proposal: Option, pub(crate) ciphers_proposal: Option, pub(crate) digests_proposal: Option, pub(crate) max_frame_length: usize, } -impl Config { +impl Config +where + K: crate::KeyProvider, +{ /// Create config - pub fn new(key_pair: SecioKeyPair) -> Self { + pub fn new(key_provider: K) -> Self { Config { - key: key_pair, + key_provider, agreements_proposal: None, ciphers_proposal: None, digests_proposal: None, diff --git a/secio/src/handshake/procedure.rs b/secio/src/handshake/procedure.rs index 5133b616..7e838b35 100644 --- a/secio/src/handshake/procedure.rs +++ b/secio/src/handshake/procedure.rs @@ -9,7 +9,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use tokio_util::codec::length_delimited::Builder; use crate::{ - codec::{secure_stream::SecureStream, Hmac}, + codec::{hmac_compat::Hmac, secure_stream::SecureStream}, crypto::{cipher::CipherType, new_stream, BoxStreamCipher, CryptoMode}, error::SecioError, handshake::Config, @@ -17,7 +17,7 @@ use crate::{ handshake_context::HandshakeContext, handshake_struct::{Exchange, PublicKey}, }, - EphemeralPublicKey, KeyPairInner, + EphemeralPublicKey, KeyProvider, }; use bytes::BytesMut; use tokio::io::AsyncWriteExt; @@ -31,12 +31,13 @@ use tokio::io::AsyncWriteExt; /// On success, returns an object that implements the `AsyncWrite` and `AsyncRead` trait, /// plus the public key of the remote, plus the ephemeral public key used during /// negotiation. -pub(in crate::handshake) async fn handshake( +pub(in crate::handshake) async fn handshake( socket: T, - config: Config, + config: Config, ) -> Result<(SecureStream, PublicKey, EphemeralPublicKey), SecioError> where T: AsyncRead + AsyncWrite + Send + 'static + Unpin, + K: KeyProvider, { // The handshake messages all start with a 4-bytes message length prefix. let mut socket = Builder::new() @@ -98,21 +99,24 @@ where exchanges.epubkey = tmp_pub_key; let data_to_sign = crate::sha256_compat::sha256(&data_to_sign); - let message = match crate::secp256k1_compat::message_from_slice(data_to_sign.as_ref()) { - Ok(msg) => msg, - Err(_) => { - debug!("message has wrong format"); - return Err(SecioError::InvalidMessage); - } - }; - let signature = match ephemeral_context.config.key.inner { - KeyPairInner::Secp256k1 { ref private } => { - crate::secp256k1_compat::sign(&message, private) - } + exchanges.signature = { + #[cfg(not(feature = "async-trait"))] + let signature = ephemeral_context + .config + .key_provider + .sign_ecdsa(AsRef::<[u8]>::as_ref(&data_to_sign)) + .map_err(Into::into)?; + #[cfg(feature = "async-trait")] + let signature = ephemeral_context + .config + .key_provider + .sign_ecdsa_async(AsRef::<[u8]>::as_ref(&data_to_sign)) + .await + .map_err(Into::into)?; + signature }; - exchanges.signature = crate::secp256k1_compat::signature_to_vec(signature); exchanges }; let local_exchanges = exchanges.encode(); @@ -152,26 +156,12 @@ where let data_to_verify = crate::sha256_compat::sha256(&data_to_verify); - let message = match crate::secp256k1_compat::message_from_slice(data_to_verify.as_ref()) { - Ok(msg) => msg, - Err(_) => { - debug!("remote's message has wrong format"); - return Err(SecioError::InvalidMessage); - } - }; - - let signature = crate::secp256k1_compat::signature_from_der(&remote_exchanges.signature); - let remote_public_key = match ephemeral_context.state.remote.public_key { - PublicKey::Secp256k1(ref key) => crate::secp256k1_compat::pubkey_from_slice(key), - }; - - if let (Ok(signature), Ok(remote_public_key)) = (signature, remote_public_key) { - if !crate::secp256k1_compat::verify(&message, &signature, &remote_public_key) { - debug!("failed to verify the remote's signature"); - return Err(SecioError::SignatureVerificationFailed); - } - } else { - debug!("remote's secp256k1 signature has wrong format"); + if !::verify_ecdsa( + ephemeral_context.state.remote.public_key.inner_ref(), + &data_to_verify, + &remote_exchanges.signature, + ) { + debug!("failed to verify the remote's signature"); return Err(SecioError::SignatureVerificationFailed); } @@ -300,7 +290,7 @@ fn generate_stream_cipher_and_hmac( #[cfg(test)] mod tests { use super::stretch_key; - use crate::{codec::Hmac, handshake::Config, Digest, SecioKeyPair}; + use crate::{codec::hmac_compat::Hmac, handshake::Config, Digest, KeyProvider, SecioKeyPair}; use bytes::BytesMut; use futures::channel; @@ -309,7 +299,11 @@ mod tests { net::{TcpListener, TcpStream}, }; - fn handshake_with_self_success(config_1: Config, config_2: Config, data: &'static [u8]) { + fn handshake_with_self_success( + config_1: Config, + config_2: Config, + data: &'static [u8], + ) { let rt = tokio::runtime::Runtime::new().unwrap(); let (sender, receiver) = channel::oneshot::channel::(); let (addr_sender, addr_receiver) = channel::oneshot::channel::<::std::net::SocketAddr>(); diff --git a/secio/src/lib.rs b/secio/src/lib.rs index e9fef860..75e33f9a 100644 --- a/secio/src/lib.rs +++ b/secio/src/lib.rs @@ -63,7 +63,9 @@ impl SecioKeyPair { match self.inner { KeyPairInner::Secp256k1 { ref private } => { let pubkey = crate::secp256k1_compat::from_secret_key(private); - PublicKey::Secp256k1(crate::secp256k1_compat::serialize_pubkey(&pubkey)) + PublicKey { + key: crate::secp256k1_compat::serialize_pubkey(&pubkey), + } } } } @@ -74,13 +76,19 @@ impl SecioKeyPair { } } -#[derive(Clone, Debug)] +#[derive(Clone)] enum KeyPairInner { Secp256k1 { private: crate::secp256k1_compat::SecretKey, }, } +impl std::fmt::Debug for KeyPairInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("KeyPair").finish() + } +} + /// Possible digest algorithms. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Digest { @@ -100,3 +108,109 @@ impl Digest { } } } + +/// KeyProvider on ecdh procedure +#[cfg_attr(all(target_arch = "wasm32", feature = "async-trait"), async_trait::async_trait(?Send))] +#[cfg_attr( + all(not(target_arch = "wasm32"), feature = "async-trait"), + async_trait::async_trait +)] +pub trait KeyProvider: std::clone::Clone + Send + Sync + 'static { + /// Error + type Error: Into; + + /// Constructs a signature for `msg` using the secret key `sk` + #[cfg(feature = "async-trait")] + async fn sign_ecdsa_async + Send>( + &self, + message: T, + ) -> Result, Self::Error> { + self.sign_ecdsa(message) + } + + /// Constructs a signature for `msg` using the secret key `sk` + fn sign_ecdsa>(&self, message: T) -> Result, Self::Error>; + + /// Creates a new public key from the [`KeyProvider`]. + fn pubkey(&self) -> Vec; + + /// Checks that `sig` is a valid ECDSA signature for `msg` using the pubkey. + fn verify_ecdsa(pubkey: P, message: T, signature: F) -> bool + where + P: AsRef<[u8]>, + T: AsRef<[u8]>, + F: AsRef<[u8]>; +} + +impl KeyProvider for SecioKeyPair { + type Error = error::SecioError; + + fn sign_ecdsa>(&self, message: T) -> Result, Self::Error> { + let msg = match crate::secp256k1_compat::message_from_slice(message.as_ref()) { + Ok(m) => m, + Err(_) => { + log::debug!("message has wrong format"); + return Err(error::SecioError::InvalidMessage); + } + }; + let signature = match self.inner { + KeyPairInner::Secp256k1 { ref private } => crate::secp256k1_compat::sign(&msg, private), + }; + + Ok(crate::secp256k1_compat::signature_to_vec(signature)) + } + + fn pubkey(&self) -> Vec { + match self.inner { + KeyPairInner::Secp256k1 { ref private } => crate::secp256k1_compat::serialize_pubkey( + &crate::secp256k1_compat::from_secret_key(private), + ), + } + } + + fn verify_ecdsa(pubkey: P, message: T, signature: F) -> bool + where + P: AsRef<[u8]>, + T: AsRef<[u8]>, + F: AsRef<[u8]>, + { + let signature = crate::secp256k1_compat::signature_from_der(signature.as_ref()); + let msg = crate::secp256k1_compat::message_from_slice(message.as_ref()); + let pubkey = crate::secp256k1_compat::pubkey_from_slice(pubkey.as_ref()); + + if let (Ok(signature), Ok(message), Ok(pubkey)) = (signature, msg, pubkey) { + if !crate::secp256k1_compat::verify(&message, &signature, &pubkey) { + log::debug!("failed to verify the remote's signature"); + return false; + } + } else { + log::debug!("remote's secp256k1 signature has wrong format"); + return false; + } + true + } +} +/// Empty key provider +#[derive(Debug, Clone)] +pub struct NoopKeyProvider; + +impl KeyProvider for NoopKeyProvider { + type Error = error::SecioError; + + fn sign_ecdsa>(&self, _message: T) -> Result, Self::Error> { + Err(error::SecioError::NotSupportKeyProvider) + } + + fn pubkey(&self) -> Vec { + Vec::new() + } + + fn verify_ecdsa(_pubkey: P, _message: T, _signature: F) -> bool + where + P: AsRef<[u8]>, + T: AsRef<[u8]>, + F: AsRef<[u8]>, + { + false + } +} diff --git a/tentacle/Cargo.toml b/tentacle/Cargo.toml index cb2e3f1b..0a3e9186 100644 --- a/tentacle/Cargo.toml +++ b/tentacle/Cargo.toml @@ -43,7 +43,7 @@ molecule = "0.7.0" igd = { version = "0.12", optional = true } #tls -tokio-rustls = { version = "0.23.0", optional = true } +tokio-rustls = { version = "0.24.0", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] # rand 0.8 not support wasm32 @@ -76,6 +76,7 @@ default = ["tokio-runtime", "tokio-timer"] ws = ["tokio-tungstenite"] tls = ["tokio-rustls"] upnp = ["igd"] +secio-async-trait = ["secio/async-trait"] unstable = [] openssl-vendored = ["secio/openssl-vendored"] diff --git a/tentacle/examples/block_send.rs b/tentacle/examples/block_send.rs index 99b71102..e88dc04a 100644 --- a/tentacle/examples/block_send.rs +++ b/tentacle/examples/block_send.rs @@ -13,15 +13,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + Send + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/examples/heavy_task_schedule.rs b/tentacle/examples/heavy_task_schedule.rs index 61be344d..dfb72309 100644 --- a/tentacle/examples/heavy_task_schedule.rs +++ b/tentacle/examples/heavy_task_schedule.rs @@ -114,15 +114,15 @@ impl ServiceHandle for SHandle { } } -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + Send + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/examples/simple.rs b/tentacle/examples/simple.rs index f8e3d4ea..c526d727 100644 --- a/tentacle/examples/simple.rs +++ b/tentacle/examples/simple.rs @@ -182,11 +182,11 @@ fn main() { // There are many other options in service builder, which are not used here, please refer to the documentation for details // // For the foreseeable future, there is no idea of dynamic addition and deletion agreements -fn create_server() -> Service { +fn create_server() -> Service { ServiceBuilder::default() .insert_protocol(create_meta(0.into())) .insert_protocol(create_meta(1.into())) - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(SHandle) } @@ -195,12 +195,12 @@ fn create_server() -> Service { /// Proto 2 open failure /// /// Because server only supports 0,1 -fn create_client() -> Service { +fn create_client() -> Service { ServiceBuilder::default() .insert_protocol(create_meta(0.into())) .insert_protocol(create_meta(1.into())) .insert_protocol(create_meta(2.into())) - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(SHandle) } diff --git a/tentacle/examples/simple_using_spawn.rs b/tentacle/examples/simple_using_spawn.rs index 0ffa015f..748b56f0 100644 --- a/tentacle/examples/simple_using_spawn.rs +++ b/tentacle/examples/simple_using_spawn.rs @@ -126,11 +126,11 @@ fn main() { } } -fn create_server() -> Service { +fn create_server() -> Service { ServiceBuilder::default() .insert_protocol(create_meta(0.into())) .insert_protocol(create_meta(1.into())) - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(SHandle) } @@ -139,12 +139,12 @@ fn create_server() -> Service { /// Proto 2 open failure /// /// Because server only supports 0,1 -fn create_client() -> Service { +fn create_client() -> Service { ServiceBuilder::default() .insert_protocol(create_meta(0.into())) .insert_protocol(create_meta(1.into())) .insert_protocol(create_meta(2.into())) - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(SHandle) } diff --git a/tentacle/examples/use_poll.rs b/tentacle/examples/use_poll.rs index 30a20de3..9aaf4579 100644 --- a/tentacle/examples/use_poll.rs +++ b/tentacle/examples/use_poll.rs @@ -66,10 +66,10 @@ fn create_meta(id: ProtocolId, recv: Receiver<()>) -> ProtocolMeta { .build() } -fn create_server(recv: Receiver<()>) -> Service { +fn create_server(recv: Receiver<()>) -> Service { ServiceBuilder::default() .insert_protocol(create_meta(0.into(), recv)) - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(SHandle) } diff --git a/tentacle/src/builder.rs b/tentacle/src/builder.rs index 43b62162..087e8ef8 100644 --- a/tentacle/src/builder.rs +++ b/tentacle/src/builder.rs @@ -7,9 +7,9 @@ use tokio_util::codec::LengthDelimitedCodec; use crate::service::config::TlsConfig; use crate::{ protocol_select::SelectFn, - secio::SecioKeyPair, + secio::KeyProvider, service::{ - config::{Meta, ServiceConfig}, + config::{HandshakeType, Meta, ServiceConfig}, ProtocolHandle, ProtocolMeta, Service, TcpSocket, }, traits::{Codec, ProtocolSpawn, ServiceHandle, ServiceProtocol, SessionProtocol}, @@ -18,26 +18,45 @@ use crate::{ }; /// Builder for Service -#[derive(Default)] -pub struct ServiceBuilder { +pub struct ServiceBuilder { inner: IntMap, - key_pair: Option, + handshake_type: HandshakeType, forever: bool, config: ServiceConfig, } -impl ServiceBuilder { +impl Default for ServiceBuilder { + fn default() -> Self { + Self { + handshake_type: HandshakeType::Noop, + inner: IntMap::default(), + forever: false, + config: ServiceConfig::default(), + } + } +} + +impl ServiceBuilder +where + K: KeyProvider, +{ /// New a default empty builder pub fn new() -> Self { Default::default() } /// Combine the configuration of this builder with service handle to create a Service. - pub fn build(self, handle: H) -> Service + pub fn build(self, handle: H) -> Service where - H: ServiceHandle + Unpin, + H: ServiceHandle + Unpin + 'static, { - Service::new(self.inner, handle, self.key_pair, self.forever, self.config) + Service::new( + self.inner, + handle, + self.handshake_type, + self.forever, + self.config, + ) } /// Insert a custom protocol @@ -46,11 +65,11 @@ impl ServiceBuilder { self } - /// Enable encrypted communication mode. + /// Handshake encryption layer protocol selection /// /// If you do not need encrypted communication, you do not need to call this method - pub fn key_pair(mut self, key_pair: SecioKeyPair) -> Self { - self.key_pair = Some(key_pair); + pub fn handshake_type(mut self, handshake_type: HandshakeType) -> Self { + self.handshake_type = handshake_type; self } @@ -157,7 +176,7 @@ impl ServiceBuilder { /// /// for example, set all tcp bind to `127.0.0.1:1080`, set keepalive: /// - /// ```rust + /// ```ignore /// use socket2; /// use tentacle::{service::TcpSocket, builder::ServiceBuilder}; /// #[cfg(unix)] diff --git a/tentacle/src/context.rs b/tentacle/src/context.rs index eedd13af..5a0bf9a8 100644 --- a/tentacle/src/context.rs +++ b/tentacle/src/context.rs @@ -1,7 +1,6 @@ use bytes::Bytes; use futures::prelude::*; use std::{ - collections::HashMap, ops::{Deref, DerefMut}, sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, @@ -15,8 +14,7 @@ use crate::{ channel::{mpsc, mpsc::Priority}, error::SendErrorKind, multiaddr::Multiaddr, - protocol_select::ProtocolInfo, - secio::{PublicKey, SecioKeyPair}, + secio::PublicKey, service::{ event::ServiceTask, ServiceAsyncControl, ServiceControl, SessionType, TargetProtocol, TargetSession, @@ -120,21 +118,14 @@ type Result = std::result::Result<(), SendErrorKind>; // TODO: Need to maintain the network topology map here? pub struct ServiceContext { listens: Vec, - key_pair: Option, inner: ServiceAsyncControl, } impl ServiceContext { /// New - pub(crate) fn new( - task_sender: mpsc::Sender, - proto_infos: HashMap, - key_pair: Option, - closed: Arc, - ) -> Self { + pub(crate) fn new(task_sender: mpsc::Sender, closed: Arc) -> Self { ServiceContext { - inner: ServiceControl::new(task_sender, proto_infos, closed).into(), - key_pair, + inner: ServiceControl::new(task_sender, closed).into(), listens: Vec::new(), } } @@ -246,18 +237,6 @@ impl ServiceContext { &self.inner } - /// Get service protocol message, Map(ID, Name), but can't modify - #[inline] - pub fn protocols(&self) -> &Arc> { - self.inner.protocols() - } - - /// Get the key pair of self - #[inline] - pub fn key_pair(&self) -> Option<&SecioKeyPair> { - self.key_pair.as_ref() - } - /// Get service listen address list #[inline] pub fn listens(&self) -> &[Multiaddr] { @@ -331,7 +310,6 @@ impl ServiceContext { pub(crate) fn clone_self(&self) -> Self { ServiceContext { inner: self.inner.clone(), - key_pair: self.key_pair.clone(), listens: self.listens.clone(), } } diff --git a/tentacle/src/service.rs b/tentacle/src/service.rs index 12c35344..35ab88d8 100644 --- a/tentacle/src/service.rs +++ b/tentacle/src/service.rs @@ -1,6 +1,7 @@ use futures::{channel::mpsc, future::poll_fn, prelude::*, stream::StreamExt, SinkExt}; use log::{debug, error, trace}; use nohash_hasher::IntMap; +use secio::KeyProvider; use std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -22,8 +23,7 @@ use crate::{ protocol_handle_stream::{ ServiceProtocolEvent, ServiceProtocolStream, SessionProtocolEvent, SessionProtocolStream, }, - protocol_select::ProtocolInfo, - secio::{PublicKey, SecioKeyPair}, + secio::PublicKey, service::{ config::{ServiceConfig, State}, event::{ServiceEventAndError, ServiceTask}, @@ -34,7 +34,6 @@ use crate::{ traits::ServiceHandle, transports::{MultiIncoming, MultiTransport, Transport}, utils::extract_peer_id, - yamux::Config as YamuxConfig, ProtocolId, SessionId, }; @@ -45,7 +44,9 @@ pub(crate) mod future_task; mod helper; pub use crate::service::{ - config::{ProtocolHandle, ProtocolMeta, TargetProtocol, TargetSession, TcpSocket}, + config::{ + HandshakeType, ProtocolHandle, ProtocolMeta, TargetProtocol, TargetSession, TcpSocket, + }, control::{ServiceAsyncControl, ServiceControl}, event::{ServiceError, ServiceEvent}, helper::SessionType, @@ -57,13 +58,15 @@ pub use crate::service::config::TlsConfig; type Result = std::result::Result; -struct InnerService { +struct InnerService { protocol_configs: IntMap, sessions: IntMap, multi_transport: MultiTransport, + handshake_type: HandshakeType, + listens: HashSet, #[cfg(all(not(target_arch = "wasm32"), feature = "upnp"))] @@ -105,7 +108,7 @@ struct InnerService { } /// An abstraction of p2p service, currently only supports TCP/websocket protocol -pub struct Service { +pub struct Service { /// Can be upgrade to list service level protocols handle: T, service_context: ServiceContext, @@ -114,18 +117,19 @@ pub struct Service { // Future task manager future_task_manager: Option, - inner_service: Option, + inner_service: Option>, } -impl Service +impl Service where T: ServiceHandle + Unpin, + K: KeyProvider, { /// New a Service pub(crate) fn new( protocol_configs: IntMap, handle: T, - key_pair: Option, + handshake_type: HandshakeType, forever: bool, config: ServiceConfig, ) -> Self { @@ -133,13 +137,6 @@ where mpsc::channel(config.session_config.channel_size); let (task_sender, task_receiver) = priority_mpsc::channel(config.session_config.channel_size); - let proto_infos = protocol_configs - .values() - .map(|meta| { - let proto_info = ProtocolInfo::new(&meta.name(), meta.support_versions()); - (meta.id(), proto_info) - }) - .collect(); let (future_task_sender, future_task_receiver) = mpsc::channel(config.session_config.channel_size); let (user_handle_sender, user_handle_receiver) = @@ -152,8 +149,7 @@ where None }; - let service_context = - ServiceContext::new(task_sender, proto_infos, key_pair, shutdown.clone()); + let service_context = ServiceContext::new(task_sender, shutdown.clone()); Service { handle, @@ -170,6 +166,7 @@ where before_sends: HashMap::default(), handle_sender: user_handle_sender, future_task_sender, + handshake_type, multi_transport: { #[cfg(target_arch = "wasm32")] let transport = MultiTransport::new(config.timeout); @@ -200,42 +197,6 @@ where } } - /// Yamux config for service - /// - /// Panic when max_frame_length < yamux_max_window_size - pub fn yamux_config(mut self, config: YamuxConfig) -> Self { - assert!( - self.inner_service.as_ref().unwrap().config.max_frame_length as u32 - >= config.max_stream_window_size - ); - self.inner_service - .as_mut() - .unwrap() - .config - .session_config - .yamux_config = config; - self - } - - /// Secio max frame length - /// - /// Panic when max_frame_length < yamux_max_window_size - pub fn max_frame_length(mut self, size: usize) -> Self { - assert!( - size as u32 - >= self - .inner_service - .as_ref() - .unwrap() - .config - .session_config - .yamux_config - .max_stream_window_size - ); - self.inner_service.as_mut().unwrap().config.max_frame_length = size; - self - } - /// Listen on the given address. /// /// Return really listen multiaddr, but if use `/dns4/localhost/tcp/80`, @@ -323,12 +284,15 @@ where } } -impl InnerService { +impl InnerService +where + K: KeyProvider, +{ #[cfg(not(target_arch = "wasm32"))] fn spawn_listener(&mut self, incoming: MultiIncoming, listen_address: Multiaddr) { let listener = Listener { inner: incoming, - key_pair: self.service_context.key_pair().cloned(), + handshake_type: self.handshake_type.clone(), event_sender: self.session_event_sender.clone(), max_frame_length: self.config.max_frame_length, timeout: self.config.timeout, @@ -383,7 +347,7 @@ impl InnerService { self.dial_protocols.insert(address.clone(), target); let dial_future = self.multi_transport.clone().dial(address.clone())?; - let key_pair = self.service_context.key_pair().cloned(); + let handshake_type = self.handshake_type.clone(); let timeout = self.config.timeout; let max_frame_length = self.config.max_frame_length; @@ -397,7 +361,7 @@ impl InnerService { ty: SessionType::Outbound, remote_address: addr, listen_address: None, - key_pair, + handshake_type, event_sender: sender, max_frame_length, timeout, @@ -561,7 +525,7 @@ impl InnerService { ty, remote_address, listen_address, - key_pair: self.service_context.key_pair().cloned(), + handshake_type: self.handshake_type.clone(), event_sender: self.session_event_sender.clone(), max_frame_length: self.config.max_frame_length, timeout: self.config.timeout, diff --git a/tentacle/src/service/config.rs b/tentacle/src/service/config.rs index f08cda29..ef482478 100644 --- a/tentacle/src/service/config.rs +++ b/tentacle/src/service/config.rs @@ -344,6 +344,36 @@ impl ProtocolHandle { } } +/// Handshake encryption layer protocol selection +#[non_exhaustive] +pub enum HandshakeType { + /// Enable secio + Secio(T), + /// Disable all built-in encryption layer + Noop, +} + +impl From for HandshakeType +where + K: secio::KeyProvider, +{ + fn from(value: K) -> Self { + HandshakeType::Secio(value) + } +} + +impl Clone for HandshakeType +where + T: Clone, +{ + fn clone(&self) -> Self { + match self { + HandshakeType::Secio(s) => HandshakeType::Secio(s.clone()), + HandshakeType::Noop => HandshakeType::Noop, + } + } +} + /// Service state #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum State { diff --git a/tentacle/src/service/control.rs b/tentacle/src/service/control.rs index 3ee9d090..3148a861 100644 --- a/tentacle/src/service/control.rs +++ b/tentacle/src/service/control.rs @@ -1,16 +1,12 @@ use futures::prelude::*; +use std::sync::{atomic::Ordering, Arc}; use std::time::Duration; -use std::{ - collections::HashMap, - sync::{atomic::Ordering, Arc}, -}; use crate::{ channel::mpsc, error::SendErrorKind, multiaddr::Multiaddr, - protocol_select::ProtocolInfo, service::{event::ServiceTask, TargetProtocol, TargetSession}, ProtocolId, SessionId, }; @@ -23,20 +19,14 @@ type Result = std::result::Result<(), SendErrorKind>; #[derive(Clone)] pub struct ServiceControl { pub(crate) task_sender: mpsc::Sender, - pub(crate) proto_infos: Arc>, closed: Arc, } impl ServiceControl { /// New - pub(crate) fn new( - task_sender: mpsc::Sender, - proto_infos: HashMap, - closed: Arc, - ) -> Self { + pub(crate) fn new(task_sender: mpsc::Sender, closed: Arc) -> Self { ServiceControl { task_sender, - proto_infos: Arc::new(proto_infos), closed, } } @@ -70,12 +60,6 @@ impl ServiceControl { }) } - /// Get service protocol message, Map(ID, Name), but can't modify - #[inline] - pub fn protocols(&self) -> &Arc> { - &self.proto_infos - } - /// Create a new listener #[inline] pub fn listen(&self, address: Multiaddr) -> Result { @@ -257,7 +241,6 @@ impl From for ServiceAsyncControl { fn from(control: ServiceControl) -> Self { ServiceAsyncControl { task_sender: control.task_sender, - proto_infos: control.proto_infos, closed: control.closed, } } @@ -267,7 +250,6 @@ impl From for ServiceControl { fn from(control: ServiceAsyncControl) -> Self { ServiceControl { task_sender: control.task_sender, - proto_infos: control.proto_infos, closed: control.closed, } } @@ -277,7 +259,6 @@ impl From for ServiceControl { #[derive(Clone)] pub struct ServiceAsyncControl { task_sender: mpsc::Sender, - proto_infos: Arc>, closed: Arc, } @@ -308,12 +289,6 @@ impl ServiceAsyncControl { }) } - /// Get service protocol message, Map(ID, Name), but can't modify - #[inline] - pub fn protocols(&self) -> &Arc> { - &self.proto_infos - } - /// Create a new listener #[inline] pub async fn listen(&self, address: Multiaddr) -> Result { diff --git a/tentacle/src/service/helper.rs b/tentacle/src/service/helper.rs index 504092fb..1829fbc2 100644 --- a/tentacle/src/service/helper.rs +++ b/tentacle/src/service/helper.rs @@ -1,7 +1,7 @@ use futures::{channel::mpsc, prelude::*}; use log::{debug, error, trace}; use multiaddr::Multiaddr; -use secio::handshake::Config; +use secio::{handshake::Config, KeyProvider}; use std::{ io, pin::Pin, @@ -13,7 +13,7 @@ use yamux::session::SessionType as YamuxType; use crate::{ error::{HandshakeErrorKind, TransportErrorKind}, - service::future_task::BoxedFutureTask, + service::{future_task::BoxedFutureTask, HandshakeType}, session::SessionEvent, transports::MultiIncoming, }; @@ -72,8 +72,8 @@ impl From for YamuxType { } } -pub(crate) struct HandshakeContext { - pub(crate) key_pair: Option, +pub(crate) struct HandshakeContext { + pub(crate) handshake_type: HandshakeType, pub(crate) event_sender: mpsc::Sender, pub(crate) max_frame_length: usize, pub(crate) timeout: Duration, @@ -82,16 +82,19 @@ pub(crate) struct HandshakeContext { pub(crate) listen_address: Option, } -impl HandshakeContext { +impl HandshakeContext +where + K: KeyProvider, +{ pub async fn handshake(mut self, socket: H) where H: AsyncRead + AsyncWrite + Send + 'static + Unpin, { - match self.key_pair { - Some(key_pair) => { + match self.handshake_type { + HandshakeType::Secio(key_provider) => { let result = crate::runtime::timeout( self.timeout, - Config::new(key_pair) + Config::new(key_provider) .max_frame_length(self.max_frame_length) .handshake(socket), ) @@ -135,7 +138,7 @@ impl HandshakeContext { error!("handshake result send back error: {:?}", err); } } - None => { + HandshakeType::Noop => { let event = SessionEvent::HandshakeSuccess { handle: Box::new(socket), public_key: None, @@ -152,9 +155,9 @@ impl HandshakeContext { } #[cfg(not(target_arch = "wasm32"))] -pub struct Listener { +pub struct Listener { pub(crate) inner: MultiIncoming, - pub(crate) key_pair: Option, + pub(crate) handshake_type: HandshakeType, pub(crate) event_sender: mpsc::Sender, pub(crate) max_frame_length: usize, pub(crate) timeout: Duration, @@ -163,7 +166,10 @@ pub struct Listener { } #[cfg(not(target_arch = "wasm32"))] -impl Listener { +impl Listener +where + K: KeyProvider, +{ fn close(&self, io_err: io::Error) { let mut event_sender = self.event_sender.clone(); let mut future_sender = self.future_task_sender.clone(); @@ -194,7 +200,7 @@ impl Listener { ty: SessionType::Inbound, remote_address, listen_address: Some(self.listen_addr.clone()), - key_pair: self.key_pair.clone(), + handshake_type: self.handshake_type.clone(), event_sender: self.event_sender.clone(), max_frame_length: self.max_frame_length, timeout: self.timeout, @@ -216,7 +222,13 @@ impl Listener { } #[cfg(not(target_arch = "wasm32"))] -impl Stream for Listener { +impl Unpin for Listener {} + +#[cfg(not(target_arch = "wasm32"))] +impl Stream for Listener +where + K: KeyProvider, +{ type Item = (); fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { diff --git a/tentacle/tests/test_before_function.rs b/tentacle/tests/test_before_function.rs index 4d1a6623..05624c85 100644 --- a/tentacle/tests/test_before_function.rs +++ b/tentacle/tests/test_before_function.rs @@ -18,15 +18,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_block_future_task.rs b/tentacle/tests/test_block_future_task.rs index e47b217e..68701fff 100644 --- a/tentacle/tests/test_block_future_task.rs +++ b/tentacle/tests/test_block_future_task.rs @@ -4,14 +4,15 @@ use tentacle::{ async_trait, builder::{MetaBuilder, ServiceBuilder}, context::ProtocolContext, + secio::NoopKeyProvider, service::{ProtocolHandle, ProtocolMeta, Service}, traits::{ServiceHandle, ServiceProtocol}, ProtocolId, }; -pub fn create(meta: ProtocolMeta, shandle: F) -> Service +pub fn create(meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { ServiceBuilder::default() .insert_protocol(meta) diff --git a/tentacle/tests/test_block_send.rs b/tentacle/tests/test_block_send.rs index ec228785..9fc8e42d 100644 --- a/tentacle/tests/test_block_send.rs +++ b/tentacle/tests/test_block_send.rs @@ -18,15 +18,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_block_send_session.rs b/tentacle/tests/test_block_send_session.rs index 3abf6a1e..409dcaa2 100644 --- a/tentacle/tests/test_block_send_session.rs +++ b/tentacle/tests/test_block_send_session.rs @@ -18,15 +18,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_close.rs b/tentacle/tests/test_close.rs index 7d3a8e22..4e1ad359 100644 --- a/tentacle/tests/test_close.rs +++ b/tentacle/tests/test_close.rs @@ -11,9 +11,13 @@ use tentacle::{ use std::{sync::mpsc::channel, thread, time::Duration}; -pub fn create(secio: bool, metas: impl Iterator, shandle: F) -> Service +pub fn create( + secio: bool, + metas: impl Iterator, + shandle: F, +) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default().forever(true); @@ -23,7 +27,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) @@ -163,7 +167,7 @@ fn test(secio: bool, shutdown: bool) { } fn start_service( - mut service: Service, + mut service: Service, listen_addr: Multiaddr, handle: &tokio::runtime::Handle, ) where diff --git a/tentacle/tests/test_dial.rs b/tentacle/tests/test_dial.rs index 462eebcf..37096b26 100644 --- a/tentacle/tests/test_dial.rs +++ b/tentacle/tests/test_dial.rs @@ -18,9 +18,9 @@ use tentacle::{ ProtocolId, SessionId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default() .insert_protocol(meta) @@ -28,7 +28,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_disconnect.rs b/tentacle/tests/test_disconnect.rs index 8f1e83e7..7e4e2b9b 100644 --- a/tentacle/tests/test_disconnect.rs +++ b/tentacle/tests/test_disconnect.rs @@ -11,15 +11,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_kill.rs b/tentacle/tests/test_kill.rs index 8bd3590b..eec7428c 100644 --- a/tentacle/tests/test_kill.rs +++ b/tentacle/tests/test_kill.rs @@ -41,9 +41,9 @@ fn current_used_cpu() -> Option { } } -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default() .insert_protocol(meta) @@ -51,7 +51,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_large_pending_messge.rs b/tentacle/tests/test_large_pending_messge.rs index 96732a5f..06b0b67b 100644 --- a/tentacle/tests/test_large_pending_messge.rs +++ b/tentacle/tests/test_large_pending_messge.rs @@ -12,9 +12,9 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default() .insert_protocol(meta) @@ -23,7 +23,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_peer_id.rs b/tentacle/tests/test_peer_id.rs index 6e6ea0c3..2c01c9c9 100644 --- a/tentacle/tests/test_peer_id.rs +++ b/tentacle/tests/test_peer_id.rs @@ -15,14 +15,14 @@ use tentacle::{ ProtocolId, }; -pub fn create(key_pair: SecioKeyPair, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(key_pair: SecioKeyPair, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { ServiceBuilder::default() .insert_protocol(meta) .forever(true) - .key_pair(key_pair) + .handshake_type(key_pair.into()) .build(shandle) } diff --git a/tentacle/tests/test_priority.rs b/tentacle/tests/test_priority.rs index bcf7ea80..1ef7ef33 100644 --- a/tentacle/tests/test_priority.rs +++ b/tentacle/tests/test_priority.rs @@ -18,9 +18,9 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default() .insert_protocol(meta) @@ -28,7 +28,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_protocol_open.rs b/tentacle/tests/test_protocol_open.rs index 5f1b6f1d..60ff2443 100644 --- a/tentacle/tests/test_protocol_open.rs +++ b/tentacle/tests/test_protocol_open.rs @@ -18,15 +18,15 @@ use tentacle::{ ProtocolId, }; -pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service +pub fn create(secio: bool, meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let builder = ServiceBuilder::default().insert_protocol(meta); if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_protocol_open_close_on_spawn.rs b/tentacle/tests/test_protocol_open_close_on_spawn.rs index bfcb68aa..d7a5988a 100644 --- a/tentacle/tests/test_protocol_open_close_on_spawn.rs +++ b/tentacle/tests/test_protocol_open_close_on_spawn.rs @@ -96,9 +96,13 @@ impl ProtocolSpawn for PHandle { } } -pub fn create(secio: bool, metas: impl Iterator, shandle: F) -> Service +pub fn create( + secio: bool, + metas: impl Iterator, + shandle: F, +) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default().forever(true); @@ -108,7 +112,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_session_handle_open.rs b/tentacle/tests/test_session_handle_open.rs index 506b5720..faa48a97 100644 --- a/tentacle/tests/test_session_handle_open.rs +++ b/tentacle/tests/test_session_handle_open.rs @@ -69,9 +69,13 @@ impl ServiceHandle for SHandle { } } -pub fn create(secio: bool, metas: impl Iterator, shandle: F) -> Service +pub fn create( + secio: bool, + metas: impl Iterator, + shandle: F, +) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default().forever(true); @@ -81,7 +85,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_session_protocol_open_close.rs b/tentacle/tests/test_session_protocol_open_close.rs index 25f1ef72..5afeb317 100644 --- a/tentacle/tests/test_session_protocol_open_close.rs +++ b/tentacle/tests/test_session_protocol_open_close.rs @@ -76,9 +76,13 @@ impl SessionProtocol for PHandle { } } -pub fn create(secio: bool, metas: impl Iterator, shandle: F) -> Service +pub fn create( + secio: bool, + metas: impl Iterator, + shandle: F, +) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default().forever(true); @@ -88,7 +92,7 @@ where if secio { builder - .key_pair(SecioKeyPair::secp256k1_generated()) + .handshake_type(SecioKeyPair::secp256k1_generated().into()) .build(shandle) } else { builder.build(shandle) diff --git a/tentacle/tests/test_tls_dial.rs b/tentacle/tests/test_tls_dial.rs index e4a90423..be6917d3 100644 --- a/tentacle/tests/test_tls_dial.rs +++ b/tentacle/tests/test_tls_dial.rs @@ -3,6 +3,7 @@ use futures::channel; use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys}; use std::io::BufReader; use std::str::FromStr; +use std::sync::Arc; use std::{fs, thread}; use tentacle::{ async_trait, @@ -10,6 +11,7 @@ use tentacle::{ context::{ProtocolContext, ProtocolContextMutRef, ServiceContext}, error::{DialerErrorKind, ListenErrorKind}, multiaddr::Multiaddr, + secio::NoopKeyProvider, service::{ ProtocolHandle, ProtocolMeta, Service, ServiceError, ServiceEvent, SessionType, TargetProtocol, TlsConfig, @@ -24,9 +26,9 @@ use tokio_rustls::rustls::{ SupportedProtocolVersion, ALL_CIPHER_SUITES, }; -pub fn create(meta: ProtocolMeta, shandle: F, cert_path: String) -> Service +pub fn create(meta: ProtocolMeta, shandle: F, cert_path: String) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default() .insert_protocol(meta) @@ -272,7 +274,7 @@ pub fn make_server_config(config: &NetConfig) -> ServerConfig { for cacert in &cacerts { client_auth_roots.add(cacert).unwrap(); } - let client_auth = AllowAnyAuthenticatedClient::new(client_auth_roots); + let client_auth = Arc::new(AllowAnyAuthenticatedClient::new(client_auth_roots)); let server_config = server_config.with_client_cert_verifier(client_auth); diff --git a/tentacle/tests/test_tls_reconnect.rs b/tentacle/tests/test_tls_reconnect.rs index 4602b0b7..83694e5b 100644 --- a/tentacle/tests/test_tls_reconnect.rs +++ b/tentacle/tests/test_tls_reconnect.rs @@ -3,6 +3,7 @@ use crossbeam_channel::Receiver; use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys}; use std::io::BufReader; use std::str::FromStr; +use std::sync::Arc; use std::time::Duration; use std::{fs, thread}; use tentacle::bytes::Bytes; @@ -12,6 +13,7 @@ use tentacle::{ builder::{MetaBuilder, ServiceBuilder}, context::{ProtocolContext, ProtocolContextMutRef}, multiaddr::Multiaddr, + secio::NoopKeyProvider, service::{ProtocolHandle, ProtocolMeta, Service, TargetProtocol, TlsConfig}, traits::{ServiceHandle, ServiceProtocol}, ProtocolId, @@ -23,9 +25,9 @@ use tokio_rustls::rustls::{ SupportedProtocolVersion, ALL_CIPHER_SUITES, }; -pub fn create(meta: ProtocolMeta, shandle: F, cert_path: String) -> Service +pub fn create(meta: ProtocolMeta, shandle: F, cert_path: String) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { let mut builder = ServiceBuilder::default() .insert_protocol(meta) @@ -215,7 +217,7 @@ pub fn make_server_config(config: &NetConfig) -> ServerConfig { for cacert in &cacerts { client_auth_roots.add(cacert).unwrap(); } - let client_auth = AllowAnyAuthenticatedClient::new(client_auth_roots); + let client_auth = Arc::new(AllowAnyAuthenticatedClient::new(client_auth_roots)); let server_config = server_config.with_client_cert_verifier(client_auth); diff --git a/tentacle/tests/test_uninterrupter_poll.rs b/tentacle/tests/test_uninterrupter_poll.rs index d50efe4c..e26f82b9 100644 --- a/tentacle/tests/test_uninterrupter_poll.rs +++ b/tentacle/tests/test_uninterrupter_poll.rs @@ -5,6 +5,7 @@ use tentacle::{ bytes::Bytes, context::{ProtocolContext, ProtocolContextMutRef}, multiaddr::Multiaddr, + secio::NoopKeyProvider, service::{ProtocolHandle, ProtocolMeta, Service, TargetProtocol}, traits::{ServiceHandle, ServiceProtocol}, ProtocolId, @@ -47,9 +48,9 @@ fn create_meta(id: ProtocolId) -> ProtocolMeta { .build() } -pub fn create(meta: ProtocolMeta, shandle: F) -> Service +pub fn create(meta: ProtocolMeta, shandle: F) -> Service where - F: ServiceHandle + Unpin, + F: ServiceHandle + Unpin + 'static, { ServiceBuilder::default() .insert_protocol(meta)