11 #include <unordered_map>
14 #include <openssl/conf.h>
15 #ifndef OPENSSL_NO_ENGINE
16 #include <openssl/engine.h>
18 #include <openssl/err.h>
19 #ifndef DISABLE_OCSP_STAPLING
20 #include <openssl/ocsp.h>
21 #endif /* DISABLE_OCSP_STAPLING */
22 #include <openssl/pkcs12.h>
23 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
24 #include <openssl/provider.h>
25 #endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */
26 #include <openssl/rand.h>
27 #include <openssl/ssl.h>
30 #if OPENSSL_VERSION_MAJOR >= 3
31 #include <openssl/param_build.h>
32 #include <openssl/core.h>
33 #include <openssl/core_names.h>
34 #include <openssl/evp.h>
36 #include <openssl/hmac.h>
41 #endif /* HAVE_LIBSODIUM */
46 #if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL)
47 /* OpenSSL < 1.1.0 needs support for threading/locking in the calling application. */
50 static std::vector
<std::mutex
> openssllocks
;
53 static void openssl_pthreads_locking_callback(int mode
, int type
, const char *file
, int line
)
55 if (mode
& CRYPTO_LOCK
) {
56 openssllocks
.at(type
).lock();
59 openssllocks
.at(type
).unlock();
63 static unsigned long openssl_pthreads_id_callback()
65 return (unsigned long)pthread_self();
69 static void openssl_thread_setup()
71 openssllocks
= std::vector
<std::mutex
>(CRYPTO_num_locks());
72 CRYPTO_set_id_callback(&openssl_pthreads_id_callback
);
73 CRYPTO_set_locking_callback(&openssl_pthreads_locking_callback
);
76 static void openssl_thread_cleanup()
78 CRYPTO_set_locking_callback(nullptr);
82 #endif /* (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL) */
84 static std::atomic
<uint64_t> s_users
;
86 #if OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS)
87 static LockGuarded
<std::unordered_map
<std::string
, std::unique_ptr
<OSSL_PROVIDER
, decltype(&OSSL_PROVIDER_unload
)>>> s_providers
;
89 #ifndef OPENSSL_NO_ENGINE
90 static LockGuarded
<std::unordered_map
<std::string
, std::unique_ptr
<ENGINE
, decltype(&ENGINE_free
)>>> s_engines
;
94 static int s_ticketsKeyIndex
{-1};
95 static int s_countersIndex
{-1};
96 static int s_keyLogIndex
{-1};
98 void registerOpenSSLUser()
100 if (s_users
.fetch_add(1) == 0) {
101 #ifdef HAVE_OPENSSL_INIT_CRYPTO
102 #ifndef DISABLE_OPENSSL_ERROR_STRINGS
103 uint64_t cryptoOpts
= OPENSSL_INIT_LOAD_CONFIG
;
104 const uint64_t sslOpts
= 0;
105 #else /* DISABLE_OPENSSL_ERROR_STRINGS */
106 uint64_t cryptoOpts
= OPENSSL_INIT_LOAD_CONFIG
|OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS
;
107 const uint64_t sslOpts
= OPENSSL_INIT_NO_LOAD_SSL_STRINGS
;
108 #endif /* DISABLE_OPENSSL_ERROR_STRINGS */
109 /* load the default configuration file (or one specified via OPENSSL_CONF),
110 which can then be used to load engines.
112 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
113 /* Since 661595ca0933fe631faeadd14a189acd5d4185e0 we can no longer rely on the ciphers and digests
114 required for TLS to be loaded by OPENSSL_init_ssl(), so let's give up and load everything */
115 #else /* OPENSSL_VERSION_MAJOR >= 3 */
116 /* Do not load all ciphers and digests, we only need a few of them and these
117 will be loaded by OPENSSL_init_ssl(). */
118 cryptoOpts
|= OPENSSL_INIT_NO_ADD_ALL_CIPHERS
|OPENSSL_INIT_NO_ADD_ALL_DIGESTS
;
119 #endif /* OPENSSL_VERSION_MAJOR >= 3 */
121 OPENSSL_init_crypto(cryptoOpts
, nullptr);
122 OPENSSL_init_ssl(sslOpts
, nullptr);
123 #endif /* HAVE_OPENSSL_INIT_CRYPTO */
125 #if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x2090100fL))
126 /* load error strings for both libcrypto and libssl */
127 SSL_load_error_strings();
128 /* load all ciphers and digests needed for TLS support */
129 OpenSSL_add_ssl_algorithms();
130 openssl_thread_setup();
132 s_ticketsKeyIndex
= SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
134 if (s_ticketsKeyIndex
== -1) {
135 throw std::runtime_error("Error getting an index for tickets key");
138 s_countersIndex
= SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
140 if (s_countersIndex
== -1) {
141 throw std::runtime_error("Error getting an index for counters");
144 s_keyLogIndex
= SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
146 if (s_keyLogIndex
== -1) {
147 throw std::runtime_error("Error getting an index for TLS key logging");
152 void unregisterOpenSSLUser()
154 if (s_users
.fetch_sub(1) == 1) {
155 #if OPENSSL_VERSION_MAJOR < 3 || !defined(HAVE_TLS_PROVIDERS)
156 #ifndef OPENSSL_NO_ENGINE
157 for (auto& [name
, engine
] : *s_engines
.lock()) {
158 ENGINE_finish(engine
.get());
161 s_engines
.lock()->clear();
164 #if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x2090100fL))
169 CONF_modules_finish();
171 CONF_modules_unload(1);
173 CRYPTO_cleanup_all_ex_data();
174 openssl_thread_cleanup();
179 #if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS)
180 std::pair
<bool, std::string
> libssl_load_provider(const std::string
& providerName
)
182 if (s_users
.load() == 0) {
183 /* We need to make sure that OpenSSL has been properly initialized before loading an engine.
184 This messes up our accounting a bit, so some memory might not be properly released when
185 the program exits when engines are in use. */
186 registerOpenSSLUser();
189 auto providers
= s_providers
.lock();
190 if (providers
->count(providerName
) > 0) {
191 return { false, "TLS provider already loaded" };
194 auto provider
= std::unique_ptr
<OSSL_PROVIDER
, decltype(&OSSL_PROVIDER_unload
)>(OSSL_PROVIDER_load(nullptr, providerName
.c_str()), OSSL_PROVIDER_unload
);
195 if (provider
== nullptr) {
196 return { false, "unable to load TLS provider '" + providerName
+ "'" };
199 providers
->insert({providerName
, std::move(provider
)});
202 #endif /* HAVE_LIBSSL && OPENSSL_VERSION_MAJOR >= 3 && HAVE_TLS_PROVIDERS */
204 #if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS)
205 std::pair
<bool, std::string
> libssl_load_engine([[maybe_unused
]] const std::string
& engineName
, [[maybe_unused
]] const std::optional
<std::string
>& defaultString
)
207 #ifdef OPENSSL_NO_ENGINE
208 return { false, "OpenSSL has been built without engine support" };
210 if (s_users
.load() == 0) {
211 /* We need to make sure that OpenSSL has been properly initialized before loading an engine.
212 This messes up our accounting a bit, so some memory might not be properly released when
213 the program exits when engines are in use. */
214 registerOpenSSLUser();
217 auto engines
= s_engines
.lock();
218 if (engines
->count(engineName
) > 0) {
219 return { false, "TLS engine already loaded" };
222 auto engine
= std::unique_ptr
<ENGINE
, decltype(&ENGINE_free
)>(ENGINE_by_id(engineName
.c_str()), ENGINE_free
);
223 if (engine
== nullptr) {
224 return { false, "unable to load TLS engine '" + engineName
+ "'" };
227 if (!ENGINE_init(engine
.get())) {
228 return { false, "Unable to init TLS engine '" + engineName
+ "'" };
232 if (ENGINE_set_default_string(engine
.get(), defaultString
->c_str()) == 0) {
233 return { false, "error while setting the TLS engine default string" };
237 engines
->insert({engineName
, std::move(engine
)});
241 #endif /* HAVE_LIBSSL && !HAVE_TLS_PROVIDERS */
243 void* libssl_get_ticket_key_callback_data(SSL
* s
)
245 SSL_CTX
* sslCtx
= SSL_get_SSL_CTX(s
);
246 if (sslCtx
== nullptr) {
250 return SSL_CTX_get_ex_data(sslCtx
, s_ticketsKeyIndex
);
253 void libssl_set_ticket_key_callback_data(SSL_CTX
* ctx
, void* data
)
255 SSL_CTX_set_ex_data(ctx
, s_ticketsKeyIndex
, data
);
258 #if OPENSSL_VERSION_MAJOR >= 3
259 int libssl_ticket_key_callback(SSL
* /* s */, OpenSSLTLSTicketKeysRing
& keyring
, unsigned char keyName
[TLS_TICKETS_KEY_NAME_SIZE
], unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, EVP_MAC_CTX
* hctx
, int enc
)
261 int libssl_ticket_key_callback(SSL
* /* s */, OpenSSLTLSTicketKeysRing
& keyring
, unsigned char keyName
[TLS_TICKETS_KEY_NAME_SIZE
], unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, HMAC_CTX
* hctx
, int enc
)
265 const auto key
= keyring
.getEncryptionKey();
266 if (key
== nullptr) {
270 return key
->encrypt(keyName
, iv
, ectx
, hctx
);
273 bool activeEncryptionKey
= false;
275 const auto key
= keyring
.getDecryptionKey(keyName
, activeEncryptionKey
);
276 if (key
== nullptr) {
277 /* we don't know this key, just create a new ticket */
281 if (!key
->decrypt(iv
, ectx
, hctx
)) {
285 if (!activeEncryptionKey
) {
286 /* this key is not active, please encrypt the ticket content with the currently active one */
293 static int libssl_server_name_callback(SSL
* ssl
, int* /* alert */, void* /* arg */)
295 if (SSL_get_servername(ssl
, TLSEXT_NAMETYPE_host_name
) != nullptr) {
296 return SSL_TLSEXT_ERR_OK
;
299 return SSL_TLSEXT_ERR_NOACK
;
302 static void libssl_info_callback(const SSL
*ssl
, int where
, int /* ret */)
304 SSL_CTX
* sslCtx
= SSL_get_SSL_CTX(ssl
);
305 if (sslCtx
== nullptr) {
309 TLSErrorCounters
* counters
= reinterpret_cast<TLSErrorCounters
*>(SSL_CTX_get_ex_data(sslCtx
, s_countersIndex
));
310 if (counters
== nullptr) {
314 if (where
& SSL_CB_ALERT
) {
315 const long lastError
= ERR_peek_last_error();
316 switch (ERR_GET_REASON(lastError
)) {
317 #ifdef SSL_R_DH_KEY_TOO_SMALL
318 case SSL_R_DH_KEY_TOO_SMALL
:
319 ++counters
->d_dhKeyTooSmall
;
321 #endif /* SSL_R_DH_KEY_TOO_SMALL */
322 case SSL_R_NO_SHARED_CIPHER
:
323 ++counters
->d_noSharedCipher
;
325 case SSL_R_UNKNOWN_PROTOCOL
:
326 ++counters
->d_unknownProtocol
;
328 case SSL_R_UNSUPPORTED_PROTOCOL
:
329 #ifdef SSL_R_VERSION_TOO_LOW
330 case SSL_R_VERSION_TOO_LOW
:
331 #endif /* SSL_R_VERSION_TOO_LOW */
332 ++counters
->d_unsupportedProtocol
;
334 case SSL_R_INAPPROPRIATE_FALLBACK
:
335 ++counters
->d_inappropriateFallBack
;
337 case SSL_R_UNKNOWN_CIPHER_TYPE
:
338 ++counters
->d_unknownCipherType
;
340 case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE
:
341 ++counters
->d_unknownKeyExchangeType
;
343 case SSL_R_UNSUPPORTED_ELLIPTIC_CURVE
:
344 ++counters
->d_unsupportedEC
;
352 void libssl_set_error_counters_callback(std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>& ctx
, TLSErrorCounters
* counters
)
354 SSL_CTX_set_ex_data(ctx
.get(), s_countersIndex
, counters
);
355 SSL_CTX_set_info_callback(ctx
.get(), libssl_info_callback
);
358 #ifndef DISABLE_OCSP_STAPLING
359 int libssl_ocsp_stapling_callback(SSL
* ssl
, const std::map
<int, std::string
>& ocspMap
)
361 auto pkey
= SSL_get_privatekey(ssl
);
362 if (pkey
== nullptr) {
363 return SSL_TLSEXT_ERR_NOACK
;
366 /* look for an OCSP response for the corresponding private key type (RSA, ECDSA..) */
367 const auto& data
= ocspMap
.find(EVP_PKEY_base_id(pkey
));
368 if (data
== ocspMap
.end()) {
369 return SSL_TLSEXT_ERR_NOACK
;
372 /* we need to allocate a copy because OpenSSL will free the pointer passed to SSL_set_tlsext_status_ocsp_resp() */
373 void* copy
= OPENSSL_malloc(data
->second
.size());
374 if (copy
== nullptr) {
375 return SSL_TLSEXT_ERR_NOACK
;
378 memcpy(copy
, data
->second
.data(), data
->second
.size());
379 SSL_set_tlsext_status_ocsp_resp(ssl
, copy
, data
->second
.size());
380 return SSL_TLSEXT_ERR_OK
;
383 static bool libssl_validate_ocsp_response(const std::string
& response
)
385 auto responsePtr
= reinterpret_cast<const unsigned char *>(response
.data());
386 std::unique_ptr
<OCSP_RESPONSE
, void(*)(OCSP_RESPONSE
*)> resp(d2i_OCSP_RESPONSE(nullptr, &responsePtr
, response
.size()), OCSP_RESPONSE_free
);
387 if (resp
== nullptr) {
388 throw std::runtime_error("Unable to parse OCSP response");
391 int status
= OCSP_response_status(resp
.get());
392 if (status
!= OCSP_RESPONSE_STATUS_SUCCESSFUL
) {
393 throw std::runtime_error("OCSP response status is not successful: " + std::to_string(status
));
396 std::unique_ptr
<OCSP_BASICRESP
, void(*)(OCSP_BASICRESP
*)> basic(OCSP_response_get1_basic(resp
.get()), OCSP_BASICRESP_free
);
397 if (basic
== nullptr) {
398 throw std::runtime_error("Error getting a basic OCSP response");
401 if (OCSP_resp_count(basic
.get()) != 1) {
402 throw std::runtime_error("More than one single response in an OCSP basic response");
405 auto singleResponse
= OCSP_resp_get0(basic
.get(), 0);
406 if (singleResponse
== nullptr) {
407 throw std::runtime_error("Error getting a single response from the basic OCSP response");
411 ASN1_GENERALIZEDTIME
* revTime
= nullptr;
412 ASN1_GENERALIZEDTIME
* thisUpdate
= nullptr;
413 ASN1_GENERALIZEDTIME
* nextUpdate
= nullptr;
415 auto singleResponseStatus
= OCSP_single_get0_status(singleResponse
, &reason
, &revTime
, &thisUpdate
, &nextUpdate
);
416 if (singleResponseStatus
!= V_OCSP_CERTSTATUS_GOOD
) {
417 throw std::runtime_error("Invalid status for OCSP single response (" + std::to_string(singleResponseStatus
) + ")");
419 if (thisUpdate
== nullptr || nextUpdate
== nullptr) {
420 throw std::runtime_error("Error getting validity of OCSP single response");
423 auto validityResult
= OCSP_check_validity(thisUpdate
, nextUpdate
, /* 5 minutes of leeway */ 5 * 60, -1);
424 if (validityResult
== 0) {
425 throw std::runtime_error("OCSP single response is not yet, or no longer, valid");
431 static std::map
<int, std::string
> libssl_load_ocsp_responses(const std::vector
<std::string
>& ocspFiles
, std::vector
<int> keyTypes
, std::vector
<std::string
>& warnings
)
433 std::map
<int, std::string
> ocspResponses
;
435 if (ocspFiles
.size() > keyTypes
.size()) {
436 throw std::runtime_error("More OCSP files than certificates and keys loaded!");
440 for (const auto& filename
: ocspFiles
) {
441 std::ifstream
file(filename
, std::ios::binary
);
445 file
.read(buffer
, sizeof(buffer
));
448 warnings
.push_back("Unable to load OCSP response from " + filename
);
451 content
.append(buffer
, file
.gcount());
456 libssl_validate_ocsp_response(content
);
457 ocspResponses
.insert({keyTypes
.at(count
), std::move(content
)});
459 catch (const std::exception
& e
) {
460 warnings
.push_back("Error checking the validity of OCSP response from '" + filename
+ "': " + e
.what());
466 return ocspResponses
;
469 #ifdef HAVE_OCSP_BASIC_SIGN
470 bool libssl_generate_ocsp_response(const std::string
& certFile
, const std::string
& caCert
, const std::string
& caKey
, const std::string
& outFile
, int ndays
, int nmin
)
472 const EVP_MD
* rmd
= EVP_sha256();
474 auto filePtr
= pdns::UniqueFilePtr(fopen(certFile
.c_str(), "r"));
476 throw std::runtime_error("Unable to open '" + certFile
+ "' when loading the certificate to generate an OCSP response");
478 auto cert
= std::unique_ptr
<X509
, void(*)(X509
*)>(PEM_read_X509_AUX(filePtr
.get(), nullptr, nullptr, nullptr), X509_free
);
480 filePtr
= pdns::UniqueFilePtr(fopen(caCert
.c_str(), "r"));
482 throw std::runtime_error("Unable to open '" + caCert
+ "' when loading the issuer certificate to generate an OCSP response");
484 auto issuer
= std::unique_ptr
<X509
, void(*)(X509
*)>(PEM_read_X509_AUX(filePtr
.get(), nullptr, nullptr, nullptr), X509_free
);
485 filePtr
= pdns::UniqueFilePtr(fopen(caKey
.c_str(), "r"));
487 throw std::runtime_error("Unable to open '" + caKey
+ "' when loading the issuer key to generate an OCSP response");
489 auto issuerKey
= std::unique_ptr
<EVP_PKEY
, void(*)(EVP_PKEY
*)>(PEM_read_PrivateKey(filePtr
.get(), nullptr, nullptr, nullptr), EVP_PKEY_free
);
492 auto bs
= std::unique_ptr
<OCSP_BASICRESP
, void(*)(OCSP_BASICRESP
*)>(OCSP_BASICRESP_new(), OCSP_BASICRESP_free
);
493 auto thisupd
= std::unique_ptr
<ASN1_TIME
, void(*)(ASN1_TIME
*)>(X509_gmtime_adj(nullptr, 0), ASN1_TIME_free
);
494 auto nextupd
= std::unique_ptr
<ASN1_TIME
, void(*)(ASN1_TIME
*)>(X509_time_adj_ex(nullptr, ndays
, nmin
* 60, nullptr), ASN1_TIME_free
);
496 auto cid
= std::unique_ptr
<OCSP_CERTID
, void(*)(OCSP_CERTID
*)>(OCSP_cert_to_id(rmd
, cert
.get(), issuer
.get()), OCSP_CERTID_free
);
497 OCSP_basic_add1_status(bs
.get(), cid
.get(), V_OCSP_CERTSTATUS_GOOD
, 0, nullptr, thisupd
.get(), nextupd
.get());
499 if (OCSP_basic_sign(bs
.get(), issuer
.get(), issuerKey
.get(), rmd
, nullptr, OCSP_NOCERTS
) != 1) {
500 throw std::runtime_error("Error while signing the OCSP response");
503 auto resp
= std::unique_ptr
<OCSP_RESPONSE
, void(*)(OCSP_RESPONSE
*)>(OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL
, bs
.get()), OCSP_RESPONSE_free
);
504 auto bio
= std::unique_ptr
<BIO
, void(*)(BIO
*)>(BIO_new_file(outFile
.c_str(), "wb"), BIO_vfree
);
506 throw std::runtime_error("Error opening file for writing the OCSP response");
509 // i2d_OCSP_RESPONSE_bio(bio.get(), resp.get()) is unusable from C++ because of an invalid cast
510 ASN1_i2d_bio((i2d_of_void
*)i2d_OCSP_RESPONSE
, bio
.get(), (unsigned char*)resp
.get());
514 #endif /* HAVE_OCSP_BASIC_SIGN */
515 #endif /* DISABLE_OCSP_STAPLING */
517 static int libssl_get_last_key_type(std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>& ctx
)
519 #ifdef HAVE_SSL_CTX_GET0_PRIVATEKEY
520 auto pkey
= SSL_CTX_get0_privatekey(ctx
.get());
522 auto temp
= std::unique_ptr
<SSL
, void(*)(SSL
*)>(SSL_new(ctx
.get()), SSL_free
);
526 auto pkey
= SSL_get_privatekey(temp
.get());
533 return EVP_PKEY_base_id(pkey
);
536 LibsslTLSVersion
libssl_tls_version_from_string(const std::string
& str
)
538 if (str
== "tls1.0") {
539 return LibsslTLSVersion::TLS10
;
541 if (str
== "tls1.1") {
542 return LibsslTLSVersion::TLS11
;
544 if (str
== "tls1.2") {
545 return LibsslTLSVersion::TLS12
;
547 if (str
== "tls1.3") {
548 return LibsslTLSVersion::TLS13
;
550 throw std::runtime_error("Unknown TLS version '" + str
);
553 const std::string
& libssl_tls_version_to_string(LibsslTLSVersion version
)
555 static const std::map
<LibsslTLSVersion
, std::string
> versions
= {
556 { LibsslTLSVersion::TLS10
, "tls1.0" },
557 { LibsslTLSVersion::TLS11
, "tls1.1" },
558 { LibsslTLSVersion::TLS12
, "tls1.2" },
559 { LibsslTLSVersion::TLS13
, "tls1.3" }
562 const auto& it
= versions
.find(version
);
563 if (it
== versions
.end()) {
564 throw std::runtime_error("Unknown TLS version (" + std::to_string((int)version
) + ")");
569 bool libssl_set_min_tls_version(std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>& ctx
, LibsslTLSVersion version
)
571 #if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION) || defined(SSL_CTX_set_min_proto_version)
572 /* These functions have been introduced in 1.1.0, and the use of SSL_OP_NO_* is deprecated
573 Warning: SSL_CTX_set_min_proto_version is a function-like macro in OpenSSL */
576 case LibsslTLSVersion::TLS10
:
579 case LibsslTLSVersion::TLS11
:
580 vers
= TLS1_1_VERSION
;
582 case LibsslTLSVersion::TLS12
:
583 vers
= TLS1_2_VERSION
;
585 case LibsslTLSVersion::TLS13
:
586 #ifdef TLS1_3_VERSION
587 vers
= TLS1_3_VERSION
;
590 #endif /* TLS1_3_VERSION */
596 if (SSL_CTX_set_min_proto_version(ctx
.get(), vers
) != 1) {
601 long vers
= SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
;
603 case LibsslTLSVersion::TLS10
:
605 case LibsslTLSVersion::TLS11
:
606 vers
|= SSL_OP_NO_TLSv1
;
608 case LibsslTLSVersion::TLS12
:
609 vers
|= SSL_OP_NO_TLSv1
| SSL_OP_NO_TLSv1_1
;
611 case LibsslTLSVersion::TLS13
:
612 vers
|= SSL_OP_NO_TLSv1
| SSL_OP_NO_TLSv1_1
| SSL_OP_NO_TLSv1_2
;
618 long options
= SSL_CTX_get_options(ctx
.get());
619 SSL_CTX_set_options(ctx
.get(), options
| vers
);
624 OpenSSLTLSTicketKeysRing::OpenSSLTLSTicketKeysRing(size_t capacity
)
626 d_ticketKeys
.write_lock()->set_capacity(capacity
);
629 OpenSSLTLSTicketKeysRing::~OpenSSLTLSTicketKeysRing() = default;
631 void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr
<OpenSSLTLSTicketKey
>&& newKey
)
633 d_ticketKeys
.write_lock()->push_front(std::move(newKey
));
636 std::shared_ptr
<OpenSSLTLSTicketKey
> OpenSSLTLSTicketKeysRing::getEncryptionKey()
638 return d_ticketKeys
.read_lock()->front();
641 std::shared_ptr
<OpenSSLTLSTicketKey
> OpenSSLTLSTicketKeysRing::getDecryptionKey(unsigned char name
[TLS_TICKETS_KEY_NAME_SIZE
], bool& activeKey
)
643 auto keys
= d_ticketKeys
.read_lock();
644 for (auto& key
: *keys
) {
645 if (key
->nameMatches(name
)) {
646 activeKey
= (key
== keys
->front());
653 size_t OpenSSLTLSTicketKeysRing::getKeysCount()
655 return d_ticketKeys
.read_lock()->size();
658 void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string
& keyFile
)
660 bool keyLoaded
= false;
661 std::ifstream
file(keyFile
);
664 auto newKey
= std::make_shared
<OpenSSLTLSTicketKey
>(file
);
665 addKey(std::move(newKey
));
668 while (!file
.fail());
670 catch (const std::exception
& e
) {
671 /* if we haven't been able to load at least one key, fail */
680 void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t /* now */)
682 auto newKey
= std::make_shared
<OpenSSLTLSTicketKey
>();
683 addKey(std::move(newKey
));
686 OpenSSLTLSTicketKey::OpenSSLTLSTicketKey()
688 if (RAND_bytes(d_name
, sizeof(d_name
)) != 1) {
689 throw std::runtime_error("Error while generating the name of the OpenSSL TLS ticket key");
692 if (RAND_bytes(d_cipherKey
, sizeof(d_cipherKey
)) != 1) {
693 throw std::runtime_error("Error while generating the cipher key of the OpenSSL TLS ticket key");
696 if (RAND_bytes(d_hmacKey
, sizeof(d_hmacKey
)) != 1) {
697 throw std::runtime_error("Error while generating the HMAC key of the OpenSSL TLS ticket key");
699 #ifdef HAVE_LIBSODIUM
700 sodium_mlock(d_name
, sizeof(d_name
));
701 sodium_mlock(d_cipherKey
, sizeof(d_cipherKey
));
702 sodium_mlock(d_hmacKey
, sizeof(d_hmacKey
));
703 #endif /* HAVE_LIBSODIUM */
706 OpenSSLTLSTicketKey::OpenSSLTLSTicketKey(std::ifstream
& file
)
708 file
.read(reinterpret_cast<char*>(d_name
), sizeof(d_name
));
709 file
.read(reinterpret_cast<char*>(d_cipherKey
), sizeof(d_cipherKey
));
710 file
.read(reinterpret_cast<char*>(d_hmacKey
), sizeof(d_hmacKey
));
713 throw std::runtime_error("Unable to load a ticket key from the OpenSSL tickets key file");
715 #ifdef HAVE_LIBSODIUM
716 sodium_mlock(d_name
, sizeof(d_name
));
717 sodium_mlock(d_cipherKey
, sizeof(d_cipherKey
));
718 sodium_mlock(d_hmacKey
, sizeof(d_hmacKey
));
719 #endif /* HAVE_LIBSODIUM */
722 OpenSSLTLSTicketKey::~OpenSSLTLSTicketKey()
724 #ifdef HAVE_LIBSODIUM
725 sodium_munlock(d_name
, sizeof(d_name
));
726 sodium_munlock(d_cipherKey
, sizeof(d_cipherKey
));
727 sodium_munlock(d_hmacKey
, sizeof(d_hmacKey
));
729 OPENSSL_cleanse(d_name
, sizeof(d_name
));
730 OPENSSL_cleanse(d_cipherKey
, sizeof(d_cipherKey
));
731 OPENSSL_cleanse(d_hmacKey
, sizeof(d_hmacKey
));
732 #endif /* HAVE_LIBSODIUM */
735 bool OpenSSLTLSTicketKey::nameMatches(const unsigned char name
[TLS_TICKETS_KEY_NAME_SIZE
]) const
737 return (memcmp(d_name
, name
, sizeof(d_name
)) == 0);
740 #if OPENSSL_VERSION_MAJOR >= 3
741 static const std::string sha256KeyName
{"sha256"};
744 #if OPENSSL_VERSION_MAJOR >= 3
745 int OpenSSLTLSTicketKey::encrypt(unsigned char keyName
[TLS_TICKETS_KEY_NAME_SIZE
], unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, EVP_MAC_CTX
* hctx
) const
747 int OpenSSLTLSTicketKey::encrypt(unsigned char keyName
[TLS_TICKETS_KEY_NAME_SIZE
], unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, HMAC_CTX
* hctx
) const
750 memcpy(keyName
, d_name
, sizeof(d_name
));
752 if (RAND_bytes(iv
, EVP_MAX_IV_LENGTH
) != 1) {
756 if (EVP_EncryptInit_ex(ectx
, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey
, iv
) != 1) {
760 #if OPENSSL_VERSION_MAJOR >= 3
761 using ParamsBuilder
= std::unique_ptr
<OSSL_PARAM_BLD
, decltype(&OSSL_PARAM_BLD_free
)>;
762 using Params
= std::unique_ptr
<OSSL_PARAM
, decltype(&OSSL_PARAM_free
)>;
764 auto params_build
= ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free
);
765 if (params_build
== nullptr) {
769 if (OSSL_PARAM_BLD_push_utf8_string(params_build
.get(), OSSL_MAC_PARAM_DIGEST
, sha256KeyName
.c_str(), sha256KeyName
.size()) == 0) {
773 auto params
= Params(OSSL_PARAM_BLD_to_param(params_build
.get()), OSSL_PARAM_free
);
774 if (params
== nullptr) {
778 if (EVP_MAC_CTX_set_params(hctx
, params
.get()) == 0) {
782 if (EVP_MAC_init(hctx
, d_hmacKey
, sizeof(d_hmacKey
), nullptr) == 0) {
786 if (HMAC_Init_ex(hctx
, d_hmacKey
, sizeof(d_hmacKey
), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
794 #if OPENSSL_VERSION_MAJOR >= 3
795 bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, EVP_MAC_CTX
* hctx
) const
797 bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv
, EVP_CIPHER_CTX
* ectx
, HMAC_CTX
* hctx
) const
800 #if OPENSSL_VERSION_MAJOR >= 3
801 using ParamsBuilder
= std::unique_ptr
<OSSL_PARAM_BLD
, decltype(&OSSL_PARAM_BLD_free
)>;
802 using Params
= std::unique_ptr
<OSSL_PARAM
, decltype(&OSSL_PARAM_free
)>;
804 auto params_build
= ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free
);
805 if (params_build
== nullptr) {
809 if (OSSL_PARAM_BLD_push_utf8_string(params_build
.get(), OSSL_MAC_PARAM_DIGEST
, sha256KeyName
.c_str(), sha256KeyName
.size()) == 0) {
813 auto params
= Params(OSSL_PARAM_BLD_to_param(params_build
.get()), OSSL_PARAM_free
);
814 if (params
== nullptr) {
818 if (EVP_MAC_CTX_set_params(hctx
, params
.get()) == 0) {
822 if (EVP_MAC_init(hctx
, d_hmacKey
, sizeof(d_hmacKey
), nullptr) == 0) {
826 if (HMAC_Init_ex(hctx
, d_hmacKey
, sizeof(d_hmacKey
), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
831 if (EVP_DecryptInit_ex(ectx
, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey
, iv
) != 1) {
838 std::pair
<std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>, std::vector
<std::string
>> libssl_init_server_context(const TLSConfig
& config
,
839 std::map
<int, std::string
>& ocspResponses
)
841 std::vector
<std::string
> warnings
;
842 auto ctx
= std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>(SSL_CTX_new(SSLv23_server_method()), SSL_CTX_free
);
845 throw pdns::OpenSSL::error("Error creating an OpenSSL server context");
851 SSL_OP_NO_COMPRESSION
|
852 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
853 SSL_OP_SINGLE_DH_USE
|
854 SSL_OP_SINGLE_ECDH_USE
;
856 if (!config
.d_enableTickets
|| config
.d_numberOfTicketsKeys
== 0) {
857 /* for TLS 1.3 this means no stateless tickets, but stateful tickets might still be issued,
858 which is something we don't want. */
859 sslOptions
|= SSL_OP_NO_TICKET
;
860 /* really disable all tickets */
861 #ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
862 SSL_CTX_set_num_tickets(ctx
.get(), 0);
863 #endif /* HAVE_SSL_CTX_SET_NUM_TICKETS */
867 #ifdef SSL_OP_ENABLE_KTLS
868 sslOptions
|= SSL_OP_ENABLE_KTLS
;
869 #endif /* SSL_OP_ENABLE_KTLS */
872 if (config
.d_sessionTimeout
> 0) {
873 SSL_CTX_set_timeout(ctx
.get(), config
.d_sessionTimeout
);
876 if (config
.d_preferServerCiphers
) {
877 sslOptions
|= SSL_OP_CIPHER_SERVER_PREFERENCE
;
878 #ifdef SSL_OP_PRIORITIZE_CHACHA
879 sslOptions
|= SSL_OP_PRIORITIZE_CHACHA
;
880 #endif /* SSL_OP_PRIORITIZE_CHACHA */
883 if (!config
.d_enableRenegotiation
) {
884 #ifdef SSL_OP_NO_RENEGOTIATION
885 sslOptions
|= SSL_OP_NO_RENEGOTIATION
;
886 #elif defined(SSL_OP_NO_CLIENT_RENEGOTIATION)
887 sslOptions
|= SSL_OP_NO_CLIENT_RENEGOTIATION
;
891 #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
892 sslOptions
|= SSL_OP_IGNORE_UNEXPECTED_EOF
;
895 SSL_CTX_set_options(ctx
.get(), sslOptions
);
896 if (!libssl_set_min_tls_version(ctx
, config
.d_minTLSVersion
)) {
897 throw std::runtime_error("Failed to set the minimum version to '" + libssl_tls_version_to_string(config
.d_minTLSVersion
));
900 #ifdef SSL_CTX_set_ecdh_auto
901 SSL_CTX_set_ecdh_auto(ctx
.get(), 1);
904 if (config
.d_maxStoredSessions
== 0) {
905 /* disable stored sessions entirely */
906 SSL_CTX_set_session_cache_mode(ctx
.get(), SSL_SESS_CACHE_OFF
);
909 /* use the internal built-in cache to store sessions */
910 SSL_CTX_set_session_cache_mode(ctx
.get(), SSL_SESS_CACHE_SERVER
);
911 SSL_CTX_sess_set_cache_size(ctx
.get(), config
.d_maxStoredSessions
);
915 #ifdef SSL_MODE_RELEASE_BUFFERS
916 if (config
.d_releaseBuffers
) {
917 mode
|= SSL_MODE_RELEASE_BUFFERS
;
921 if (config
.d_asyncMode
) {
922 #ifdef SSL_MODE_ASYNC
923 mode
|= SSL_MODE_ASYNC
;
925 warnings
.push_back("Warning: TLS async mode requested but not supported");
929 SSL_CTX_set_mode(ctx
.get(), mode
);
931 /* we need to set this callback to acknowledge the server name sent by the client,
932 otherwise it will not stored in the session and will not be accessible when the
933 session is resumed, causing SSL_get_servername to return nullptr */
934 SSL_CTX_set_tlsext_servername_callback(ctx
.get(), &libssl_server_name_callback
);
936 std::vector
<int> keyTypes
;
937 /* load certificate and private key */
938 for (const auto& pair
: config
.d_certKeyPairs
) {
940 #if defined(HAVE_SSL_CTX_USE_CERT_AND_KEY)
941 // If no separate key is given, treat it as a pkcs12 file
942 auto filePtr
= pdns::UniqueFilePtr(fopen(pair
.d_cert
.c_str(), "r"));
944 throw std::runtime_error("Unable to open file " + pair
.d_cert
);
946 auto p12
= std::unique_ptr
<PKCS12
, void(*)(PKCS12
*)>(d2i_PKCS12_fp(filePtr
.get(), nullptr), PKCS12_free
);
948 throw std::runtime_error("Unable to open PKCS12 file " + pair
.d_cert
);
950 EVP_PKEY
*keyptr
= nullptr;
951 X509
*certptr
= nullptr;
952 STACK_OF(X509
) *captr
= nullptr;
953 if (!PKCS12_parse(p12
.get(), (pair
.d_password
? pair
.d_password
->c_str() : nullptr), &keyptr
, &certptr
, &captr
)) {
954 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
956 /* we might be opening a PKCS12 file that uses RC2 CBC or 3DES CBC which, since OpenSSL 3.0.0, requires loading the legacy provider */
957 auto libCtx
= OSSL_LIB_CTX_get0_global_default();
958 /* check whether the legacy provider is already loaded */
959 if (!OSSL_PROVIDER_available(libCtx
, "legacy")) {
961 auto provider
= OSSL_PROVIDER_load(libCtx
, "legacy");
962 if (provider
!= nullptr) {
963 if (PKCS12_parse(p12
.get(), (pair
.d_password
? pair
.d_password
->c_str() : nullptr), &keyptr
, &certptr
, &captr
)) {
966 /* we do not want to keep that provider around after that */
967 OSSL_PROVIDER_unload(provider
);
971 #endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */
972 ERR_print_errors_fp(stderr
);
973 throw std::runtime_error("An error occured while parsing PKCS12 file " + pair
.d_cert
);
974 #if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
976 #endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */
978 auto key
= std::unique_ptr
<EVP_PKEY
, void(*)(EVP_PKEY
*)>(keyptr
, EVP_PKEY_free
);
979 auto cert
= std::unique_ptr
<X509
, void(*)(X509
*)>(certptr
, X509_free
);
980 auto ca
= std::unique_ptr
<STACK_OF(X509
), void(*)(STACK_OF(X509
)*)>(captr
, [](STACK_OF(X509
)* st
){ sk_X509_free(st
); });
982 if (SSL_CTX_use_cert_and_key(ctx
.get(), cert
.get(), key
.get(), ca
.get(), 1) != 1) {
983 ERR_print_errors_fp(stderr
);
984 throw std::runtime_error("An error occurred while trying to load the TLS certificate and key from PKCS12 file " + pair
.d_cert
);
987 throw std::runtime_error("PKCS12 files are not supported by your openssl version");
988 #endif /* HAVE_SSL_CTX_USE_CERT_AND_KEY */
990 if (SSL_CTX_use_certificate_chain_file(ctx
.get(), pair
.d_cert
.c_str()) != 1) {
991 ERR_print_errors_fp(stderr
);
992 throw std::runtime_error("An error occurred while trying to load the TLS server certificate file: " + pair
.d_cert
);
994 if (SSL_CTX_use_PrivateKey_file(ctx
.get(), pair
.d_key
->c_str(), SSL_FILETYPE_PEM
) != 1) {
995 ERR_print_errors_fp(stderr
);
996 throw std::runtime_error("An error occurred while trying to load the TLS server private key file: " + pair
.d_key
.value());
999 if (SSL_CTX_check_private_key(ctx
.get()) != 1) {
1000 ERR_print_errors_fp(stderr
);
1001 throw std::runtime_error("The key from '" + pair
.d_key
.value() + "' does not match the certificate from '" + pair
.d_cert
+ "'");
1003 /* store the type of the new key, we might need it later to select the right OCSP stapling response */
1004 auto keyType
= libssl_get_last_key_type(ctx
);
1006 throw std::runtime_error("The key from '" + pair
.d_key
.value() + "' has an unknown type");
1008 keyTypes
.push_back(keyType
);
1011 #ifndef DISABLE_OCSP_STAPLING
1012 if (!config
.d_ocspFiles
.empty()) {
1014 ocspResponses
= libssl_load_ocsp_responses(config
.d_ocspFiles
, std::move(keyTypes
), warnings
);
1016 catch(const std::exception
& e
) {
1017 throw std::runtime_error("Unable to load OCSP responses: " + std::string(e
.what()));
1020 #endif /* DISABLE_OCSP_STAPLING */
1022 if (!config
.d_ciphers
.empty() && SSL_CTX_set_cipher_list(ctx
.get(), config
.d_ciphers
.c_str()) != 1) {
1023 throw std::runtime_error("The TLS ciphers could not be set: " + config
.d_ciphers
);
1026 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
1027 if (!config
.d_ciphers13
.empty() && SSL_CTX_set_ciphersuites(ctx
.get(), config
.d_ciphers13
.c_str()) != 1) {
1028 throw std::runtime_error("The TLS 1.3 ciphers could not be set: " + config
.d_ciphers13
);
1030 #endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */
1032 return {std::move(ctx
), std::move(warnings
)};
1035 #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
1036 static void libssl_key_log_file_callback(const SSL
* ssl
, const char* line
)
1038 SSL_CTX
* sslCtx
= SSL_get_SSL_CTX(ssl
);
1039 if (sslCtx
== nullptr) {
1043 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): OpenSSL's API
1044 auto* filePtr
= reinterpret_cast<FILE*>(SSL_CTX_get_ex_data(sslCtx
, s_keyLogIndex
));
1045 if (filePtr
== nullptr) {
1049 fprintf(filePtr
, "%s\n", line
);
1052 #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
1054 pdns::UniqueFilePtr
libssl_set_key_log_file(std::unique_ptr
<SSL_CTX
, decltype(&SSL_CTX_free
)>& ctx
, const std::string
& logFile
)
1056 #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
1057 auto filePtr
= pdns::openFileForWriting(logFile
, 0600, false, true);
1060 throw std::runtime_error("Error opening file " + logFile
+ " for writing: " + stringerror(error
));
1062 SSL_CTX_set_ex_data(ctx
.get(), s_keyLogIndex
, filePtr
.get());
1063 SSL_CTX_set_keylog_callback(ctx
.get(), &libssl_key_log_file_callback
);
1066 return pdns::UniqueFilePtr(nullptr);
1067 #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
1070 /* called in a client context, if the client advertised more than one ALPN values and the server returned more than one as well, to select the one to use. */
1072 void libssl_set_npn_select_callback(SSL_CTX
* ctx
, int (*cb
)(SSL
* s
, unsigned char** out
, unsigned char* outlen
, const unsigned char* in
, unsigned int inlen
, void* arg
), void* arg
)
1074 #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
1075 SSL_CTX_set_next_proto_select_cb(ctx
, cb
, arg
);
1078 #endif /* DISABLE_NPN */
1080 void libssl_set_alpn_select_callback(SSL_CTX
* ctx
, int (*cb
)(SSL
* s
, const unsigned char** out
, unsigned char* outlen
, const unsigned char* in
, unsigned int inlen
, void* arg
), void* arg
)
1082 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
1083 SSL_CTX_set_alpn_select_cb(ctx
, cb
, arg
);
1087 bool libssl_set_alpn_protos(SSL_CTX
* ctx
, const std::vector
<std::vector
<uint8_t>>& protos
)
1089 #ifdef HAVE_SSL_CTX_SET_ALPN_PROTOS
1090 std::vector
<uint8_t> wire
;
1091 for (const auto& proto
: protos
) {
1092 if (proto
.size() > std::numeric_limits
<uint8_t>::max()) {
1093 throw std::runtime_error("Invalid ALPN value");
1095 uint8_t length
= proto
.size();
1096 wire
.push_back(length
);
1097 wire
.insert(wire
.end(), proto
.begin(), proto
.end());
1099 return SSL_CTX_set_alpn_protos(ctx
, wire
.data(), wire
.size()) == 0;
1106 std::string
libssl_get_error_string()
1108 BIO
*mem
= BIO_new(BIO_s_mem());
1109 ERR_print_errors(mem
);
1111 size_t len
= BIO_get_mem_data(mem
, &p
);
1112 std::string
msg(p
, len
);
1113 // replace newlines by /
1114 if (msg
.back() == '\n') {
1117 std::replace(msg
.begin(), msg
.end(), '\n', '/');
1121 #endif /* HAVE_LIBSSL */