Repository: seanmonstar/reqwest (language: rust)

Issue:
danger_accept_invalid_certs doesn't work with rustls-tls
version 0.11.0


Discussion / hints:
Do you have any more details of when it doesn't work? I just tried it in reqwest's test suite (`cargo test --no-default-features --features rustls-tls --test badssl`), and with the option set it fetches a self-signed certificate.
I just ran into the same issue.

> error trying to connect: invalid certificate: BadDER" 

I found out that this seems to happen when using TLS 1.3 … as for that case the `NoVerifier` implementation doesn't work.

It looks like the `ServerCertVerifier` trait has some default functions, which fail the certificate.

Creating my own `NoVerifier` with the following code works:

~~~rust
struct NoVerifier;

    impl ServerCertVerifier for NoVerifier {
        fn verify_server_cert(
            &self,
            _roots: &RootCertStore,
            _presented_certs: &[Certificate],
            _dns_name: DNSNameRef,
            _ocsp_response: &[u8],
        ) -> Result<ServerCertVerified, TLSError> {
            Ok(ServerCertVerified::assertion())
        }

        fn verify_tls12_signature(
            &self,
            _message: &[u8],
            _cert: &Certificate,
            _dss: &DigitallySignedStruct,
        ) -> Result<HandshakeSignatureValid, TLSError> {
            Ok(HandshakeSignatureValid::assertion())
        }

        fn verify_tls13_signature(
            &self,
            _message: &[u8],
            _cert: &Certificate,
            _dss: &DigitallySignedStruct,
        ) -> Result<HandshakeSignatureValid, TLSError> {
            Ok(HandshakeSignatureValid::assertion())
        }
    }
~~~

And then use it like:

~~~rust
    pub fn make_insecure(client: reqwest::ClientBuilder) -> reqwest::ClientBuilder {
        log::warn!("Disabling TLS verification for client. Do not use this in production!");
        let mut tls = ClientConfig::new();
        tls.dangerous()
            .set_certificate_verifier(std::sync::Arc::new(NoVerifier));

        client.use_preconfigured_tls(tls)
    }
~~~
Oh cool find! Would you like to open a PR adding that to the existing NoVerifier?

Fix patch:
diff --git a/src/tls.rs b/src/tls.rs
index d0c53fa62..3c3696b22 100644
--- a/src/tls.rs
+++ b/src/tls.rs
@@ -1,5 +1,8 @@
 #[cfg(feature = "__rustls")]
-use rustls::{RootCertStore, ServerCertVerified, ServerCertVerifier, TLSError};
+use rustls::{
+    internal::msgs::handshake::DigitallySignedStruct, HandshakeSignatureValid, RootCertStore,
+    ServerCertVerified, ServerCertVerifier, TLSError,
+};
 use std::fmt;
 #[cfg(feature = "__rustls")]
 use tokio_rustls::webpki::DNSNameRef;
@@ -323,6 +326,24 @@ impl ServerCertVerifier for NoVerifier {
     ) -> Result<ServerCertVerified, TLSError> {
         Ok(ServerCertVerified::assertion())
     }
+
+    fn verify_tls12_signature(
+        &self,
+        _message: &[u8],
+        _cert: &rustls::Certificate,
+        _dss: &DigitallySignedStruct,
+    ) -> Result<HandshakeSignatureValid, TLSError> {
+        Ok(HandshakeSignatureValid::assertion())
+    }
+
+    fn verify_tls13_signature(
+        &self,
+        _message: &[u8],
+        _cert: &rustls::Certificate,
+        _dss: &DigitallySignedStruct,
+    ) -> Result<HandshakeSignatureValid, TLSError> {
+        Ok(HandshakeSignatureValid::assertion())
+    }
 }
 
 #[cfg(test)]


Test patch: