Closed hros closed 1 year ago
The HTTP server component of cpprestsdk has never been supported on any platform, and exists basically only to test the client component
The question is how to setup the client for https communication
That is supposedly suported!
I am asking for code example for the client, using certificates to communicate using tls
I have solved the issue Here are the steps taken:
create public/private key pair and certificate for the REST Server:
openssl ecparam -genkey -name prime256v1 -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
openssl req -new -x509 -sha256 -key private-key.pem -subj /CN=localhost -out certificate.pem
replacing the file names private-key.pem
, public-key.pem
and certificate.pem
with whatever names you prefer, and changing localhost
to the ip address of the server
The https server code:
#include <cpprest/http_listener.h>
#include <cpprest/json.h>
using namespace web; using namespace web::http; using namespace web::http::experimental::listener; namespace net = boost::asio; namespace ssl = net::ssl;
string url = "https://" + host + ":" + to_string(port); http_listener_config conf; conf.set_ssl_context_callback([&cert, &privkey](ssl::context &ctx) { try { ctx.set_options(ssl::context::default_workarounds | ssl::context::no_sslv2 | ssl::context::no_tlsv1 | ssl::context::no_tlsv1_1 | ssl::context::single_dh_use); ctx.use_certificate_chain_file(cert); ctx.use_private_key_file(privkey, ssl::context::pem); } catch (exception const &e) { clog << "ERROR: " << e.what() << endl; } }); listener = http_listener(utility::conversions::to_string_t(url), conf); listener.support(methods::GET, get_handler); listener.open().wait(); cout << "Listening for requests at: " << host << ":" << port << endl;
where `host` and `port` are the ip address and port of the server; `cert` and `privkey` are the filenames of the certificate and private key that were generated in the previous step
`get handler` is a function of type: `http_response get_handler(http_request request)`, which parses the request and returns the response (similar code for other methods: `method::POST`, ...)
3. **the client code:**
```cpp
#define _TURN_OFF_PLATFORM_STRING
#include <cpprest/http_client.h>
#include <cpprest/json.h>
using namespace web;
using namespace web::http;
using namespace web::http::client;
namespace net = boost::asio;
namespace ssl = net::ssl;
string url = "https://" + host + ":" + (to_string(port));
http_client_config conf;
try {
conf.set_ssl_context_callback([](boost::asio::ssl::context &ctx) {
ctx.load_verify_file(cert);
});
} catch (std::exception const &e) {
clog << "ERROR: " << e.what() << endl;
}
http_client client(uri_builder(url).to_uri(), conf);
client.request(...);
using the server's certificate (cert
is the file name of the certificate)
proceed with issuing a request as usual (there are numerous examples
Note that defining _TURN_OFF_PLATFORM_STRING
disables the U
macro used to cast string
to string_t
which can cause conflicts. Use utility::string_t
instead of the U
macro
Although other issues state that https on Linux is supported (link), I am having difficulties getting it to work
I created certificates and keys by following the instructions, creating the files:
rootca.key
,rootca.crt
,rootca.srl
,user.key
,user.crt
,user,csr
,dh2048.pem
.I am running on Ubuntu 20.04 (in WSL-2). I created the server:
where
cert
andprivkey
are string variables set torootca.crt
,rootca.key
respectivelyWhen I run the server, I am able to use the browser to test the server and get the json reply (after ignoring the browser's warning of
NET::ERR_CERT_AUTHORITY_INVALID
and continuing to browse the "unsafe" uri)My problem is that I am not able to get the client to communicate with the server. I would like the client and server to use TLS and have the client be verified by the certificate that is signed by the server (
user.crt
?) My code is:but when I
make_request
I get anError in SSL handshake
when I pass the cert file eitheruser.crt
orrootca.crt
. note that the client code works when using unencrypted httpI tried accessing the server with
curl
, and I found two options that worl:curl --cacert rootca.crt https://url
curl --cacert rootca.crt --key user.key https://url
It seems that the server is not requiring a user keyWhat am I missing?