From 743b0aeef6aedc310f22a76d51a4720bd1ad6e12 Mon Sep 17 00:00:00 2001 From: Leonardo Lima Date: Sun, 28 Jul 2024 11:02:36 -0500 Subject: [PATCH] wip: add optional crypto provider to client config --- src/client.rs | 10 +++++++--- src/config.rs | 8 ++++++++ src/raw_client.rs | 30 ++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/client.rs b/src/client.rs index 81cbd38..da8a95d 100644 --- a/src/client.rs +++ b/src/client.rs @@ -116,10 +116,14 @@ impl ClientType { config.validate_domain(), socks5, config.timeout(), + config.crypto_provider(), + )?, + None => RawClient::new_ssl( + url.as_str(), + config.validate_domain(), + config.timeout(), + config.crypto_provider(), )?, - None => { - RawClient::new_ssl(url.as_str(), config.validate_domain(), config.timeout())? - } }; Ok(ClientType::SSL(client)) diff --git a/src/config.rs b/src/config.rs index 47da1f9..b807ab2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,7 @@ use std::time::Duration; +use rustls::crypto::CryptoProvider; + /// Configuration for an electrum client /// /// Refer to [`Client::from_config`] and [`ClientType::from_config`]. @@ -12,6 +14,7 @@ pub struct Config { socks5: Option, /// timeout in seconds, default None (depends on TcpStream default) timeout: Option, + crypto_provider: Option, /// number of retry if any error, default 1 retry: u8, /// when ssl, validate the domain, default true @@ -135,6 +138,10 @@ impl Config { pub fn builder() -> ConfigBuilder { ConfigBuilder::new() } + + pub fn crypto_provider(&self) -> Option { + self.crypto_provider + } } impl Default for Config { @@ -144,6 +151,7 @@ impl Default for Config { timeout: None, retry: 1, validate_domain: true, + crypto_provider: None, } } } diff --git a/src/raw_client.rs b/src/raw_client.rs index 1b83c73..ac82586 100644 --- a/src/raw_client.rs +++ b/src/raw_client.rs @@ -22,6 +22,8 @@ use bitcoin::{Script, Txid}; #[cfg(feature = "use-openssl")] use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode}; +use rustls::crypto::aws_lc_rs::default_provider; +use rustls::crypto::{self, CryptoProvider}; #[cfg(all( any( feature = "default", @@ -368,6 +370,7 @@ impl RawClient { socket_addrs: A, validate_domain: bool, timeout: Option, + crypto_provider: Option, ) -> Result { debug!( "new_ssl socket_addrs.domain():{:?} validate_domain:{} timeout:{:?}", @@ -378,16 +381,28 @@ impl RawClient { if validate_domain { socket_addrs.domain().ok_or(Error::MissingDomain)?; } + + let crypto_provider = match crypto_provider { + Some(provider) => provider, + None => { + #[cfg(feature = "use-rustls")] + crypto::aws_lc_rs::default_provider(); + + #[cfg(feature = "use-rustls-ring")] + crypto::ring::default_provider() + } + }; + match timeout { Some(timeout) => { let stream = connect_with_total_timeout(socket_addrs.clone(), timeout)?; stream.set_read_timeout(Some(timeout))?; stream.set_write_timeout(Some(timeout))?; - Self::new_ssl_from_stream(socket_addrs, validate_domain, stream) + Self::new_ssl_from_stream(socket_addrs, validate_domain, stream, crypto_provider) } None => { let stream = TcpStream::connect(socket_addrs.clone())?; - Self::new_ssl_from_stream(socket_addrs, validate_domain, stream) + Self::new_ssl_from_stream(socket_addrs, validate_domain, stream, crypto_provider) } } } @@ -397,10 +412,11 @@ impl RawClient { socket_addr: A, validate_domain: bool, tcp_stream: TcpStream, + crypto_provider: CryptoProvider, ) -> Result { use std::convert::TryFrom; - let builder = ClientConfig::builder(); + let builder = ClientConfig::builder_with_provider(crypto_provider.into()); let config = if validate_domain { socket_addr.domain().ok_or(Error::MissingDomain)?; @@ -480,6 +496,7 @@ impl RawClient { validate_domain: bool, proxy: &crate::Socks5Config, timeout: Option, + crypto_provider: Option, ) -> Result, Error> { let target = target_addr.to_target_addr()?; @@ -496,7 +513,12 @@ impl RawClient { stream.get_mut().set_read_timeout(timeout)?; stream.get_mut().set_write_timeout(timeout)?; - RawClient::new_ssl_from_stream(target, validate_domain, stream.into_inner()) + RawClient::new_ssl_from_stream( + target, + validate_domain, + stream.into_inner(), + crypto_provider, + ) } }