Okay, so recently I found that the link
https://api.cobinhood.com/v1/market/trading_pairs
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("https://api.cobinhood.com/v1/market/trading_pairs/") }', libcore/result.rs:945:5
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.
fn main() {
println!("{}", reqwest::get("https://api.cobinhood.com/v1/market/trading_pairs").unwrap().text().unwrap());
I'm on Arch Linux.
vername api.cobinhood.com
CONNECTED(00000003)
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 = *.cobinhood.com
verify return:1
Certificate chain
0 s:/CN=*.cobinhood.com
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
-----BEGIN CERTIFICATE-----
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
8ZocD0jU1PY=
-----END CERTIFICATE-----
subject=/CN=*.cobinhood.com
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
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 93AB7E6A8DE6EC5F13D3C35B9982F21DC268582587AAC1E7A824E6EE5A4B449A
Session-ID-ctx:
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.
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?
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.
Running it with native
:
thread 'main' panicked at 'Call failed: Tls(Ssl(ErrorStack([Error {
code: 336134278,
library: "SSL routines",
function: "SSL3_GET_SERVER_CERTIFICATE",
reason: "certificate verify failed",
file: "s3_clnt.c",
line: 1180 }])))',
libcore/result.rs:945:5
Running with openssl
:
thread 'main' panicked at 'Call failed: Tls(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error {
code: 336134278,
library: "SSL routines",
function: "SSL3_GET_SERVER_CERTIFICATE",
reason: "certificate verify failed",
file: "s3_clnt.c",
line: 1180 }]))) })',
libcore/result.rs:945:5
With rustls
:
Headers={
"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=/; domain=.cobinhood.com; HttpOnly; Secure",
"access-control-allow-origin": "*",
"via": "1.1 google",
"alt-svc": "clear",
"expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
"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?).
Ok so running:
cargo run --example get --features "openssl" -- "https://api.cobinhood.com/v1/market/trading_pairs"
The result is:
Get https://api.cobinhood.com/v1/market/trading_pairs
thread 'main' panicked at 'Call failed: Tls(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 336134278,
library: "SSL routines",
function: "SSL3_GET_SERVER_CERTIFICATE",
reason: "certificate verify failed",
file: "s3_clnt.c",
line: 1180 }]))) })', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Same using native.