|
|
@@ -376,7 +376,7 @@ private:
|
|
|
|
|
|
class SSLServer : public Server {
|
|
|
public:
|
|
|
- SSLServer(const char *cert_path, const char *private_key_path);
|
|
|
+ SSLServer(const char *cert_path, const char *private_key_path, const char *client_CA_cert_path, const char *trusted_cert_path);
|
|
|
|
|
|
virtual ~SSLServer();
|
|
|
|
|
|
@@ -387,11 +387,14 @@ private:
|
|
|
|
|
|
SSL_CTX *ctx_;
|
|
|
std::mutex ctx_mutex_;
|
|
|
+ const char *client_CA_cert_path_;
|
|
|
+ const char *trusted_cert_path_;
|
|
|
};
|
|
|
|
|
|
class SSLClient : public Client {
|
|
|
public:
|
|
|
- SSLClient(const char *host, int port = 443, time_t timeout_sec = 300);
|
|
|
+ SSLClient(const char *host, int port = 443, time_t timeout_sec = 300,
|
|
|
+ const char *client_cert_path = nullptr, const char *client_key_path = nullptr);
|
|
|
|
|
|
virtual ~SSLClient();
|
|
|
|
|
|
@@ -2234,7 +2237,9 @@ read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count,
|
|
|
// TODO: OpenSSL 1.0.2 occasionally crashes...
|
|
|
// The upcoming 1.1.0 is going to be thread safe.
|
|
|
SSL_CTX *ctx, std::mutex &ctx_mutex,
|
|
|
- U SSL_connect_or_accept, V setup, T callback) {
|
|
|
+ U SSL_connect_or_accept, V setup, T callback,
|
|
|
+ const char* client_CA_cert_path = nullptr,
|
|
|
+ const char* trusted_cert_path = nullptr) {
|
|
|
SSL *ssl = nullptr;
|
|
|
{
|
|
|
std::lock_guard<std::mutex> guard(ctx_mutex);
|
|
|
@@ -2260,9 +2265,24 @@ read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ if(client_CA_cert_path){
|
|
|
+ STACK_OF(X509_NAME)* list;
|
|
|
+ //list of client CAs to request from client
|
|
|
+ list = SSL_load_client_CA_file(client_CA_cert_path);
|
|
|
+ SSL_set_client_CA_list(ssl, list);
|
|
|
+ //certificate chain to verify received client certificate against
|
|
|
+ //please run c_rehash in the cert folder first
|
|
|
+ SSL_CTX_load_verify_locations(ctx,client_CA_cert_path,trusted_cert_path);
|
|
|
+ }
|
|
|
+
|
|
|
bool ret = false;
|
|
|
|
|
|
if (SSL_connect_or_accept(ssl) == 1) {
|
|
|
+ /*
|
|
|
+ auto client_cert = SSL_get_peer_certificate(ssl);
|
|
|
+ if(client_cert)
|
|
|
+ printf("Connected client: %s\n", client_cert->name);
|
|
|
+ */
|
|
|
if (keep_alive_max_count > 0) {
|
|
|
auto count = keep_alive_max_count;
|
|
|
while (count > 0 &&
|
|
|
@@ -2338,7 +2358,11 @@ inline std::string SSLSocketStream::get_remote_addr() const {
|
|
|
|
|
|
// SSL HTTP server implementation
|
|
|
inline SSLServer::SSLServer(const char *cert_path,
|
|
|
- const char *private_key_path) {
|
|
|
+ const char *private_key_path,
|
|
|
+ const char *client_CA_cert_path = nullptr,
|
|
|
+ const char *trusted_cert_path = nullptr)
|
|
|
+ : client_CA_cert_path_(client_CA_cert_path),
|
|
|
+ trusted_cert_path_(trusted_cert_path){
|
|
|
ctx_ = SSL_CTX_new(SSLv23_server_method());
|
|
|
|
|
|
if (ctx_) {
|
|
|
@@ -2356,6 +2380,11 @@ inline SSLServer::SSLServer(const char *cert_path,
|
|
|
1) {
|
|
|
SSL_CTX_free(ctx_);
|
|
|
ctx_ = nullptr;
|
|
|
+ } else if(client_CA_cert_path_) {
|
|
|
+ SSL_CTX_set_verify(ctx_,
|
|
|
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, //SSL_VERIFY_CLIENT_ONCE,
|
|
|
+ nullptr
|
|
|
+ );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -2372,11 +2401,14 @@ inline bool SSLServer::read_and_close_socket(socket_t sock) {
|
|
|
[](SSL * /*ssl*/) { return true; },
|
|
|
[this](Stream &strm, bool last_connection, bool &connection_close) {
|
|
|
return process_request(strm, last_connection, connection_close);
|
|
|
- });
|
|
|
+ },
|
|
|
+ client_CA_cert_path_,
|
|
|
+ trusted_cert_path_);
|
|
|
}
|
|
|
|
|
|
// SSL HTTP client implementation
|
|
|
-inline SSLClient::SSLClient(const char *host, int port, time_t timeout_sec)
|
|
|
+inline SSLClient::SSLClient(const char *host, int port, time_t timeout_sec,
|
|
|
+ const char *client_cert_path, const char *client_key_path)
|
|
|
: Client(host, port, timeout_sec) {
|
|
|
ctx_ = SSL_CTX_new(SSLv23_client_method());
|
|
|
|
|
|
@@ -2384,6 +2416,13 @@ inline SSLClient::SSLClient(const char *host, int port, time_t timeout_sec)
|
|
|
[&](const char *b, const char *e) {
|
|
|
host_components_.emplace_back(std::string(b, e));
|
|
|
});
|
|
|
+ if(client_cert_path && client_key_path) {
|
|
|
+ if (SSL_CTX_use_certificate_file(ctx_, client_cert_path, SSL_FILETYPE_PEM) != 1
|
|
|
+ ||SSL_CTX_use_PrivateKey_file(ctx_, client_key_path, SSL_FILETYPE_PEM) != 1) {
|
|
|
+ SSL_CTX_free(ctx_);
|
|
|
+ ctx_ = nullptr;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
inline SSLClient::~SSLClient() {
|