]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/libssl.hh
Merge pull request #14020 from omoerbeek/rec-compiling-rust-dcos
[thirdparty/pdns.git] / pdns / libssl.hh
CommitLineData
9da20db2
RG
1#pragma once
2
0898164e 3#include <atomic>
0ef9ab19 4#include <fstream>
9da20db2
RG
5#include <map>
6#include <memory>
489caa9f 7#include <optional>
9da20db2
RG
8#include <string>
9#include <vector>
6de19ce2 10#include <optional>
9da20db2
RG
11
12#include "config.h"
0ef9ab19
RG
13#include "circular_buffer.hh"
14#include "lock.hh"
931536a5 15#include "misc.hh"
9da20db2 16
bcf26e85 17enum class LibsslTLSVersion : uint8_t { Unknown, TLS10, TLS11, TLS12, TLS13 };
9da20db2 18
6de19ce2
CHB
19struct TLSCertKeyPair
20{
21 std::string d_cert;
22 std::optional<std::string> d_key;
23 std::optional<std::string> d_password;
24 explicit TLSCertKeyPair(const std::string& cert, std::optional<std::string> key = std::nullopt, std::optional<std::string> password = std::nullopt):
c92e6020 25 d_cert(cert), d_key(std::move(key)), d_password(std::move(password)) {
6de19ce2
CHB
26 }
27};
28
b54e94dc
RG
29class TLSConfig
30{
31public:
6de19ce2 32 std::vector<TLSCertKeyPair> d_certKeyPairs;
b54e94dc
RG
33 std::vector<std::string> d_ocspFiles;
34
35 std::string d_ciphers;
36 std::string d_ciphers13;
37 std::string d_ticketKeyFile;
7f8a5a32 38 std::string d_keyLogFile;
b54e94dc
RG
39
40 size_t d_maxStoredSessions{20480};
25426675 41 time_t d_sessionTimeout{0};
b54e94dc
RG
42 time_t d_ticketsKeyRotationDelay{43200};
43 uint8_t d_numberOfTicketsKeys{5};
44 LibsslTLSVersion d_minTLSVersion{LibsslTLSVersion::TLS10};
45
12543371 46 bool d_preferServerCiphers{true};
b54e94dc 47 bool d_enableTickets{true};
08d3b723
RG
48 /* whether OpenSSL will release I/O buffers when the connection
49 becomes idle, saving memory */
50 bool d_releaseBuffers{true};
c223b99b
RG
51 /* whether so-called secure renegotiation should be allowed for TLS < 1.3 */
52 bool d_enableRenegotiation{false};
489caa9f
RG
53 /* enable TLS async mode, if supported by any engine */
54 bool d_asyncMode{false};
5afc196c
RG
55 /* enable kTLS mode, if supported */
56 bool d_ktls{false};
e80c3b09 57 /* set read ahead mode, if supported */
65454336 58 bool d_readAhead{true};
b54e94dc
RG
59};
60
f34fdcc5
RG
61struct TLSErrorCounters
62{
63 std::atomic<uint64_t> d_dhKeyTooSmall{0}; /* the other side sent a DH value that is not large enough */
64 std::atomic<uint64_t> d_inappropriateFallBack{0}; /* SCSV indicates that the client previously tried a higher version,
65 something bad is happening */
66 std::atomic<uint64_t> d_noSharedCipher{0}; /* we could not agree on a cipher to use */
67 std::atomic<uint64_t> d_unknownCipherType{0}; /* unknown cipher type */
68 std::atomic<uint64_t> d_unknownKeyExchangeType{0}; /* * unknown exchange type, weird */
69 std::atomic<uint64_t> d_unknownProtocol{0}; /* unknown protocol (SSLv2 or TLS 1.4, who knows? */
70 std::atomic<uint64_t> d_unsupportedEC{0}; /* unsupported elliptic curve */
71 std::atomic<uint64_t> d_unsupportedProtocol{0}; /* we don't accept this TLS version, sorry */
72};
73
9da20db2
RG
74#ifdef HAVE_LIBSSL
75#include <openssl/ssl.h>
76
77void registerOpenSSLUser();
78void unregisterOpenSSLUser();
79
0ef9ab19
RG
80/* From rfc5077 Section 4. Recommended Ticket Construction */
81#define TLS_TICKETS_KEY_NAME_SIZE (16)
82
83/* AES-256 */
84#define TLS_TICKETS_CIPHER_KEY_SIZE (32)
85#define TLS_TICKETS_CIPHER_ALGO (EVP_aes_256_cbc)
86
87/* HMAC SHA-256 */
88#define TLS_TICKETS_MAC_KEY_SIZE (32)
89#define TLS_TICKETS_MAC_ALGO (EVP_sha256)
90
91class OpenSSLTLSTicketKey
92{
93public:
94 OpenSSLTLSTicketKey();
95 OpenSSLTLSTicketKey(std::ifstream& file);
96 ~OpenSSLTLSTicketKey();
97
98 bool nameMatches(const unsigned char name[TLS_TICKETS_KEY_NAME_SIZE]) const;
f5e1b85e
FM
99
100#if OPENSSL_VERSION_MAJOR >= 3
101 int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const;
102 bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const;
103#else
b9839ca5
FM
104 int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const;
105 bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const;
f5e1b85e 106#endif
0ef9ab19
RG
107
108private:
109 unsigned char d_name[TLS_TICKETS_KEY_NAME_SIZE];
110 unsigned char d_cipherKey[TLS_TICKETS_CIPHER_KEY_SIZE];
111 unsigned char d_hmacKey[TLS_TICKETS_MAC_KEY_SIZE];
112};
113
114class OpenSSLTLSTicketKeysRing
115{
116public:
117 OpenSSLTLSTicketKeysRing(size_t capacity);
118 ~OpenSSLTLSTicketKeysRing();
0ef9ab19
RG
119 std::shared_ptr<OpenSSLTLSTicketKey> getEncryptionKey();
120 std::shared_ptr<OpenSSLTLSTicketKey> getDecryptionKey(unsigned char name[TLS_TICKETS_KEY_NAME_SIZE], bool& activeKey);
121 size_t getKeysCount();
122 void loadTicketsKeys(const std::string& keyFile);
123 void rotateTicketsKey(time_t now);
124
125private:
c92e6020
RG
126 void addKey(std::shared_ptr<OpenSSLTLSTicketKey>&& newKey);
127
17e1699b 128 SharedLockGuarded<boost::circular_buffer<std::shared_ptr<OpenSSLTLSTicketKey> > > d_ticketKeys;
0ef9ab19
RG
129};
130
131void* libssl_get_ticket_key_callback_data(SSL* s);
132void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data);
f5e1b85e
FM
133
134#if OPENSSL_VERSION_MAJOR >= 3
135int 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);
136#else
b9839ca5 137int 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);
f5e1b85e 138#endif
0ef9ab19 139
2ba75ea7 140#ifndef DISABLE_OCSP_STAPLING
9da20db2 141int libssl_ocsp_stapling_callback(SSL* ssl, const std::map<int, std::string>& ocspMap);
9da20db2
RG
142#ifdef HAVE_OCSP_BASIC_SIGN
143bool libssl_generate_ocsp_response(const std::string& certFile, const std::string& caCert, const std::string& caKey, const std::string& outFile, int ndays, int nmin);
144#endif
2ba75ea7 145#endif /* DISABLE_OCSP_STAPLING */
9da20db2 146
e99550b8 147void libssl_set_error_counters_callback(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, TLSErrorCounters* counters);
f34fdcc5 148
9da20db2 149LibsslTLSVersion libssl_tls_version_from_string(const std::string& str);
656a5e55 150const std::string& libssl_tls_version_to_string(LibsslTLSVersion version);
e99550b8 151bool libssl_set_min_tls_version(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, LibsslTLSVersion version);
9da20db2 152
d1ce3058
RG
153/* return the created context, and a list of warning messages for issues not severe enough
154 to trigger raising an exception, like failing to load an OCSP response file */
e99550b8 155std::pair<std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>, std::vector<std::string>> libssl_init_server_context(const TLSConfig& config,
d1ce3058 156 std::map<int, std::string>& ocspResponses);
b54e94dc 157
931536a5 158pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& ctx, const std::string& logFile);
cc1f4ed8 159
e82bf80f 160/* 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. */
d6d8802b 161#ifndef DISABLE_NPN
70dd1aed 162void 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);
d6d8802b
RG
163#endif /* DISABLE_NPN */
164
e82bf80f 165/* called in a server context, to select an ALPN value advertised by the client if any */
70dd1aed 166void 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);
e82bf80f 167/* set the supported ALPN protos in client context */
70dd1aed 168bool libssl_set_alpn_protos(SSL_CTX* ctx, const std::vector<std::vector<uint8_t>>& protos);
e82bf80f 169
cc1f4ed8
O
170std::string libssl_get_error_string();
171
b7664acd
FM
172#if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS)
173std::pair<bool, std::string> libssl_load_provider(const std::string& engineName);
174#endif /* HAVE_LIBSSL && OPENSSL_VERSION_MAJOR >= 3 && HAVE_TLS_PROVIDERS */
175
176#if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS)
489caa9f 177std::pair<bool, std::string> libssl_load_engine(const std::string& engineName, const std::optional<std::string>& defaultString);
b7664acd 178#endif /* HAVE_LIBSSL && !HAVE_TLS_PROVIDERS */
489caa9f 179
9da20db2 180#endif /* HAVE_LIBSSL */