Skip to content

Commit 6fe96fd

Browse files
committed
Merge #150: fix(insecure-tls): NoCertificateVerification implementation
05771a8 fix: `NoCertificateVerification` implementation (Leonardo Lima) Pull request description: fixes #149 bitcoindevkit/bdk#1598 <!-- You can erase any parts of this template not applicable to your Pull Request. --> ### Description <!-- Describe the purpose of this PR, what's being adding and/or fixed --> It has been noticed some issues by both users and developers, as reported in #149, bitcoindevkit/bdk#1598 and wizardsardine/liana#1300, when using the library with `use-rustls-{ring}` feature to connect to electrum servers that use self-signed certificates, there are even some issues when trying to connect to `ssl://electrum.blockstream.info:50002` server. To connect in an insecure manner either with `rustls` or `openssl` features, the user can set the `validate_domain` field in the `Config` to false, this will either set the `SslVerifyMode::NONE` when using `openssl`, or use the custom `NoCertificateVerification` for the `rustls::client::danger::ServerCertVerifier` trait when using `rustls`, that said it should ignore the certificate verification when used. At the current library state, it's failing because we didn't set up the supported `rustls::SignatureScheme` properly, returning an empty vector at the moment. This PR focuses on fixing this issue by relying on the `CryptoProvider` in usage to get the correct and supported signature schemes. As part of the research to understand the problem, I've noticed that ideally, we should still use both the `rustls::webpki::verify_tls12_signature` and `rustls::webpki::verify_tls12_signature` and only rely on `rustls::client::danger::ServerCertVerified::assertion()` to ignore the certificate verification, however, it would still fail in scenarios such as bitcoindevkit/bdk#1598 which uses X.509 certificates with any version other than 3 (it uses version 1), see [here](https://github.com/rustls/webpki/blob/1a0d1646d0bb1b7851bf81c6244cab09c352d8ef/src/cert.rs#L202-L218). I kept the current behavior to also ignore the TLS signature, but I still would like to bring this to the discussion, should we validate it properly and update the documentation to mention the `webpki` limitation instead ? ### Notes to the reviewers I kept the current behavior to also ignore the TLS signature, but I still would like to bring this to the discussion, should we validate it properly and update the documentation to mention the `webpki` limitation instead ? <!-- In this section you can include notes directed to the reviewers, like explaining why some parts of the PR were done in a specific way --> ### Changelog notice - Updates the `NoCertificateVerification` implementation for the `rustls::client::danger::ServerCertVerifier` to use the `rustls::SignatureScheme` from `CryptoProvider` in use. <!-- Notice the release manager should include in the release tag message changelog --> <!-- See https://keepachangelog.com/en/1.0.0/ for examples --> ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [ ] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [ ] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [ ] I'm linking the issue being fixed by this PR ACKs for top commit: LLFourn: ACK 05771a8 ValuedMammal: ACK 05771a8 notmandatory: ACK 05771a8 Tree-SHA512: f74dedf458853fb19cd21dedb5b92158acd865ee0ab0fd6bbb2b3e267bac22edc7cf004d2dc0068f66d2665d87e6dd419231710a02317e3b2bfaa9f408b30759
2 parents 0b97659 + 05771a8 commit 6fe96fd

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

src/raw_client.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -299,46 +299,52 @@ impl RawClient<ElectrumSslStream> {
299299
))]
300300
mod danger {
301301
use crate::raw_client::ServerName;
302-
use rustls::client::danger::ServerCertVerified;
303-
use rustls::pki_types::CertificateDer;
304-
use rustls::pki_types::UnixTime;
305-
use rustls::Error;
302+
use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified};
303+
use rustls::crypto::CryptoProvider;
304+
use rustls::pki_types::{CertificateDer, UnixTime};
305+
use rustls::DigitallySignedStruct;
306306

307307
#[derive(Debug)]
308-
pub struct NoCertificateVerification {}
308+
pub struct NoCertificateVerification(CryptoProvider);
309+
310+
impl NoCertificateVerification {
311+
pub fn new(provider: CryptoProvider) -> Self {
312+
Self(provider)
313+
}
314+
}
309315

310316
impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
311317
fn verify_server_cert(
312318
&self,
313-
_end_entity: &CertificateDer,
314-
_intermediates: &[CertificateDer],
315-
_server_name: &ServerName,
316-
_ocsp_response: &[u8],
319+
_end_entity: &CertificateDer<'_>,
320+
_intermediates: &[CertificateDer<'_>],
321+
_server_name: &ServerName<'_>,
322+
_ocsp: &[u8],
317323
_now: UnixTime,
318-
) -> Result<ServerCertVerified, Error> {
324+
) -> Result<ServerCertVerified, rustls::Error> {
319325
Ok(ServerCertVerified::assertion())
320326
}
321327

322328
fn verify_tls12_signature(
323329
&self,
324330
_message: &[u8],
325331
_cert: &CertificateDer<'_>,
326-
_dss: &rustls::DigitallySignedStruct,
327-
) -> Result<rustls::client::danger::HandshakeSignatureValid, Error> {
328-
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
332+
_dss: &DigitallySignedStruct,
333+
) -> Result<HandshakeSignatureValid, rustls::Error> {
334+
Ok(HandshakeSignatureValid::assertion())
329335
}
330336

331337
fn verify_tls13_signature(
332338
&self,
333339
_message: &[u8],
334340
_cert: &CertificateDer<'_>,
335-
_dss: &rustls::DigitallySignedStruct,
336-
) -> Result<rustls::client::danger::HandshakeSignatureValid, Error> {
337-
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
341+
_dss: &DigitallySignedStruct,
342+
) -> Result<HandshakeSignatureValid, rustls::Error> {
343+
Ok(HandshakeSignatureValid::assertion())
338344
}
339345

340346
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
341-
vec![]
347+
self.0.signature_verification_algorithms.supported_schemes()
342348
}
343349
}
344350
}
@@ -420,7 +426,10 @@ impl RawClient<ElectrumSslStream> {
420426
builder
421427
.dangerous()
422428
.with_custom_certificate_verifier(std::sync::Arc::new(
423-
danger::NoCertificateVerification {},
429+
#[cfg(feature = "use-rustls")]
430+
danger::NoCertificateVerification::new(rustls::crypto::aws_lc_rs::default_provider()),
431+
#[cfg(feature = "use-rustls-ring")]
432+
danger::NoCertificateVerification::new(rustls::crypto::ring::default_provider()),
424433
))
425434
.with_no_client_auth()
426435
};

0 commit comments

Comments
 (0)