My Https C++ Code Doesn't Work On Some Sites (binance)
I made a https class in C++ using OpenSSL. It works on most sites/urls, but doesn't work with the following sites/urls:
- https://api.binance.com/api/v1/klines?symbol=BTCUSDT&interval=1m&startTime=0&limit=1
- https://api.binance.com/api/v1/exchangeInfo
I can open them using a browser/wget/postman, so they aren't bad link. I'm also sure my request/headers are valid & correct. I suspected SSL versions problems, but I tried all the versions in OpenSSL but no luck (SSLv3, TLS 1.1/1.2)
The server close my connection immediately, even before I send my headers.
This is an example of what my request looks like, and I don't think it's wrong. Because I can't find anything wrong and the same code works with other sites/urls.
GET /api/v1/exchangeInfo HTTP/1.1
Accept: */*
Accept-Encoding: gzip,deflate
Connection: keep-alive
Host: api.binance.com
User-Agent: evo
I have no idea what caused it. Anyone knows why?
Thanks!!
SslSocket ssl;
st = ssl.create();
st = ssl.connect("api.binance.com:443");
const char* req_header = "GET /api/v1/exchangeInfo HTTP/1.1\r\n"
"Host: " "api.binance.com" "\r\n"
"\r\n";
st = ssl.send(req_header, strlen(req_header));
while (true){
char buff[ 1024 ] = {};
size_t recv_size = 0;
st = ssl.recv(recv_size, buff, sizeof(buff) - 1);
if (!st) break;
if (recv_size > 0)
fwrite(buff, 1, recv_size, stdout);
}
I did something like this to setup my ssl socket:
const SSL_METHOD *method = SSLv23_client_method();
_ctx = SSL_CTX_new(method);
_ssl = SSL_new(_ctx);
SSL_set_fd(_ssl, _socket.fd());
_socket.connect(addr);
SSL_connect(_ssl);
printf("SSL_get_version2: %s\n", SSL_get_version(_ssl));
Answer
This site requires that the client is using the SNI extension. Without SNI extension you get this:
$ openssl s_client -connect api.binance.com:443
...
140269619467928:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:772:
...
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
With SNI extension you get this:
$ openssl s_client -connect api.binance.com:443 -servername api.binance.com
...
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
To use SNI in your code use SSL_set_tlsext_host_name. See this code in s_client.c for how to use this function.
Related Questions
- → Comparing two large files are taking over four hours
- → Setting JSON node name to variable value
- → Compiling GLUT using Emscripten
- → Evaluate check box from a scanned image in node.js
- → Find an easy web server framework for mobile game
- → my https C++ code doesn't work on some sites (binance)
- → Error while opening pivx wallet on ubuntu
- → Why sending a POST by AJAX is interpreted by the HTTP Server as OPTIONS and sending by CURL is effectively a PUT?
- → Python reading in one line multiple types for a calculator
- → How do I properly pass an argument to a function
- → Accessing Websql database with Qt
- → Using Mysql C API for c++ codes
- → How do I set constants at run-time in a c++ header file, imported through Cython?