]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/libssl.cc
rec: mention rust compiler in compiling docs
[thirdparty/pdns.git] / pdns / libssl.cc
1
2 #include "config.h"
3 #include "libssl.hh"
4
5 #ifdef HAVE_LIBSSL
6
7 #include <atomic>
8 #include <fstream>
9 #include <cstring>
10 #include <mutex>
11 #include <unordered_map>
12 #include <pthread.h>
13
14 #include <openssl/conf.h>
15 #ifndef OPENSSL_NO_ENGINE
16 #include <openssl/engine.h>
17 #endif
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>
28 #include <fcntl.h>
29
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>
35 #else
36 #include <openssl/hmac.h>
37 #endif
38
39 #ifdef HAVE_LIBSODIUM
40 #include <sodium.h>
41 #endif /* HAVE_LIBSODIUM */
42
43 #undef CERT
44 #include "misc.hh"
45
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. */
48
49 #include "lock.hh"
50 static std::vector<std::mutex> openssllocks;
51
52 extern "C" {
53 static void openssl_pthreads_locking_callback(int mode, int type, const char *file, int line)
54 {
55 if (mode & CRYPTO_LOCK) {
56 openssllocks.at(type).lock();
57
58 } else {
59 openssllocks.at(type).unlock();
60 }
61 }
62
63 static unsigned long openssl_pthreads_id_callback()
64 {
65 return (unsigned long)pthread_self();
66 }
67 }
68
69 static void openssl_thread_setup()
70 {
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);
74 }
75
76 static void openssl_thread_cleanup()
77 {
78 CRYPTO_set_locking_callback(nullptr);
79 openssllocks.clear();
80 }
81
82 #endif /* (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL) */
83
84 static std::atomic<uint64_t> s_users;
85
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;
88 #else
89 #ifndef OPENSSL_NO_ENGINE
90 static LockGuarded<std::unordered_map<std::string, std::unique_ptr<ENGINE, decltype(&ENGINE_free)>>> s_engines;
91 #endif
92 #endif
93
94 static int s_ticketsKeyIndex{-1};
95 static int s_countersIndex{-1};
96 static int s_keyLogIndex{-1};
97
98 void registerOpenSSLUser()
99 {
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.
111 */
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 */
120
121 OPENSSL_init_crypto(cryptoOpts, nullptr);
122 OPENSSL_init_ssl(sslOpts, nullptr);
123 #endif /* HAVE_OPENSSL_INIT_CRYPTO */
124
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();
131 #endif
132 s_ticketsKeyIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
133
134 if (s_ticketsKeyIndex == -1) {
135 throw std::runtime_error("Error getting an index for tickets key");
136 }
137
138 s_countersIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
139
140 if (s_countersIndex == -1) {
141 throw std::runtime_error("Error getting an index for counters");
142 }
143
144 s_keyLogIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
145
146 if (s_keyLogIndex == -1) {
147 throw std::runtime_error("Error getting an index for TLS key logging");
148 }
149 }
150 }
151
152 void unregisterOpenSSLUser()
153 {
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());
159 engine.reset();
160 }
161 s_engines.lock()->clear();
162 #endif
163 #endif
164 #if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x2090100fL))
165 ERR_free_strings();
166
167 EVP_cleanup();
168
169 CONF_modules_finish();
170 CONF_modules_free();
171 CONF_modules_unload(1);
172
173 CRYPTO_cleanup_all_ex_data();
174 openssl_thread_cleanup();
175 #endif
176 }
177 }
178
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)
181 {
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();
187 }
188
189 auto providers = s_providers.lock();
190 if (providers->count(providerName) > 0) {
191 return { false, "TLS provider already loaded" };
192 }
193
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 + "'" };
197 }
198
199 providers->insert({providerName, std::move(provider)});
200 return { true, "" };
201 }
202 #endif /* HAVE_LIBSSL && OPENSSL_VERSION_MAJOR >= 3 && HAVE_TLS_PROVIDERS */
203
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)
206 {
207 #ifdef OPENSSL_NO_ENGINE
208 return { false, "OpenSSL has been built without engine support" };
209 #else
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();
215 }
216
217 auto engines = s_engines.lock();
218 if (engines->count(engineName) > 0) {
219 return { false, "TLS engine already loaded" };
220 }
221
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 + "'" };
225 }
226
227 if (!ENGINE_init(engine.get())) {
228 return { false, "Unable to init TLS engine '" + engineName + "'" };
229 }
230
231 if (defaultString) {
232 if (ENGINE_set_default_string(engine.get(), defaultString->c_str()) == 0) {
233 return { false, "error while setting the TLS engine default string" };
234 }
235 }
236
237 engines->insert({engineName, std::move(engine)});
238 return { true, "" };
239 #endif
240 }
241 #endif /* HAVE_LIBSSL && !HAVE_TLS_PROVIDERS */
242
243 void* libssl_get_ticket_key_callback_data(SSL* s)
244 {
245 SSL_CTX* sslCtx = SSL_get_SSL_CTX(s);
246 if (sslCtx == nullptr) {
247 return nullptr;
248 }
249
250 return SSL_CTX_get_ex_data(sslCtx, s_ticketsKeyIndex);
251 }
252
253 void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data)
254 {
255 SSL_CTX_set_ex_data(ctx, s_ticketsKeyIndex, data);
256 }
257
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)
260 #else
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)
262 #endif
263 {
264 if (enc != 0) {
265 const auto key = keyring.getEncryptionKey();
266 if (key == nullptr) {
267 return -1;
268 }
269
270 return key->encrypt(keyName, iv, ectx, hctx);
271 }
272
273 bool activeEncryptionKey = false;
274
275 const auto key = keyring.getDecryptionKey(keyName, activeEncryptionKey);
276 if (key == nullptr) {
277 /* we don't know this key, just create a new ticket */
278 return 0;
279 }
280
281 if (!key->decrypt(iv, ectx, hctx)) {
282 return -1;
283 }
284
285 if (!activeEncryptionKey) {
286 /* this key is not active, please encrypt the ticket content with the currently active one */
287 return 2;
288 }
289
290 return 1;
291 }
292
293 static int libssl_server_name_callback(SSL* ssl, int* /* alert */, void* /* arg */)
294 {
295 if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) != nullptr) {
296 return SSL_TLSEXT_ERR_OK;
297 }
298
299 return SSL_TLSEXT_ERR_NOACK;
300 }
301
302 static void libssl_info_callback(const SSL *ssl, int where, int /* ret */)
303 {
304 SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
305 if (sslCtx == nullptr) {
306 return;
307 }
308
309 TLSErrorCounters* counters = reinterpret_cast<TLSErrorCounters*>(SSL_CTX_get_ex_data(sslCtx, s_countersIndex));
310 if (counters == nullptr) {
311 return;
312 }
313
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;
320 break;
321 #endif /* SSL_R_DH_KEY_TOO_SMALL */
322 case SSL_R_NO_SHARED_CIPHER:
323 ++counters->d_noSharedCipher;
324 break;
325 case SSL_R_UNKNOWN_PROTOCOL:
326 ++counters->d_unknownProtocol;
327 break;
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;
333 break;
334 case SSL_R_INAPPROPRIATE_FALLBACK:
335 ++counters->d_inappropriateFallBack;
336 break;
337 case SSL_R_UNKNOWN_CIPHER_TYPE:
338 ++counters->d_unknownCipherType;
339 break;
340 case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE:
341 ++counters->d_unknownKeyExchangeType;
342 break;
343 case SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:
344 ++counters->d_unsupportedEC;
345 break;
346 default:
347 break;
348 }
349 }
350 }
351
352 void libssl_set_error_counters_callback(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, TLSErrorCounters* counters)
353 {
354 SSL_CTX_set_ex_data(ctx.get(), s_countersIndex, counters);
355 SSL_CTX_set_info_callback(ctx.get(), libssl_info_callback);
356 }
357
358 #ifndef DISABLE_OCSP_STAPLING
359 int libssl_ocsp_stapling_callback(SSL* ssl, const std::map<int, std::string>& ocspMap)
360 {
361 auto pkey = SSL_get_privatekey(ssl);
362 if (pkey == nullptr) {
363 return SSL_TLSEXT_ERR_NOACK;
364 }
365
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;
370 }
371
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;
376 }
377
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;
381 }
382
383 static bool libssl_validate_ocsp_response(const std::string& response)
384 {
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");
389 }
390
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));
394 }
395
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");
399 }
400
401 if (OCSP_resp_count(basic.get()) != 1) {
402 throw std::runtime_error("More than one single response in an OCSP basic response");
403 }
404
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");
408 }
409
410 int reason;
411 ASN1_GENERALIZEDTIME* revTime = nullptr;
412 ASN1_GENERALIZEDTIME* thisUpdate = nullptr;
413 ASN1_GENERALIZEDTIME* nextUpdate = nullptr;
414
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) + ")");
418 }
419 if (thisUpdate == nullptr || nextUpdate == nullptr) {
420 throw std::runtime_error("Error getting validity of OCSP single response");
421 }
422
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");
426 }
427
428 return true;
429 }
430
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)
432 {
433 std::map<int, std::string> ocspResponses;
434
435 if (ocspFiles.size() > keyTypes.size()) {
436 throw std::runtime_error("More OCSP files than certificates and keys loaded!");
437 }
438
439 size_t count = 0;
440 for (const auto& filename : ocspFiles) {
441 std::ifstream file(filename, std::ios::binary);
442 std::string content;
443 while (file) {
444 char buffer[4096];
445 file.read(buffer, sizeof(buffer));
446 if (file.bad()) {
447 file.close();
448 warnings.push_back("Unable to load OCSP response from " + filename);
449 continue;
450 }
451 content.append(buffer, file.gcount());
452 }
453 file.close();
454
455 try {
456 libssl_validate_ocsp_response(content);
457 ocspResponses.insert({keyTypes.at(count), std::move(content)});
458 }
459 catch (const std::exception& e) {
460 warnings.push_back("Error checking the validity of OCSP response from '" + filename + "': " + e.what());
461 continue;
462 }
463 ++count;
464 }
465
466 return ocspResponses;
467 }
468
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)
471 {
472 const EVP_MD* rmd = EVP_sha256();
473
474 auto filePtr = pdns::UniqueFilePtr(fopen(certFile.c_str(), "r"));
475 if (!filePtr) {
476 throw std::runtime_error("Unable to open '" + certFile + "' when loading the certificate to generate an OCSP response");
477 }
478 auto cert = std::unique_ptr<X509, void(*)(X509*)>(PEM_read_X509_AUX(filePtr.get(), nullptr, nullptr, nullptr), X509_free);
479
480 filePtr = pdns::UniqueFilePtr(fopen(caCert.c_str(), "r"));
481 if (!filePtr) {
482 throw std::runtime_error("Unable to open '" + caCert + "' when loading the issuer certificate to generate an OCSP response");
483 }
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"));
486 if (!filePtr) {
487 throw std::runtime_error("Unable to open '" + caKey + "' when loading the issuer key to generate an OCSP response");
488 }
489 auto issuerKey = std::unique_ptr<EVP_PKEY, void(*)(EVP_PKEY*)>(PEM_read_PrivateKey(filePtr.get(), nullptr, nullptr, nullptr), EVP_PKEY_free);
490 filePtr.reset();
491
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);
495
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());
498
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");
501 }
502
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);
505 if (!bio) {
506 throw std::runtime_error("Error opening file for writing the OCSP response");
507 }
508
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());
511
512 return true;
513 }
514 #endif /* HAVE_OCSP_BASIC_SIGN */
515 #endif /* DISABLE_OCSP_STAPLING */
516
517 static int libssl_get_last_key_type(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx)
518 {
519 #ifdef HAVE_SSL_CTX_GET0_PRIVATEKEY
520 auto pkey = SSL_CTX_get0_privatekey(ctx.get());
521 #else
522 auto temp = std::unique_ptr<SSL, void(*)(SSL*)>(SSL_new(ctx.get()), SSL_free);
523 if (!temp) {
524 return -1;
525 }
526 auto pkey = SSL_get_privatekey(temp.get());
527 #endif
528
529 if (!pkey) {
530 return -1;
531 }
532
533 return EVP_PKEY_base_id(pkey);
534 }
535
536 LibsslTLSVersion libssl_tls_version_from_string(const std::string& str)
537 {
538 if (str == "tls1.0") {
539 return LibsslTLSVersion::TLS10;
540 }
541 if (str == "tls1.1") {
542 return LibsslTLSVersion::TLS11;
543 }
544 if (str == "tls1.2") {
545 return LibsslTLSVersion::TLS12;
546 }
547 if (str == "tls1.3") {
548 return LibsslTLSVersion::TLS13;
549 }
550 throw std::runtime_error("Unknown TLS version '" + str);
551 }
552
553 const std::string& libssl_tls_version_to_string(LibsslTLSVersion version)
554 {
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" }
560 };
561
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) + ")");
565 }
566 return it->second;
567 }
568
569 bool libssl_set_min_tls_version(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, LibsslTLSVersion version)
570 {
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 */
574 int vers;
575 switch(version) {
576 case LibsslTLSVersion::TLS10:
577 vers = TLS1_VERSION;
578 break;
579 case LibsslTLSVersion::TLS11:
580 vers = TLS1_1_VERSION;
581 break;
582 case LibsslTLSVersion::TLS12:
583 vers = TLS1_2_VERSION;
584 break;
585 case LibsslTLSVersion::TLS13:
586 #ifdef TLS1_3_VERSION
587 vers = TLS1_3_VERSION;
588 #else
589 return false;
590 #endif /* TLS1_3_VERSION */
591 break;
592 default:
593 return false;
594 }
595
596 if (SSL_CTX_set_min_proto_version(ctx.get(), vers) != 1) {
597 return false;
598 }
599 return true;
600 #else
601 long vers = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
602 switch(version) {
603 case LibsslTLSVersion::TLS10:
604 break;
605 case LibsslTLSVersion::TLS11:
606 vers |= SSL_OP_NO_TLSv1;
607 break;
608 case LibsslTLSVersion::TLS12:
609 vers |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
610 break;
611 case LibsslTLSVersion::TLS13:
612 vers |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
613 break;
614 default:
615 return false;
616 }
617
618 long options = SSL_CTX_get_options(ctx.get());
619 SSL_CTX_set_options(ctx.get(), options | vers);
620 return true;
621 #endif
622 }
623
624 OpenSSLTLSTicketKeysRing::OpenSSLTLSTicketKeysRing(size_t capacity)
625 {
626 d_ticketKeys.write_lock()->set_capacity(capacity);
627 }
628
629 OpenSSLTLSTicketKeysRing::~OpenSSLTLSTicketKeysRing() = default;
630
631 void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr<OpenSSLTLSTicketKey>&& newKey)
632 {
633 d_ticketKeys.write_lock()->push_front(std::move(newKey));
634 }
635
636 std::shared_ptr<OpenSSLTLSTicketKey> OpenSSLTLSTicketKeysRing::getEncryptionKey()
637 {
638 return d_ticketKeys.read_lock()->front();
639 }
640
641 std::shared_ptr<OpenSSLTLSTicketKey> OpenSSLTLSTicketKeysRing::getDecryptionKey(unsigned char name[TLS_TICKETS_KEY_NAME_SIZE], bool& activeKey)
642 {
643 auto keys = d_ticketKeys.read_lock();
644 for (auto& key : *keys) {
645 if (key->nameMatches(name)) {
646 activeKey = (key == keys->front());
647 return key;
648 }
649 }
650 return nullptr;
651 }
652
653 size_t OpenSSLTLSTicketKeysRing::getKeysCount()
654 {
655 return d_ticketKeys.read_lock()->size();
656 }
657
658 void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string& keyFile)
659 {
660 bool keyLoaded = false;
661 std::ifstream file(keyFile);
662 try {
663 do {
664 auto newKey = std::make_shared<OpenSSLTLSTicketKey>(file);
665 addKey(std::move(newKey));
666 keyLoaded = true;
667 }
668 while (!file.fail());
669 }
670 catch (const std::exception& e) {
671 /* if we haven't been able to load at least one key, fail */
672 if (!keyLoaded) {
673 throw;
674 }
675 }
676
677 file.close();
678 }
679
680 void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t /* now */)
681 {
682 auto newKey = std::make_shared<OpenSSLTLSTicketKey>();
683 addKey(std::move(newKey));
684 }
685
686 OpenSSLTLSTicketKey::OpenSSLTLSTicketKey()
687 {
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");
690 }
691
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");
694 }
695
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");
698 }
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 */
704 }
705
706 OpenSSLTLSTicketKey::OpenSSLTLSTicketKey(std::ifstream& file)
707 {
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));
711
712 if (file.fail()) {
713 throw std::runtime_error("Unable to load a ticket key from the OpenSSL tickets key file");
714 }
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 */
720 }
721
722 OpenSSLTLSTicketKey::~OpenSSLTLSTicketKey()
723 {
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));
728 #else
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 */
733 }
734
735 bool OpenSSLTLSTicketKey::nameMatches(const unsigned char name[TLS_TICKETS_KEY_NAME_SIZE]) const
736 {
737 return (memcmp(d_name, name, sizeof(d_name)) == 0);
738 }
739
740 #if OPENSSL_VERSION_MAJOR >= 3
741 static const std::string sha256KeyName{"sha256"};
742 #endif
743
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
746 #else
747 int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const
748 #endif
749 {
750 memcpy(keyName, d_name, sizeof(d_name));
751
752 if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) != 1) {
753 return -1;
754 }
755
756 if (EVP_EncryptInit_ex(ectx, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey, iv) != 1) {
757 return -1;
758 }
759
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)>;
763
764 auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free);
765 if (params_build == nullptr) {
766 return -1;
767 }
768
769 if (OSSL_PARAM_BLD_push_utf8_string(params_build.get(), OSSL_MAC_PARAM_DIGEST, sha256KeyName.c_str(), sha256KeyName.size()) == 0) {
770 return -1;
771 }
772
773 auto params = Params(OSSL_PARAM_BLD_to_param(params_build.get()), OSSL_PARAM_free);
774 if (params == nullptr) {
775 return -1;
776 }
777
778 if (EVP_MAC_CTX_set_params(hctx, params.get()) == 0) {
779 return -1;
780 }
781
782 if (EVP_MAC_init(hctx, d_hmacKey, sizeof(d_hmacKey), nullptr) == 0) {
783 return -1;
784 }
785 #else
786 if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
787 return -1;
788 }
789 #endif
790
791 return 1;
792 }
793
794 #if OPENSSL_VERSION_MAJOR >= 3
795 bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const
796 #else
797 bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const
798 #endif
799 {
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)>;
803
804 auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free);
805 if (params_build == nullptr) {
806 return false;
807 }
808
809 if (OSSL_PARAM_BLD_push_utf8_string(params_build.get(), OSSL_MAC_PARAM_DIGEST, sha256KeyName.c_str(), sha256KeyName.size()) == 0) {
810 return false;
811 }
812
813 auto params = Params(OSSL_PARAM_BLD_to_param(params_build.get()), OSSL_PARAM_free);
814 if (params == nullptr) {
815 return false;
816 }
817
818 if (EVP_MAC_CTX_set_params(hctx, params.get()) == 0) {
819 return false;
820 }
821
822 if (EVP_MAC_init(hctx, d_hmacKey, sizeof(d_hmacKey), nullptr) == 0) {
823 return false;
824 }
825 #else
826 if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
827 return false;
828 }
829 #endif
830
831 if (EVP_DecryptInit_ex(ectx, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey, iv) != 1) {
832 return false;
833 }
834
835 return true;
836 }
837
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)
840 {
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);
843
844 if (!ctx) {
845 throw pdns::OpenSSL::error("Error creating an OpenSSL server context");
846 }
847
848 int sslOptions =
849 SSL_OP_NO_SSLv2 |
850 SSL_OP_NO_SSLv3 |
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;
855
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 */
864 }
865
866 if (config.d_ktls) {
867 #ifdef SSL_OP_ENABLE_KTLS
868 sslOptions |= SSL_OP_ENABLE_KTLS;
869 #endif /* SSL_OP_ENABLE_KTLS */
870 }
871
872 if (config.d_sessionTimeout > 0) {
873 SSL_CTX_set_timeout(ctx.get(), config.d_sessionTimeout);
874 }
875
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 */
881 }
882
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;
888 #endif
889 }
890
891 #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
892 sslOptions |= SSL_OP_IGNORE_UNEXPECTED_EOF;
893 #endif
894
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));
898 }
899
900 #ifdef SSL_CTX_set_ecdh_auto
901 SSL_CTX_set_ecdh_auto(ctx.get(), 1);
902 #endif
903
904 if (config.d_maxStoredSessions == 0) {
905 /* disable stored sessions entirely */
906 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF);
907 }
908 else {
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);
912 }
913
914 long mode = 0;
915 #ifdef SSL_MODE_RELEASE_BUFFERS
916 if (config.d_releaseBuffers) {
917 mode |= SSL_MODE_RELEASE_BUFFERS;
918 }
919 #endif
920
921 if (config.d_asyncMode) {
922 #ifdef SSL_MODE_ASYNC
923 mode |= SSL_MODE_ASYNC;
924 #else
925 warnings.push_back("Warning: TLS async mode requested but not supported");
926 #endif
927 }
928
929 SSL_CTX_set_mode(ctx.get(), mode);
930
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);
935
936 std::vector<int> keyTypes;
937 /* load certificate and private key */
938 for (const auto& pair : config.d_certKeyPairs) {
939 if (!pair.d_key) {
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"));
943 if (!filePtr) {
944 throw std::runtime_error("Unable to open file " + pair.d_cert);
945 }
946 auto p12 = std::unique_ptr<PKCS12, void(*)(PKCS12*)>(d2i_PKCS12_fp(filePtr.get(), nullptr), PKCS12_free);
947 if (!p12) {
948 throw std::runtime_error("Unable to open PKCS12 file " + pair.d_cert);
949 }
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
955 bool failed = true;
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")) {
960 /* it's not */
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)) {
964 failed = false;
965 }
966 /* we do not want to keep that provider around after that */
967 OSSL_PROVIDER_unload(provider);
968 }
969 }
970 if (failed) {
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
975 }
976 #endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */
977 }
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); });
981
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);
985 }
986 #else
987 throw std::runtime_error("PKCS12 files are not supported by your openssl version");
988 #endif /* HAVE_SSL_CTX_USE_CERT_AND_KEY */
989 } else {
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);
993 }
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());
997 }
998 }
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 + "'");
1002 }
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);
1005 if (keyType < 0) {
1006 throw std::runtime_error("The key from '" + pair.d_key.value() + "' has an unknown type");
1007 }
1008 keyTypes.push_back(keyType);
1009 }
1010
1011 #ifndef DISABLE_OCSP_STAPLING
1012 if (!config.d_ocspFiles.empty()) {
1013 try {
1014 ocspResponses = libssl_load_ocsp_responses(config.d_ocspFiles, std::move(keyTypes), warnings);
1015 }
1016 catch(const std::exception& e) {
1017 throw std::runtime_error("Unable to load OCSP responses: " + std::string(e.what()));
1018 }
1019 }
1020 #endif /* DISABLE_OCSP_STAPLING */
1021
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);
1024 }
1025
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);
1029 }
1030 #endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */
1031
1032 return {std::move(ctx), std::move(warnings)};
1033 }
1034
1035 #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
1036 static void libssl_key_log_file_callback(const SSL* ssl, const char* line)
1037 {
1038 SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
1039 if (sslCtx == nullptr) {
1040 return;
1041 }
1042
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) {
1046 return;
1047 }
1048
1049 fprintf(filePtr, "%s\n", line);
1050 fflush(filePtr);
1051 }
1052 #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
1053
1054 pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, const std::string& logFile)
1055 {
1056 #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
1057 auto filePtr = pdns::openFileForWriting(logFile, 0600, false, true);
1058 if (!filePtr) {
1059 auto error = errno;
1060 throw std::runtime_error("Error opening file " + logFile + " for writing: " + stringerror(error));
1061 }
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);
1064 return filePtr;
1065 #else
1066 return pdns::UniqueFilePtr(nullptr);
1067 #endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
1068 }
1069
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. */
1071 #ifndef DISABLE_NPN
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)
1073 {
1074 #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
1075 SSL_CTX_set_next_proto_select_cb(ctx, cb, arg);
1076 #endif
1077 }
1078 #endif /* DISABLE_NPN */
1079
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)
1081 {
1082 #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
1083 SSL_CTX_set_alpn_select_cb(ctx, cb, arg);
1084 #endif
1085 }
1086
1087 bool libssl_set_alpn_protos(SSL_CTX* ctx, const std::vector<std::vector<uint8_t>>& protos)
1088 {
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");
1094 }
1095 uint8_t length = proto.size();
1096 wire.push_back(length);
1097 wire.insert(wire.end(), proto.begin(), proto.end());
1098 }
1099 return SSL_CTX_set_alpn_protos(ctx, wire.data(), wire.size()) == 0;
1100 #else
1101 return false;
1102 #endif
1103 }
1104
1105
1106 std::string libssl_get_error_string()
1107 {
1108 BIO *mem = BIO_new(BIO_s_mem());
1109 ERR_print_errors(mem);
1110 char *p;
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') {
1115 msg.pop_back();
1116 }
1117 std::replace(msg.begin(), msg.end(), '\n', '/');
1118 BIO_free(mem);
1119 return msg;
1120 }
1121 #endif /* HAVE_LIBSSL */