reqwest
reqwest copied to clipboard
Failing to connect with rustls-tls in reqwest 0.12
I've been using the reqwest library for a long time with rustls-tls and self-signed certificates. However, when upgrading to version 0.12 the connection fails and the returning error does not help much. It simply says connection error.
What changed in this version that could cause the failure?
The code is very much like this:
let mut contents_cert = Vec::new();
File::open("./pki/ECC-secp256r1/ca_cert_and_key.pem").unwrap()
.read_to_end(&mut contents_cert).unwrap();
let root_cert = reqwest::Certificate::from_pem(&contents_cert).unwrap();
let mut client_cert = Vec::new();
let cert_and_key_name = "./pki/ECC-secp256r1/meter_client01_cert_and_key.pem".to_string();
File::open(cert_and_key_name).unwrap()
.read_to_end(&mut client_cert).unwrap();
let identify = reqwest::Identity::from_pem(&client_cert).unwrap();
// Cria um cliente que ira fazer as requisições para o servidor IEEE 2030.5
let client = Client::builder()
.timeout(Duration::from_secs(5))
.add_root_certificate(root_cert)
.identity(identify)
.connection_verbose(true)
.https_only(true)
.danger_accept_invalid_certs(true) // para rustls
.max_tls_version(reqwest::tls::Version::TLS_1_2)
.use_rustls_tls()
.build().unwrap();
let result = client.get (url.clone())
.send()
.await;
Thank you very much in advance, Gustavo
Interesting. Does it work with native-tls? Could you enable logging to see the logs from rustls?
You'll need to enable rustls/logging
of v0.22.x, and turn on a logger such as env-logger
.
I can add that the peer_certificate()
method now returns only first 2 bytes of server's TLS certificate (I also use rustls
) https://github.com/seanmonstar/reqwest/blob/7a5df2126081b83d29758ef31f9f38369ac85ae4/src/tls.rs#L583
Not sure if its related, since other than that the connections works as expected
@djc if you have time, does either of the above issues sound familiar? Perhaps I goofed something when updating.
I can add that the
peer_certificate()
method now returns only first 2 bytes of server's TLS certificate (I also userustls
)https://github.com/seanmonstar/reqwest/blob/7a5df2126081b83d29758ef31f9f38369ac85ae4/src/tls.rs#L583
Not sure if its related, since other than that the connections works as expected
This definitely seems unrelated.
I've been using the reqwest library for a long time with rustls-tls and self-signed certificates. However, when upgrading to version 0.12 the connection fails and the returning error does not help much. It simply says connection error.
What is the exact error? @seanmonstar are you wrapping rustls errors somehow? We usually try pretty hard to provide detailed errors.
I mean, it's wrapped in a reqwest::Error
, but it has the io::Error
as a source. I suspect there is more useful information available, we just need it to understand the problem :)
I finally got the error:
Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("utfpr.edu.br")), port: Some(8443), path: "/upt", query: None, fragment: None }, source: Error { kind: Connect, source: Some(Custom { kind: Other, error: Custom { kind: InvalidData, error: PeerMisbehaved(SignedKxWithWrongAlgorithm) } }) } }
I finally got the error:
Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("utfpr.edu.br")), port: Some(8443), path: "/upt", query: None, fragment: None }, source: Error { kind: Connect, source: Some(Custom { kind: Other, error: Custom { kind: InvalidData, error: PeerMisbehaved(SignedKxWithWrongAlgorithm) } }) } }
It seems to be certificate signature algorithm differing from signature algorithm negotiated for connection. However, i'm using the same certificates that i used with reqwest 0.11.27.
Would you be able to post a packet capture of this failure happening, and/or warn-level logs emitted from the rustls client? (RUST_LOG=warn
if your process incorporates env_logger
).
Might also help if you can disclose the server that you are trying to connect to.
The server domain is in the error message. Also, just noting down some versions: the upgrade went from rustls 0.21 to 0.22 (not yet on 0.23).
Would you be able to post a packet capture of this failure happening, and/or warn-level logs emitted from the rustls client? (
RUST_LOG=warn
if your process incorporatesenv_logger
).
[2024-03-22T14:25:47Z WARN rustls::client::tls12] peer signed kx with wrong algorithm (got Unknown(0) expect [ED25519, ECDSA_NISTP521_SHA512, ECDSA_NISTP384_SHA384, ECDSA_NISTP256_SHA256]) Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("utfpr.edu.br")), port: Some(8443), path: "/upt", query: None, fragment: None }, source: Error { kind: Connect, source: Some(Custom { kind: Other, error: Custom { kind: InvalidData, error: PeerMisbehaved(SignedKxWithWrongAlgorithm) } }) } }
Might also help if you can disclose the server that you are trying to connect to.
The server is implemented in Java (spring boot). Remember that i said that i'm using the same code / certificates for at least two years. It just stop to work with reqwest 0.12.
My certificates are ECDSA_SECP256R1.
Same error with reqwest 0.12.1, with returned to rustls 0.21.
[2024-03-22T14:57:37Z WARN rustls::client::tls12] peer signed kx with wrong algorithm (got Unknown(0) expect [ED25519, ECDSA_NISTP521_SHA512, ECDSA_NISTP384_SHA384, ECDSA_NISTP256_SHA256])
Would you be able to post a packet capture of this failure happening, and/or warn-level logs emitted from the rustls client? (
RUST_LOG=warn
if your process incorporatesenv_logger
).[2024-03-22T14:25:47Z WARN rustls::client::tls12] peer signed kx with wrong algorithm (got Unknown(0) expect [ED25519, ECDSA_NISTP521_SHA512, ECDSA_NISTP384_SHA384, ECDSA_NISTP256_SHA256]) Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("utfpr.edu.br")), port: Some(8443), path: "/upt", query: None, fragment: None }, source: Error { kind: Connect, source: Some(Custom { kind: Other, error: Custom { kind: InvalidData, error: PeerMisbehaved(SignedKxWithWrongAlgorithm) } }) } }
Thanks!
Over here https://github.com/seanmonstar/reqwest/blob/master/src/tls.rs#L557-L558 offers SignatureScheme::ECDSA_SHA1_Legacy
, but rustls has so little support for ECDSA-SHA1 nowadays that it cannot check that it is compatible with the selected ciphersuite.
We could resolve that by:
- reqwest doesn't offer SHA1 -- but that seems silly in the context of the purpose of that code
- rustls could regain enough knowledge about SHA1 to pass this check -- I think this resolution seems preferable?
So, getting to the bottom of the cause of this on discord with @cpu :
In rustls 0.22 we removed the default function definition for ServerCertVerifier::supported_verify_schemes
. In eb94f26919e881177ad3d9cd172f47d1a8263799 (contained in reqwest 0.12.0 & 0.12.1) this was supplied in reqwest's verifier (see https://github.com/seanmonstar/reqwest/blob/master/src/tls.rs#L557-L558, compare to https://github.com/rustls/rustls/commit/e9c15abe0633416aefc783bbc5f7ab525e899c77#diff-6a346e34b62dcc7aa7ea373ca29791ac4c81c55202d265397418507d3235a4e3R408) but with a larger than previous set of offered signature schemes (and, because that list is in priority order, SHA1 is preferred).
So should I update reqwest to pick a different set of signature schemes?
I think that's one option - you could change your NoVerifier
impl to return the default list we were using before it was removed from the trait. I think you could also just remove SignatureScheme::ECDSA_SHA1_Legacy
.
On the other hand, Ctz worked up a fix on our side as well: https://github.com/rustls/rustls/pull/1869 and we're backporting it into 0.22: https://github.com/rustls/rustls/pull/1870 I believe taking that fix in an updated Rustls dependency would also resolve the problem without needing a change on your side.
Fix for this is in:
- https://crates.io/crates/rustls/0.23.4
- https://crates.io/crates/rustls/0.22.3
Thank you all! With that, and another release of reqwest this morning, a cargo update
should help. Feel free to open an issue again if there's different problems.
Thank both of you. I tested reqwest 0.12.2 and it working again. :)