Reqwest throws an SSL error

Okay, so recently I found that the link if fetched by reqwest (which uses hyper under the hood) throws an SSL error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error {
 kind: Io(Custom { 
     kind: Other, error: Ssl(ErrorStack([Error { 
         code: 336134278, 
         library: "SSL routines", 
         function: "SSL3_GET_SERVER_CERTIFICATE", 
         reason: "certificate verify failed", 
         file: "s3_clnt.c", 
         line: 1180
 }])) }), 
    url: Some("") }', libcore/

This error might be related the following stackoverflow issue - here. However, I’m not too familiar with how and why this happens and how to approach solving, given that my browsers work fine. I have a good sucpicion that given that Hyper uses the Ubuntu native ssl library, this is not a Rust issue at all, but was hoping someone could advise me on how to fix it.

This works for me:

extern crate reqwest;

fn main() {
    println!("{}", reqwest::get("").unwrap().text().unwrap());

I’m on Arch Linux.

Yeah that same line copied gives me same error still… I’m on Ubuntu 14.04 LTS. Which version of reqwest you used?

The latest. What is the output of this command?

openssl s_client -connect -servername

The output is:

depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA
verify return:1
depth=0 CN = *
verify return:1
Certificate chain
 0 s:/CN=*
   i:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA
 1 s:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Server certificate
issuer=/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
SSL handshake has read 4316 bytes and written 459 bytes
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 93AB7E6A8DE6EC5F13D3C35B9982F21DC268582587AAC1E7A824E6EE5A4B449A
    Master-Key: 792B9784E50A9AC0D33A93590E947A0D5E2C27E9E59DABC84BA26A334043EB9AD76B0F121263A327E8A3652E6E29B4C6
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 64800 (seconds)
    TLS session ticket:
    0000 - c7 8d ea 4b 7b 08 3e 61-cb 1e ff 15 d5 bb 24 23   ...K{.>a......$#
    0010 - 2e 90 27 b6 a1 7e 60 0e-ee 02 48 b7 f5 2e b7 87   ..'..~`...H.....
    0020 - 8d df e4 68 1d ce 46 52-ea 21 bb 64 e6 c1 ca 39   ...h..FR.!.d...9
    0030 - 06 73 f5 15 33 6b 0e 41-67 62 d4 52 8f 5b 4c 5b   .s..3k.Agb.R.[L[
    0040 - 7c 41 1f 82 95 7e f7 2e-72 68 a8 f5 9b ad 48 81   |A...~..rh....H.
    0050 - 23 40 18 0e 2c b1 4f c8-7c 15 c9 53 77 01 ef 46   #@..,.O.|..Sw..F
    0060 - 27 92 0f 45 3c d9 8c bf-4d 83 02 b2 76 ce 62 4a   '..E<...M...v.bJ
    0070 - cf 74 fd f3 7d 64 2f 77-10 df c4 77 06 5a de bb   .t..}d/w...w.Z..
    0080 - 07 3f 08 2c ab 92 2d 5e-c2 0f c8 54 5c cd 04 31   .?.,..-^...T\..1
    0090 - 8a ba bf 14 f4 10 1f c5-a3 f8 9c 78 c6 f2 b4 99   ...........x....
    00a0 - 48 f8 b3 dc 58 4e 5d 99-8d e0 f3 4c ce ac f3 3b   H...XN]....L...;

    Start Time: 1522010135
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

It’s interesting, cause I think (75% sure) that I did this fine when I was in the UK. I’m now in Bulgaria testing this and it gives me this… could that be somehow related?

PS: So indeed just tested the code on my machine at work, which is in the UK and I don’t get that error.

The output of s_client looks normal. I just tested this on a fresh 14.04 container and it works fine too. There must be something wrong with the system you’re running the test on: outdated packages, crates, etc.

Hmm… all of my dependencies are listed as "*" and I’ve just done cargo clean on the project after updating my Rust compiler to the latest one (now at 1.26-nightly). But if the system package output in normal how come the reqwest can crash? And as mentioned is it possible somehow my location to matter?

This is the only https address that throws this error?

Absolutely. Someone might be trying to man-in-the-middle your traffic. Hotel wifis are common culprits.

However, I’m in a home wifi. Unless my ISP is doing something weird…

I would suggest calling with my mio_httpc library. As it is unrelated to reqwest/hyper/tokio. If it also does not work it is actually an SSL issue not a http client library issue.

You can try calling with both rustls or openssl (example in README). If it is an ssl issue, I’m not sure there are more than two possibilities. Someone is either MITMing or system time on your machine is wildly wrong.

Wow, so very interesting results. I’ve tried as suggested to run with mio_httpc since its a totally unrelated package to my current stack.

  1. Running it with native:
thread 'main' panicked at 'Call failed: Tls(Ssl(ErrorStack([Error {
    code: 336134278, 
    library: "SSL routines", 
    reason: "certificate verify failed", 
    file: "s3_clnt.c",
    line: 1180 }])))', 
  1. Running with openssl:
thread 'main' panicked at 'Call failed: Tls(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { 
    code: 336134278, 
    library: "SSL routines", 
    reason: "certificate verify failed", 
    file: "s3_clnt.c", 
    line: 1180 }]))) })', 
  1. With rustls:
    "date": "Mon, 26 Mar 2018 14:45:04 GMT", 
    "content-type": "application/json", 
    "transfer-encoding": "chunked", 
    "connection": "keep-alive", 
    "set-cookie": "__cfduid=dd68aa5eef5cf7503350ce21af08170841522075504; expires=Tue, 26-Mar-19 14:45:04 GMT; path=/;; HttpOnly; Secure", 
    "access-control-allow-origin": "*", 
    "via": "1.1 google", 
    "alt-svc": "clear", 
    "expect-ct": "max-age=604800, report-uri=\"\"", 
    "server": "cloudflare", 
    "cf-ray": "401a661decce4050-SOF", 
    "content-encoding": "gzip"}
Body: {"success":true,"result":{"trading_pairs": [...]}}

As a result it works with rustls and fails with openssl. Unfortunately, I’m no expert on SSL details to be able to make any reasonable conclusion (my assumption is this is potential issue with the openssl library installed on my Ubuntu 14.10?).

rustls uses different root certificates ( compared to openssl which uses the system root certificates. Perhaps those need to be updated.

I’ve tried adding the website CA certificate in my ubuntu but still same issue… Weird that in the 16.04 at work this does not happen yet the OpenSSL version is the same.

Could you post an strace of the failing native or openssl example?

Ok so running:

cargo run --example get --features "openssl" -- ""

The result is:

thread 'main' panicked at 'Call failed: Tls(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 336134278, 
library: "SSL routines", 
reason: "certificate verify failed", 
file: "s3_clnt.c", 
line: 1180 }]))) })', libcore/
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Same using native.

had same issue too

I change my ssl certificate to wildcard ssl because decide to protect another new website. this type od secure cert cheaply covers all the subdomains which I need.