I am trying to write a basic TLS client and server program using nghttp2. The code works fine when verification of peer is turned off but i get the following error when verification is switched on.
error: certificate verify failed
Certificates
So i have created a self signed CA certificate and signed another certificate using the CA certificate
The certificate bundle is as follows
I have also added the CA certificate in the trusted certificates directory using
update-ca-certificates
Does openssl s_client work?
That's where i am getting stuck. openssl s_client does indeed work and i do getting verification ok message as shown here
The command is as follows
openssl s_client -connect 127.0.0.1:3002
Server code
#include <iostream>
#include <nghttp2/asio_http2_server.h>
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
int main(int argc, char *argv[]) {
boost::system::error_code ec;
boost::asio::ssl::context tls(boost::asio::ssl::context::tlsv12);
tls.use_private_key_file("ausf.pem", boost::asio::ssl::context::pem);
tls.use_certificate_chain_file("ausf.crt");
configure_tls_context_easy(ec, tls);
http2 server;
server.handle("/index.html", [](const request &req, const response &res) {
res.write_head(200);
res.end(file_generator("index.html"));
});
/*server.handle("/", [](const request &req, const response &res) {
res.write_head(200);
res.end("hello, world\n");
});*/
if (server.listen_and_serve(ec, tls, "localhost", "3002")) {
std::cerr << "error: " << ec.message() << std::endl;
}
}
Client Code:
#include <iostream>
#include <nghttp2/asio_http2_client.h>
using boost::asio::ip::tcp;
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::client;
int main(int argc, char *argv[]) {
boost::system::error_code ec;
boost::asio::io_service io_service;
boost::asio::ssl::context tls(boost::asio::ssl::context::tlsv12);
//tls.set_default_verify_paths();
// disabled to make development easier...
tls.set_verify_mode(boost::asio::ssl::context::verify_peer);
tls.set_default_verify_paths();
std::string hostname = "localhost";
configure_tls_context(ec, tls);
// connect to localhost:3000
session sess(io_service, tls, "localhost", "3002");
sess.on_connect([&sess](tcp::resolver::iterator endpoint_it) {
boost::system::error_code ec;
auto req = sess.submit(ec, "GET", "https://localhost:3002/");
req->on_response([&sess](const response &res) {
std::cerr << "response received!" << std::endl;
res.on_data([&sess](const uint8_t *data, std::size_t len) {
std::cerr.write(reinterpret_cast<const char *>(data), len);
std::cerr << std::endl;
});
});
req->on_push([](const request &push) {
std::cerr << "push request received!" << std::endl;
push.on_response([](const response &res) {
std::cerr << "push response received!" << std::endl;
res.on_data([](const uint8_t *data, std::size_t len) {
std::cerr.write(reinterpret_cast<const char *>(data), len);
std::cerr << std::endl;
});
});
});
});
sess.on_error([](const boost::system::error_code &ec) {
std::cerr << "error: " << ec.message() << std::endl;
});
io_service.run();
}
How come the client code is failing to verify the certificates but openssl s_client is able to do so?
Thanks for the help.
Alright so as it turns out that since i am querying localhost, the certificate must have localhost as the common name.
So i created a new CSR with common name as localhost and got it signed by CA.
However, why does this error does not occur is openssl s_client is still a mystery to me