]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsdistdist/libssl.cc
Merge pull request #9229 from rgacogne/dnsdist-webserver-allow-from
[thirdparty/pdns.git] / pdns / dnsdistdist / libssl.cc
CommitLineData
ede152ec
RG
1
2#include "config.h"
3#include "libssl.hh"
4
5#ifdef HAVE_LIBSSL
6
7#include <atomic>
be3183ed
RG
8#include <fstream>
9#include <cstring>
f0941861 10#include <mutex>
ede152ec 11#include <pthread.h>
be3183ed 12
ede152ec
RG
13#include <openssl/conf.h>
14#include <openssl/err.h>
be3183ed 15#include <openssl/ocsp.h>
ede152ec
RG
16#include <openssl/rand.h>
17#include <openssl/ssl.h>
18
0ef9ab19
RG
19#ifdef HAVE_LIBSODIUM
20#include <sodium.h>
21#endif /* HAVE_LIBSODIUM */
22
18e4fac1 23#if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL)
ede152ec 24/* OpenSSL < 1.1.0 needs support for threading/locking in the calling application. */
f0941861
RG
25
26#include "lock.hh"
27static std::vector<std::mutex> openssllocks;
ede152ec
RG
28
29extern "C" {
30static void openssl_pthreads_locking_callback(int mode, int type, const char *file, int line)
31{
32 if (mode & CRYPTO_LOCK) {
f0941861 33 openssllocks.at(type).lock();
ede152ec
RG
34
35 } else {
f0941861 36 openssllocks.at(type).unlock();
ede152ec
RG
37 }
38}
39
40static unsigned long openssl_pthreads_id_callback()
41{
42 return (unsigned long)pthread_self();
43}
44}
45
46static void openssl_thread_setup()
47{
f0941861
RG
48 openssllocks = std::vector<std::mutex>(CRYPTO_num_locks());
49 CRYPTO_set_id_callback(&openssl_pthreads_id_callback);
50 CRYPTO_set_locking_callback(&openssl_pthreads_locking_callback);
ede152ec
RG
51}
52
53static void openssl_thread_cleanup()
54{
f0941861
RG
55 CRYPTO_set_locking_callback(nullptr);
56 openssllocks.clear();
ede152ec
RG
57}
58
18e4fac1 59#endif /* (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090100fL) */
ede152ec 60
0ef9ab19
RG
61static std::atomic<uint64_t> s_users;
62static int s_ticketsKeyIndex{-1};
f34fdcc5 63static int s_countersIndex{-1};
7f8a5a32 64static int s_keyLogIndex{-1};
0ef9ab19 65
ede152ec
RG
66void registerOpenSSLUser()
67{
68 if (s_users.fetch_add(1) == 0) {
629440d4 69#ifdef HAVE_OPENSSL_INIT_CRYPTO
81fe6363
RG
70 /* load the default configuration file (or one specified via OPENSSL_CONF),
71 which can then be used to load engines */
72 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, nullptr);
18e4fac1
RG
73#endif
74
75#if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x2090100fL))
7f8a5a32
RG
76 SSL_load_error_strings();
77 OpenSSL_add_ssl_algorithms();
78 openssl_thread_setup();
79#endif
0ef9ab19
RG
80 s_ticketsKeyIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
81
82 if (s_ticketsKeyIndex == -1) {
83 throw std::runtime_error("Error getting an index for tickets key");
84 }
f34fdcc5
RG
85
86 s_countersIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
87
88 if (s_countersIndex == -1) {
89 throw std::runtime_error("Error getting an index for counters");
90 }
7f8a5a32
RG
91
92 s_keyLogIndex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
93
94 if (s_keyLogIndex == -1) {
95 throw std::runtime_error("Error getting an index for TLS key logging");
96 }
0ef9ab19 97 }
ede152ec
RG
98}
99
100void unregisterOpenSSLUser()
101{
102 if (s_users.fetch_sub(1) == 1) {
18e4fac1 103#if (OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined LIBRESSL_VERSION_NUMBER && LIBRESSL_VERSION_NUMBER < 0x2090100fL))
ede152ec
RG
104 ERR_free_strings();
105
106 EVP_cleanup();
107
108 CONF_modules_finish();
109 CONF_modules_free();
110 CONF_modules_unload(1);
111
112 CRYPTO_cleanup_all_ex_data();
113 openssl_thread_cleanup();
4479df79 114#endif
0ef9ab19
RG
115 }
116}
117
118void* libssl_get_ticket_key_callback_data(SSL* s)
119{
120 SSL_CTX* sslCtx = SSL_get_SSL_CTX(s);
121 if (sslCtx == nullptr) {
122 return nullptr;
123 }
124
125 return SSL_CTX_get_ex_data(sslCtx, s_ticketsKeyIndex);
126}
127
128void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data)
129{
130 SSL_CTX_set_ex_data(ctx, s_ticketsKeyIndex, data);
131}
132
133int 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)
134{
135 if (enc) {
136 const auto key = keyring.getEncryptionKey();
137 if (key == nullptr) {
138 return -1;
139 }
140
141 return key->encrypt(keyName, iv, ectx, hctx);
142 }
143
144 bool activeEncryptionKey = false;
145
146 const auto key = keyring.getDecryptionKey(keyName, activeEncryptionKey);
147 if (key == nullptr) {
148 /* we don't know this key, just create a new ticket */
149 return 0;
150 }
151
152 if (key->decrypt(iv, ectx, hctx) == false) {
153 return -1;
154 }
155
156 if (!activeEncryptionKey) {
157 /* this key is not active, please encrypt the ticket content with the currently active one */
158 return 2;
159 }
160
161 return 1;
ede152ec
RG
162}
163
f34fdcc5
RG
164static void libssl_info_callback(const SSL *ssl, int where, int ret)
165{
166 SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
167 if (sslCtx == nullptr) {
168 return;
169 }
170
171 TLSErrorCounters* counters = reinterpret_cast<TLSErrorCounters*>(SSL_CTX_get_ex_data(sslCtx, s_countersIndex));
172 if (counters == nullptr) {
173 return;
174 }
175
176 if (where & SSL_CB_ALERT) {
177 const long lastError = ERR_peek_last_error();
178 switch (ERR_GET_REASON(lastError)) {
179#ifdef SSL_R_DH_KEY_TOO_SMALL
180 case SSL_R_DH_KEY_TOO_SMALL:
181 ++counters->d_dhKeyTooSmall;
182 break;
183#endif /* SSL_R_DH_KEY_TOO_SMALL */
184 case SSL_R_NO_SHARED_CIPHER:
185 ++counters->d_noSharedCipher;
186 break;
187 case SSL_R_UNKNOWN_PROTOCOL:
188 ++counters->d_unknownProtocol;
189 break;
190 case SSL_R_UNSUPPORTED_PROTOCOL:
191#ifdef SSL_R_VERSION_TOO_LOW
192 case SSL_R_VERSION_TOO_LOW:
193#endif /* SSL_R_VERSION_TOO_LOW */
194 ++counters->d_unsupportedProtocol;
195 break;
196 case SSL_R_INAPPROPRIATE_FALLBACK:
197 ++counters->d_inappropriateFallBack;
198 break;
199 case SSL_R_UNKNOWN_CIPHER_TYPE:
200 ++counters->d_unknownCipherType;
201 break;
202 case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE:
203 ++counters->d_unknownKeyExchangeType;
204 break;
205 case SSL_R_UNSUPPORTED_ELLIPTIC_CURVE:
206 ++counters->d_unsupportedEC;
207 break;
208 default:
209 break;
210 }
211 }
212}
213
214void libssl_set_error_counters_callback(std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)>& ctx, TLSErrorCounters* counters)
215{
216 SSL_CTX_set_ex_data(ctx.get(), s_countersIndex, counters);
217 SSL_CTX_set_info_callback(ctx.get(), libssl_info_callback);
218}
219
be3183ed
RG
220int libssl_ocsp_stapling_callback(SSL* ssl, const std::map<int, std::string>& ocspMap)
221{
222 auto pkey = SSL_get_privatekey(ssl);
223 if (pkey == nullptr) {
224 return SSL_TLSEXT_ERR_NOACK;
225 }
226
227 /* look for an OCSP response for the corresponding private key type (RSA, ECDSA..) */
228 const auto& data = ocspMap.find(EVP_PKEY_base_id(pkey));
229 if (data == ocspMap.end()) {
230 return SSL_TLSEXT_ERR_NOACK;
231 }
232
233 /* we need to allocate a copy because OpenSSL will free the pointer passed to SSL_set_tlsext_status_ocsp_resp() */
234 void* copy = OPENSSL_malloc(data->second.size());
235 if (copy == nullptr) {
236 return SSL_TLSEXT_ERR_NOACK;
237 }
238
239 memcpy(copy, data->second.data(), data->second.size());
240 SSL_set_tlsext_status_ocsp_resp(ssl, copy, data->second.size());
241 return SSL_TLSEXT_ERR_OK;
242}
243
244static bool libssl_validate_ocsp_response(const std::string& response)
245{
246 auto responsePtr = reinterpret_cast<const unsigned char *>(response.data());
247 std::unique_ptr<OCSP_RESPONSE, void(*)(OCSP_RESPONSE*)> resp(d2i_OCSP_RESPONSE(nullptr, &responsePtr, response.size()), OCSP_RESPONSE_free);
248 if (resp == nullptr) {
249 throw std::runtime_error("Unable to parse OCSP response");
250 }
251
252 int status = OCSP_response_status(resp.get());
253 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
254 throw std::runtime_error("OCSP response status is not successful: " + std::to_string(status));
255 }
256
257 std::unique_ptr<OCSP_BASICRESP, void(*)(OCSP_BASICRESP*)> basic(OCSP_response_get1_basic(resp.get()), OCSP_BASICRESP_free);
258 if (basic == nullptr) {
259 throw std::runtime_error("Error getting a basic OCSP response");
260 }
261
262 if (OCSP_resp_count(basic.get()) != 1) {
263 throw std::runtime_error("More than one single response in an OCSP basic response");
264 }
265
266 auto singleResponse = OCSP_resp_get0(basic.get(), 0);
267 if (singleResponse == nullptr) {
268 throw std::runtime_error("Error getting a single response from the basic OCSP response");
269 }
270
271 int reason;
272 ASN1_GENERALIZEDTIME* revTime = nullptr;
273 ASN1_GENERALIZEDTIME* thisUpdate = nullptr;
274 ASN1_GENERALIZEDTIME* nextUpdate = nullptr;
275
276 auto singleResponseStatus = OCSP_single_get0_status(singleResponse, &reason, &revTime, &thisUpdate, &nextUpdate);
277 if (singleResponseStatus != V_OCSP_CERTSTATUS_GOOD) {
278 throw std::runtime_error("Invalid status for OCSP single response (" + std::to_string(singleResponseStatus) + ")");
279 }
280 if (thisUpdate == nullptr || nextUpdate == nullptr) {
281 throw std::runtime_error("Error getting validity of OCSP single response");
282 }
283
284 auto validityResult = OCSP_check_validity(thisUpdate, nextUpdate, /* 5 minutes of leeway */ 5 * 60, -1);
285 if (validityResult == 0) {
286 throw std::runtime_error("OCSP single response is not yet, or no longer, valid");
287 }
288
289 return true;
290}
291
292std::map<int, std::string> libssl_load_ocsp_responses(const std::vector<std::string>& ocspFiles, std::vector<int> keyTypes)
293{
294 std::map<int, std::string> ocspResponses;
295
296 if (ocspFiles.size() > keyTypes.size()) {
297 throw std::runtime_error("More OCSP files than certificates and keys loaded!");
298 }
299
300 size_t count = 0;
301 for (const auto& filename : ocspFiles) {
302 std::ifstream file(filename, std::ios::binary);
303 std::string content;
304 while(file) {
305 char buffer[4096];
306 file.read(buffer, sizeof(buffer));
307 if (file.bad()) {
308 file.close();
309 throw std::runtime_error("Unable to load OCSP response from '" + filename + "'");
310 }
311 content.append(buffer, file.gcount());
312 }
313 file.close();
314
315 try {
316 libssl_validate_ocsp_response(content);
317 ocspResponses.insert({keyTypes.at(count), std::move(content)});
318 }
319 catch (const std::exception& e) {
320 throw std::runtime_error("Error checking the validity of OCSP response from '" + filename + "': " + e.what());
321 }
322 ++count;
323 }
324
325 return ocspResponses;
326}
327
328int libssl_get_last_key_type(std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)>& ctx)
329{
629440d4 330#ifdef HAVE_SSL_CTX_GET0_PRIVATEKEY
be3183ed
RG
331 auto pkey = SSL_CTX_get0_privatekey(ctx.get());
332#else
333 auto temp = std::unique_ptr<SSL, void(*)(SSL*)>(SSL_new(ctx.get()), SSL_free);
334 if (!temp) {
335 return -1;
336 }
337 auto pkey = SSL_get_privatekey(temp.get());
338#endif
339
340 if (!pkey) {
341 return -1;
342 }
343
344 return EVP_PKEY_base_id(pkey);
345}
346
8c15553e
RG
347#ifdef HAVE_OCSP_BASIC_SIGN
348bool libssl_generate_ocsp_response(const std::string& certFile, const std::string& caCert, const std::string& caKey, const std::string& outFile, int ndays, int nmin)
349{
350 const EVP_MD* rmd = EVP_sha256();
351
352 auto fp = std::unique_ptr<FILE, int(*)(FILE*)>(fopen(certFile.c_str(), "r"), fclose);
353 if (!fp) {
354 throw std::runtime_error("Unable to open '" + certFile + "' when loading the certificate to generate an OCSP response");
355 }
356 auto cert = std::unique_ptr<X509, void(*)(X509*)>(PEM_read_X509_AUX(fp.get(), nullptr, nullptr, nullptr), X509_free);
357
358 fp = std::unique_ptr<FILE, int(*)(FILE*)>(fopen(caCert.c_str(), "r"), fclose);
359 if (!fp) {
360 throw std::runtime_error("Unable to open '" + caCert + "' when loading the issuer certificate to generate an OCSP response");
361 }
362 auto issuer = std::unique_ptr<X509, void(*)(X509*)>(PEM_read_X509_AUX(fp.get(), nullptr, nullptr, nullptr), X509_free);
363 fp = std::unique_ptr<FILE, int(*)(FILE*)>(fopen(caKey.c_str(), "r"), fclose);
364 if (!fp) {
365 throw std::runtime_error("Unable to open '" + caKey + "' when loading the issuer key to generate an OCSP response");
366 }
367 auto issuerKey = std::unique_ptr<EVP_PKEY, void(*)(EVP_PKEY*)>(PEM_read_PrivateKey(fp.get(), nullptr, nullptr, nullptr), EVP_PKEY_free);
368 fp.reset();
369
370 auto bs = std::unique_ptr<OCSP_BASICRESP, void(*)(OCSP_BASICRESP*)>(OCSP_BASICRESP_new(), OCSP_BASICRESP_free);
371 auto thisupd = std::unique_ptr<ASN1_TIME, void(*)(ASN1_TIME*)>(X509_gmtime_adj(nullptr, 0), ASN1_TIME_free);
372 auto nextupd = std::unique_ptr<ASN1_TIME, void(*)(ASN1_TIME*)>(X509_time_adj_ex(nullptr, ndays, nmin * 60, nullptr), ASN1_TIME_free);
373
374 auto cid = std::unique_ptr<OCSP_CERTID, void(*)(OCSP_CERTID*)>(OCSP_cert_to_id(rmd, cert.get(), issuer.get()), OCSP_CERTID_free);
375 OCSP_basic_add1_status(bs.get(), cid.get(), V_OCSP_CERTSTATUS_GOOD, 0, nullptr, thisupd.get(), nextupd.get());
376
377 if (OCSP_basic_sign(bs.get(), issuer.get(), issuerKey.get(), rmd, nullptr, OCSP_NOCERTS) != 1) {
378 throw std::runtime_error("Error while signing the OCSP response");
379 }
380
381 auto resp = std::unique_ptr<OCSP_RESPONSE, void(*)(OCSP_RESPONSE*)>(OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs.get()), OCSP_RESPONSE_free);
382 auto bio = std::unique_ptr<BIO, void(*)(BIO*)>(BIO_new_file(outFile.c_str(), "wb"), BIO_vfree);
383 if (!bio) {
384 throw std::runtime_error("Error opening file for writing the OCSP response");
385 }
386
387 // i2d_OCSP_RESPONSE_bio(bio.get(), resp.get()) is unusable from C++ because of an invalid cast
388 ASN1_i2d_bio((i2d_of_void*)i2d_OCSP_RESPONSE, bio.get(), (unsigned char*)resp.get());
389
390 return true;
391}
392#endif /* HAVE_OCSP_BASIC_SIGN */
393
be8355a2
RG
394LibsslTLSVersion libssl_tls_version_from_string(const std::string& str)
395{
396 if (str == "tls1.0") {
397 return LibsslTLSVersion::TLS10;
398 }
399 if (str == "tls1.1") {
400 return LibsslTLSVersion::TLS11;
401 }
402 if (str == "tls1.2") {
403 return LibsslTLSVersion::TLS12;
404 }
405 if (str == "tls1.3") {
406 return LibsslTLSVersion::TLS13;
407 }
408 throw std::runtime_error("Unknown TLS version '" + str);
409}
410
656a5e55
RG
411const std::string& libssl_tls_version_to_string(LibsslTLSVersion version)
412{
413 static const std::map<LibsslTLSVersion, std::string> versions = {
414 { LibsslTLSVersion::TLS10, "tls1.0" },
415 { LibsslTLSVersion::TLS11, "tls1.1" },
416 { LibsslTLSVersion::TLS12, "tls1.2" },
417 { LibsslTLSVersion::TLS13, "tls1.3" }
418 };
419
420 const auto& it = versions.find(version);
421 if (it == versions.end()) {
422 throw std::runtime_error("Unknown TLS version (" + std::to_string((int)version) + ")");
423 }
424 return it->second;
425}
426
be8355a2
RG
427bool libssl_set_min_tls_version(std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)>& ctx, LibsslTLSVersion version)
428{
629440d4
RG
429#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION) || defined(SSL_CTX_set_min_proto_version)
430 /* These functions have been introduced in 1.1.0, and the use of SSL_OP_NO_* is deprecated
431 Warning: SSL_CTX_set_min_proto_version is a function-like macro in OpenSSL */
be8355a2
RG
432 int vers;
433 switch(version) {
434 case LibsslTLSVersion::TLS10:
435 vers = TLS1_VERSION;
436 break;
437 case LibsslTLSVersion::TLS11:
438 vers = TLS1_1_VERSION;
439 break;
440 case LibsslTLSVersion::TLS12:
441 vers = TLS1_2_VERSION;
442 break;
443 case LibsslTLSVersion::TLS13:
656a5e55 444#ifdef TLS1_3_VERSION
be8355a2 445 vers = TLS1_3_VERSION;
656a5e55
RG
446#else
447 return false;
448#endif /* TLS1_3_VERSION */
be8355a2
RG
449 break;
450 default:
451 return false;
452 }
453
454 if (SSL_CTX_set_min_proto_version(ctx.get(), vers) != 1) {
455 return false;
456 }
457 return true;
458#else
459 long vers = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
460 switch(version) {
461 case LibsslTLSVersion::TLS10:
462 break;
463 case LibsslTLSVersion::TLS11:
464 vers |= SSL_OP_NO_TLSv1;
465 break;
466 case LibsslTLSVersion::TLS12:
467 vers |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
468 break;
469 case LibsslTLSVersion::TLS13:
470 vers |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
471 break;
472 default:
473 return false;
474 }
475
476 long options = SSL_CTX_get_options(ctx.get());
477 SSL_CTX_set_options(ctx.get(), options | vers);
478 return true;
479#endif
480}
481
0ef9ab19
RG
482OpenSSLTLSTicketKeysRing::OpenSSLTLSTicketKeysRing(size_t capacity)
483{
0ef9ab19
RG
484 d_ticketKeys.set_capacity(capacity);
485}
486
487OpenSSLTLSTicketKeysRing::~OpenSSLTLSTicketKeysRing()
488{
0ef9ab19
RG
489}
490
491void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr<OpenSSLTLSTicketKey> newKey)
492{
493 WriteLock wl(&d_lock);
494 d_ticketKeys.push_front(newKey);
495}
496
497std::shared_ptr<OpenSSLTLSTicketKey> OpenSSLTLSTicketKeysRing::getEncryptionKey()
498{
499 ReadLock rl(&d_lock);
500 return d_ticketKeys.front();
501}
502
503std::shared_ptr<OpenSSLTLSTicketKey> OpenSSLTLSTicketKeysRing::getDecryptionKey(unsigned char name[TLS_TICKETS_KEY_NAME_SIZE], bool& activeKey)
504{
505 ReadLock rl(&d_lock);
506 for (auto& key : d_ticketKeys) {
507 if (key->nameMatches(name)) {
508 activeKey = (key == d_ticketKeys.front());
509 return key;
510 }
511 }
512 return nullptr;
513}
514
515size_t OpenSSLTLSTicketKeysRing::getKeysCount()
516{
517 ReadLock rl(&d_lock);
518 return d_ticketKeys.size();
519}
520
521void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string& keyFile)
522{
523 bool keyLoaded = false;
524 std::ifstream file(keyFile);
525 try {
526 do {
527 auto newKey = std::make_shared<OpenSSLTLSTicketKey>(file);
528 addKey(newKey);
529 keyLoaded = true;
530 }
531 while (!file.fail());
532 }
533 catch (const std::exception& e) {
534 /* if we haven't been able to load at least one key, fail */
535 if (!keyLoaded) {
536 throw;
537 }
538 }
539
540 file.close();
541}
542
543void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t now)
544{
545 auto newKey = std::make_shared<OpenSSLTLSTicketKey>();
546 addKey(newKey);
547}
548
549OpenSSLTLSTicketKey::OpenSSLTLSTicketKey()
550{
551 if (RAND_bytes(d_name, sizeof(d_name)) != 1) {
552 throw std::runtime_error("Error while generating the name of the OpenSSL TLS ticket key");
553 }
554
555 if (RAND_bytes(d_cipherKey, sizeof(d_cipherKey)) != 1) {
556 throw std::runtime_error("Error while generating the cipher key of the OpenSSL TLS ticket key");
557 }
558
559 if (RAND_bytes(d_hmacKey, sizeof(d_hmacKey)) != 1) {
560 throw std::runtime_error("Error while generating the HMAC key of the OpenSSL TLS ticket key");
561 }
562#ifdef HAVE_LIBSODIUM
563 sodium_mlock(d_name, sizeof(d_name));
564 sodium_mlock(d_cipherKey, sizeof(d_cipherKey));
565 sodium_mlock(d_hmacKey, sizeof(d_hmacKey));
566#endif /* HAVE_LIBSODIUM */
567}
568
569OpenSSLTLSTicketKey::OpenSSLTLSTicketKey(ifstream& file)
570{
571 file.read(reinterpret_cast<char*>(d_name), sizeof(d_name));
572 file.read(reinterpret_cast<char*>(d_cipherKey), sizeof(d_cipherKey));
573 file.read(reinterpret_cast<char*>(d_hmacKey), sizeof(d_hmacKey));
574
575 if (file.fail()) {
576 throw std::runtime_error("Unable to load a ticket key from the OpenSSL tickets key file");
577 }
578#ifdef HAVE_LIBSODIUM
579 sodium_mlock(d_name, sizeof(d_name));
580 sodium_mlock(d_cipherKey, sizeof(d_cipherKey));
581 sodium_mlock(d_hmacKey, sizeof(d_hmacKey));
582#endif /* HAVE_LIBSODIUM */
583}
584
585OpenSSLTLSTicketKey::~OpenSSLTLSTicketKey()
586{
587#ifdef HAVE_LIBSODIUM
588 sodium_munlock(d_name, sizeof(d_name));
589 sodium_munlock(d_cipherKey, sizeof(d_cipherKey));
590 sodium_munlock(d_hmacKey, sizeof(d_hmacKey));
591#else
592 OPENSSL_cleanse(d_name, sizeof(d_name));
593 OPENSSL_cleanse(d_cipherKey, sizeof(d_cipherKey));
594 OPENSSL_cleanse(d_hmacKey, sizeof(d_hmacKey));
595#endif /* HAVE_LIBSODIUM */
596}
597
598bool OpenSSLTLSTicketKey::nameMatches(const unsigned char name[TLS_TICKETS_KEY_NAME_SIZE]) const
599{
600 return (memcmp(d_name, name, sizeof(d_name)) == 0);
601}
602
603int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx) const
604{
605 memcpy(keyName, d_name, sizeof(d_name));
606
607 if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) != 1) {
608 return -1;
609 }
610
611 if (EVP_EncryptInit_ex(ectx, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey, iv) != 1) {
612 return -1;
613 }
614
615 if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
616 return -1;
617 }
618
619 return 1;
620}
621
622bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx) const
623{
624 if (HMAC_Init_ex(hctx, d_hmacKey, sizeof(d_hmacKey), TLS_TICKETS_MAC_ALGO(), nullptr) != 1) {
625 return false;
626 }
627
628 if (EVP_DecryptInit_ex(ectx, TLS_TICKETS_CIPHER_ALGO(), nullptr, d_cipherKey, iv) != 1) {
629 return false;
630 }
631
632 return true;
633}
634
b54e94dc
RG
635std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)> libssl_init_server_context(const TLSConfig& config,
636 std::map<int, std::string>& ocspResponses)
637{
638 auto ctx = std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)>(SSL_CTX_new(SSLv23_server_method()), SSL_CTX_free);
639
640 int sslOptions =
641 SSL_OP_NO_SSLv2 |
642 SSL_OP_NO_SSLv3 |
643 SSL_OP_NO_COMPRESSION |
644 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
645 SSL_OP_SINGLE_DH_USE |
646 SSL_OP_SINGLE_ECDH_USE;
647
648 if (!config.d_enableTickets || config.d_numberOfTicketsKeys == 0) {
649 /* for TLS 1.3 this means no stateless tickets, but stateful tickets might still be issued,
650 which is something we don't want. */
651 sslOptions |= SSL_OP_NO_TICKET;
652 /* really disable all tickets */
653#ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
654 SSL_CTX_set_num_tickets(ctx.get(), 0);
655#endif /* HAVE_SSL_CTX_SET_NUM_TICKETS */
656 }
657
25426675
MH
658 if (config.d_sessionTimeout > 0) {
659 SSL_CTX_set_timeout(ctx.get(), config.d_sessionTimeout);
660 }
661
b54e94dc
RG
662 if (config.d_preferServerCiphers) {
663 sslOptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;
664 }
665
666 SSL_CTX_set_options(ctx.get(), sslOptions);
667 if (!libssl_set_min_tls_version(ctx, config.d_minTLSVersion)) {
668 throw std::runtime_error("Failed to set the minimum version to '" + libssl_tls_version_to_string(config.d_minTLSVersion));
669 }
670
671#ifdef SSL_CTX_set_ecdh_auto
672 SSL_CTX_set_ecdh_auto(ctx.get(), 1);
673#endif
674
675 if (config.d_maxStoredSessions == 0) {
676 /* disable stored sessions entirely */
677 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_OFF);
678 }
679 else {
680 /* use the internal built-in cache to store sessions */
681 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER);
682 SSL_CTX_sess_set_cache_size(ctx.get(), config.d_maxStoredSessions);
683 }
684
685 std::vector<int> keyTypes;
686 /* load certificate and private key */
687 for (const auto& pair : config.d_certKeyPairs) {
688 if (SSL_CTX_use_certificate_chain_file(ctx.get(), pair.first.c_str()) != 1) {
689 ERR_print_errors_fp(stderr);
690 throw std::runtime_error("An error occurred while trying to load the TLS server certificate file: " + pair.first);
691 }
692 if (SSL_CTX_use_PrivateKey_file(ctx.get(), pair.second.c_str(), SSL_FILETYPE_PEM) != 1) {
693 ERR_print_errors_fp(stderr);
694 throw std::runtime_error("An error occurred while trying to load the TLS server private key file: " + pair.second);
695 }
696 if (SSL_CTX_check_private_key(ctx.get()) != 1) {
697 ERR_print_errors_fp(stderr);
698 throw std::runtime_error("The key from '" + pair.second + "' does not match the certificate from '" + pair.first + "'");
699 }
700 /* store the type of the new key, we might need it later to select the right OCSP stapling response */
701 auto keyType = libssl_get_last_key_type(ctx);
702 if (keyType < 0) {
703 throw std::runtime_error("The key from '" + pair.second + "' has an unknown type");
704 }
705 keyTypes.push_back(keyType);
706 }
707
708 if (!config.d_ocspFiles.empty()) {
709 try {
710 ocspResponses = libssl_load_ocsp_responses(config.d_ocspFiles, keyTypes);
711 }
712 catch(const std::exception& e) {
713 throw std::runtime_error("Unable to load OCSP responses: " + std::string(e.what()));
714 }
715 }
716
717 if (!config.d_ciphers.empty() && SSL_CTX_set_cipher_list(ctx.get(), config.d_ciphers.c_str()) != 1) {
718 throw std::runtime_error("The TLS ciphers could not be set: " + config.d_ciphers);
719 }
720
721#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
722 if (!config.d_ciphers13.empty() && SSL_CTX_set_ciphersuites(ctx.get(), config.d_ciphers13.c_str()) != 1) {
723 throw std::runtime_error("The TLS 1.3 ciphers could not be set: " + config.d_ciphers13);
724 }
725#endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */
726
727 return ctx;
728}
729
7f8a5a32
RG
730#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
731static void libssl_key_log_file_callback(const SSL* ssl, const char* line)
732{
733 SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
734 if (sslCtx == nullptr) {
735 return;
736 }
737
738 auto fp = reinterpret_cast<FILE*>(SSL_CTX_get_ex_data(sslCtx, s_keyLogIndex));
739 if (fp == nullptr) {
740 return;
741 }
742
743 fprintf(fp, "%s\n", line);
9b56c83d 744 fflush(fp);
7f8a5a32
RG
745}
746#endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
747
748std::unique_ptr<FILE, int(*)(FILE*)> libssl_set_key_log_file(std::unique_ptr<SSL_CTX, void(*)(SSL_CTX*)>& ctx, const std::string& logFile)
749{
750#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
751 auto fp = std::unique_ptr<FILE, int(*)(FILE*)>(fopen(logFile.c_str(), "a"), fclose);
752 if (!fp) {
753 throw std::runtime_error("Error opening TLS log file '" + logFile + "'");
754 }
755
756 SSL_CTX_set_ex_data(ctx.get(), s_keyLogIndex, fp.get());
757 SSL_CTX_set_keylog_callback(ctx.get(), &libssl_key_log_file_callback);
758
759 return fp;
760#else
761 return std::unique_ptr<FILE, int(*)(FILE*)>(nullptr, fclose);
762#endif /* HAVE_SSL_CTX_SET_KEYLOG_CALLBACK */
763}
764
ede152ec 765#endif /* HAVE_LIBSSL */