Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ def set_version(self):
)
major_version = re.search(r'set\(USERVER_MAJOR_VERSION (.*)\)', content).group(1).strip()
minor_version = re.search(r'set\(USERVER_MINOR_VERSION (.*)\)', content).group(1).strip()
hotfix_version = 1

self.version = f'{major_version}.{minor_version}' # pylint: disable=attribute-defined-outside-init
self.version = f'{major_version}.{minor_version}.{hotfix_version}.1' # pylint: disable=attribute-defined-outside-init

def layout(self):
cmake_layout(self)
Expand Down
8 changes: 4 additions & 4 deletions core/include/userver/engine/io/tls_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <string>
#include <vector>

#include <userver/crypto/ssl_ctx.hpp>
//#include <userver/crypto/ssl.hpp>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented include

#include <userver/crypto/certificate.hpp>
#include <userver/crypto/private_key.hpp>
#include <userver/engine/deadline.hpp>
Expand Down Expand Up @@ -42,10 +44,8 @@ class [[nodiscard]] TlsWrapper final : public RwBase {
/// Starts a TLS server on an opened socket
static TlsWrapper StartTlsServer(
Socket&& socket,
const crypto::CertificatesChain& cert_chain,
const crypto::PrivateKey& key,
Deadline deadline,
const std::vector<crypto::Certificate>& extra_cert_authorities = {}
const crypto::SslCtx& ctx,
Deadline deadline
);

~TlsWrapper() override;
Expand Down
10 changes: 6 additions & 4 deletions core/src/clients/http/client_crl_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,14 @@ struct TlsServer {
auto deadline = engine::Deadline::FromDuration(utest::kMaxTestWaitTime);
auto socket = tcp_listener_.socket.Accept(deadline);

auto tls_server = engine::io::TlsWrapper::StartTlsServer(
std::move(socket),
crypto::SslCtx ssl_ctx = crypto::SslCtx::CreateServerTlsContext(
crypto::LoadCertificatesChainFromString(kServerCertificate),
crypto::PrivateKey::LoadFromString(kRevokedServerPrivateKey),
deadline,
cas
cas);
auto tls_server = engine::io::TlsWrapper::StartTlsServer(
std::move(socket),
ssl_ctx,
deadline
);

std::array<char, 2048> data{};
Expand Down
136 changes: 7 additions & 129 deletions core/src/engine/io/tls_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ USERVER_NAMESPACE_BEGIN
namespace engine::io {
namespace {

struct SslCtxDeleter {
void operator()(SSL_CTX* ctx) const noexcept { SSL_CTX_free(ctx); }
};
using SslCtx = std::unique_ptr<SSL_CTX, SslCtxDeleter>;

struct SslDeleter {
void operator()(SSL* ssl) const noexcept { SSL_free(ssl); }
};
Expand Down Expand Up @@ -190,65 +185,11 @@ int SSL_write_ex(SSL* ssl, const void* data, size_t len, size_t* bytes_written)
}
#endif

SslCtx MakeSslCtx() {
crypto::Openssl::Init();

SslCtx ssl_ctx{SSL_CTX_new(SSLv23_method())};
if (!ssl_ctx) {
throw TlsException(crypto::FormatSslError("Failed create an SSL context: SSL_CTX_new"));
}
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
if (1 != SSL_CTX_set_min_proto_version(ssl_ctx.get(), TLS1_VERSION)) {
throw TlsException(crypto::FormatSslError("Failed create an SSL context: SSL_CTX_set_min_proto_version"));
}
#endif

constexpr auto options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
| SSL_OP_NO_RENEGOTIATION
#endif
;
SSL_CTX_set_options(ssl_ctx.get(), options);
SSL_CTX_set_mode(ssl_ctx.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_clear_mode(ssl_ctx.get(), SSL_MODE_AUTO_RETRY);
if (1 != SSL_CTX_set_default_verify_paths(ssl_ctx.get())) {
LOG_LIMITED_WARNING() << crypto::FormatSslError("Failed create an SSL context: SSL_CTX_set_default_verify_paths"
);
}
return ssl_ctx;
}

enum InterruptAction {
kPass,
kFail,
};

void SetServerName(SslCtx& ctx, std::string_view server_name) {
if (server_name.empty()) {
return;
}

X509_VERIFY_PARAM* verify_param = SSL_CTX_get0_param(ctx.get());
if (!verify_param) {
throw TlsException("Failed to set up client TLS wrapper: SSL_CTX_get0_param");
}
if (1 != X509_VERIFY_PARAM_set1_host(verify_param, server_name.data(), server_name.size())) {
throw TlsException(crypto::FormatSslError("Failed to set up client TLS wrapper: X509_VERIFY_PARAM_set1_host"));
}
SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr);
}

void AddCertAuthorities(SslCtx& ctx, const std::vector<crypto::Certificate>& cert_authorities) {
UASSERT(!cert_authorities.empty());
auto* store = SSL_CTX_get_cert_store(ctx.get());
UASSERT(store);
for (const auto& ca : cert_authorities) {
if (1 != X509_STORE_add_cert(store, ca.GetNative())) {
throw TlsException(crypto::FormatSslError("Failed to set up client TLS wrapper: X509_STORE_add_cert"));
}
}
}

} // namespace

class TlsWrapper::ReadContextAccessor final : public engine::impl::ContextAccessor {
Expand Down Expand Up @@ -284,7 +225,7 @@ class TlsWrapper::Impl {
SyncBioData(SSL_get_rbio(ssl.get()), &other.bio_data);
}

void SetUp(SslCtx&& ssl_ctx) {
void SetUp(const crypto::SslCtx& ssl_ctx) {
Bio socket_bio{BIO_new(GetSocketBioMethod())};
if (!socket_bio) {
throw TlsException(crypto::FormatSslError("Failed to set up TLS wrapper: BIO_new"));
Expand All @@ -293,7 +234,7 @@ class TlsWrapper::Impl {
SyncBioData(socket_bio.get(), nullptr);
BIO_set_init(socket_bio.get(), 1);

ssl.reset(SSL_new(ssl_ctx.get()));
ssl.reset(SSL_new(static_cast<SSL_CTX*>(ssl_ctx.GetRawSslCtx())));
if (!ssl) {
throw TlsException(crypto::FormatSslError("Failed to set up TLS wrapper: SSL_new"));
}
Expand Down Expand Up @@ -454,11 +395,8 @@ engine::impl::ContextAccessor& TlsWrapper::ReadContextAccessor::GetSocketContext
TlsWrapper::TlsWrapper(Socket&& socket) : impl_(std::move(socket)) { SetupContextAccessors(); }

TlsWrapper TlsWrapper::StartTlsClient(Socket&& socket, const std::string& server_name, Deadline deadline) {
auto ssl_ctx = MakeSslCtx();
SetServerName(ssl_ctx, server_name);

TlsWrapper wrapper{std::move(socket)};
wrapper.impl_->SetUp(std::move(ssl_ctx));
wrapper.impl_->SetUp(crypto::SslCtx::CreateClientTlsContext(server_name));
wrapper.impl_->ClientConnect(server_name, deadline);
return wrapper;
}
Expand All @@ -471,79 +409,19 @@ TlsWrapper TlsWrapper::StartTlsClient(
Deadline deadline,
const std::vector<crypto::Certificate>& extra_cert_authorities
) {
auto ssl_ctx = MakeSslCtx();
SetServerName(ssl_ctx, server_name);

if (!extra_cert_authorities.empty()) {
AddCertAuthorities(ssl_ctx, extra_cert_authorities);
}

if (cert) {
if (1 != SSL_CTX_use_certificate(ssl_ctx.get(), cert.GetNative())) {
throw TlsException(crypto::FormatSslError("Failed to set up client TLS wrapper: SSL_CTX_use_certificate"));
}
}

if (key) {
if (1 != SSL_CTX_use_PrivateKey(ssl_ctx.get(), key.GetNative())) {
throw TlsException(crypto::FormatSslError("Failed to set up client TLS wrapper: SSL_CTX_use_PrivateKey"));
}
}

TlsWrapper wrapper{std::move(socket)};
wrapper.impl_->SetUp(std::move(ssl_ctx));
wrapper.impl_->SetUp(crypto::SslCtx::CreateClientTlsContext(server_name, cert, key, extra_cert_authorities));
wrapper.impl_->ClientConnect(server_name, deadline);
return wrapper;
}

TlsWrapper TlsWrapper::StartTlsServer(
Socket&& socket,
const crypto::CertificatesChain& cert_chain,
const crypto::PrivateKey& key,
Deadline deadline,
const std::vector<crypto::Certificate>& extra_cert_authorities
const crypto::SslCtx& ctx,
Deadline deadline
) {
auto ssl_ctx = MakeSslCtx();

if (!extra_cert_authorities.empty()) {
AddCertAuthorities(ssl_ctx, extra_cert_authorities);
SSL_CTX_set_verify(ssl_ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
LOG_INFO() << "Client SSL cert will be verified";
} else {
LOG_INFO() << "Client SSL cert will not be verified";
}

if (cert_chain.empty()) {
throw TlsException(crypto::FormatSslError("Empty certificate chain provided"));
}

if (1 != SSL_CTX_use_certificate(ssl_ctx.get(), cert_chain.begin()->GetNative())) {
throw TlsException(crypto::FormatSslError("Failed to set up server TLS wrapper: SSL_CTX_use_certificate"));
}

if (cert_chain.size() > 1) {
auto cert_it = std::next(cert_chain.begin());
for (; cert_it != cert_chain.end(); ++cert_it) {
// cast in openssl1.0 macro expansion
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
if (SSL_CTX_add_extra_chain_cert(ssl_ctx.get(), cert_it->GetNative()) <= 0) {
throw TlsException(
crypto::FormatSslError("Failed to set up server TLS wrapper: SSL_CTX_add_extra_chain_cert")
);
}

// After SSL_CTX_add_extra_chain_cert we should not free the cert
const auto ret = X509_up_ref(cert_it->GetNative());
UASSERT(ret == 1);
}
}

if (1 != SSL_CTX_use_PrivateKey(ssl_ctx.get(), key.GetNative())) {
throw TlsException(crypto::FormatSslError("Failed to set up server TLS wrapper: SSL_CTX_use_PrivateKey"));
}

TlsWrapper wrapper{std::move(socket)};
wrapper.impl_->SetUp(std::move(ssl_ctx));
wrapper.impl_->SetUp(ctx);
wrapper.impl_->bio_data.current_deadline = deadline;

auto ret = SSL_accept(wrapper.impl_->ssl.get());
Expand Down
14 changes: 8 additions & 6 deletions core/src/engine/io/tls_wrapper_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ constexpr auto kDeadlineMaxTime = std::chrono::seconds{60};
auto [server, client] = tcp_listener.MakeSocketPair(deadline);

std::atomic<bool> reading{true};
crypto::SslCtx ssl_ctx = crypto::SslCtx::CreateServerTlsContext(crypto::LoadCertificatesChainFromString(cert),
crypto::PrivateKey::LoadFromString(key));
auto server_task = engine::AsyncNoSpan(
[&reading, deadline](auto&& server) {
[&reading, deadline, &ssl_ctx](auto&& server) {
auto tls_server = io::TlsWrapper::StartTlsServer(
std::forward<decltype(server)>(server),
crypto::LoadCertificatesChainFromString(cert),
crypto::PrivateKey::LoadFromString(key),
ssl_ctx,
deadline
);

Expand Down Expand Up @@ -137,12 +138,13 @@ BENCHMARK(tls_write_all_buffered)->RangeMultiplier(2)->Range(1 << 6, 1 << 12)->U
auto [server, client] = tcp_listener.MakeSocketPair(deadline);

std::atomic<bool> reading{true};
crypto::SslCtx ssl_ctx = crypto::SslCtx::CreateServerTlsContext(crypto::LoadCertificatesChainFromString(cert),
crypto::PrivateKey::LoadFromString(key));
auto server_task = engine::AsyncNoSpan(
[&reading, deadline](auto&& server) {
[&reading, deadline, &ssl_ctx](auto&& server) {
auto tls_server = io::TlsWrapper::StartTlsServer(
std::forward<decltype(server)>(server),
crypto::LoadCertificatesChainFromString(cert),
crypto::PrivateKey::LoadFromString(key),
ssl_ctx,
deadline
);

Expand Down
Loading