diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/openssl/method | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/openssl/method')
-rw-r--r-- | library/cpp/openssl/method/io.cpp | 122 | ||||
-rw-r--r-- | library/cpp/openssl/method/io.h | 31 | ||||
-rw-r--r-- | library/cpp/openssl/method/ut/io_ut.cpp | 52 | ||||
-rw-r--r-- | library/cpp/openssl/method/ut/ya.make | 9 | ||||
-rw-r--r-- | library/cpp/openssl/method/ya.make | 14 |
5 files changed, 228 insertions, 0 deletions
diff --git a/library/cpp/openssl/method/io.cpp b/library/cpp/openssl/method/io.cpp new file mode 100644 index 0000000000..d184b6456c --- /dev/null +++ b/library/cpp/openssl/method/io.cpp @@ -0,0 +1,122 @@ +#include "io.h" + +#include <util/generic/singleton.h> +#include <util/generic/yexception.h> +#include <util/system/compiler.h> +#include <util/system/yassert.h> + +namespace { + using NOpenSSL::TAbstractIO; + + TAbstractIO* IO(BIO* bio) noexcept { + void* ptr = BIO_get_data(bio); + Y_VERIFY(ptr); + return static_cast<TAbstractIO*>(ptr); + } + + template<class T, class Callable, class... Args> + T ExceptionBoundary(BIO* bio, Callable&& f, T err, Args&&... args) noexcept { + try { + return (IO(bio)->*f)(args...); + } catch (...) { + return err; + } + } + + int Write(BIO* bio, const char* data, int dlen) noexcept { + return ExceptionBoundary(bio, &TAbstractIO::WriteOld, -1, data, dlen); + } + + int Read(BIO* bio, char* data, int dlen) noexcept { + return ExceptionBoundary(bio, &TAbstractIO::ReadOld, -1, data, dlen); + } + + int Puts(BIO* bio, const char* buf) noexcept { + return ExceptionBoundary(bio, &TAbstractIO::Puts, -1, buf); + } + + int Gets(BIO* bio, char* buf, int size) noexcept { + return ExceptionBoundary(bio, &TAbstractIO::Gets, -1, buf, size); + } + + long Ctrl(BIO* bio, int cmd, long larg, void* parg) noexcept { + return ExceptionBoundary(bio, &TAbstractIO::Ctrl, -1, cmd, larg, parg); + } + + int Create(BIO* bio) noexcept { + BIO_set_data(bio, nullptr); + BIO_set_init(bio, 1); + return 1; + } + + int Destroy(BIO* bio) noexcept { + BIO_set_data(bio, nullptr); + BIO_set_init(bio, 0); + return 1; + } + + NOpenSSL::TBioMethod* Method() { + return SingletonWithPriority<NOpenSSL::TBioMethod, 32768>( + BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, + "AbstractIO", + Write, + Read, + Puts, + Gets, + Ctrl, + Create, + Destroy, + nullptr + ); + } +} + +namespace NOpenSSL { + + TAbstractIO::TAbstractIO() + : Bio(BIO_new(*Method())) { + if (Y_UNLIKELY(!Bio)) { + throw std::bad_alloc(); + } + BIO_set_data(Bio, this); + } + + TAbstractIO::~TAbstractIO() { + BIO_free(Bio); + } + + int TAbstractIO::WriteOld(const char* data, int dlen) { + size_t written = 0; + + int ret = Write(data, dlen, &written); + if (ret <= 0) { + return ret; + } + + return written; + } + + int TAbstractIO::ReadOld(char* data, int dlen) { + size_t readbytes = 0; + + int ret = Read(data, dlen, &readbytes); + if (ret <= 0) { + return ret; + } + + return readbytes; + } + + long TAbstractIO::Ctrl(int cmd, long larg, void* parg) { + Y_UNUSED(larg); + Y_UNUSED(parg); + + if (cmd == BIO_CTRL_FLUSH) { + Flush(); + return 1; + } + + return 0; + } + +} // namespace NOpenSSL diff --git a/library/cpp/openssl/method/io.h b/library/cpp/openssl/method/io.h new file mode 100644 index 0000000000..f1d3df978d --- /dev/null +++ b/library/cpp/openssl/method/io.h @@ -0,0 +1,31 @@ +#pragma once + +#include <library/cpp/openssl/holders/bio.h> + +namespace NOpenSSL { + +class TAbstractIO { +public: + TAbstractIO(); + virtual ~TAbstractIO(); + + virtual int Write(const char* data, size_t dlen, size_t* written) = 0; + virtual int Read(char* data, size_t dlen, size_t* readbytes) = 0; + virtual int Puts(const char* buf) = 0; + virtual int Gets(char* buf, int size) = 0; + + virtual long Ctrl(int cmd, long larg, void* parg); + virtual void Flush() = 0; + + int WriteOld(const char* data, int dlen); + int ReadOld(char* data, int dlen); + + inline operator BIO* () noexcept { + return Bio; + } + +private: + BIO* Bio; +}; + +} // namespace NOpenSSL diff --git a/library/cpp/openssl/method/ut/io_ut.cpp b/library/cpp/openssl/method/ut/io_ut.cpp new file mode 100644 index 0000000000..bff2b23d31 --- /dev/null +++ b/library/cpp/openssl/method/ut/io_ut.cpp @@ -0,0 +1,52 @@ +#include <library/cpp/openssl/method/io.h> + +#include <library/cpp/testing/unittest/registar.h> + +class TTestIO : public NOpenSSL::TAbstractIO { +public: + int Write(const char* data, size_t dlen, size_t* written) override { + Y_UNUSED(data); + *written = dlen; + return 1; + } + + int Read(char* data, size_t dlen, size_t* readbytes) override { + Y_UNUSED(data); + Y_UNUSED(dlen); + *readbytes = 0; + return 0; + } + + int Puts(const char* buf) override { + if (buf == nullptr) { + return 0; + } + + return strlen(buf); + } + + int Gets(char* buf, int size) override { + Y_UNUSED(buf); + Y_UNUSED(size); + return 0; + } + + void Flush() override { + + } +}; + +Y_UNIT_TEST_SUITE(IO) { + Y_UNIT_TEST(AbstractIO) { + static const char s[] = "12345"; + + TTestIO test; + + UNIT_ASSERT(BIO_write(test, s, sizeof(s)) == sizeof(s)); + UNIT_ASSERT(BIO_puts(test, s) == strlen(s)); + + char buf[128]; + UNIT_ASSERT(BIO_read(test, buf, sizeof(buf)) == 0); + UNIT_ASSERT(BIO_gets(test, buf, sizeof(buf)) == 0); + } +} diff --git a/library/cpp/openssl/method/ut/ya.make b/library/cpp/openssl/method/ut/ya.make new file mode 100644 index 0000000000..3645ad17e6 --- /dev/null +++ b/library/cpp/openssl/method/ut/ya.make @@ -0,0 +1,9 @@ +UNITTEST_FOR(library/cpp/openssl/method) + +OWNER(somov deshevoy) + +SRCS( + io_ut.cpp +) + +END() diff --git a/library/cpp/openssl/method/ya.make b/library/cpp/openssl/method/ya.make new file mode 100644 index 0000000000..c8f6f18b6b --- /dev/null +++ b/library/cpp/openssl/method/ya.make @@ -0,0 +1,14 @@ +LIBRARY() + +OWNER(somov deshevoy) + +PEERDIR( + contrib/libs/openssl + library/cpp/openssl/holders +) + +SRCS( + io.cpp +) + +END() |