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