summaryrefslogtreecommitdiff
path: root/src/WinTLSSession.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/WinTLSSession.cc')
-rw-r--r--src/WinTLSSession.cc178
1 files changed, 63 insertions, 115 deletions
diff --git a/src/WinTLSSession.cc b/src/WinTLSSession.cc
index 66e82803..8f916657 100644
--- a/src/WinTLSSession.cc
+++ b/src/WinTLSSession.cc
@@ -60,8 +60,7 @@
namespace {
using namespace aria2;
-struct WinSecPkgContext_CipherInfo
-{
+struct WinSecPkgContext_CipherInfo {
DWORD dwVersion;
DWORD dwProtocol;
DWORD dwCipherSuite;
@@ -87,8 +86,7 @@ static const ULONG kReqAFlags =
ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT | ASC_REQ_CONFIDENTIALITY |
ASC_REQ_EXTENDED_ERROR | ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_STREAM;
-class TLSBuffer : public ::SecBuffer
-{
+class TLSBuffer : public ::SecBuffer {
public:
explicit TLSBuffer(ULONG type, ULONG size, void* data)
{
@@ -98,8 +96,7 @@ public:
}
};
-class TLSBufferDesc : public ::SecBufferDesc
-{
+class TLSBufferDesc : public ::SecBufferDesc {
public:
explicit TLSBufferDesc(SecBuffer* arr, ULONG buffers)
{
@@ -140,12 +137,12 @@ TLSSession* TLSSession::make(TLSContext* ctx)
}
WinTLSSession::WinTLSSession(WinTLSContext* ctx)
- : sockfd_(0),
- side_(ctx->getSide()),
- cred_(ctx->getCredHandle()),
- writeBuffered_(0),
- state_(st_constructed),
- status_(SEC_E_OK)
+ : sockfd_(0),
+ side_(ctx->getSide()),
+ cred_(ctx->getCredHandle()),
+ writeBuffered_(0),
+ state_(st_constructed),
+ status_(SEC_E_OK)
{
memset(&handle_, 0, sizeof(handle_));
}
@@ -205,32 +202,16 @@ int WinTLSSession::closeConnection()
TLSBufferDesc desc(&ctx, 1);
ULONG flags = 0;
if (side_ == TLS_CLIENT) {
- SEC_CHAR* host = hostname_.empty() ?
- nullptr :
- const_cast<SEC_CHAR*>(hostname_.c_str());
- status_ = ::InitializeSecurityContext(cred_,
- &handle_,
- host,
- kReqFlags,
- 0,
- 0,
- nullptr,
- 0,
- &handle_,
- &desc,
- &flags,
- nullptr);
+ SEC_CHAR* host = hostname_.empty()
+ ? nullptr
+ : const_cast<SEC_CHAR*>(hostname_.c_str());
+ status_ = ::InitializeSecurityContext(cred_, &handle_, host, kReqFlags, 0,
+ 0, nullptr, 0, &handle_, &desc,
+ &flags, nullptr);
}
else {
- status_ = ::AcceptSecurityContext(cred_,
- &handle_,
- nullptr,
- kReqAFlags,
- 0,
- &handle_,
- &desc,
- &flags,
- nullptr);
+ status_ = ::AcceptSecurityContext(cred_, &handle_, nullptr, kReqAFlags, 0,
+ &handle_, &desc, &flags, nullptr);
}
if (status_ == SEC_E_OK || status_ == SEC_I_CONTEXT_EXPIRED) {
size_t len = ctx.cbBuffer;
@@ -300,8 +281,7 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
}
A2_LOG_DEBUG(fmt("WinTLS: Write request: %" PRIu64 " buffered: %" PRIu64,
- (uint64_t)len,
- (uint64_t)writeBuf_.size()));
+ (uint64_t)len, (uint64_t)writeBuf_.size()));
// Write remaining buffered data, if any.
size_t written = 0;
@@ -331,8 +311,8 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
if (!streamSizes_) {
streamSizes_.reset(new SecPkgContext_StreamSizes());
- status_ = ::QueryContextAttributes(
- &handle_, SECPKG_ATTR_STREAM_SIZES, streamSizes_.get());
+ status_ = ::QueryContextAttributes(&handle_, SECPKG_ATTR_STREAM_SIZES,
+ streamSizes_.get());
if (status_ != SEC_E_OK || !streamSizes_->cbMaximumMessage) {
state_ = st_error;
return TLS_ERR_ERROR;
@@ -372,10 +352,9 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
auto buf = make_unique<char[]>(dl);
TLSBuffer buffers[] = {
TLSBuffer(SECBUFFER_STREAM_HEADER, streamSizes_->cbHeader, buf.get()),
- TLSBuffer(
- SECBUFFER_DATA, writeBuffered_, buf.get() + streamSizes_->cbHeader),
- TLSBuffer(SECBUFFER_STREAM_TRAILER,
- streamSizes_->cbTrailer,
+ TLSBuffer(SECBUFFER_DATA, writeBuffered_,
+ buf.get() + streamSizes_->cbHeader),
+ TLSBuffer(SECBUFFER_STREAM_TRAILER, streamSizes_->cbTrailer,
buf.get() + streamSizes_->cbHeader + writeBuffered_),
TLSBuffer(SECBUFFER_EMPTY, 0, nullptr),
};
@@ -440,8 +419,7 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
}
A2_LOG_DEBUG(fmt("WinTLS: Write result: %" PRIu64 " buffered: %" PRIu64,
- (uint64_t)len,
- (uint64_t)writeBuf_.size()));
+ (uint64_t)len, (uint64_t)writeBuf_.size()));
if (!len) {
return TLS_ERR_WOULDBLOCK;
}
@@ -451,8 +429,7 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
ssize_t WinTLSSession::readData(void* data, size_t len)
{
A2_LOG_DEBUG(fmt("WinTLS: Read request: %" PRIu64 " buffered: %" PRIu64,
- (uint64_t)len,
- (uint64_t)readBuf_.size()));
+ (uint64_t)len, (uint64_t)readBuf_.size()));
if (len == 0) {
return 0;
}
@@ -595,8 +572,7 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
return len;
}
-int WinTLSSession::tlsConnect(const std::string& hostname,
- TLSVersion& version,
+int WinTLSSession::tlsConnect(const std::string& hostname, TLSVersion& version,
std::string& handshakeErr)
{
// Handshaking will require sending multiple read/write exchanges until the
@@ -630,17 +606,8 @@ restart:
TLSBufferDesc desc(&buf, 1);
SEC_CHAR* host =
hostname_.empty() ? nullptr : const_cast<SEC_CHAR*>(hostname_.c_str());
- status_ = ::InitializeSecurityContext(cred_,
- nullptr,
- host,
- kReqFlags,
- 0,
- 0,
- nullptr,
- 0,
- &handle_,
- &desc,
- &flags,
+ status_ = ::InitializeSecurityContext(cred_, nullptr, host, kReqFlags, 0, 0,
+ nullptr, 0, &handle_, &desc, &flags,
nullptr);
if (status_ != SEC_I_CONTINUE_NEEDED) {
// Has to be SEC_I_CONTINUE_NEEDED, as we did not actually send data
@@ -741,38 +708,23 @@ restart:
};
TLSBufferDesc indesc(inbufs, 2);
TLSBuffer outbufs[] = {
- TLSBuffer(SECBUFFER_TOKEN, 0, nullptr),
- TLSBuffer(SECBUFFER_ALERT, 0, nullptr),
+ TLSBuffer(SECBUFFER_TOKEN, 0, nullptr),
+ TLSBuffer(SECBUFFER_ALERT, 0, nullptr),
};
TLSBufferDesc outdesc(outbufs, 2);
if (side_ == TLS_CLIENT) {
- SEC_CHAR* host = hostname_.empty() ?
- nullptr :
- const_cast<SEC_CHAR*>(hostname_.c_str());
- status_ = ::InitializeSecurityContext(cred_,
- &handle_,
- host,
- kReqFlags,
- 0,
- 0,
- &indesc,
- 0,
- nullptr,
- &outdesc,
- &flags,
- nullptr);
+ SEC_CHAR* host = hostname_.empty()
+ ? nullptr
+ : const_cast<SEC_CHAR*>(hostname_.c_str());
+ status_ = ::InitializeSecurityContext(cred_, &handle_, host, kReqFlags, 0,
+ 0, &indesc, 0, nullptr, &outdesc,
+ &flags, nullptr);
}
else {
- status_ =
- ::AcceptSecurityContext(cred_,
- state_ == st_initialized ? nullptr : &handle_,
- &indesc,
- kReqAFlags,
- 0,
- state_ == st_initialized ? &handle_ : nullptr,
- &outdesc,
- &flags,
- nullptr);
+ status_ = ::AcceptSecurityContext(
+ cred_, state_ == st_initialized ? nullptr : &handle_, &indesc,
+ kReqAFlags, 0, state_ == st_initialized ? &handle_ : nullptr,
+ &outdesc, &flags, nullptr);
}
if (status_ == SEC_E_INCOMPLETE_MESSAGE) {
// Not enough raw bytes read yet to decode a full message.
@@ -811,8 +763,7 @@ restart:
A2_LOG_ERROR(fmt("WinTLS: Channel setup failed. Schannel provider did "
"not fulfill requested flags. "
"Excepted: %lu Actual: %lu",
- kReqFlags,
- flags));
+ kReqFlags, flags));
status_ = SEC_E_INTERNAL_ERROR;
state_ = st_error;
return TLS_ERR_ERROR;
@@ -832,24 +783,23 @@ restart:
A2_LOG_INFO(
fmt("WinTLS: connected with: %s", getCipherSuite(&handle_).c_str()));
switch (getProtocolVersion(&handle_)) {
- case 0x300:
- version = TLS_PROTO_SSL3;
- break;
- case 0x301:
- version = TLS_PROTO_TLS10;
- break;
- case 0x302:
- version = TLS_PROTO_TLS11;
- break;
- case 0x303:
- version = TLS_PROTO_TLS12;
- break;
- default:
- version = TLS_PROTO_NONE;
- break;
+ case 0x300:
+ version = TLS_PROTO_SSL3;
+ break;
+ case 0x301:
+ version = TLS_PROTO_TLS10;
+ break;
+ case 0x302:
+ version = TLS_PROTO_TLS11;
+ break;
+ case 0x303:
+ version = TLS_PROTO_TLS12;
+ break;
+ default:
+ version = TLS_PROTO_NONE;
+ break;
}
return TLS_ERR_OK;
-
}
A2_LOG_ERROR("WinTLS: Unreachable reached during tlsConnect! This is a bug!");
@@ -867,15 +817,11 @@ std::string WinTLSSession::getLastErrorString()
{
std::stringstream ss;
wchar_t* buf = nullptr;
- auto rv = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
- status_,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPWSTR) & buf,
- 1024,
- nullptr);
+ auto rv = FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, status_, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buf,
+ 1024, nullptr);
if (rv && buf) {
ss << "Error: " << wCharToUtf8(buf) << "(" << std::hex << status_ << ")";
LocalFree(buf);
@@ -886,4 +832,6 @@ std::string WinTLSSession::getLastErrorString()
return ss.str();
}
+size_t WinTLSSession::getRecvBufferedLength() { return decBuf_.size(); }
+
} // namespace aria2