"key" renamed to "cert_key", added "protocols", "ciphers", "ciphersuites", "dhparam" options.

This commit is contained in:
XMRig
2018-10-26 22:33:00 +07:00
parent 4981dc3444
commit 00faf6769c
5 changed files with 222 additions and 13 deletions

View File

@@ -25,7 +25,6 @@
#define XMRIG_STRING_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -27,15 +27,28 @@
#include "rapidjson/document.h"
xmrig::TlsConfig::TlsConfig()
xmrig::TlsConfig::TlsConfig() :
m_protocols(0)
{
}
xmrig::TlsConfig::TlsConfig(const rapidjson::Value &object)
/**
* "cert" load TLS certificate chain from file.
* "cert_key" load TLS private key from file.
* "ciphers" set list of available ciphers (TLSv1.2 and below).
* "ciphersuites" set list of available TLSv1.3 ciphersuites.
* "dhparam" load DH parameters for DHE ciphers from file.
*/
xmrig::TlsConfig::TlsConfig(const rapidjson::Value &object) :
m_protocols(0)
{
setProtocols(object["protocols"]);
setCert(object["cert"].GetString());
setKey(object["key"].GetString());
setKey(object["cert_key"].GetString());
setCiphers(object["ciphers"].GetString());
setCipherSuites(object["ciphersuites"].GetString());
setDH(object["dhparam"].GetString());
}
@@ -51,8 +64,70 @@ rapidjson::Value xmrig::TlsConfig::toJSON(rapidjson::Document &doc) const
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember("cert", m_cert.toJSON(), allocator);
obj.AddMember("key", m_key.toJSON(), allocator);
if (m_protocols > 0) {
Value protocols(kArrayType);
if (m_protocols & TLSv1) {
protocols.PushBack("TLSv1", allocator);
}
if (m_protocols & TLSv1_1) {
protocols.PushBack("TLSv1.1", allocator);
}
if (m_protocols & TLSv1_2) {
protocols.PushBack("TLSv1.2", allocator);
}
if (m_protocols & TLSv1_3) {
protocols.PushBack("TLSv1.3", allocator);
}
obj.AddMember("protocols", protocols, allocator);
}
else {
obj.AddMember("protocols", kNullType, allocator);
}
obj.AddMember("cert", m_cert.toJSON(), allocator);
obj.AddMember("cert_key", m_key.toJSON(), allocator);
obj.AddMember("ciphers", m_ciphers.toJSON(), allocator);
obj.AddMember("ciphersuites", m_cipherSuites.toJSON(), allocator);
obj.AddMember("dhparam", m_dhparam.toJSON(), allocator);
return obj;
}
void xmrig::TlsConfig::setProtocols(const rapidjson::Value &protocols)
{
m_protocols = 0;
if (protocols.IsUint()) {
return setProtocols(protocols.GetUint());
}
if (!protocols.IsArray()) {
return;
}
for (const rapidjson::Value &value : protocols.GetArray()) {
const char *protocol = value.GetString();
if (protocol == nullptr) {
continue;
}
if (strcmp(protocol, "TLSv1") == 0) {
m_protocols |= TLSv1;
}
else if (strcmp(protocol, "TLSv1.1") == 0) {
m_protocols |= TLSv1_1;
}
else if (strcmp(protocol, "TLSv1.2") == 0) {
m_protocols |= TLSv1_2;
}
else if (strcmp(protocol, "TLSv1.3") == 0) {
m_protocols |= TLSv1_3;
}
}
}

View File

