Merge bitcoindevkit/rust-electrum-client#135: Add use-rustls-ring feature

8d71f9597c feat: add use-rustls-ring feature (thunderbiscuit)

Pull request description:

  This PR adds the ability to build the client using the `ring` dependency for `rustls` instead of the new default `aws-lc-rs`.

  As of the [`0.23.0` release](https://github.com/rustls/rustls/releases/tag/v%2F0.23.0), rustls changed its default cryptography provider to [aws-lc-rs](https://crates.io/crates/aws-lc-rs). This new library is actually a set of bindings to a C library maintained by AWS, and they provide prebuilt bindings for [some platforms](https://aws.github.io/aws-lc-rs/platform_support.html) but not all. On these other platforms, the compilation step will attempt to build the bindings, requiring extra dependencies (CMake, libclang and others depending on the platform). This compilation step is what is currently breaking our Android and Swift builds for bdk-ffi. It is certainly possible to build the bindings (and the AWS docs on it are very nice), but for some reason I have not been able to make it work everywhere yet (local, CI, Windows).

  This PR enables us to use the previous default `ring` library for rustls. I basically have to turn off the default features on `rustls` and re-enable all of them _except_ for the `aws_lc_rs`. We also have a few feature-gated constructs in the library, for which I needed to add the new proposed `use-rustls-ring` feature in order to make all of this work for us. Let me know if there are maybe better ways to achieve this!

ACKs for top commit:
  oleonardolima:
    ACK 8d71f9597c
  notmandatory:
    ACK 8d71f9597c

Tree-SHA512: 5ea8bfac7a18700e32035518e9e8253252c8ff9064b011e14a060ac8ed7b478876ee408ce06a89af9e53de837ffa9a13fbe5030d12b48a76558fd4e8187e5651
This commit is contained in:
Steve Myers 2024-07-31 17:02:32 -05:00
commit 54797a0be8
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
5 changed files with 48 additions and 14 deletions

View File

@ -45,3 +45,4 @@ jobs:
- run: cargo check --verbose --no-default-features --features=minimal,debug-calls
- run: cargo check --verbose --no-default-features --features=proxy,use-openssl
- run: cargo check --verbose --no-default-features --features=proxy,use-rustls
- run: cargo check --verbose --no-default-features --features=proxy,use-rustls-ring

View File

@ -25,7 +25,7 @@ serde_json = { version = "^1.0" }
# Optional dependencies
openssl = { version = "0.10", optional = true }
rustls = { version = "0.23", optional = true }
rustls = { version = "0.23", optional = true, default-features = false }
webpki-roots = { version = "0.25", optional = true }
byteorder = { version = "1.0", optional = true }
@ -41,5 +41,6 @@ default = ["proxy", "use-rustls"]
minimal = []
debug-calls = []
proxy = ["byteorder", "winapi", "libc"]
use-rustls = ["webpki-roots", "rustls"]
use-rustls = ["webpki-roots", "rustls/default"]
use-rustls-ring = ["webpki-roots", "rustls/ring", "rustls/logging", "rustls/std", "rustls/tls12"]
use-openssl = ["openssl"]

View File

@ -25,14 +25,22 @@ extern crate log;
#[cfg(feature = "use-openssl")]
extern crate openssl;
#[cfg(all(
any(feature = "default", feature = "use-rustls"),
any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
),
not(feature = "use-openssl")
))]
extern crate rustls;
extern crate serde;
extern crate serde_json;
#[cfg(any(feature = "use-rustls", feature = "default"))]
#[cfg(any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
))]
extern crate webpki_roots;
#[cfg(any(feature = "default", feature = "proxy"))]
@ -51,7 +59,8 @@ mod batch;
#[cfg(any(
all(feature = "proxy", feature = "use-openssl"),
all(feature = "proxy", feature = "use-rustls")
all(feature = "proxy", feature = "use-rustls"),
all(feature = "proxy", feature = "use-rustls-ring")
))]
pub mod client;
@ -66,7 +75,8 @@ pub use api::ElectrumApi;
pub use batch::Batch;
#[cfg(any(
all(feature = "proxy", feature = "use-openssl"),
all(feature = "proxy", feature = "use-rustls")
all(feature = "proxy", feature = "use-rustls"),
all(feature = "proxy", feature = "use-rustls-ring")
))]
pub use client::*;
pub use config::{Config, ConfigBuilder, Socks5Config};

View File

@ -23,7 +23,11 @@ use bitcoin::{Script, Txid};
use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
#[cfg(all(
any(feature = "default", feature = "use-rustls"),
any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
),
not(feature = "use-openssl")
))]
use rustls::{
@ -286,7 +290,11 @@ impl RawClient<ElectrumSslStream> {
}
#[cfg(all(
any(feature = "default", feature = "use-rustls"),
any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
),
not(feature = "use-openssl")
))]
mod danger {
@ -336,13 +344,21 @@ mod danger {
}
#[cfg(all(
any(feature = "default", feature = "use-rustls"),
any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
),
not(feature = "use-openssl")
))]
/// Transport type used to establish a Rustls TLS encrypted/authenticated connection with the server
pub type ElectrumSslStream = StreamOwned<ClientConnection, TcpStream>;
#[cfg(all(
any(feature = "default", feature = "use-rustls"),
any(
feature = "default",
feature = "use-rustls",
feature = "use-rustls-ring"
),
not(feature = "use-openssl")
))]
impl RawClient<ElectrumSslStream> {
@ -451,7 +467,11 @@ impl RawClient<ElectrumProxyStream> {
Ok(stream.into())
}
#[cfg(any(feature = "use-openssl", feature = "use-rustls"))]
#[cfg(any(
feature = "use-openssl",
feature = "use-rustls",
feature = "use-rustls-ring"
))]
/// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
/// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
/// allows to specify, for instance, `.onion` addresses.

View File

@ -315,8 +315,7 @@ pub enum Error {
CouldntLockReader,
/// Broken IPC communication channel: the other thread probably has exited
Mpsc,
#[cfg(feature = "use-rustls")]
#[cfg(any(feature = "use-rustls", feature = "use-rustls-ring"))]
/// Could not create a rustls client connection
CouldNotCreateConnection(rustls::Error),
@ -340,7 +339,10 @@ impl Display for Error {
Error::SslHandshakeError(e) => Display::fmt(e, f),
#[cfg(feature = "use-openssl")]
Error::InvalidSslMethod(e) => Display::fmt(e, f),
#[cfg(feature = "use-rustls")]
#[cfg(any(
feature = "use-rustls",
feature = "use-rustls-ring",
))]
Error::CouldNotCreateConnection(e) => Display::fmt(e, f),
Error::Message(e) => f.write_str(e),