@@ -21,11 +21,6 @@ USERVER_NAMESPACE_BEGIN
2121namespace engine ::io {
2222namespace {
2323
24- struct SslCtxDeleter {
25- void operator ()(SSL_CTX* ctx) const noexcept { SSL_CTX_free (ctx); }
26- };
27- using SslCtx = std::unique_ptr<SSL_CTX, SslCtxDeleter>;
28-
2924struct SslDeleter {
3025 void operator ()(SSL* ssl) const noexcept { SSL_free (ssl); }
3126};
@@ -190,65 +185,11 @@ int SSL_write_ex(SSL* ssl, const void* data, size_t len, size_t* bytes_written)
190185}
191186#endif
192187
193- SslCtx MakeSslCtx () {
194- crypto::Openssl::Init ();
195-
196- SslCtx ssl_ctx{SSL_CTX_new (SSLv23_method ())};
197- if (!ssl_ctx) {
198- throw TlsException (crypto::FormatSslError (" Failed create an SSL context: SSL_CTX_new" ));
199- }
200- #if OPENSSL_VERSION_NUMBER >= 0x010100000L
201- if (1 != SSL_CTX_set_min_proto_version (ssl_ctx.get (), TLS1_VERSION)) {
202- throw TlsException (crypto::FormatSslError (" Failed create an SSL context: SSL_CTX_set_min_proto_version" ));
203- }
204- #endif
205-
206- constexpr auto options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
207- #if OPENSSL_VERSION_NUMBER >= 0x010100000L
208- | SSL_OP_NO_RENEGOTIATION
209- #endif
210- ;
211- SSL_CTX_set_options (ssl_ctx.get (), options);
212- SSL_CTX_set_mode (ssl_ctx.get (), SSL_MODE_ENABLE_PARTIAL_WRITE);
213- SSL_CTX_clear_mode (ssl_ctx.get (), SSL_MODE_AUTO_RETRY);
214- if (1 != SSL_CTX_set_default_verify_paths (ssl_ctx.get ())) {
215- LOG_LIMITED_WARNING () << crypto::FormatSslError (" Failed create an SSL context: SSL_CTX_set_default_verify_paths"
216- );
217- }
218- return ssl_ctx;
219- }
220-
221188enum InterruptAction {
222189 kPass ,
223190 kFail ,
224191};
225192
226- void SetServerName (SslCtx& ctx, std::string_view server_name) {
227- if (server_name.empty ()) {
228- return ;
229- }
230-
231- X509_VERIFY_PARAM* verify_param = SSL_CTX_get0_param (ctx.get ());
232- if (!verify_param) {
233- throw TlsException (" Failed to set up client TLS wrapper: SSL_CTX_get0_param" );
234- }
235- if (1 != X509_VERIFY_PARAM_set1_host (verify_param, server_name.data (), server_name.size ())) {
236- throw TlsException (crypto::FormatSslError (" Failed to set up client TLS wrapper: X509_VERIFY_PARAM_set1_host" ));
237- }
238- SSL_CTX_set_verify (ctx.get (), SSL_VERIFY_PEER, nullptr );
239- }
240-
241- void AddCertAuthorities (SslCtx& ctx, const std::vector<crypto::Certificate>& cert_authorities) {
242- UASSERT (!cert_authorities.empty ());
243- auto * store = SSL_CTX_get_cert_store (ctx.get ());
244- UASSERT (store);
245- for (const auto & ca : cert_authorities) {
246- if (1 != X509_STORE_add_cert (store, ca.GetNative ())) {
247- throw TlsException (crypto::FormatSslError (" Failed to set up client TLS wrapper: X509_STORE_add_cert" ));
248- }
249- }
250- }
251-
252193} // namespace
253194
254195class TlsWrapper ::ReadContextAccessor final : public engine::impl::ContextAccessor {
@@ -284,7 +225,7 @@ class TlsWrapper::Impl {
284225 SyncBioData (SSL_get_rbio (ssl.get ()), &other.bio_data );
285226 }
286227
287- void SetUp (SslCtx& & ssl_ctx) {
228+ void SetUp (const crypto:: SslCtx& ssl_ctx) {
288229 Bio socket_bio{BIO_new (GetSocketBioMethod ())};
289230 if (!socket_bio) {
290231 throw TlsException (crypto::FormatSslError (" Failed to set up TLS wrapper: BIO_new" ));
@@ -293,7 +234,7 @@ class TlsWrapper::Impl {
293234 SyncBioData (socket_bio.get (), nullptr );
294235 BIO_set_init (socket_bio.get (), 1 );
295236
296- ssl.reset (SSL_new (ssl_ctx.get ( )));
237+ ssl.reset (SSL_new (static_cast <SSL_CTX*>( ssl_ctx.GetRawSslCtx () )));
297238 if (!ssl) {
298239 throw TlsException (crypto::FormatSslError (" Failed to set up TLS wrapper: SSL_new" ));
299240 }
@@ -489,11 +430,8 @@ engine::impl::ContextAccessor& TlsWrapper::ReadContextAccessor::GetSocketContext
489430TlsWrapper::TlsWrapper (Socket&& socket) : impl_(std::move(socket)) { SetupContextAccessors (); }
490431
491432TlsWrapper TlsWrapper::StartTlsClient (Socket&& socket, const std::string& server_name, Deadline deadline) {
492- auto ssl_ctx = MakeSslCtx ();
493- SetServerName (ssl_ctx, server_name);
494-
495433 TlsWrapper wrapper{std::move (socket)};
496- wrapper.impl_ ->SetUp (std::move (ssl_ctx ));
434+ wrapper.impl_ ->SetUp (crypto::SslCtx::CreateClientTlsContext (server_name ));
497435 wrapper.impl_ ->ClientConnect (server_name, deadline);
498436 return wrapper;
499437}
@@ -506,79 +444,15 @@ TlsWrapper TlsWrapper::StartTlsClient(
506444 Deadline deadline,
507445 const std::vector<crypto::Certificate>& extra_cert_authorities
508446) {
509- auto ssl_ctx = MakeSslCtx ();
510- SetServerName (ssl_ctx, server_name);
511-
512- if (!extra_cert_authorities.empty ()) {
513- AddCertAuthorities (ssl_ctx, extra_cert_authorities);
514- }
515-
516- if (cert) {
517- if (1 != SSL_CTX_use_certificate (ssl_ctx.get (), cert.GetNative ())) {
518- throw TlsException (crypto::FormatSslError (" Failed to set up client TLS wrapper: SSL_CTX_use_certificate" ));
519- }
520- }
521-
522- if (key) {
523- if (1 != SSL_CTX_use_PrivateKey (ssl_ctx.get (), key.GetNative ())) {
524- throw TlsException (crypto::FormatSslError (" Failed to set up client TLS wrapper: SSL_CTX_use_PrivateKey" ));
525- }
526- }
527-
528447 TlsWrapper wrapper{std::move (socket)};
529- wrapper.impl_ ->SetUp (std::move (ssl_ctx ));
448+ wrapper.impl_ ->SetUp (crypto::SslCtx::CreateClientTlsContext (server_name, cert, key, extra_cert_authorities ));
530449 wrapper.impl_ ->ClientConnect (server_name, deadline);
531450 return wrapper;
532451}
533452
534- TlsWrapper TlsWrapper::StartTlsServer (
535- Socket&& socket,
536- const crypto::CertificatesChain& cert_chain,
537- const crypto::PrivateKey& key,
538- Deadline deadline,
539- const std::vector<crypto::Certificate>& extra_cert_authorities
540- ) {
541- auto ssl_ctx = MakeSslCtx ();
542-
543- if (!extra_cert_authorities.empty ()) {
544- AddCertAuthorities (ssl_ctx, extra_cert_authorities);
545- SSL_CTX_set_verify (ssl_ctx.get (), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr );
546- LOG_INFO () << " Client SSL cert will be verified" ;
547- } else {
548- LOG_INFO () << " Client SSL cert will not be verified" ;
549- }
550-
551- if (cert_chain.empty ()) {
552- throw TlsException (crypto::FormatSslError (" Empty certificate chain provided" ));
553- }
554-
555- if (1 != SSL_CTX_use_certificate (ssl_ctx.get (), cert_chain.begin ()->GetNative ())) {
556- throw TlsException (crypto::FormatSslError (" Failed to set up server TLS wrapper: SSL_CTX_use_certificate" ));
557- }
558-
559- if (cert_chain.size () > 1 ) {
560- auto cert_it = std::next (cert_chain.begin ());
561- for (; cert_it != cert_chain.end (); ++cert_it) {
562- // cast in openssl1.0 macro expansion
563- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
564- if (SSL_CTX_add_extra_chain_cert (ssl_ctx.get (), cert_it->GetNative ()) <= 0 ) {
565- throw TlsException (
566- crypto::FormatSslError (" Failed to set up server TLS wrapper: SSL_CTX_add_extra_chain_cert" )
567- );
568- }
569-
570- // After SSL_CTX_add_extra_chain_cert we should not free the cert
571- const auto ret = X509_up_ref (cert_it->GetNative ());
572- UASSERT (ret == 1 );
573- }
574- }
575-
576- if (1 != SSL_CTX_use_PrivateKey (ssl_ctx.get (), key.GetNative ())) {
577- throw TlsException (crypto::FormatSslError (" Failed to set up server TLS wrapper: SSL_CTX_use_PrivateKey" ));
578- }
579-
453+ TlsWrapper TlsWrapper::StartTlsServer (Socket&& socket, const crypto::SslCtx& ctx, Deadline deadline) {
580454 TlsWrapper wrapper{std::move (socket)};
581- wrapper.impl_ ->SetUp (std::move (ssl_ctx) );
455+ wrapper.impl_ ->SetUp (ctx );
582456 wrapper.impl_ ->bio_data .current_deadline = deadline;
583457
584458 auto ret = SSL_accept (wrapper.impl_ ->ssl .get ());
0 commit comments