electrum: add rustls
as the default ssl implementation
This commit is contained in:
parent
f5a201b98d
commit
c4dc741310
@ -7,16 +7,21 @@ authors = ["Alekos Filini <alekos.filini@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
log = "^0.4"
|
||||
bitcoin = { version = "0.23", features = ["use-serde"] }
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = { version = "^1.0" }
|
||||
|
||||
# Optional dependencies
|
||||
socks = { version = "^0.3", optional = true }
|
||||
openssl = { version = "^0.10", optional = true }
|
||||
|
||||
[dependencies.bitcoin]
|
||||
version = "0.23"
|
||||
features = ["use-serde"]
|
||||
rustls = { version = "0.16.0", optional = true, features = ["dangerous_configuration"] }
|
||||
webpki = { version = "0.21.0", optional = true }
|
||||
webpki-roots = { version = "^0.19", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["socks", "webpki", "webpki-roots", "rustls"]
|
||||
minimal = []
|
||||
debug-calls = []
|
||||
proxy = ["socks"]
|
||||
ssl = ["openssl"]
|
||||
use-rustls = ["webpki", "webpki-roots", "rustls"]
|
||||
use-openssl = ["openssl"]
|
||||
|
9
core/electrum_client/examples/plaintext.rs
Normal file
9
core/electrum_client/examples/plaintext.rs
Normal file
@ -0,0 +1,9 @@
|
||||
extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
let mut client = Client::new("kirsche.emzy.de:50001").unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
13
core/electrum_client/examples/ssl.rs
Normal file
13
core/electrum_client/examples/ssl.rs
Normal file
@ -0,0 +1,13 @@
|
||||
extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
let mut client = Client::new_ssl(
|
||||
"electrum2.hodlister.co:50002",
|
||||
Some("electrum2.hodlister.co"),
|
||||
)
|
||||
.unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
21
core/electrum_client/examples/tor.rs
Normal file
21
core/electrum_client/examples/tor.rs
Normal file
@ -0,0 +1,21 @@
|
||||
extern crate electrum_client;
|
||||
|
||||
use electrum_client::Client;
|
||||
|
||||
fn main() {
|
||||
// NOTE: This assumes Tor is running localy, with an unauthenticated Socks5 listening at
|
||||
// localhost:9050
|
||||
|
||||
let mut client = Client::new_proxy("ozahtqwp25chjdjd.onion:50001", "127.0.0.1:9050").unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
|
||||
// works both with onion v2/v3 (if your Tor supports them)
|
||||
let mut client = Client::new_proxy(
|
||||
"v7gtzf7nua6hdmb2wtqaqioqmesdb4xrlly4zwr7bvayxv2bpg665pqd.onion:50001",
|
||||
"127.0.0.1:9050",
|
||||
)
|
||||
.unwrap();
|
||||
let res = client.server_features();
|
||||
println!("{:#?}", res);
|
||||
}
|
@ -13,13 +13,23 @@ use bitcoin::consensus::encode::{deserialize, serialize};
|
||||
use bitcoin::hashes::hex::{FromHex, ToHex};
|
||||
use bitcoin::{Script, Txid};
|
||||
|
||||
#[cfg(feature = "ssl")]
|
||||
#[cfg(feature = "use-openssl")]
|
||||
use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
|
||||
#[cfg(all(
|
||||
any(feature = "default", feature = "use-rustls"),
|
||||
not(feature = "use-openssl")
|
||||
))]
|
||||
use rustls::{ClientConfig, ClientSession, StreamOwned};
|
||||
|
||||
#[cfg(feature = "socks")]
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
use socks::{Socks5Stream, ToTargetAddr};
|
||||
|
||||
#[cfg(any(feature = "socks", feature = "proxy"))]
|
||||
#[cfg(any(
|
||||
feature = "default",
|
||||
feature = "use-rustls",
|
||||
feature = "use-openssl",
|
||||
feature = "proxy"
|
||||
))]
|
||||
use stream::ClonableStream;
|
||||
|
||||
use batch::Batch;
|
||||
@ -76,7 +86,7 @@ impl Client<TcpStream> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssl")]
|
||||
#[cfg(feature = "use-openssl")]
|
||||
impl Client<ClonableStream<SslStream<TcpStream>>> {
|
||||
pub fn new_ssl<A: ToSocketAddrs>(socket_addr: A, domain: Option<&str>) -> Result<Self, Error> {
|
||||
let mut builder =
|
||||
@ -107,7 +117,71 @@ impl Client<ClonableStream<SslStream<TcpStream>>> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "proxy")]
|
||||
#[cfg(all(
|
||||
any(feature = "default", feature = "use-rustls"),
|
||||
not(feature = "use-openssl")
|
||||
))]
|
||||
mod danger {
|
||||
use rustls;
|
||||
use webpki;
|
||||
|
||||
pub struct NoCertificateVerification {}
|
||||
|
||||
impl rustls::ServerCertVerifier for NoCertificateVerification {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_roots: &rustls::RootCertStore,
|
||||
_presented_certs: &[rustls::Certificate],
|
||||
_dns_name: webpki::DNSNameRef<'_>,
|
||||
_ocsp: &[u8],
|
||||
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
|
||||
Ok(rustls::ServerCertVerified::assertion())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "default", feature = "use-rustls"),
|
||||
not(feature = "use-openssl")
|
||||
))]
|
||||
impl Client<ClonableStream<StreamOwned<ClientSession, TcpStream>>> {
|
||||
pub fn new_ssl<A: ToSocketAddrs>(socket_addr: A, domain: Option<&str>) -> Result<Self, Error> {
|
||||
let mut config = ClientConfig::new();
|
||||
if domain.is_none() {
|
||||
config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(std::sync::Arc::new(danger::NoCertificateVerification {}))
|
||||
} else {
|
||||
// TODO: cert pinning
|
||||
config
|
||||
.root_store
|
||||
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||
}
|
||||
|
||||
let tcp_stream = TcpStream::connect(socket_addr)?;
|
||||
let session = ClientSession::new(
|
||||
&std::sync::Arc::new(config),
|
||||
webpki::DNSNameRef::try_from_ascii_str(domain.unwrap_or("not.validated"))
|
||||
.map_err(|_| Error::InvalidDNSNameError(domain.unwrap_or("<NONE>").to_string()))?,
|
||||
);
|
||||
let stream = StreamOwned::new(session, tcp_stream);
|
||||
let stream: ClonableStream<_> = stream.into();
|
||||
|
||||
let buf_reader = BufReader::new(stream.clone());
|
||||
|
||||
Ok(Self {
|
||||
stream,
|
||||
buf_reader,
|
||||
headers: VecDeque::new(),
|
||||
script_notifications: BTreeMap::new(),
|
||||
|
||||
#[cfg(feature = "debug-calls")]
|
||||
calls: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
impl Client<ClonableStream<Socks5Stream>> {
|
||||
pub fn new_proxy<A: ToSocketAddrs, T: ToTargetAddr>(
|
||||
target_addr: T,
|
||||
@ -478,7 +552,7 @@ impl<S: Read + Write> Client<S> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "debug-calls")]
|
||||
pub fn calls_made(&self) -> u32 {
|
||||
pub fn calls_made(&self) -> usize {
|
||||
self.calls
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,29 @@
|
||||
pub extern crate bitcoin;
|
||||
extern crate log;
|
||||
#[cfg(feature = "ssl")]
|
||||
#[cfg(feature = "use-openssl")]
|
||||
extern crate openssl;
|
||||
#[cfg(all(
|
||||
any(feature = "default", feature = "use-rustls"),
|
||||
not(feature = "use-openssl")
|
||||
))]
|
||||
extern crate rustls;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
#[cfg(feature = "proxy")]
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
extern crate socks;
|
||||
#[cfg(any(feature = "use-rustls", feature = "default"))]
|
||||
extern crate webpki;
|
||||
#[cfg(any(feature = "use-rustls", feature = "default"))]
|
||||
extern crate webpki_roots;
|
||||
|
||||
pub mod batch;
|
||||
pub mod client;
|
||||
#[cfg(any(feature = "socks", feature = "proxy"))]
|
||||
#[cfg(any(
|
||||
feature = "default",
|
||||
feature = "use-rustls",
|
||||
feature = "use-openssl",
|
||||
feature = "proxy"
|
||||
))]
|
||||
mod stream;
|
||||
#[cfg(test)]
|
||||
mod test_stream;
|
||||
|
@ -167,10 +167,11 @@ pub enum Error {
|
||||
NotSubscribed(ScriptHash),
|
||||
InvalidResponse(serde_json::Value),
|
||||
Message(String),
|
||||
InvalidDNSNameError(String),
|
||||
|
||||
#[cfg(feature = "ssl")]
|
||||
#[cfg(feature = "use-openssl")]
|
||||
InvalidSslMethod(openssl::error::ErrorStack),
|
||||
#[cfg(feature = "ssl")]
|
||||
#[cfg(feature = "use-openssl")]
|
||||
SslHandshakeError(openssl::ssl::HandshakeError<std::net::TcpStream>),
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user