mirror of https://github.com/aria2/aria2
Merge branch 'warn-ssl3'
commit
962b8ccb05
|
@ -85,7 +85,7 @@ static inline const char* protoToString(SSLProtocol proto)
|
||||||
case kSSLProtocol2:
|
case kSSLProtocol2:
|
||||||
return "SSLv2 (!)";
|
return "SSLv2 (!)";
|
||||||
case kSSLProtocol3:
|
case kSSLProtocol3:
|
||||||
return "SSLv3";
|
return "SSLv3 (!)";
|
||||||
case kTLSProtocol1:
|
case kTLSProtocol1:
|
||||||
return "TLSv1";
|
return "TLSv1";
|
||||||
case kTLSProtocol11:
|
case kTLSProtocol11:
|
||||||
|
@ -379,6 +379,8 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
||||||
case TLS_PROTO_TLS12:
|
case TLS_PROTO_TLS12:
|
||||||
(void)SSLSetProtocolVersionMin(sslCtx_, kTLSProtocol12);
|
(void)SSLSetProtocolVersionMin(sslCtx_, kTLSProtocol12);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocolAll, false);
|
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocolAll, false);
|
||||||
|
@ -394,6 +396,8 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
||||||
// fall through
|
// fall through
|
||||||
case TLS_PROTO_TLS12:
|
case TLS_PROTO_TLS12:
|
||||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
|
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -695,6 +699,7 @@ OSStatus AppleTLSSession::sockRead(void* data, size_t* len)
|
||||||
}
|
}
|
||||||
|
|
||||||
int AppleTLSSession::tlsConnect(const std::string& hostname,
|
int AppleTLSSession::tlsConnect(const std::string& hostname,
|
||||||
|
TLSVersion& version,
|
||||||
std::string& handshakeErr)
|
std::string& handshakeErr)
|
||||||
{
|
{
|
||||||
if (state_ != st_initialized) {
|
if (state_ != st_initialized) {
|
||||||
|
@ -713,7 +718,7 @@ int AppleTLSSession::tlsConnect(const std::string& hostname,
|
||||||
return TLS_ERR_WOULDBLOCK;
|
return TLS_ERR_WOULDBLOCK;
|
||||||
|
|
||||||
case errSSLServerAuthCompleted:
|
case errSSLServerAuthCompleted:
|
||||||
return tlsConnect(hostname, handshakeErr);
|
return tlsConnect(hostname, version, handshakeErr);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
handshakeErr = getLastErrorString();
|
handshakeErr = getLastErrorString();
|
||||||
|
@ -732,13 +737,31 @@ int AppleTLSSession::tlsConnect(const std::string& hostname,
|
||||||
protoToString(proto),
|
protoToString(proto),
|
||||||
suiteToString(suite).c_str()));
|
suiteToString(suite).c_str()));
|
||||||
|
|
||||||
|
switch (proto) {
|
||||||
|
case kSSLProtocol3:
|
||||||
|
version = TLS_PROTO_SSL3;
|
||||||
|
break;
|
||||||
|
case kTLSProtocol1:
|
||||||
|
version = TLS_PROTO_TLS10;
|
||||||
|
break;
|
||||||
|
case kTLSProtocol11:
|
||||||
|
version = TLS_PROTO_TLS11;
|
||||||
|
break;
|
||||||
|
case kTLSProtocol12:
|
||||||
|
version = TLS_PROTO_TLS12;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
version = TLS_PROTO_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AppleTLSSession::tlsAccept()
|
int AppleTLSSession::tlsAccept(TLSVersion& version)
|
||||||
{
|
{
|
||||||
std::string hostname, err;
|
std::string hostname, err;
|
||||||
return tlsConnect(hostname, err);
|
return tlsConnect(hostname, version, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AppleTLSSession::getLastErrorString()
|
std::string AppleTLSSession::getLastErrorString()
|
||||||
|
|
|
@ -96,12 +96,13 @@ public:
|
||||||
// When returning TLS_ERR_ERROR, provide certificate validation error
|
// When returning TLS_ERR_ERROR, provide certificate validation error
|
||||||
// in |handshakeErr|.
|
// in |handshakeErr|.
|
||||||
virtual int tlsConnect(const std::string& hostname,
|
virtual int tlsConnect(const std::string& hostname,
|
||||||
|
TLSVersion& version,
|
||||||
std::string& handshakeErr) CXX11_OVERRIDE;
|
std::string& handshakeErr) CXX11_OVERRIDE;
|
||||||
|
|
||||||
// Performs server side handshake. This function returns TLS_ERR_OK
|
// Performs server side handshake. This function returns TLS_ERR_OK
|
||||||
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
||||||
// blocks, or TLS_ERR_ERROR.
|
// blocks, or TLS_ERR_ERROR.
|
||||||
virtual int tlsAccept() CXX11_OVERRIDE;
|
virtual int tlsAccept(TLSVersion& version) CXX11_OVERRIDE;
|
||||||
|
|
||||||
// Returns last error string
|
// Returns last error string
|
||||||
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
||||||
|
|
|
@ -40,6 +40,39 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "SocketCore.h"
|
#include "SocketCore.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace aria2;
|
||||||
|
|
||||||
|
TLSVersion getProtocolFromSession(gnutls_session_t& session) {
|
||||||
|
auto proto = gnutls_protocol_get_version(session);
|
||||||
|
switch(proto) {
|
||||||
|
case GNUTLS_SSL3:
|
||||||
|
return TLS_PROTO_SSL3;
|
||||||
|
|
||||||
|
#ifdef GNUTLS_TLS1_0
|
||||||
|
case GNUTLS_TLS1_0:
|
||||||
|
return TLS_PROTO_TLS10;
|
||||||
|
#endif // GNUTLS_TLS1_0
|
||||||
|
|
||||||
|
#ifdef GNUTLS_TLS1_1
|
||||||
|
case GNUTLS_TLS1_1:
|
||||||
|
return TLS_PROTO_TLS11;
|
||||||
|
break;
|
||||||
|
#endif // GNUTLS_TLS1_1
|
||||||
|
|
||||||
|
#ifdef GNUTLS_TLS1_2
|
||||||
|
case GNUTLS_TLS1_2:
|
||||||
|
return TLS_PROTO_TLS12;
|
||||||
|
break;
|
||||||
|
#endif // GNUTLS_TLS1_2
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TLS_PROTO_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
TLSSession* TLSSession::make(TLSContext* ctx)
|
TLSSession* TLSSession::make(TLSContext* ctx)
|
||||||
|
@ -197,7 +230,8 @@ ssize_t GnuTLSSession::readData(void* data, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
int GnuTLSSession::tlsConnect(const std::string& hostname,
|
int GnuTLSSession::tlsConnect(const std::string& hostname,
|
||||||
std::string& handshakeErr)
|
TLSVersion& version,
|
||||||
|
std::string& handshakeErr)
|
||||||
{
|
{
|
||||||
handshakeErr = "";
|
handshakeErr = "";
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -297,14 +331,18 @@ int GnuTLSSession::tlsConnect(const std::string& hostname,
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version = getProtocolFromSession(sslSession_);
|
||||||
|
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GnuTLSSession::tlsAccept()
|
int GnuTLSSession::tlsAccept(TLSVersion& version)
|
||||||
{
|
{
|
||||||
for(;;) {
|
for(;;) {
|
||||||
rv_ = gnutls_handshake(sslSession_);
|
rv_ = gnutls_handshake(sslSession_);
|
||||||
if(rv_ == GNUTLS_E_SUCCESS) {
|
if(rv_ == GNUTLS_E_SUCCESS) {
|
||||||
|
version = getProtocolFromSession(sslSession_);
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
if(rv_ == GNUTLS_E_AGAIN || rv_ == GNUTLS_E_INTERRUPTED) {
|
if(rv_ == GNUTLS_E_AGAIN || rv_ == GNUTLS_E_INTERRUPTED) {
|
||||||
|
|
|
@ -56,8 +56,9 @@ public:
|
||||||
virtual ssize_t writeData(const void* data, size_t len) CXX11_OVERRIDE;
|
virtual ssize_t writeData(const void* data, size_t len) CXX11_OVERRIDE;
|
||||||
virtual ssize_t readData(void* data, size_t len) CXX11_OVERRIDE;
|
virtual ssize_t readData(void* data, size_t len) CXX11_OVERRIDE;
|
||||||
virtual int tlsConnect
|
virtual int tlsConnect
|
||||||
(const std::string& hostname, std::string& handshakeErr) CXX11_OVERRIDE;
|
(const std::string& hostname, TLSVersion& version, std::string& handshakeErr)
|
||||||
virtual int tlsAccept() CXX11_OVERRIDE;
|
CXX11_OVERRIDE;
|
||||||
|
virtual int tlsAccept(TLSVersion& version) CXX11_OVERRIDE;
|
||||||
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
||||||
private:
|
private:
|
||||||
gnutls_session_t sslSession_;
|
gnutls_session_t sslSession_;
|
||||||
|
|
|
@ -157,7 +157,7 @@ ssize_t OpenSSLTLSSession::readData(void* data, size_t len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenSSLTLSSession::handshake()
|
int OpenSSLTLSSession::handshake(TLSVersion& version)
|
||||||
{
|
{
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
if(tlsContext_->getSide() == TLS_CLIENT) {
|
if(tlsContext_->getSide() == TLS_CLIENT) {
|
||||||
|
@ -181,15 +181,45 @@ int OpenSSLTLSSession::handshake()
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(SSL_version(ssl_)) {
|
||||||
|
case SSL3_VERSION:
|
||||||
|
version = TLS_PROTO_SSL3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef TLS1_VERSION
|
||||||
|
case TLS1_VERSION:
|
||||||
|
version = TLS_PROTO_TLS10;
|
||||||
|
break;
|
||||||
|
#endif // TLS1_VERSION
|
||||||
|
|
||||||
|
#ifdef TLS1_1_VERSION
|
||||||
|
case TLS1_1_VERSION:
|
||||||
|
version = TLS_PROTO_TLS11;
|
||||||
|
break;
|
||||||
|
#endif // TLS1_1_VERSION
|
||||||
|
|
||||||
|
#ifdef TLS1_2_VERSION
|
||||||
|
case TLS1_2_VERSION:
|
||||||
|
version = TLS_PROTO_TLS12;
|
||||||
|
break;
|
||||||
|
#endif // TLS1_2_VERSION
|
||||||
|
|
||||||
|
default:
|
||||||
|
version = TLS_PROTO_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenSSLTLSSession::tlsConnect(const std::string& hostname,
|
int OpenSSLTLSSession::tlsConnect(const std::string& hostname,
|
||||||
std::string& handshakeErr)
|
TLSVersion& version,
|
||||||
|
std::string& handshakeErr)
|
||||||
{
|
{
|
||||||
handshakeErr = "";
|
handshakeErr = "";
|
||||||
int ret;
|
int ret;
|
||||||
ret = handshake();
|
ret = handshake(version);
|
||||||
if(ret != TLS_ERR_OK) {
|
if(ret != TLS_ERR_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -267,12 +297,13 @@ int OpenSSLTLSSession::tlsConnect(const std::string& hostname,
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenSSLTLSSession::tlsAccept()
|
int OpenSSLTLSSession::tlsAccept(TLSVersion& version)
|
||||||
{
|
{
|
||||||
return handshake();
|
return handshake(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OpenSSLTLSSession::getLastErrorString()
|
std::string OpenSSLTLSSession::getLastErrorString()
|
||||||
|
|
|
@ -56,11 +56,12 @@ public:
|
||||||
virtual ssize_t writeData(const void* data, size_t len) CXX11_OVERRIDE;
|
virtual ssize_t writeData(const void* data, size_t len) CXX11_OVERRIDE;
|
||||||
virtual ssize_t readData(void* data, size_t len) CXX11_OVERRIDE;
|
virtual ssize_t readData(void* data, size_t len) CXX11_OVERRIDE;
|
||||||
virtual int tlsConnect
|
virtual int tlsConnect
|
||||||
(const std::string& hostname, std::string& handshakeErr) CXX11_OVERRIDE;
|
(const std::string& hostname, TLSVersion& version, std::string& handshakeErr)
|
||||||
virtual int tlsAccept() CXX11_OVERRIDE;
|
CXX11_OVERRIDE;
|
||||||
|
virtual int tlsAccept(TLSVersion& version) CXX11_OVERRIDE;
|
||||||
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
||||||
private:
|
private:
|
||||||
int handshake();
|
int handshake(TLSVersion& version);
|
||||||
SSL* ssl_;
|
SSL* ssl_;
|
||||||
OpenSSLTLSContext* tlsContext_;
|
OpenSSLTLSContext* tlsContext_;
|
||||||
// Last error code from openSSL library functions
|
// Last error code from openSSL library functions
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "DlRetryEx.h"
|
#include "DlRetryEx.h"
|
||||||
|
@ -830,6 +831,7 @@ bool SocketCore::tlsConnect(const std::string& hostname)
|
||||||
|
|
||||||
bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
||||||
{
|
{
|
||||||
|
TLSVersion ver = TLS_PROTO_NONE;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
std::string handshakeError;
|
std::string handshakeError;
|
||||||
wantRead_ = false;
|
wantRead_ = false;
|
||||||
|
@ -860,9 +862,9 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
||||||
// Fall through
|
// Fall through
|
||||||
case A2_TLS_HANDSHAKING:
|
case A2_TLS_HANDSHAKING:
|
||||||
if(tlsctx->getSide() == TLS_CLIENT) {
|
if(tlsctx->getSide() == TLS_CLIENT) {
|
||||||
rv = tlsSession_->tlsConnect(hostname, handshakeError);
|
rv = tlsSession_->tlsConnect(hostname, ver, handshakeError);
|
||||||
} else {
|
} else {
|
||||||
rv = tlsSession_->tlsAccept();
|
rv = tlsSession_->tlsAccept(ver);
|
||||||
}
|
}
|
||||||
if(rv == TLS_ERR_OK) {
|
if(rv == TLS_ERR_OK) {
|
||||||
secure_ = A2_TLS_CONNECTED;
|
secure_ = A2_TLS_CONNECTED;
|
||||||
|
@ -883,6 +885,30 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
if (!hostname.empty()) {
|
||||||
|
ss << hostname << " (";
|
||||||
|
}
|
||||||
|
std::pair<std::string, uint16_t> peer;
|
||||||
|
getPeerInfo(peer);
|
||||||
|
ss << peer.first << ":" << peer.second;
|
||||||
|
if (!hostname.empty()) {
|
||||||
|
ss << ")";
|
||||||
|
}
|
||||||
|
auto peerInfo = ss.str();
|
||||||
|
|
||||||
|
switch(ver) {
|
||||||
|
case TLS_PROTO_NONE:
|
||||||
|
A2_LOG_WARN(fmt(MSG_WARN_UNKNOWN_TLS_CONNECTION, peerInfo.c_str()));
|
||||||
|
break;
|
||||||
|
case TLS_PROTO_SSL3:
|
||||||
|
A2_LOG_WARN(fmt(MSG_WARN_OLD_TLS_CONNECTION, "SSLv3", peerInfo.c_str()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum TLSSessionSide {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TLSVersion {
|
enum TLSVersion {
|
||||||
|
TLS_PROTO_NONE,
|
||||||
TLS_PROTO_SSL3,
|
TLS_PROTO_SSL3,
|
||||||
TLS_PROTO_TLS10,
|
TLS_PROTO_TLS10,
|
||||||
TLS_PROTO_TLS11,
|
TLS_PROTO_TLS11,
|
||||||
|
|
|
@ -99,12 +99,13 @@ public:
|
||||||
// if the underlying transport blocks, or TLS_ERR_ERROR.
|
// if the underlying transport blocks, or TLS_ERR_ERROR.
|
||||||
// When returning TLS_ERR_ERROR, provide certificate validation error
|
// When returning TLS_ERR_ERROR, provide certificate validation error
|
||||||
// in |handshakeErr|.
|
// in |handshakeErr|.
|
||||||
virtual int tlsConnect(const std::string& hostname, std::string& handshakeErr) = 0;
|
virtual int tlsConnect(const std::string& hostname, TLSVersion& version,
|
||||||
|
std::string& handshakeErr) = 0;
|
||||||
|
|
||||||
// Performs server side handshake. This function returns TLS_ERR_OK
|
// Performs server side handshake. This function returns TLS_ERR_OK
|
||||||
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
||||||
// blocks, or TLS_ERR_ERROR.
|
// blocks, or TLS_ERR_ERROR.
|
||||||
virtual int tlsAccept() = 0;
|
virtual int tlsAccept(TLSVersion& version) = 0;
|
||||||
|
|
||||||
// Returns last error string
|
// Returns last error string
|
||||||
virtual std::string getLastErrorString() = 0;
|
virtual std::string getLastErrorString() = 0;
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
#define SCH_USE_STRONG_CRYPTO 0x00400000
|
#define SCH_USE_STRONG_CRYPTO 0x00400000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WEAK_CIPHER_BITS 56
|
||||||
|
#define STRONG_CIPHER_BITS 128
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
WinTLSContext::WinTLSContext(TLSSessionSide side, TLSVersion ver)
|
WinTLSContext::WinTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||||
|
@ -82,6 +85,9 @@ WinTLSContext::WinTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||||
// fall through
|
// fall through
|
||||||
case TLS_PROTO_TLS12:
|
case TLS_PROTO_TLS12:
|
||||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
|
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -97,9 +103,23 @@ WinTLSContext::WinTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||||
// fall through
|
// fall through
|
||||||
case TLS_PROTO_TLS12:
|
case TLS_PROTO_TLS12:
|
||||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_SERVER;
|
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_SERVER;
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
credentials_.dwMinimumCipherStrength = 128; // bit
|
|
||||||
|
switch (ver) {
|
||||||
|
case TLS_PROTO_SSL3:
|
||||||
|
// User explicitly wanted SSLv3 and therefore weak ciphers.
|
||||||
|
credentials_.dwMinimumCipherStrength = WEAK_CIPHER_BITS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Strong protocol versions: Use a minimum strength, which might be later
|
||||||
|
// refined using SCH_USE_STRONG_CRYPTO in the flags.
|
||||||
|
credentials_.dwMinimumCipherStrength = STRONG_CIPHER_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
setVerifyPeer(side_ == TLS_CLIENT);
|
setVerifyPeer(side_ == TLS_CLIENT);
|
||||||
}
|
}
|
||||||
|
@ -126,19 +146,30 @@ void WinTLSContext::setVerifyPeer(bool verify)
|
||||||
{
|
{
|
||||||
cred_.reset();
|
cred_.reset();
|
||||||
|
|
||||||
|
// Never automatically push any client or server certs. We'll do cert setup
|
||||||
|
// ourselves.
|
||||||
|
credentials_.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
|
||||||
|
|
||||||
|
if (credentials_.dwMinimumCipherStrength > WEAK_CIPHER_BITS) {
|
||||||
|
// Enable strong crypto if we already set a minimum cipher streams.
|
||||||
|
// This might actually require evem stronger algorithms, which is a good
|
||||||
|
// thing.
|
||||||
|
credentials_.dwFlags |= SCH_USE_STRONG_CRYPTO;
|
||||||
|
}
|
||||||
|
|
||||||
if (side_ != TLS_CLIENT || !verify) {
|
if (side_ != TLS_CLIENT || !verify) {
|
||||||
credentials_.dwFlags = SCH_CRED_NO_DEFAULT_CREDS |
|
// No verfication for servers and if user explicitly requested it
|
||||||
SCH_CRED_MANUAL_CRED_VALIDATION |
|
credentials_.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION |
|
||||||
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
||||||
SCH_CRED_IGNORE_REVOCATION_OFFLINE |
|
SCH_CRED_IGNORE_REVOCATION_OFFLINE |
|
||||||
SCH_CRED_NO_SERVERNAME_CHECK | SCH_USE_STRONG_CRYPTO;
|
SCH_CRED_NO_SERVERNAME_CHECK;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
credentials_.dwFlags =
|
// Verify other side's cert chain.
|
||||||
SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_AUTO_CRED_VALIDATION |
|
credentials_.dwFlags |= SCH_CRED_AUTO_CRED_VALIDATION |
|
||||||
SCH_CRED_REVOCATION_CHECK_CHAIN | SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
|
SCH_CRED_REVOCATION_CHECK_CHAIN |
|
||||||
SCH_USE_STRONG_CRYPTO;
|
SCH_CRED_IGNORE_NO_REVOCATION_CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CredHandle* WinTLSContext::getCredHandle()
|
CredHandle* WinTLSContext::getCredHandle()
|
||||||
|
|
|
@ -119,6 +119,17 @@ inline static std::string getCipherSuite(CtxtHandle* handle)
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static uint32_t getProtocolVersion(CtxtHandle* handle)
|
||||||
|
{
|
||||||
|
WinSecPkgContext_CipherInfo info = {SECPKGCONTEXT_CIPHERINFO_V1};
|
||||||
|
if (QueryContextAttributes(handle, SECPKG_ATTR_CIPHER_INFO, &info) ==
|
||||||
|
SEC_E_OK) {
|
||||||
|
return info.dwProtocol;
|
||||||
|
}
|
||||||
|
// XXX Assume the best?!
|
||||||
|
return std::numeric_limits<uint32_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
@ -272,7 +283,8 @@ ssize_t WinTLSSession::writeData(const void* data, size_t len)
|
||||||
state_ == st_handshake_read) {
|
state_ == st_handshake_read) {
|
||||||
// Renegotiating
|
// Renegotiating
|
||||||
std::string hn, err;
|
std::string hn, err;
|
||||||
auto connect = tlsConnect(hn, err);
|
TLSVersion ver;
|
||||||
|
auto connect = tlsConnect(hn, ver, err);
|
||||||
if (connect != TLS_ERR_OK) {
|
if (connect != TLS_ERR_OK) {
|
||||||
return connect;
|
return connect;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +480,8 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
state_ == st_handshake_read) {
|
state_ == st_handshake_read) {
|
||||||
// Renegotiating
|
// Renegotiating
|
||||||
std::string hn, err;
|
std::string hn, err;
|
||||||
auto connect = tlsConnect(hn, err);
|
TLSVersion ver;
|
||||||
|
auto connect = tlsConnect(hn, ver, err);
|
||||||
if (connect != TLS_ERR_OK) {
|
if (connect != TLS_ERR_OK) {
|
||||||
return connect;
|
return connect;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +561,8 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
state_ = st_initialized;
|
state_ = st_initialized;
|
||||||
A2_LOG_INFO("WinTLS: Renegotiate");
|
A2_LOG_INFO("WinTLS: Renegotiate");
|
||||||
std::string hn, err;
|
std::string hn, err;
|
||||||
auto connect = tlsConnect(hn, err);
|
TLSVersion ver;
|
||||||
|
auto connect = tlsConnect(hn, ver, err);
|
||||||
if (connect == TLS_ERR_WOULDBLOCK) {
|
if (connect == TLS_ERR_WOULDBLOCK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -579,6 +593,7 @@ ssize_t WinTLSSession::readData(void* data, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
int WinTLSSession::tlsConnect(const std::string& hostname,
|
int WinTLSSession::tlsConnect(const std::string& hostname,
|
||||||
|
TLSVersion& version,
|
||||||
std::string& handshakeErr)
|
std::string& handshakeErr)
|
||||||
{
|
{
|
||||||
// Handshaking will require sending multiple read/write exchanges until the
|
// Handshaking will require sending multiple read/write exchanges until the
|
||||||
|
@ -813,7 +828,25 @@ restart:
|
||||||
state_ = st_connected;
|
state_ = st_connected;
|
||||||
A2_LOG_INFO(
|
A2_LOG_INFO(
|
||||||
fmt("WinTLS: connected with: %s", getCipherSuite(&handle_).c_str()));
|
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;
|
||||||
|
}
|
||||||
return TLS_ERR_OK;
|
return TLS_ERR_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
A2_LOG_ERROR("WinTLS: Unreachable reached during tlsConnect! This is a bug!");
|
A2_LOG_ERROR("WinTLS: Unreachable reached during tlsConnect! This is a bug!");
|
||||||
|
@ -821,10 +854,10 @@ restart:
|
||||||
return TLS_ERR_ERROR;
|
return TLS_ERR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WinTLSSession::tlsAccept()
|
int WinTLSSession::tlsAccept(TLSVersion& version)
|
||||||
{
|
{
|
||||||
std::string host, err;
|
std::string host, err;
|
||||||
return tlsConnect(host, err);
|
return tlsConnect(host, version, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WinTLSSession::getLastErrorString()
|
std::string WinTLSSession::getLastErrorString()
|
||||||
|
|
|
@ -176,12 +176,13 @@ public:
|
||||||
// When returning TLS_ERR_ERROR, provide certificate validation error
|
// When returning TLS_ERR_ERROR, provide certificate validation error
|
||||||
// in |handshakeErr|.
|
// in |handshakeErr|.
|
||||||
virtual int tlsConnect(const std::string& hostname,
|
virtual int tlsConnect(const std::string& hostname,
|
||||||
|
TLSVersion& version,
|
||||||
std::string& handshakeErr) CXX11_OVERRIDE;
|
std::string& handshakeErr) CXX11_OVERRIDE;
|
||||||
|
|
||||||
// Performs server side handshake. This function returns TLS_ERR_OK
|
// Performs server side handshake. This function returns TLS_ERR_OK
|
||||||
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
// if it succeeds, or TLS_ERR_WOULDBLOCK if the underlying transport
|
||||||
// blocks, or TLS_ERR_ERROR.
|
// blocks, or TLS_ERR_ERROR.
|
||||||
virtual int tlsAccept() CXX11_OVERRIDE;
|
virtual int tlsAccept(TLSVersion& version) CXX11_OVERRIDE;
|
||||||
|
|
||||||
// Returns last error string
|
// Returns last error string
|
||||||
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
||||||
|
|
|
@ -183,6 +183,14 @@
|
||||||
#define MSG_WARN_NO_CA_CERT \
|
#define MSG_WARN_NO_CA_CERT \
|
||||||
_("You may encounter the certificate verification error with HTTPS server." \
|
_("You may encounter the certificate verification error with HTTPS server." \
|
||||||
" See --ca-certificate and --check-certificate option.")
|
" See --ca-certificate and --check-certificate option.")
|
||||||
|
#define MSG_WARN_UNKNOWN_TLS_CONNECTION \
|
||||||
|
_("aria2c had to connect to the other side using an unknown TLS protocol. " \
|
||||||
|
"The integrity and confidentiality of the connection might be " \
|
||||||
|
"compromised.\nPeer: %s")
|
||||||
|
#define MSG_WARN_OLD_TLS_CONNECTION \
|
||||||
|
_("aria2c had to connect to the other side using an old and vulnerable TLS" \
|
||||||
|
" protocol. The integrity and confidentiality of the connection might be" \
|
||||||
|
" compromised.\nProtocol: %s, Peer: %s")
|
||||||
#define MSG_SHOW_FILES _("Printing the contents of file '%s'...")
|
#define MSG_SHOW_FILES _("Printing the contents of file '%s'...")
|
||||||
#define MSG_NOT_TORRENT_METALINK _("This file is neither Torrent nor Metalink" \
|
#define MSG_NOT_TORRENT_METALINK _("This file is neither Torrent nor Metalink" \
|
||||||
" file. Skipping.")
|
" file. Skipping.")
|
||||||
|
|
Loading…
Reference in New Issue