• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 19741624072

27 Nov 2025 03:45PM UTC coverage: 73.086% (+0.02%) from 73.065%
19741624072

Pull #16570

github

web-flow
Merge 08a2cdb1d into f94a3f63f
Pull Request #16570: rec: rewrite all unwrap calls in web.rs

38523 of 63408 branches covered (60.75%)

Branch coverage included in aggregate %.

128044 of 164496 relevant lines covered (77.84%)

6531485.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/pdns/libssl.hh
1
#pragma once
2

3
#include <atomic>
4
#include <fstream>
5
#include <map>
6
#include <memory>
7
#include <optional>
8
#include <string>
9
#include <vector>
10
#include <optional>
11

12
#include "config.h"
13
#include "circular_buffer.hh"
14
#include "lock.hh"
15
#include "misc.hh"
16

17
enum class LibsslTLSVersion : uint8_t { Unknown, TLS10, TLS11, TLS12, TLS13 };
18

19
struct 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):
25
    d_cert(cert), d_key(std::move(key)), d_password(std::move(password)) {
286✔
26
  }
286✔
27
};
28

29
class TLSConfig
30
{
31
public:
32
  std::vector<TLSCertKeyPair> d_certKeyPairs;
33
  std::vector<std::string> d_ocspFiles;
34

35
  std::string d_ciphers;
36
  std::string d_ciphers13;
37
  std::string d_ticketKeyFile;
38
  std::string d_keyLogFile;
39

40
  size_t d_maxStoredSessions{20480};
41
  time_t d_sessionTimeout{0};
42
  time_t d_ticketsKeyRotationDelay{43200};
43
  uint8_t d_numberOfTicketsKeys{5};
44
  LibsslTLSVersion d_minTLSVersion{LibsslTLSVersion::TLS10};
45

46
  bool d_preferServerCiphers{true};
47
  bool d_enableTickets{true};
48
  /* whether OpenSSL will release I/O buffers when the connection
49
     becomes idle, saving memory */
50
  bool d_releaseBuffers{true};
51
  /* whether so-called secure renegotiation should be allowed for TLS < 1.3 */
52
  bool d_enableRenegotiation{false};
53
  /* enable TLS async mode, if supported by any engine */
54
  bool d_asyncMode{false};
55
  /* enable kTLS mode, if supported */
56
  bool d_ktls{false};
57
  /* set read ahead mode, if supported */
58
  bool d_readAhead{true};
59
};
60

61
struct 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

74
#ifdef HAVE_LIBSSL
75
#include <openssl/ssl.h>
76

77
void registerOpenSSLUser();
78
void unregisterOpenSSLUser();
79

80
/* From rfc5077 Section 4. Recommended Ticket Construction */
81
#define TLS_TICKETS_KEY_NAME_SIZE (16)
4✔
82

83
/* AES-256 */
84
#define TLS_TICKETS_CIPHER_KEY_SIZE (32)
4✔
85
#define TLS_TICKETS_CIPHER_ALGO (EVP_aes_256_cbc)
1,110✔
86

87
/* HMAC SHA-256 */
88
#define TLS_TICKETS_MAC_KEY_SIZE (32)
4✔
89
#define TLS_TICKETS_MAC_ALGO (EVP_sha256)
90

91
class OpenSSLTLSTicketKey
92
{
93
public:
94
  OpenSSLTLSTicketKey();
95
  OpenSSLTLSTicketKey(std::ifstream& file);
96
  OpenSSLTLSTicketKey(const std::string& key);
97
  ~OpenSSLTLSTicketKey();
98

99
  bool nameMatches(const unsigned char name[TLS_TICKETS_KEY_NAME_SIZE]) const;
100

101
#if OPENSSL_VERSION_MAJOR >= 3
102
  int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const;
103
  bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx) const;
104
#else
105
  int encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const;
106
  bool decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx) const;
107
#endif
108

109
  [[nodiscard]] std::string content() const;
110

111
private:
112
  unsigned char d_name[TLS_TICKETS_KEY_NAME_SIZE];
113
  unsigned char d_cipherKey[TLS_TICKETS_CIPHER_KEY_SIZE];