@@ -36,20 +36,40 @@ namespace xmrig {
class TlsConfig
{
public:
enum Versions {
TLSv1 = 1,
TLSv1_1 = 2,
TLSv1_2 = 4,
TLSv1_3 = 8
};
TlsConfig();
TlsConfig(const rapidjson::Value &object);
~TlsConfig();
inline bool isValid() const { return !m_cert.isEmpty() && !m_key.isEmpty(); }
inline const char *cert() const { return m_cert.data(); }
inline const char *key() const { return m_key.data(); }
inline void setCert(const char *cert) { m_cert = cert; }
inline void setKey(const char *key) { m_key = key; }
inline bool isValid() const { return !m_cert.isEmpty() && !m_key.isEmpty(); }
inline const char *cert() const { return m_cert.data(); }
inline const char *ciphers() const { return m_ciphers.isEmpty() ? nullptr : m_ciphers.data(); }
inline const char *cipherSuites() const { return m_cipherSuites.isEmpty() ? nullptr : m_cipherSuites.data(); }
inline const char *dhparam() const { return m_dhparam.isEmpty() ? nullptr : m_dhparam.data(); }
inline const char *key() const { return m_key.data(); }
inline uint32_t protocols() const { return m_protocols; }
inline void setCert(const char *cert) { m_cert = cert; }
inline void setCiphers(const char *ciphers) { m_ciphers = ciphers; }
inline void setCipherSuites(const char *ciphers) { m_cipherSuites = ciphers; }
inline void setDH(const char *dhparam) { m_dhparam = dhparam; }
inline void setKey(const char *key) { m_key = key; }
inline void setProtocols(uint32_t protocols) { m_protocols = protocols; }
rapidjson::Value toJSON(rapidjson::Document &doc) const;
void setProtocols(const rapidjson::Value &protocols);
private:
uint32_t m_protocols;
String m_cert;
String m_ciphers;
String m_cipherSuites;
String m_dhparam;
String m_key;
};

View File

@@ -60,18 +60,125 @@ bool xmrig::TlsContext::load(const TlsConfig &config)
}
if (SSL_CTX_use_certificate_chain_file(m_ctx, config.cert()) <= 0) {
LOG_ERR("Failed to load certificate chain file \"%s\"", config.cert());
LOG_ERR("SSL_CTX_use_certificate_chain_file(\"%s\") failed.", config.cert());
return false;
}
if (SSL_CTX_use_PrivateKey_file(m_ctx, config.key(), SSL_FILETYPE_PEM) <= 0) {
LOG_ERR("Failed to load private key file \"%s\"", config.key());
LOG_ERR("SSL_CTX_use_PrivateKey_file(\"%s\") failed.", config.key());
return false;
}
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
SSL_CTX_set_options(m_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
# if OPENSSL_VERSION_NUMBER >= 0x1010100fL
SSL_CTX_set_max_early_data(m_ctx, 0);
# endif
setProtocols(config.protocols());
return setCiphers(config.ciphers()) && setCipherSuites(config.cipherSuites()) && setDH(config.dhparam());
}
bool xmrig::TlsContext::setCiphers(const char *ciphers)
{
if (ciphers == nullptr || SSL_CTX_set_cipher_list(m_ctx, ciphers) == 1) {
return true;
}
LOG_ERR("SSL_CTX_set_cipher_list(\"%s\") failed.", ciphers);
return true;
}
bool xmrig::TlsContext::setCipherSuites(const char *ciphersuites)
{
if (ciphersuites == nullptr) {
return true;
}
# if OPENSSL_VERSION_NUMBER >= 0x1010100fL
if (SSL_CTX_set_ciphersuites(m_ctx, ciphersuites) == 1) {
return true;
}
# endif
LOG_ERR("SSL_CTX_set_ciphersuites(\"%s\") failed.", ciphersuites);
return false;
}
bool xmrig::TlsContext::setDH(const char *dhparam)
{
if (dhparam == nullptr) {
return true;
}
BIO *bio = BIO_new_file(dhparam, "r");
if (bio == nullptr) {
LOG_ERR("BIO_new_file(\"%s\") failed.", dhparam);
return false;
}
DH *dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
if (dh == nullptr) {
LOG_ERR("PEM_read_bio_DHparams(\"%s\") failed.", dhparam);
BIO_free(bio);
return false;
}
const int rc = SSL_CTX_set_tmp_dh(m_ctx, dh);
DH_free(dh);
BIO_free(bio);
if (rc == 0) {
LOG_ERR("SSL_CTX_set_tmp_dh(\"%s\") failed.", dhparam);
return false;
}
return true;
}
void xmrig::TlsContext::setProtocols(uint32_t protocols)
{
if (protocols == 0) {
return;
}
if (!(protocols & TlsConfig::TLSv1)) {
SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1);
}
# ifdef SSL_OP_NO_TLSv1_1
SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_1);
if (!(protocols & TlsConfig::TLSv1_1)) {
SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_1);
}
# endif
# ifdef SSL_OP_NO_TLSv1_2
SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_2);
if (!(protocols & TlsConfig::TLSv1_2)) {
SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_2);
}
# endif
# ifdef SSL_OP_NO_TLSv1_3
SSL_CTX_clear_options(m_ctx, SSL_OP_NO_TLSv1_3);
if (!(protocols & TlsConfig::TLSv1_3)) {
SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_3);
}
# endif
}

View File

@@ -26,6 +26,9 @@
#define XMRIG_TLSCONTEXT_H
#include <stdint.h>
typedef struct ssl_ctx_st SSL_CTX;
@@ -46,6 +49,11 @@ public:
inline SSL_CTX *ctx() const { return m_ctx; }
private:
bool setCiphers(const char *ciphers);
bool setCipherSuites(const char *ciphersuites);
bool setDH(const char *dhparam);
void setProtocols(uint32_t protocols);
SSL_CTX *m_ctx;
};