mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 04:02:15 +02:00
Implement tls-cipher and tls-ciphersuite
Signed-off-by: Arne Schwabe <arne@openvpn.net>
This commit is contained in:
parent
fa5f0f0b02
commit
6e463ca1f4
@ -442,6 +442,8 @@ namespace openvpn {
|
||||
int default_key_direction = -1;
|
||||
std::string tls_version_min_override;
|
||||
std::string tls_cert_profile_override;
|
||||
std::string tls_cipher_list;
|
||||
std::string tls_ciphersuite_list;
|
||||
std::string gui_version;
|
||||
std::string sso_methods;
|
||||
bool allow_local_lan_access;
|
||||
@ -697,6 +699,8 @@ namespace openvpn {
|
||||
state->default_key_direction = config.defaultKeyDirection;
|
||||
state->tls_version_min_override = config.tlsVersionMinOverride;
|
||||
state->tls_cert_profile_override = config.tlsCertProfileOverride;
|
||||
state->tls_cipher_list = config.tlsCipherList;
|
||||
state->tls_ciphersuite_list = config.tlsCiphersuitesList;
|
||||
state->allow_local_lan_access = config.allowLocalLanAccess;
|
||||
state->gui_version = config.guiVersion;
|
||||
state->sso_methods = config.ssoMethods;
|
||||
@ -978,6 +982,8 @@ namespace openvpn {
|
||||
cc.default_key_direction = state->default_key_direction;
|
||||
cc.tls_version_min_override = state->tls_version_min_override;
|
||||
cc.tls_cert_profile_override = state->tls_cert_profile_override;
|
||||
cc.tls_cipher_list = state->tls_cipher_list;
|
||||
cc.tls_ciphersuite_list = state->tls_ciphersuite_list;
|
||||
cc.gui_version = state->gui_version;
|
||||
cc.sso_methods = state->sso_methods;
|
||||
cc.hw_addr_override = state->hw_addr_override;
|
||||
|
@ -277,6 +277,13 @@ namespace openvpn {
|
||||
// doesn't specify tls-cert-profile
|
||||
std::string tlsCertProfileOverride;
|
||||
|
||||
// Overrides the list of tls ciphers like the tls-cipher option
|
||||
std::string tlsCipherList;
|
||||
|
||||
// Overrides the list of TLS 1.3 ciphersuites like the tls-ciphersuites
|
||||
// option
|
||||
std::string tlsCiphersuitesList;
|
||||
|
||||
// Pass custom key/value pairs to OpenVPN server.
|
||||
std::vector<KeyValue> peerInfo;
|
||||
|
||||
|
@ -149,6 +149,8 @@ namespace openvpn {
|
||||
bool allow_local_lan_access = false;
|
||||
std::string tls_version_min_override;
|
||||
std::string tls_cert_profile_override;
|
||||
std::string tls_cipher_list;
|
||||
std::string tls_ciphersuite_list;
|
||||
PeerInfo::Set::Ptr extra_peer_info;
|
||||
#ifdef OPENVPN_GREMLIN
|
||||
Gremlin::Config::Ptr gremlin_config;
|
||||
@ -729,6 +731,8 @@ namespace openvpn {
|
||||
cc->load(opt, lflags);
|
||||
cc->set_tls_version_min_override(config.tls_version_min_override);
|
||||
cc->set_tls_cert_profile_override(config.tls_cert_profile_override);
|
||||
cc->set_tls_cipher_list(config.tls_cipher_list);
|
||||
cc->set_tls_ciphersuite_list(config.tls_ciphersuite_list);
|
||||
if (!cc->get_mode().is_client())
|
||||
throw option_error("only client configuration supported");
|
||||
|
||||
|
@ -404,6 +404,17 @@ namespace openvpn {
|
||||
tls_cert_profile = type;
|
||||
}
|
||||
|
||||
virtual void set_tls_cipher_list(const std::string& override)
|
||||
{
|
||||
if(!override.empty())
|
||||
tls_cipher_list = override;
|
||||
}
|
||||
|
||||
virtual void set_tls_ciphersuite_list(const std::string& override)
|
||||
{
|
||||
// mbed TLS does not have TLS 1.3 support
|
||||
}
|
||||
|
||||
virtual void set_tls_cert_profile_override(const std::string& override)
|
||||
{
|
||||
TLSCertProfile::apply_override(tls_cert_profile, override);
|
||||
@ -549,6 +560,10 @@ namespace openvpn {
|
||||
// parse tls-cert-profile
|
||||
tls_cert_profile = TLSCertProfile::parse_tls_cert_profile(opt, relay_prefix);
|
||||
|
||||
// Overrides for tls cipher suites
|
||||
if (opt.exists("tls-cipher"))
|
||||
tls_cipher_list = opt.get_optional("tls-cipher", 1, 256);
|
||||
|
||||
// unsupported cert verification options
|
||||
{
|
||||
}
|
||||
@ -613,6 +628,7 @@ namespace openvpn {
|
||||
VerifyX509Name verify_x509_name; // --verify-x509-name feature
|
||||
TLSVersion::Type tls_version_min; // minimum TLS version that we will negotiate
|
||||
TLSCertProfile::Type tls_cert_profile;
|
||||
std::string tls_cipher_list;
|
||||
X509Track::ConfigSet x509_track_config;
|
||||
bool local_cert_enabled;
|
||||
bool allow_name_constraints;
|
||||
@ -835,7 +851,14 @@ namespace openvpn {
|
||||
// in mbed TLS config.h.
|
||||
mbedtls_ssl_conf_renegotiation(sslconf, MBEDTLS_SSL_RENEGOTIATION_DISABLED);
|
||||
|
||||
mbedtls_ssl_conf_ciphersuites(sslconf, mbedtls_ctx_private::ciphersuites);
|
||||
if (!c.tls_cipher_list.empty())
|
||||
{
|
||||
set_mbedtls_cipherlist(c.tls_cipher_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_conf_ciphersuites(sslconf, mbedtls_ctx_private::ciphersuites);
|
||||
}
|
||||
|
||||
// set CA chain
|
||||
if (c.ca_chain)
|
||||
@ -935,9 +958,44 @@ namespace openvpn {
|
||||
}
|
||||
|
||||
mbedtls_ssl_config *sslconf; // SSL configuration parameters for SSL connection object
|
||||
std::unique_ptr<int[]> allowed_ciphers; //! Hold the array that is used for setting the allowed ciphers
|
||||
// must have the same lifetime as sslconf
|
||||
MbedTLSContext *parent;
|
||||
|
||||
private:
|
||||
|
||||
void set_mbedtls_cipherlist(const std::string& cipher_list)
|
||||
{
|
||||
auto num_ciphers = std::count(cipher_list.begin(), cipher_list.end(), ':') + 1;
|
||||
|
||||
allowed_ciphers.reset(new int[num_ciphers+1]);
|
||||
|
||||
std::stringstream cipher_list_ss(cipher_list);
|
||||
std::string ciphersuite;
|
||||
|
||||
int i=0;
|
||||
while(std::getline(cipher_list_ss, ciphersuite, ':'))
|
||||
{
|
||||
auto cipher_id = mbedtls_ssl_get_ciphersuite_id(ciphersuite.c_str());
|
||||
if (cipher_id != 0)
|
||||
{
|
||||
allowed_ciphers[i] = cipher_id;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* OpenVPN 2.x ignores silently ignores unknown cipher suites with
|
||||
* mbed TLS. We warn about them in OpenVPN 3.x */
|
||||
OPENVPN_LOG_SSL("mbed TLS -- warning ignoring unknown cipher suite '"
|
||||
<< ciphersuite << "' in tls-cipher");
|
||||
}
|
||||
}
|
||||
|
||||
// Last element needs to be null
|
||||
allowed_ciphers[i] = 0;
|
||||
mbedtls_ssl_conf_ciphersuites(sslconf, allowed_ciphers.get());
|
||||
}
|
||||
|
||||
// cleartext read callback
|
||||
static int ct_read_func(void *arg, unsigned char *data, size_t length)
|
||||
{
|
||||
@ -986,6 +1044,7 @@ namespace openvpn {
|
||||
ssl = nullptr;
|
||||
sslconf = nullptr;
|
||||
overflow = false;
|
||||
allowed_ciphers = nullptr;
|
||||
}
|
||||
|
||||
void erase()
|
||||
|
@ -282,6 +282,18 @@ namespace openvpn {
|
||||
TLSCertProfile::apply_override(tls_cert_profile, override);
|
||||
}
|
||||
|
||||
virtual void set_tls_cipher_list(const std::string& override)
|
||||
{
|
||||
if(!override.empty())
|
||||
tls_cipher_list = override;
|
||||
}
|
||||
|
||||
virtual void set_tls_ciphersuite_list(const std::string& override)
|
||||
{
|
||||
if(!override.empty())
|
||||
tls_ciphersuite_list = override;
|
||||
}
|
||||
|
||||
void set_local_cert_enabled(const bool v) override
|
||||
{
|
||||
local_cert_enabled = v;
|
||||
@ -412,6 +424,13 @@ namespace openvpn {
|
||||
// parse tls-cert-profile
|
||||
tls_cert_profile = TLSCertProfile::parse_tls_cert_profile(opt, relay_prefix);
|
||||
|
||||
// Overrides for tls cipher suites
|
||||
if (opt.exists("tls-cipher"))
|
||||
tls_cipher_list = opt.get_optional("tls-cipher", 1, 256);
|
||||
|
||||
if (opt.exists("tls-ciphersuites"))
|
||||
tls_ciphersuite_list = opt.get_optional("tls-ciphersuites", 1, 256);
|
||||
|
||||
// unsupported cert checkers
|
||||
{
|
||||
}
|
||||
@ -554,6 +573,8 @@ namespace openvpn {
|
||||
VerifyX509Name verify_x509_name; // --verify-x509-name feature
|
||||
TLSVersion::Type tls_version_min{TLSVersion::UNDEF}; // minimum TLS version that we will negotiate
|
||||
TLSCertProfile::Type tls_cert_profile{TLSCertProfile::UNDEF};
|
||||
std::string tls_cipher_list;
|
||||
std::string tls_ciphersuite_list
|
||||
X509Track::ConfigSet x509_track_config;
|
||||
bool local_cert_enabled = true;
|
||||
bool client_session_tickets = false;
|
||||
@ -1079,25 +1100,37 @@ namespace openvpn {
|
||||
#endif
|
||||
SSL_CTX_set_options(ctx, sslopt);
|
||||
|
||||
#if defined(TLS1_3_VERSION)
|
||||
if (!config->tls_ciphersuite_list.empty())
|
||||
{
|
||||
if(!SSL_CTX_set_ciphersuites(ctx, config->tls_ciphersuite_list.c_str()))
|
||||
OPENVPN_THROW(ssl_context_error, "OpenSSLContext: SSL_CTX_set_ciphersuites_list failed");
|
||||
}
|
||||
#endif
|
||||
const char* tls_cipher_list =
|
||||
/* default list as a basis */
|
||||
"DEFAULT"
|
||||
/* Disable export ciphers, low and medium */
|
||||
":!EXP:!LOW:!MEDIUM"
|
||||
/* Disable static (EC)DH keys (no forward secrecy) */
|
||||
":!kDH:!kECDH"
|
||||
/* Disable DSA private keys */
|
||||
":!DSS"
|
||||
/* Disable RC4 cipher */
|
||||
":!RC4"
|
||||
/* Disable MD5 */
|
||||
":!MD5"
|
||||
/* Disable unsupported TLS modes */
|
||||
":!PSK:!SRP:!kRSA"
|
||||
/* Disable SSLv2 cipher suites*/
|
||||
":!SSLv2";
|
||||
|
||||
if (!SSL_CTX_set_cipher_list(ctx,
|
||||
/* default list as a basis */
|
||||
"DEFAULT"
|
||||
/* Disable export ciphers, low and medium */
|
||||
":!EXP:!LOW:!MEDIUM"
|
||||
/* Disable static (EC)DH keys (no forward secrecy) */
|
||||
":!kDH:!kECDH"
|
||||
/* Disable DSA private keys */
|
||||
":!DSS"
|
||||
/* Disable RC4 cipher */
|
||||
":!RC4"
|
||||
/* Disable MD5 */
|
||||
":!MD5"
|
||||
/* Disable unsupported TLS modes */
|
||||
":!PSK:!SRP:!kRSA"
|
||||
/* Disable SSLv2 cipher suites*/
|
||||
":!SSLv2"
|
||||
))
|
||||
if (!config->tls_cipher_list.empty())
|
||||
{
|
||||
tls_cipher_list = config->tls_cipher_list.c_str();
|
||||
}
|
||||
|
||||
if (!SSL_CTX_set_cipher_list(ctx, tls_cipher_list))
|
||||
OPENVPN_THROW(ssl_context_error, "OpenSSLContext: SSL_CTX_set_cipher_list failed");
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
SSL_CTX_set_ecdh_auto(ctx, 1); // this method becomes a no-op in OpenSSL 1.1
|
||||
|
Loading…
Reference in New Issue
Block a user