1717#include < botan/pkix_types.h>
1818#include < botan/certstor_flatfile.h>
1919#include < botan/x509path.h>
20+ #include < botan/tls_session_manager_memory.h>
2021
2122using namespace trantor ;
2223using namespace std ::placeholders;
2324
24- static Botan::System_RNG sessionManagerRng;
25- // Is this Ok? C++ technically doesn't guarantee static object initialization
26- // order.
27- static Botan::TLS::Session_Manager_In_Memory sessionManager (sessionManagerRng);
28- static thread_local Botan::System_RNG rng;
25+ static std::once_flag sessionManagerInitFlag;
26+ static std::shared_ptr<Botan::AutoSeeded_RNG> sessionManagerRng;
27+ static std::shared_ptr<Botan::TLS::Session_Manager_In_Memory> sessionManager;
28+ static thread_local std::shared_ptr<Botan::AutoSeeded_RNG> rng;
2929static Botan::System_Certificate_Store certStore;
3030
3131using namespace trantor ;
3232
3333class Credentials : public Botan ::Credentials_Manager
3434{
3535 public:
36- Credentials (Botan::Private_Key * key,
36+ Credentials (std::shared_ptr< Botan::Private_Key> key,
3737 Botan::X509_Certificate *cert,
3838 Botan::Certificate_Store *certStore)
3939 : certStore_(certStore), cert_(cert), key_(key)
@@ -50,28 +50,33 @@ class Credentials : public Botan::Credentials_Manager
5050 return {certStore_};
5151 }
5252
53- std::vector<Botan::X509_Certificate> cert_chain (
53+ std::vector<Botan::X509_Certificate> find_cert_chain (
5454 const std::vector<std::string> &cert_key_types,
55+ const std::vector<Botan::AlgorithmIdentifier> &cert_signature_schemes,
56+ const std::vector<Botan::X509_DN> &acceptable_CAs,
5557 const std::string &type,
5658 const std::string &context) override
5759 {
5860 (void )type;
5961 (void )context;
62+ (void )cert_signature_schemes;
63+ (void )acceptable_CAs;
6064 if (cert_ == nullptr )
6165 return {};
6266
6367 auto key_algo =
64- cert_->subject_public_key_algo ().get_oid ().to_formatted_string ();
68+ cert_->subject_public_key_algo ().oid ().to_formatted_string ();
6569 auto it =
6670 std::find (cert_key_types.begin (), cert_key_types.end (), key_algo);
6771 if (it == cert_key_types.end ())
6872 return {};
6973 return {*cert_};
7074 }
7175
72- Botan::Private_Key *private_key_for (const Botan::X509_Certificate &cert,
73- const std::string &type,
74- const std::string &context) override
76+ std::shared_ptr<Botan::Private_Key> private_key_for (
77+ const Botan::X509_Certificate &cert,
78+ const std::string &type,
79+ const std::string &context) override
7580 {
7681 (void )cert;
7782 (void )type;
@@ -80,7 +85,7 @@ class Credentials : public Botan::Credentials_Manager
8085 }
8186 Botan::Certificate_Store *certStore_ = nullptr ;
8287 Botan::X509_Certificate *cert_ = nullptr ;
83- Botan::Private_Key * key_ = nullptr ;
88+ std::shared_ptr< Botan::Private_Key> key_ = nullptr ;
8489};
8590
8691struct BotanCertificate : public Certificate
@@ -110,7 +115,7 @@ namespace trantor
110115{
111116struct SSLContext
112117{
113- std::unique_ptr <Botan::Private_Key> key;
118+ std::shared_ptr <Botan::Private_Key> key;
114119 std::unique_ptr<Botan::X509_Certificate> cert;
115120 std::shared_ptr<Botan::Certificate_Store> certStore;
116121 bool isServer = false ;
@@ -136,14 +141,16 @@ class TrantorPolicy : public Botan::TLS::Policy
136141
137142struct BotanTLSProvider : public TLSProvider ,
138143 public NonCopyable,
139- public Botan::TLS::Callbacks
144+ public Botan::TLS::Callbacks,
145+ public std::enable_shared_from_this<BotanTLSProvider>
140146{
141147 public:
142148 BotanTLSProvider (TcpConnection *conn,
143149 TLSPolicyPtr policy,
144150 SSLContextPtr ctx)
145151 : TLSProvider(conn, std::move(policy), std::move(ctx))
146152 {
153+ validationPolicy_ = std::make_shared<TrantorPolicy>();
147154 }
148155
149156 virtual void recvData (MsgBuffer *buffer) override
@@ -163,7 +170,7 @@ struct BotanTLSProvider : public TLSProvider,
163170
164171 if (tlsConnected_ == false )
165172 {
166- if (e.type () == Botan::TLS::Alert::BAD_CERTIFICATE )
173+ if (e.type () == Botan::TLS::Alert::BadCertificate )
167174 handleSSLError (SSLError::kSSLInvalidCertificate );
168175 else
169176 handleSSLError (SSLError::kSSLHandshakeError );
@@ -226,31 +233,44 @@ struct BotanTLSProvider : public TLSProvider,
226233
227234 virtual void startEncryption () override
228235 {
229- credsPtr_ = std::make_unique <Credentials>(contextPtr_->key . get () ,
236+ credsPtr_ = std::make_shared <Credentials>(contextPtr_->key ,
230237 contextPtr_->cert .get (),
231238 contextPtr_->certStore .get ());
232239 if (policyPtr_->getConfCmds ().empty () == false )
233240 LOG_WARN << " BotanTLSConnectionImpl does not support sslConfCmds." ;
241+
242+ // initialize rng and session manager if we haven't already
243+ std::call_once (sessionManagerInitFlag, []() {
244+ sessionManagerRng = std::make_shared<Botan::AutoSeeded_RNG>();
245+ sessionManager =
246+ std::make_shared<Botan::TLS::Session_Manager_In_Memory>(
247+ sessionManagerRng);
248+ });
249+ if (rng == nullptr )
250+ rng = std::make_shared<Botan::AutoSeeded_RNG>();
234251 if (contextPtr_->isServer )
235252 {
236253 // TODO: Need a more scalable way to manage session validation rules
237- validationPolicy_. requireClientCert_ =
254+ validationPolicy_-> requireClientCert_ =
238255 contextPtr_->requireClientCert ;
239- channel_ = std::make_unique<Botan::TLS::Server>(
240- *this , sessionManager, *credsPtr_, validationPolicy_, rng);
256+ channel_ = std::make_unique<Botan::TLS::Server>(shared_from_this (),
257+ sessionManager,
258+ credsPtr_,
259+ validationPolicy_,
260+ rng);
241261 }
242262 else
243263 {
244- validationPolicy_. requireClientCert_ =
264+ validationPolicy_-> requireClientCert_ =
245265 contextPtr_->requireClientCert ;
246266 // technically Botan2 does support TLS 1.0 and 1.1, but Botan3 does
247267 // not. So we just disable them to keep compatibility.
248268 if (policyPtr_->getUseOldTLS ())
249269 LOG_WARN << " Old TLS not supported by Botan (only >= TLS 1.2)" ;
250270 channel_ = std::make_unique<Botan::TLS::Client>(
251- * this ,
271+ shared_from_this () ,
252272 sessionManager,
253- * credsPtr_,
273+ credsPtr_,
254274 validationPolicy_,
255275 rng,
256276 Botan::TLS::Server_Information (policyPtr_->getHostname (),
@@ -270,32 +290,32 @@ struct BotanTLSProvider : public TLSProvider,
270290
271291 virtual ~BotanTLSProvider () override = default ;
272292
273- void tls_emit_data (const uint8_t data[], size_t size ) override
293+ void tls_emit_data (std::span< const uint8_t > data) override
274294 {
275- auto n = writeCallback_ (conn_, data, size );
295+ auto n = writeCallback_ (conn_, data. data (), data. size_bytes () );
276296 lastWriteSize_ = n;
277297
278298 // store the unsent data and send it later
279- if (n == ssize_t (size ))
299+ if (n == ssize_t (data. size_bytes () ))
280300 return ;
281301 if (n == -1 )
282302 n = 0 ;
283- appendToWriteBuffer ((const char *)data + n, size - n);
303+ appendToWriteBuffer ((const char *)data.data () + n,
304+ data.size_bytes () - n);
284305 }
285306
286307 void tls_record_received (uint64_t seq_no,
287- const uint8_t data[],
288- size_t size) override
308+ std::span<const uint8_t > data) override
289309 {
290310 (void )seq_no;
291- recvBuffer_.append ((const char *)data, size );
311+ recvBuffer_.append ((const char *)data. data (), data. size_bytes () );
292312 if (messageCallback_)
293313 messageCallback_ (conn_, &recvBuffer_);
294314 }
295315
296316 void tls_alert (Botan::TLS::Alert alert) override
297317 {
298- if (alert.type () == Botan::TLS::Alert::CLOSE_NOTIFY )
318+ if (alert.type () == Botan::TLS::Alert::CloseNotify )
299319 {
300320 LOG_TRACE << " TLS close notify received" ;
301321 if (closeCallback_)
@@ -324,7 +344,7 @@ struct BotanTLSProvider : public TLSProvider,
324344
325345 void tls_verify_cert_chain (
326346 const std::vector<Botan::X509_Certificate> &certs,
327- const std::vector<std::shared_ptr< const Botan::OCSP::Response>> &ocsp,
347+ const std::vector<std::optional< Botan::OCSP::Response>> &ocsp,
328348 const std::vector<Botan::Certificate_Store *> &trusted_roots,
329349 Botan::Usage_Type usage,
330350 const std::string &hostname,
@@ -338,38 +358,31 @@ struct BotanTLSProvider : public TLSProvider,
338358 {
339359 if (certs.size () == 0 )
340360 throw Botan::TLS::TLS_Exception (
341- Botan::TLS::Alert::NO_CERTIFICATE ,
361+ Botan::TLS::Alert::NoCertificate ,
342362 " Certificate validation failed: no certificate" );
343363 // handle self-signed certificate
344- std::vector<std::shared_ptr<const Botan::X509_Certificate>>
345- selfSigned = {
346- std::make_shared<Botan::X509_Certificate>(certs[0 ])};
364+ std::vector<Botan::X509_Certificate> selfSigned = {certs[0 ]};
347365
348366 Botan::Path_Validation_Restrictions restrictions (
349367 false , // require revocation
350- validationPolicy_. minimum_signature_strength ());
368+ validationPolicy_-> minimum_signature_strength ());
351369
352370 auto now = std::chrono::system_clock::now ();
353- const auto status =
354- Botan::PKIX::check_chain (selfSigned,
355- now,
356- hostname,
357- usage,
358- restrictions.minimum_key_strength (),
359- restrictions.trusted_hashes ());
371+ const auto status = Botan::PKIX::check_chain (
372+ selfSigned, now, hostname, usage, restrictions);
360373
361374 const auto result = Botan::PKIX::overall_status (status);
362375
363376 if (result != Botan::Certificate_Status_Code::OK)
364377 throw Botan::TLS::TLS_Exception (
365- Botan::TLS::Alert::BAD_CERTIFICATE ,
378+ Botan::TLS::Alert::BadCertificate ,
366379 std::string (" Certificate validation failed: " ) +
367380 Botan::to_string (result));
368381 }
369382 }
370383
371- TrantorPolicy validationPolicy_;
372- std::unique_ptr <Botan::Credentials_Manager> credsPtr_;
384+ std::shared_ptr< TrantorPolicy> validationPolicy_;
385+ std::shared_ptr <Botan::Credentials_Manager> credsPtr_;
373386 std::unique_ptr<Botan::TLS::Channel> channel_;
374387 bool tlsConnected_ = false ;
375388 ssize_t lastWriteSize_ = 0 ;
0 commit comments