mirror of https://github.com/aria2/aria2
Add --min-tls-version option
The --min-tls-version option specifies minimum SSL/TLS version to enable. Possible Values: SSLv3, TLSv1, TLSv1.1, TLSv1.2 Default: TLSv1pull/311/head
parent
62fba76666
commit
73d752fb1c
|
@ -1321,6 +1321,12 @@ Advanced Options
|
|||
given URIs do not support resume. See :option:`--always-resume` option.
|
||||
Default: ``0``
|
||||
|
||||
.. option:: --min-tls-version=<VERSION>
|
||||
|
||||
Specify minimum SSL/TLS version to enable.
|
||||
Possible Values: ``SSLv3``, ``TLSv1``, ``TLSv1.1``, ``TLSv1.2``
|
||||
Default: ``TLSv1``
|
||||
|
||||
.. option:: --log-level=<LEVEL>
|
||||
|
||||
Set log level to output.
|
||||
|
|
|
@ -195,9 +195,9 @@ bool checkIdentity(const SecIdentityRef id,
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
TLSContext* TLSContext::make(TLSSessionSide side)
|
||||
TLSContext* TLSContext::make(TLSSessionSide side, TLSVersion ver)
|
||||
{
|
||||
return new AppleTLSContext(side);
|
||||
return new AppleTLSContext(side, ver);
|
||||
}
|
||||
|
||||
AppleTLSContext::~AppleTLSContext()
|
||||
|
|
|
@ -49,8 +49,8 @@ namespace aria2 {
|
|||
class AppleTLSContext : public TLSContext
|
||||
{
|
||||
public:
|
||||
AppleTLSContext(TLSSessionSide side)
|
||||
: side_(side), verifyPeer_(true), credentials_(nullptr)
|
||||
AppleTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||
: side_(side), minTLSVer_(ver), verifyPeer_(true), credentials_(nullptr)
|
||||
{}
|
||||
|
||||
virtual ~AppleTLSContext();
|
||||
|
@ -89,8 +89,14 @@ public:
|
|||
|
||||
SecIdentityRef getCredentials();
|
||||
|
||||
TLSVersion getMinTLSVersion() const
|
||||
{
|
||||
return minTLSVer_;
|
||||
}
|
||||
|
||||
private:
|
||||
TLSSessionSide side_;
|
||||
TLSVersion minTLSVer_;
|
||||
bool verifyPeer_;
|
||||
SecIdentityRef credentials_;
|
||||
|
||||
|
|
|
@ -362,14 +362,36 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
|||
return;
|
||||
}
|
||||
#if defined(__MAC_10_8)
|
||||
(void)SSLSetProtocolVersionMin(sslCtx_, kSSLProtocol3);
|
||||
switch (ctx->getMinTLSVersion()) {
|
||||
case TLS_PROTO_SSL3:
|
||||
(void)SSLSetProtocolVersionMin(sslCtx_, kSSLProtocol3);
|
||||
break;
|
||||
case TLS_PROTO_TLS10:
|
||||
(void)SSLSetProtocolVersionMin(sslCtx_, kSSLProtocol1);
|
||||
break;
|
||||
case TLS_PROTO_TLS11:
|
||||
(void)SSLSetProtocolVersionMin(sslCtx_, kSSLProtocol11);
|
||||
break;
|
||||
case TLS_PROTO_TLS12:
|
||||
(void)SSLSetProtocolVersionMin(sslCtx_, kSSLProtocol12);
|
||||
break;
|
||||
}
|
||||
(void)SSLSetProtocolVersionMax(sslCtx_, kTLSProtocol12);
|
||||
#else
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocolAll, false);
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocol3, true);
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol1, true);
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol11, true);
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
|
||||
switch (ctx->getMinTLSVersion()) {
|
||||
case TLS_PROTO_SSL3:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocol3, true);
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol1, true);
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol11, true);
|
||||
// fall through
|
||||
case TLS_PROTO_TLS12:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// BEAST
|
||||
|
|
|
@ -49,14 +49,15 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
TLSContext* TLSContext::make(TLSSessionSide side)
|
||||
TLSContext* TLSContext::make(TLSSessionSide side, TLSVersion ver)
|
||||
{
|
||||
return new GnuTLSContext(side);
|
||||
return new GnuTLSContext(side, ver);
|
||||
}
|
||||
|
||||
GnuTLSContext::GnuTLSContext(TLSSessionSide side)
|
||||
GnuTLSContext::GnuTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||
: certCred_(0),
|
||||
side_(side),
|
||||
minTLSVer_(ver),
|
||||
verifyPeer_(true)
|
||||
{
|
||||
int r = gnutls_certificate_allocate_credentials(&certCred_);
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace aria2 {
|
|||
|
||||
class GnuTLSContext : public TLSContext {
|
||||
public:
|
||||
GnuTLSContext(TLSSessionSide side);
|
||||
GnuTLSContext(TLSSessionSide side, TLSVersion ver);
|
||||
|
||||
virtual ~GnuTLSContext();
|
||||
|
||||
|
@ -79,9 +79,15 @@ public:
|
|||
|
||||
gnutls_certificate_credentials_t getCertCred() const;
|
||||
|
||||
TLSVersion getMinTLSVersion() const
|
||||
{
|
||||
return minTLSVer_;
|
||||
}
|
||||
|
||||
private:
|
||||
gnutls_certificate_credentials_t certCred_;
|
||||
TLSSessionSide side_;
|
||||
TLSVersion minTLSVer_;
|
||||
bool good_;
|
||||
bool verifyPeer_;
|
||||
};
|
||||
|
|
|
@ -107,7 +107,20 @@ int GnuTLSSession::init(sock_t sockfd)
|
|||
// It seems err is not error message, but the argument string
|
||||
// which causes syntax error.
|
||||
const char* err;
|
||||
rv_ = gnutls_priority_set_direct(sslSession_, "SECURE128:-VERS-SSL3.0", &err);
|
||||
std::string pri = "SECURE128";
|
||||
switch(tlsContext_->getMinTLSVersion()) {
|
||||
case TLS_PROTO_TLS12:
|
||||
pri += ":-VERS-TLS1.1";
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
pri += ":-VERS-TLS1.0";
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
pri += ":-VERS-SSL3.0";
|
||||
default:
|
||||
break;
|
||||
};
|
||||
rv_ = gnutls_priority_set_direct(sslSession_, pri.c_str(), &err);
|
||||
if(rv_ != GNUTLS_E_SUCCESS) {
|
||||
return TLS_ERR_ERROR;
|
||||
}
|
||||
|
|
|
@ -81,12 +81,12 @@ namespace {
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
TLSContext* TLSContext::make(TLSSessionSide side)
|
||||
TLSContext* TLSContext::make(TLSSessionSide side, TLSVersion minVer)
|
||||
{
|
||||
return new OpenSSLTLSContext(side);
|
||||
return new OpenSSLTLSContext(side, minVer);
|
||||
}
|
||||
|
||||
OpenSSLTLSContext::OpenSSLTLSContext(TLSSessionSide side)
|
||||
OpenSSLTLSContext::OpenSSLTLSContext(TLSSessionSide side, TLSVersion minVer)
|
||||
: sslCtx_(nullptr),
|
||||
side_(side),
|
||||
verifyPeer_(true)
|
||||
|
@ -100,8 +100,23 @@ OpenSSLTLSContext::OpenSSLTLSContext(TLSSessionSide side)
|
|||
ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return;
|
||||
}
|
||||
// Disable SSLv2/3 and enable all workarounds for buggy servers
|
||||
SSL_CTX_set_options(sslCtx_, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
|
||||
|
||||
long ver_opts = 0;
|
||||
switch(minVer) {
|
||||
case TLS_PROTO_TLS12:
|
||||
ver_opts |= SSL_OP_NO_TLSv1_1;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
ver_opts |= SSL_OP_NO_TLSv1;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
ver_opts |= SSL_OP_NO_SSLv3;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
// Disable SSLv2 and enable all workarounds for buggy servers
|
||||
SSL_CTX_set_options(sslCtx_, SSL_OP_ALL | SSL_OP_NO_SSLv2 | ver_opts
|
||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
| SSL_OP_SINGLE_ECDH_USE
|
||||
#endif // SSL_OP_SINGLE_ECDH_USE
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace aria2 {
|
|||
|
||||
class OpenSSLTLSContext : public TLSContext {
|
||||
public:
|
||||
OpenSSLTLSContext(TLSSessionSide side);
|
||||
OpenSSLTLSContext(TLSSessionSide side, TLSVersion minVer);
|
||||
|
||||
~OpenSSLTLSContext();
|
||||
|
||||
|
|
|
@ -188,7 +188,9 @@ int MultiUrlRequestInfo::prepare()
|
|||
}
|
||||
// We set server TLS context to the SocketCore before creating
|
||||
// DownloadEngine instance.
|
||||
std::shared_ptr<TLSContext> svTlsContext(TLSContext::make(TLS_SERVER));
|
||||
auto minTLSVer = util::toTLSVersion(option_->get(PREF_MIN_TLS_VERSION));
|
||||
std::shared_ptr<TLSContext> svTlsContext
|
||||
(TLSContext::make(TLS_SERVER, minTLSVer));
|
||||
if(!svTlsContext->addCredentialFile
|
||||
(option_->get(PREF_RPC_CERTIFICATE),
|
||||
option_->get(PREF_RPC_PRIVATE_KEY))) {
|
||||
|
@ -245,7 +247,9 @@ int MultiUrlRequestInfo::prepare()
|
|||
e_->setAuthConfigFactory(std::move(authConfigFactory));
|
||||
|
||||
#ifdef ENABLE_SSL
|
||||
std::shared_ptr<TLSContext> clTlsContext(TLSContext::make(TLS_CLIENT));
|
||||
auto minTLSVer = util::toTLSVersion(option_->get(PREF_MIN_TLS_VERSION));
|
||||
std::shared_ptr<TLSContext> clTlsContext
|
||||
(TLSContext::make(TLS_CLIENT, minTLSVer));
|
||||
if(!option_->blank(PREF_CERTIFICATE)) {
|
||||
clTlsContext->addCredentialFile(option_->get(PREF_CERTIFICATE),
|
||||
option_->get(PREF_PRIVATE_KEY));
|
||||
|
|
|
@ -584,6 +584,17 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
|||
op->setChangeOptionForReserved(true);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
#ifdef ENABLE_SSL
|
||||
{
|
||||
OptionHandler* op(new ParameterOptionHandler
|
||||
(PREF_MIN_TLS_VERSION,
|
||||
TEXT_MIN_TLS_VERSION,
|
||||
A2_V_TLS10,
|
||||
{ A2_V_SSL3, A2_V_TLS10, A2_V_TLS11, A2_V_TLS12 }));
|
||||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
#endif // ENABLE_SSL
|
||||
{
|
||||
OptionHandler* op(new BooleanOptionHandler
|
||||
(PREF_NO_CONF,
|
||||
|
|
|
@ -46,9 +46,16 @@ enum TLSSessionSide {
|
|||
TLS_SERVER
|
||||
};
|
||||
|
||||
enum TLSVersion {
|
||||
TLS_PROTO_SSL3,
|
||||
TLS_PROTO_TLS10,
|
||||
TLS_PROTO_TLS11,
|
||||
TLS_PROTO_TLS12,
|
||||
};
|
||||
|
||||
class TLSContext {
|
||||
public:
|
||||
static TLSContext* make(TLSSessionSide side);
|
||||
static TLSContext* make(TLSSessionSide side, TLSVersion minVer);
|
||||
virtual ~TLSContext() {}
|
||||
|
||||
// private key `keyfile' must be decrypted.
|
||||
|
|
|
@ -63,28 +63,50 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
WinTLSContext::WinTLSContext(TLSSessionSide side) : side_(side), store_(0)
|
||||
WinTLSContext::WinTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||
: side_(side), store_(0)
|
||||
{
|
||||
memset(&credentials_, 0, sizeof(credentials_));
|
||||
credentials_.dwVersion = SCHANNEL_CRED_VERSION;
|
||||
credentials_.grbitEnabledProtocols = 0;
|
||||
if (side_ == TLS_CLIENT) {
|
||||
credentials_.grbitEnabledProtocols =
|
||||
SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT |
|
||||
SP_PROT_TLS1_2_CLIENT;
|
||||
switch (ver) {
|
||||
case TLS_PROTO_SSL3:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_SSL3_CLIENT;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_CLIENT;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS12:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
credentials_.grbitEnabledProtocols =
|
||||
SP_PROT_SSL3_SERVER | SP_PROT_TLS1_SERVER | SP_PROT_TLS1_1_SERVER |
|
||||
SP_PROT_TLS1_2_SERVER;
|
||||
switch (ver) {
|
||||
case TLS_PROTO_SSL3:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_SSL3_SERVER;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_SERVER;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_1_SERVER;
|
||||
// fall through
|
||||
case TLS_PROTO_TLS12:
|
||||
credentials_.grbitEnabledProtocols |= SP_PROT_TLS1_2_SERVER;
|
||||
}
|
||||
}
|
||||
credentials_.dwMinimumCipherStrength = 128; // bit
|
||||
|
||||
setVerifyPeer(side_ == TLS_CLIENT);
|
||||
}
|
||||
|
||||
TLSContext* TLSContext::make(TLSSessionSide side)
|
||||
TLSContext* TLSContext::make(TLSSessionSide side, TLSVersion ver)
|
||||
{
|
||||
return new WinTLSContext(side);
|
||||
return new WinTLSContext(side, ver);
|
||||
}
|
||||
|
||||
WinTLSContext::~WinTLSContext()
|
||||
|
|
|
@ -67,7 +67,7 @@ typedef std::unique_ptr<CredHandle, cred_deleter> CredPtr;
|
|||
class WinTLSContext : public TLSContext
|
||||
{
|
||||
public:
|
||||
WinTLSContext(TLSSessionSide side);
|
||||
WinTLSContext(TLSSessionSide side, TLSVersion ver);
|
||||
|
||||
virtual ~WinTLSContext();
|
||||
|
||||
|
|
|
@ -169,6 +169,10 @@ const std::string V_ARC4("arc4");
|
|||
const std::string V_HTTP("http");
|
||||
const std::string V_HTTPS("https");
|
||||
const std::string V_FTP("ftp");
|
||||
const std::string A2_V_SSL3("SSLv3");
|
||||
const std::string A2_V_TLS10("TLSv1");
|
||||
const std::string A2_V_TLS11("TLSv1.1");
|
||||
const std::string A2_V_TLS12("TLSv1.2");
|
||||
|
||||
PrefPtr PREF_VERSION = makePref("version");
|
||||
PrefPtr PREF_HELP = makePref("help");
|
||||
|
@ -367,6 +371,8 @@ PrefPtr PREF_DSCP = makePref("dscp");
|
|||
PrefPtr PREF_PAUSE_METADATA = makePref("pause-metadata");
|
||||
// values: 1*digit
|
||||
PrefPtr PREF_RLIMIT_NOFILE = makePref("rlimit-nofile");
|
||||
// vlaues: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
||||
PrefPtr PREF_MIN_TLS_VERSION = makePref("min-tls-version");
|
||||
|
||||
/**
|
||||
* FTP related preferences
|
||||
|
|
|
@ -105,6 +105,10 @@ extern const std::string V_ARC4;
|
|||
extern const std::string V_HTTP;
|
||||
extern const std::string V_HTTPS;
|
||||
extern const std::string V_FTP;
|
||||
extern const std::string A2_V_SSL3;
|
||||
extern const std::string A2_V_TLS10;
|
||||
extern const std::string A2_V_TLS11;
|
||||
extern const std::string A2_V_TLS12;
|
||||
|
||||
extern PrefPtr PREF_VERSION;
|
||||
extern PrefPtr PREF_HELP;
|
||||
|
@ -304,6 +308,8 @@ extern PrefPtr PREF_DSCP;
|
|||
extern PrefPtr PREF_PAUSE_METADATA;
|
||||
// values: 1*digit
|
||||
extern PrefPtr PREF_RLIMIT_NOFILE;
|
||||
// vlaues: SSLv3 | TLSv1 | TLSv1.1 | TLSv1.2
|
||||
extern PrefPtr PREF_MIN_TLS_VERSION;
|
||||
|
||||
/**
|
||||
* FTP related preferences
|
||||
|
|
|
@ -1011,3 +1011,5 @@
|
|||
" and the next download waiting in queue gets\n" \
|
||||
" started. But be aware that seeding item is still\n" \
|
||||
" recognized as active download in RPC method.")
|
||||
#define TEXT_MIN_TLS_VERSION \
|
||||
_(" --min-tls-version=VERSION Specify minimum SSL/TLS version to enable.")
|
||||
|
|
17
src/util.cc
17
src/util.cc
|
@ -2009,6 +2009,23 @@ bool strless(const char* a, const char* b)
|
|||
return strcmp(a, b) < 0;
|
||||
}
|
||||
|
||||
TLSVersion toTLSVersion(const std::string& ver)
|
||||
{
|
||||
if(ver == A2_V_SSL3) {
|
||||
return TLS_PROTO_SSL3;
|
||||
}
|
||||
if(ver == A2_V_TLS10) {
|
||||
return TLS_PROTO_TLS10;
|
||||
}
|
||||
if(ver == A2_V_TLS11) {
|
||||
return TLS_PROTO_TLS11;
|
||||
}
|
||||
if(ver == A2_V_TLS12) {
|
||||
return TLS_PROTO_TLS12;
|
||||
}
|
||||
return TLS_PROTO_TLS10;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -64,6 +64,10 @@
|
|||
#include "fmt.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#ifdef ENABLE_SSL
|
||||
#include "TLSContext.h"
|
||||
#endif // ENABLE_SSL
|
||||
|
||||
#ifndef HAVE_SIGACTION
|
||||
# define sigset_t int
|
||||
#endif // HAVE_SIGACTION
|
||||
|
@ -880,6 +884,8 @@ bool noProxyDomainMatch(const std::string& hostname, const std::string& domain);
|
|||
// Checks hostname matches pattern as described in RFC 6125.
|
||||
bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname);
|
||||
|
||||
TLSVersion toTLSVersion(const std::string& ver);
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace aria2
|
||||
|
|
Loading…
Reference in New Issue