| 75 | } |
| 76 | |
| 77 | static void InitSslContext(const Shared<boost::asio::ssl::context>::Ptr& context, const String& pubkey, const String& privkey, const String& cakey) |
| 78 | { |
| 79 | char errbuf[256]; |
| 80 | |
| 81 | // Enforce TLS v1.2 as minimum |
| 82 | context->set_options( |
| 83 | boost::asio::ssl::context::default_workarounds | |
| 84 | boost::asio::ssl::context::no_compression | |
| 85 | boost::asio::ssl::context::no_sslv2 | |
| 86 | boost::asio::ssl::context::no_sslv3 | |
| 87 | boost::asio::ssl::context::no_tlsv1 | |
| 88 | boost::asio::ssl::context::no_tlsv1_1 |
| 89 | ); |
| 90 | |
| 91 | // Custom TLS flags |
| 92 | SSL_CTX *sslContext = context->native_handle(); |
| 93 | |
| 94 | long flags = SSL_CTX_get_options(sslContext); |
| 95 | |
| 96 | flags |= SSL_OP_CIPHER_SERVER_PREFERENCE; |
| 97 | |
| 98 | #ifdef LIBRESSL_VERSION_NUMBER |
| 99 | flags |= SSL_OP_NO_CLIENT_RENEGOTIATION; |
| 100 | #elif OPENSSL_VERSION_NUMBER < 0x10100000L |
| 101 | SSL_CTX_set_info_callback(sslContext, [](const SSL* ssl, int where, int) { |
| 102 | if (where & SSL_CB_HANDSHAKE_DONE) { |
| 103 | ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; |
| 104 | } |
| 105 | }); |
| 106 | #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */ |
| 107 | flags |= SSL_OP_NO_RENEGOTIATION; |
| 108 | #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ |
| 109 | |
| 110 | SSL_CTX_set_options(sslContext, flags); |
| 111 | |
| 112 | SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 113 | SSL_CTX_set_session_id_context(sslContext, (const unsigned char *)"Icinga 2", 8); |
| 114 | |
| 115 | // Explicitly load ECC ciphers, required on el7 - https://github.com/Icinga/icinga2/issues/7247 |
| 116 | // SSL_CTX_set_ecdh_auto is deprecated and removed in OpenSSL 1.1.x - https://github.com/openssl/openssl/issues/1437 |
| 117 | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
| 118 | # ifdef SSL_CTX_set_ecdh_auto |
| 119 | SSL_CTX_set_ecdh_auto(sslContext, 1); |
| 120 | # endif /* SSL_CTX_set_ecdh_auto */ |
| 121 | #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ |
| 122 | |
| 123 | #if OPENSSL_VERSION_NUMBER >= 0x10100000L |
| 124 | // The built-in DH parameters have to be enabled explicitly to allow the use of ciphers that use a DHE key exchange. |
| 125 | // SSL_CTX_set_dh_auto is only documented in OpenSSL starting from version 3.0.0 but was already added in 1.1.0. |
| 126 | // https://github.com/openssl/openssl/commit/09599b52d4e295c380512ba39958a11994d63401 |
| 127 | // https://github.com/openssl/openssl/commit/0437309fdf544492e272943e892523653df2f189 |
| 128 | SSL_CTX_set_dh_auto(sslContext, 1); |
| 129 | #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ |
| 130 | |
| 131 | if (!pubkey.IsEmpty()) { |
| 132 | if (!SSL_CTX_use_certificate_chain_file(sslContext, pubkey.CStr())) { |
| 133 | ERR_error_string_n(ERR_peek_error(), errbuf, sizeof errbuf); |
| 134 | Log(LogCritical, "SSL") |
no test coverage detected