summaryrefslogtreecommitdiffhomepage
path: root/https.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-11 15:58:01 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-11 15:58:01 +0200
commit1374fac8de85fe1ac877096f18b60a1561dfc96f (patch)
treebc9c2f3bd4ac82fab786824e8903a400b6170d7c /https.cpp
parent6081819802972c716745a44e3521ccb3b3cf7b1a (diff)
Replace SSL_CTX_set_tlsext_servername_callback with SSL_client_hello_get0_ext
Diffstat (limited to 'https.cpp')
-rw-r--r--https.cpp62
1 files changed, 48 insertions, 14 deletions
diff --git a/https.cpp b/https.cpp
index a263a54..5230d60 100644
--- a/https.cpp
+++ b/https.cpp
@@ -6,6 +6,7 @@
#include "response.h"
#include <openssl/ssl.h>
+#include <openssl/crypto.h>
#include <boost/asio/buffer.hpp>
#include <boost/beast/core.hpp>
@@ -566,25 +567,62 @@ void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path,
boost::asio::buffer(dh.data(), dh.size()));
}
+int ServerNameError(SSL *s, HTTPS::Server::ctx_type& ctx_map)
+{
+ std::shared_ptr<ssl::context> ctx{ctx_map.at("")};
+ SSL_set_SSL_CTX(s, ctx->native_handle());
+ return SSL_CLIENT_HELLO_SUCCESS; // OK for now
+}
+
int servername_callback(SSL *s, int *al, void *arg)
{
- int type {SSL_get_servername_type(s)};
- std::string server_name {SSL_get_servername(s, type)};
+ HTTPS::Server::ctx_type& ctx_map = *(HTTPS::Server::ctx_type*)arg;
+
+ if (0) { // not really necessary
+ int* numbers;
+ size_t numbers_size;
+ if (SSL_client_hello_get1_extensions_present(s, &numbers, &numbers_size) != 1) {
+ std::cout << "Error on SSL_client_hello_get1_extensions_present" << std::endl;
+ return ServerNameError(s, ctx_map);
+ }
+ bool server_name_available {false};
+ for (size_t i = 0; i < numbers_size; i++)
+ if (numbers[i] == 0)
+ server_name_available = true;
+
+ OPENSSL_free(numbers);
+
+ if (!server_name_available) {
+ std::cout << "Error: No server_name available at SSL_client_hello_get1_extensions_present" << std::endl;
+ return ServerNameError(s, ctx_map);
+ }
+ }
+
+ const unsigned char* data;
+ size_t data_size;
+ // 0 is server_name
+ if (SSL_client_hello_get0_ext(s, 0, &data, &data_size) != 1) {
+ std::cout << "Warning: Error on SSL_client_hello_get0_ext: servername not available. Using dummy ctx." << std::endl;
+ return ServerNameError(s, ctx_map);
+ }
- HTTPS::Server::ctx_type* ctx_map = (HTTPS::Server::ctx_type*)arg;
+ // SNI Server Name, See https://tools.ietf.org/html/rfc6066 (TODO: why are there 5 bytes header?)
+ std::string server_name {std::string((const char*)data, (size_t)data_size)};
+ if (server_name.size() >= 5 && server_name[0] == '\0')
+ server_name = server_name.substr(5);
- auto it {ctx_map->find(server_name)};
+ auto it {ctx_map.find(server_name)};
std::shared_ptr<ssl::context> ctx{};
- if (it != ctx_map->end()) {
+ if (it != ctx_map.end()) {
ctx = it->second;
} else {
- std::cout << "Warning: server_name " << server_name << " not found in list of prepared contexts. Using dummy ctx." << std::endl;
- ctx = ctx_map->at("");
+ std::cout << "Warning: server_name " << server_name << " (" << server_name.size() << ") not found in list of prepared contexts. Using dummy ctx." << std::endl;
+ return ServerNameError(s, ctx_map);
}
SSL_set_SSL_CTX(s, ctx->native_handle());
- return SSL_TLSEXT_ERR_OK;
+ return SSL_CLIENT_HELLO_SUCCESS;
}
} // anonymous namespace
@@ -598,9 +636,7 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke
// initial dummy, before we can add specific ctx w/ certificate
std::shared_ptr<ssl::context> ctx_dummy{std::make_shared<ssl::context>(tls_method)};
load_server_certificate(*ctx_dummy, "", "");
- //SSL_CTX_set_client_hello_cb(ctx_dummy->native_handle(), servername_callback, &m_ctx);
- SSL_CTX_set_tlsext_servername_callback(ctx_dummy->native_handle(), servername_callback);
- SSL_CTX_set_tlsext_servername_arg(ctx_dummy->native_handle(), &m_ctx);
+ SSL_CTX_set_client_hello_cb(ctx_dummy->native_handle(), servername_callback, &m_ctx);
m_ctx.emplace("", ctx_dummy);
// import the real certificates
@@ -612,9 +648,7 @@ Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socke
std::cout << "Creating SSL context/cert for site " << serve_site << " on port " << socket.port << std::endl;
load_server_certificate(*ctx, site.cert_path, site.key_path);
- //SSL_CTX_set_client_hello_cb(ctx->native_handle(), servername_callback, &m_ctx);
- SSL_CTX_set_tlsext_servername_callback(ctx->native_handle(), servername_callback);
- SSL_CTX_set_tlsext_servername_arg(ctx->native_handle(), &m_ctx);
+ SSL_CTX_set_client_hello_cb(ctx->native_handle(), servername_callback, &m_ctx);
for (const auto& host: site.hosts) {
std::cout << " Adding Host " << host << std::endl;