114
  unsigned char d_hmacKey[TLS_TICKETS_MAC_KEY_SIZE];
115
};
116

117
class OpenSSLTLSTicketKeysRing
118
{
119
public:
120
  OpenSSLTLSTicketKeysRing(size_t capacity);
121
  ~OpenSSLTLSTicketKeysRing();
122
  std::shared_ptr<OpenSSLTLSTicketKey> getEncryptionKey();
123
  std::shared_ptr<OpenSSLTLSTicketKey> getDecryptionKey(unsigned char name[TLS_TICKETS_KEY_NAME_SIZE], bool& activeKey);
124
  size_t getKeysCount();
125
  void loadTicketsKeys(const std::string& keyFile);
126
  void loadTicketsKey(const std::string& key);
127
  void rotateTicketsKey(time_t now);
128

129
private:
130
  void addKey(std::shared_ptr<OpenSSLTLSTicketKey>&& newKey);
131
  SharedLockGuarded<boost::circular_buffer<std::shared_ptr<OpenSSLTLSTicketKey> > > d_ticketKeys;
132
};
133

134
void* libssl_get_ticket_key_callback_data(SSL* s);
135
void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data);
136

137
#if OPENSSL_VERSION_MAJOR >= 3
138
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);
139
#else
140
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);
141
#endif
142

143
#ifndef DISABLE_OCSP_STAPLING
144
int libssl_ocsp_stapling_callback(SSL* ssl, const std::map<int, std::string>& ocspMap);
145
#ifdef HAVE_OCSP_BASIC_SIGN
146
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);
147
#endif
148
#endif /* DISABLE_OCSP_STAPLING */
149

150
void libssl_set_error_counters_callback(SSL_CTX& ctx, TLSErrorCounters* counters);
151

152
LibsslTLSVersion libssl_tls_version_from_string(const std::string& str);
153
const std::string& libssl_tls_version_to_string(LibsslTLSVersion version);
154

155

156
namespace pdns::libssl {
157
class ServerContext
158
{
159
public:
160
  using SharedContext = std::shared_ptr<SSL_CTX>;
161
  using SNIToContextMap  = std::map<std::string, SharedContext, std::less<>>;
162

163
  SharedContext d_defaultContext;
164
  SNIToContextMap d_sniMap;
165
  std::map<int, std::string> d_ocspResponses;
166
};
167
}
168

169
/* return the created context, and a list of warning messages for issues not severe enough
170
   to trigger raising an exception, like failing to load an OCSP response file */
171
std::pair<std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>, std::vector<std::string>> libssl_init_server_context_no_sni(const TLSConfig& config,
172
                                                                                                                         std::map<int, std::string>& ocspResponses);
173
std::pair<pdns::libssl::ServerContext, std::vector<std::string>> libssl_init_server_context(const TLSConfig& config);
174

175
pdns::UniqueFilePtr libssl_set_key_log_file(SSL_CTX* ctx, const std::string& logFile);
176

177
/* called in a server context, to select an ALPN value advertised by the client if any */
178
void libssl_set_alpn_select_callback(SSL_CTX* ctx, int (*callback)(SSL* ssl, const unsigned char** out, unsigned char* outlen, const unsigned char* inPtr, unsigned int inlen, void* arg), void* arg);
179
/* set the supported ALPN protos in client context */
180
bool libssl_set_alpn_protos(SSL_CTX* ctx, const std::vector<std::vector<uint8_t>>& protos);
181

182
std::string libssl_get_error_string();
183

184
#if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS)
185
std::pair<bool, std::string> libssl_load_provider(const std::string& engineName);
186
#endif /* HAVE_LIBSSL && OPENSSL_VERSION_MAJOR >= 3 && HAVE_TLS_PROVIDERS */
187

188
#if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS)
189
std::pair<bool, std::string> libssl_load_engine(const std::string& engineName, const std::optional<std::string>& defaultString);
190
#endif /* HAVE_LIBSSL && !HAVE_TLS_PROVIDERS */
191

192
#endif /* HAVE_LIBSSL */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc