109    using namespace openssl;
 
  111    static auto defaultRSA = []() {
 
  112        BIGNUM* bn = BN_new();
 
  113        BN_set_word(bn, RSA_F4);
 
  115        auto rsa = RSA_new();
 
  128    static auto defaultEphemeralPrivateKey = []() {
 
  129        auto pkey = EVP_PKEY_new();
 
  136        if (RSA_up_ref(defaultRSA) != 1)
 
  138                "EVP_PKEY_assign_RSA: incrementing reference count failed");
 
  140        if (!EVP_PKEY_assign_RSA(pkey, defaultRSA))
 
  146    static auto defaultCert = []() {
 
  147        auto x509 = X509_new();
 
  155        X509_set_version(x509, 2);
 
  161        auto const ts = 
std::time(
nullptr) - (25 * 60 * 60);
 
  164            buf, 
sizeof(buf) - 1, 
"%y%m%d000000Z", 
std::gmtime(&ts));
 
  168        if (ASN1_TIME_set_string_X509(X509_get_notBefore(x509), buf) != 1)
 
  169            LogicError(
"Unable to set certificate validity date");
 
  172        X509_gmtime_adj(X509_get_notAfter(x509), 2 * 365 * 24 * 60 * 60);
 
  175        if (
auto b = BN_new(); b != 
nullptr)
 
  177            if (BN_rand(b, 128, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
 
  179                if (
auto a = ASN1_INTEGER_new(); a != 
nullptr)
 
  181                    if (BN_to_ASN1_INTEGER(b, a))
 
  182                        X509_set_serialNumber(x509, a);
 
  184                    ASN1_INTEGER_free(a);
 
  195            X509V3_set_ctx_nodb(&ctx);
 
  196            X509V3_set_ctx(&ctx, x509, x509, 
nullptr, 
nullptr, 0);
 
  198            if (
auto ext = X509V3_EXT_conf_nid(
 
  199                    nullptr, &ctx, NID_basic_constraints, 
"critical,CA:FALSE"))
 
  201                X509_add_ext(x509, ext, -1);
 
  202                X509_EXTENSION_free(ext);
 
  205            if (
auto ext = X509V3_EXT_conf_nid(
 
  209                    "critical,serverAuth,clientAuth"))
 
  211                X509_add_ext(x509, ext, -1);
 
  212                X509_EXTENSION_free(ext);
 
  215            if (
auto ext = X509V3_EXT_conf_nid(
 
  216                    nullptr, &ctx, NID_key_usage, 
"critical,digitalSignature"))
 
  218                X509_add_ext(x509, ext, -1);
 
  219                X509_EXTENSION_free(ext);
 
  222            if (
auto ext = X509V3_EXT_conf_nid(
 
  223                    nullptr, &ctx, NID_subject_key_identifier, 
"hash"))
 
  225                X509_add_ext(x509, ext, -1);
 
  226                X509_EXTENSION_free(ext);
 
  231        X509_set_pubkey(x509, defaultEphemeralPrivateKey);
 
  233        if (!X509_sign(x509, defaultEphemeralPrivateKey, EVP_sha256()))
 
  239    SSL_CTX* 
const ctx = context.native_handle();
 
  241    if (SSL_CTX_use_certificate(ctx, defaultCert) <= 0)
 
  244    if (SSL_CTX_use_PrivateKey(ctx, defaultEphemeralPrivateKey) <= 0)
 
 
  250    boost::asio::ssl::context& context,
 
  255    auto fmt_error = [](boost::system::error_code ec) -> 
std::string {
 
  256        return " [" + 
std::to_string(ec.value()) + 
": " + ec.message() + 
"]";
 
  259    SSL_CTX* 
const ssl = context.native_handle();
 
  261    bool cert_set = 
false;
 
  263    if (!cert_file.
empty())
 
  265        boost::system::error_code ec;
 
  267        context.use_certificate_file(
 
  268            cert_file, boost::asio::ssl::context::pem, ec);
 
  271            LogicError(
"Problem with SSL certificate file" + fmt_error(ec));
 
  276    if (!chain_file.
empty())
 
  279        FILE* f = fopen(chain_file.
c_str(), 
"r");
 
  284                "Problem opening SSL chain file" +
 
  285                fmt_error(boost::system::error_code(
 
  286                    errno, boost::system::generic_category())));
 
  293                X509* 
const x = PEM_read_X509(f, 
nullptr, 
nullptr, 
nullptr);
 
  300                    if (SSL_CTX_use_certificate(ssl, x) != 1)
 
  302                            "Problem retrieving SSL certificate from chain " 
  307                else if (SSL_CTX_add_extra_chain_cert(ssl, x) != 1)
 
  310                    LogicError(
"Problem adding SSL chain certificate.");
 
  321                    "Reading the SSL chain file generated an exception: ") +
 
  326    if (!key_file.
empty())
 
  328        boost::system::error_code ec;
 
  330        context.use_private_key_file(
 
  331            key_file, boost::asio::ssl::context::pem, ec);
 
  336                "Problem using the SSL private key file" + fmt_error(ec));
 
  340    if (SSL_CTX_check_private_key(ssl) != 1)
 
  342        LogicError(
"Invalid key in SSL private key file.");
 
 
  350        boost::asio::ssl::context::sslv23);
 
  353        boost::asio::ssl::context::default_workarounds |
 
  354        boost::asio::ssl::context::no_sslv2 |
 
  355        boost::asio::ssl::context::no_sslv3 |
 
  356        boost::asio::ssl::context::no_tlsv1 |
 
  357        boost::asio::ssl::context::no_tlsv1_1 |
 
  358        boost::asio::ssl::context::single_dh_use |
 
  359        boost::asio::ssl::context::no_compression);
 
  361    if (cipherList.
empty())
 
  365            SSL_CTX_set_cipher_list(c->native_handle(), cipherList.
c_str());
 
  375    SSL_CTX_set_options(c->native_handle(), SSL_OP_NO_RENEGOTIATION);