summaryrefslogtreecommitdiffhomepage
path: root/https.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'https.cpp')
-rw-r--r--https.cpp177
1 files changed, 154 insertions, 23 deletions
diff --git a/https.cpp b/https.cpp
index 9d0784e..0e45272 100644
--- a/https.cpp
+++ b/https.cpp
@@ -1,22 +1,27 @@
#include "https.h"
+#include "config.h"
+#include "file.h"
#include "server.h"
#include <boost/beast/version.hpp>
#if BOOST_VERSION == 107100
-#include "server_certificate.h"
-
#include <openssl/ssl.h>
+
+#include <boost/asio/buffer.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/asio/dispatch.hpp>
+#include <boost/asio/ssl/context.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
+
#include <algorithm>
+#include <cstddef>
#include <cstdlib>
#include <functional>
#include <iostream>
@@ -519,39 +524,161 @@ private:
}
};
-} // anonymous namespace
-//------------------------------------------------------------------------------
+/* Load a signed certificate into the ssl context, and configure
+ the context for use with a server.
-namespace HTTPS {
+ For this to work with the browser or operating system, it is
+ necessary to import the "Beast Test CA" certificate into
+ the local certificate store, browser, or operating system
+ depending on your environment Please see the documentation
+ accompanying the Beast certificate for more details.
+*/
+void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path, fs::path key_path)
+{
+ /*
+ The certificate was generated from CMD.EXE on Windows 10 using:
+
+ winpty openssl dhparam -out dh.pem 2048
+ winpty openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 10000 -out cert.pem -subj "//C=US\ST=CA\L=Los Angeles\O=Beast\CN=www.example.com"
+ */
+
+ std::string const dh =
+ "-----BEGIN DH PARAMETERS-----\n"
+ "MIIBCAKCAQEArzQc5mpm0Fs8yahDeySj31JZlwEphUdZ9StM2D8+Fo7TMduGtSi+\n"
+ "/HRWVwHcTFAgrxVdm+dl474mOUqqaz4MpzIb6+6OVfWHbQJmXPepZKyu4LgUPvY/\n"
+ "4q3/iDMjIS0fLOu/bLuObwU5ccZmDgfhmz1GanRlTQOiYRty3FiOATWZBRh6uv4u\n"
+ "tff4A9Bm3V9tLx9S6djq31w31Gl7OQhryodW28kc16t9TvO1BzcV3HjRPwpe701X\n"
+ "oEEZdnZWANkkpR/m/pfgdmGPU66S2sXMHgsliViQWpDCYeehrvFRHEdR9NV+XJfC\n"
+ "QMUk26jPTIVTLfXmmwU0u8vUkpR7LQKkwwIBAg==\n"
+ "-----END DH PARAMETERS-----\n";
+
+ ctx.set_password_callback(
+ [](std::size_t,
+ boost::asio::ssl::context_base::password_purpose)
+ {
+ return "test";
+ });
+
+ ctx.set_options(
+ boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::single_dh_use);
+
+ std::string cert;
+ if (cert_path == "") {
+ cert =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDnTCCAoWgAwIBAgIULkYtO+2Ddeg+qLZ+aDQpmA5b4L0wDQYJKoZIhvcNAQEL\n"
+ "BQAwXjELMAkGA1UEBhMCREUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11\n"
+ "bmljaDEVMBMGA1UECgwMUmVpY2h3ZWluIElUMRUwEwYDVQQDDAxyZWljaHdlaW4u\n"
+ "aXQwHhcNMjAwNDA1MDgwNzIyWhcNNDcwODIyMDgwNzIyWjBeMQswCQYDVQQGEwJE\n"
+ "RTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRUwEwYDVQQKDAxS\n"
+ "ZWljaHdlaW4gSVQxFTATBgNVBAMMDHJlaWNod2Vpbi5pdDCCASIwDQYJKoZIhvcN\n"
+ "AQEBBQADggEPADCCAQoCggEBALJNb0WLbz+xP+YITMMk+eeK/SIOCRFs/9aZIAyK\n"
+ "ParGauxa+8d25mlfJTAo6/G0h3sA240JHyNpOzVOogPU+v4dRWyGO0w5vHVD0caB\n"
+ "rDb1eEfmLtqfKLLUL9iPDReUh6WAE7qoNDtfoT551uSMIae1cpPUduVTnSkEgw8k\n"
+ "NjJSHYT800jSB2R+e7tJG3ErXDM63R3B8RbitZPoWACjpBxDT+Qrj0fBFS4AWw6b\n"
+ "z09uitv0RrgI6CW7xRh3UAdRwEBGHiU6HTIthX6LNgez1UL0sfu1iZ22wNmYZP/S\n"
+ "sL3b20WtSH9LN2PRJ4q3AGt6RMbmSGr65ljha9xkTFna0Y8CAwEAAaNTMFEwHQYD\n"
+ "VR0OBBYEFKd5/MGFZUAUV502vJ/Kcswax8WVMB8GA1UdIwQYMBaAFKd5/MGFZUAU\n"
+ "V502vJ/Kcswax8WVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB\n"
+ "AIBS4AfM7wiunQ2UZQQ5A0Un99+BLax9e+h11h/jGeJ+/9maY/E9MK6UG9LXoOv2\n"
+ "z32Q7Ta2xKeRu6GC/qupwYJ0Xt3LENOfogsaNCAgxKlAN48LGlRyCTvzWsEMh28j\n"
+ "RaelWonh2qQoiryKLVnRwrg8g1Bu4v+V437cIBmeZPxf0spEL9EVqlN+iS8plmel\n"
+ "7/F4ULdybKGq39tgicuS7JhnY21ZzOFoq0bWnKBbAeTndmuROdb3pEppxW6pwu0q\n"
+ "TFdMrSJE38kiQh2O9IchPQbTZ+Rdj0HE9NxStlrNr5bu6rjikRm50/G3JoXpzYdp\n"
+ "AN4ZI2QZ6R6Y+TzDixKecNk=\n"
+ "-----END CERTIFICATE-----\n"
+ ;
+ } else {
+ cert = File::getFile(cert_path);
+ }
+
+ ctx.use_certificate_chain(
+ boost::asio::buffer(cert.data(), cert.size()));
+
+ std::string key;
+ if (key_path == "") {
+ key =
+ "-----BEGIN PRIVATE KEY-----\n"
+ "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyTW9Fi28/sT/m\n"
+ "CEzDJPnniv0iDgkRbP/WmSAMij2qxmrsWvvHduZpXyUwKOvxtId7ANuNCR8jaTs1\n"
+ "TqID1Pr+HUVshjtMObx1Q9HGgaw29XhH5i7anyiy1C/Yjw0XlIelgBO6qDQ7X6E+\n"
+ "edbkjCGntXKT1HblU50pBIMPJDYyUh2E/NNI0gdkfnu7SRtxK1wzOt0dwfEW4rWT\n"
+ "6FgAo6QcQ0/kK49HwRUuAFsOm89Pborb9Ea4COglu8UYd1AHUcBARh4lOh0yLYV+\n"
+ "izYHs9VC9LH7tYmdtsDZmGT/0rC929tFrUh/Szdj0SeKtwBrekTG5khq+uZY4Wvc\n"
+ "ZExZ2tGPAgMBAAECggEBAK9bJKIa3dCgPB257/TEOtsTgJyrfROcRYkCk9iBZOC9\n"
+ "v46wdIrZTwY2wtY4iMPwLoY0c7ijTfJ/nfFxYjmujyK4Gvz+jvcKmWQizP8TrRFo\n"
+ "HWFo6o+slFQ8BspO9itIspd7/OtIXgY+qNBO959Sig7sjsEA5eXoc9pRS6vqizq0\n"
+ "j4G/UO5Amr/l3ciEJiqMJgZsIVLDKaGlqFTymydSqkB8UHQYWK1kunQxhK4Ldycu\n"
+ "hTooQE7tXM0zvoFVV6v1fldV5OFsZk2kPMNtvMO6ZEpOM4rNMlg+vJy8kB1fb3Gs\n"
+ "iFE/DCUpZsMSserQMU9/hfrYlndgsFD5Sr1EVGEebhECgYEA1gc9qx+ugdhYTY5j\n"
+ "tJDXjOsnw8KY/l/1y+mQ8XNJ9MVdBGy1WB+uWB4teiyJchV49gn2XlKUK2rcCBvZ\n"
+ "vC5CwPmFi2t70JezQgnXtDlbR0bARPlRd741i4rBpD7hEiZNCTOd2HFBpUg/CGWN\n"
+ "E4n1ksazBm6jvv3Jo6WAa07Z390CgYEA1USrFqmc/fKGQpTCdH0qYZv3hQtrb1TQ\n"
+ "9YnrbhtaC0haPpintZKjvhU3tCd1fPuIDXtMAgaaKSyoGiE2aMvLxt1/eV08BkMi\n"
+ "kGIss9poYNi5+6ZD9QAHmHJhzZtVGj8U5L8379XmwxAByiBRVVE8CW1X/e6+iJpz\n"
+ "+CLgN+zEVlsCgYEAsuOAdtxXJm4meERwL8b0cvNF3Eh1Sf/42MPTAwzCntSrh3w5\n"
+ "InvwY/RtPHWnN/ScksEG7BWHhLafTCPDHJdp8hNcvIhNB68UBDln0loyYePP5pag\n"
+ "sj4IUSbb7SUlR989elhrMTKQlM5K6QDAJrmjyVdM4S5urL9A3wgAyzAvyP0CgYAO\n"
+ "paGuc8WxdzebWQYl4/bGL2UHgSpGwid7xZYiwMQlZDm2dNuHz+NpCaICwHcEN243\n"
+ "ptEojnWGAGgnK0LGXcDIDqxTlICr2W6FRgjV7Vkf1aKoUtn1+KOM58YpzdJBdDWm\n"
+ "JC/eS+2GVhIZZLDRUDv0VcsmSIBTd3AhiZumm588YwKBgBZfNqfmHAwIP2pM1wml\n"
+ "Ck3vaLLvonghj3iQW9CFJ/SqLOnfT4KJkFObR6oGbxY0RtXsCrmSqidIKgDd0Kkq\n"
+ "L6QbHp2j3+16GBdmLNUJlfjBTNPJp69IDKztjeCX7/8JZs79p/LAv+I9Sh4lVw4O\n"
+ "IrDprlB0yzP5zigcsAZeViYJ\n"
+ "-----END PRIVATE KEY-----\n"
+ ;
+ } else {
+ key = File::getFile(key_path);
+ }
+ ctx.use_private_key(
+ boost::asio::buffer(key.data(), key.size()),
+ boost::asio::ssl::context::file_format::pem);
+
+ ctx.use_tmp_dh(
+ boost::asio::buffer(dh.data(), dh.size()));
+}
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)};
- Server* server = (Server*)arg;
- if (server_name == "lists.antcom.de"s) {
- SSL_set_SSL_CTX(s, server->m_ctx.native_handle());
- } else {
- SSL_set_SSL_CTX(s, server->m_ctx2.native_handle());
- }
+ HTTPS::Server::ctx_type* ctx_map = (HTTPS::Server::ctx_type*)arg;
+
+ ssl::context& ctx = *(ctx_map->at(server_name));
+
+ SSL_set_SSL_CTX(s, ctx.native_handle());
+
return SSL_TLSEXT_ERR_OK;
}
+} // anonymous namespace
+//------------------------------------------------------------------------------
+
+namespace HTTPS {
+
Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socket): ::Server(config, ioc), m_socket(socket)
{
- for (const auto& site: socket.serve_sites) {
- std::cout << "Creating SSL context/cert for site " << site << std::endl;
- }
+ for (const auto& serve_site: socket.serve_sites) {
+ for (const auto& site: config.Sites()) {
+ if (site.name == serve_site) {
+ std::shared_ptr<ssl::context> ctx {std::make_shared<ssl::context>(tls_method)};
- load_server_certificate(m_ctx, m_socket.cert_path, m_socket.key_path);
- load_server_certificate(m_ctx2, "/home/ernie/code/webserver/cert.pem", "/home/ernie/code/webserver/key.pem");
-
- SSL_CTX_set_tlsext_servername_callback(m_ctx.native_handle(), servername_callback);
- SSL_CTX_set_tlsext_servername_arg(m_ctx.native_handle(), this);
-
- SSL_CTX_set_tlsext_servername_callback(m_ctx2.native_handle(), servername_callback);
- SSL_CTX_set_tlsext_servername_arg(m_ctx2.native_handle(), this);
+ std::cout << "Creating SSL context/cert for site " << serve_site << std::endl;
+
+ load_server_certificate(*ctx, site.cert_path, site.key_path);
+ SSL_CTX_set_tlsext_servername_callback(ctx->native_handle(), servername_callback);
+ SSL_CTX_set_tlsext_servername_arg(ctx->native_handle(), &m_ctx);
+
+ for (const auto& host: site.hosts) {
+ std::cout << " Adding Host " << host << std::endl;
+ m_ctx.emplace(host, ctx);
+ }
+ }
+ }
+ }
}
Server::~Server()
@@ -563,10 +690,14 @@ int Server::start()
auto const address = net::ip::make_address(m_socket.address);
auto const port = static_cast<unsigned short>(std::atoi(m_socket.port.data()));
+ load_server_certificate(m_ctx_dummy, "", ""); // initial dummy, before we can add specific ctx w/ certificate
+ SSL_CTX_set_tlsext_servername_callback(m_ctx_dummy.native_handle(), servername_callback);
+ SSL_CTX_set_tlsext_servername_arg(m_ctx_dummy.native_handle(), &m_ctx);
+
// Create and launch a listening port
std::make_shared<listener>(
m_ioc,
- m_ctx,
+ m_ctx_dummy,
tcp::endpoint{address, port},
m_config,
m_socket)->run();