More SSL stuff (still doesn't work :/).

This commit is contained in:
2024-08-27 19:52:08 +02:00
parent 0be34a845a
commit a43f92fb58
7 changed files with 156 additions and 28 deletions

View File

@@ -93,7 +93,7 @@ StreamError SSLStream::open(Stream& base, const std::string& hostname) noexcept
externalBio_ = std::move(externalBio);
base_ = &base;
if (const ossl::Error error = runIOLoop(&ossl::Ssl::connect); !error.isSuccess())
if (const ossl::Error error = runIOLoop(&ossl::Ssl::connect, true); !error.isSuccess())
{
ssl_.free();
externalBio.free();
@@ -116,7 +116,7 @@ void SSLStream::close() noexcept
{
MIJIN_ASSERT(base_ != nullptr, "SSL stream is not open.");
base_ = nullptr;
(void) runIOLoop(&ossl::Ssl::shutdown);
(void) runIOLoop(&ossl::Ssl::shutdown, true);
ssl_.free();
externalBio_.free();
}
@@ -131,7 +131,7 @@ StreamError SSLStream::writeRaw(std::span<const std::uint8_t> buffer)
std::size_t bytesToWrite = buffer.size();
while (bytesToWrite > 0)
{
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::write, buffer.data() + buffer.size() - bytesToWrite,
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::write, true, buffer.data() + buffer.size() - bytesToWrite,
static_cast<int>(bytesToWrite));
if (result.isError())
{
@@ -156,15 +156,25 @@ StreamError SSLStream::readRaw(std::span<std::uint8_t> buffer, const mijin::Read
return StreamError::SUCCESS;
}
if (const StreamError error = baseToBio(); error != StreamError::SUCCESS)
{
return error;
}
if (!options.partial && options.noBlock && static_cast<std::size_t>(ssl_.pending()) < buffer.size())
{
return StreamError::WOULD_BLOCK;
}
std::size_t bytesToRead = buffer.size();
if (options.partial)
{
bytesToRead = std::min<std::size_t>(bytesToRead, ssl_.pending());
}
while (bytesToRead > 0)
{
if (const StreamError error = baseToBio(); error != StreamError::SUCCESS)
{
return error;
}
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::read, buffer.data() + buffer.size() - bytesToRead,
const ossl::Result<int> result = runIOLoop(&ossl::Ssl::read, !options.noBlock,
buffer.data() + buffer.size() - bytesToRead,
static_cast<int>(bytesToRead));
if (result.isError())
{
@@ -216,9 +226,9 @@ StreamFeatures SSLStream::getFeatures()
.tell = false,
.seek = false,
.readOptions = {
.partial = false,
.peek = false,
.noBlock = false
.partial = true,
.peek = true,
.noBlock = true
}
};
}
@@ -247,18 +257,20 @@ StreamError SSLStream::bioToBase() noexcept
StreamError SSLStream::baseToBio() noexcept
{
std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
std::size_t toRead = externalBio_.getWriteGuarantee();
while (true)
{
std::size_t bytes = 0;
std::size_t maxBytes = std::min(BIO_BUFFER_SIZE - externalBio_.ctrlWPending(), buffer.size());
std::size_t maxBytes = std::min(toRead, buffer.size());
if (maxBytes == 0)
{
// buffer is full
return StreamError::SUCCESS;
break;
}
if (const StreamError error = base_->readRaw(buffer.data(), maxBytes,{.partial = true, .noBlock = true},
if (const StreamError error = base_->readRaw(buffer.data(), maxBytes, {.partial = true, .noBlock = true},
&bytes); error != StreamError::SUCCESS)
{
return error;
@@ -274,6 +286,13 @@ StreamError SSLStream::baseToBio() noexcept
return StreamError::UNKNOWN_ERROR;
}
MIJIN_ASSERT(result.getValue() == static_cast<int>(bytes), "BIO reported more bytes in buffer than it actually accepted?");
toRead -= bytes;
}
if (const ossl::Error error = externalBio_.flush(); !error.isSuccess())
{
return StreamError::UNKNOWN_ERROR;
}
return StreamError::SUCCESS;
}
} // namespace shiken