From 3ae6205a9bac2f89053eea428dc0f7011e11456f Mon Sep 17 00:00:00 2001 From: miodragpop Date: Tue, 3 Nov 2020 16:08:31 +0100 Subject: [PATCH] tls shape-up --- src/hush/tlsmanager.cpp | 282 +++++++++--------------- src/hush/tlsmanager.h | 30 ++- src/hush/utiltls.cpp | 462 +--------------------------------------- src/hush/utiltls.h | 42 +--- src/net.cpp | 57 ++--- src/net.h | 6 - src/util.cpp | 2 - 7 files changed, 132 insertions(+), 749 deletions(-) diff --git a/src/hush/tlsmanager.cpp b/src/hush/tlsmanager.cpp index ceb5dae31..d978bb7e7 100644 --- a/src/hush/tlsmanager.cpp +++ b/src/hush/tlsmanager.cpp @@ -15,6 +15,8 @@ using namespace std; namespace hush { + static WOLFSSL_EVP_PKEY *mykey; + static WOLFSSL_X509 *mycert; // this is the 'dh crypto environment' to be shared between two peers and it is meant to be public, therefore // it is OK to hard code it (or as an alternative to read it from a file) @@ -56,13 +58,15 @@ static WOLFSSL_DH *get_dh2048(void) WOLFSSL_DH *dh = wolfSSL_DH_new(); - if (dh == NULL) + if (dh == NULL) { return NULL; + } if (wc_DhSetKey((DhKey*)dh->internal, dhp_2048, sizeof(dhp_2048), dhg_2048, sizeof(dhg_2048)) != 0) { wolfSSL_DH_free(dh); return NULL; } + return dh; } @@ -74,93 +78,11 @@ DH *tmp_dh_callback(WOLFSSL *ssl, int is_export, int keylength) return get_dh2048(); } -/** if 'tls' debug category is enabled, collect info about certificates relevant to the passed context and print them on logs */ -static void dumpCertificateDebugInfo(int preverify_ok, WOLFSSL_X509_STORE_CTX* chainContext) -{ - if (!LogAcceptCategory("tls")) { - return; - } - - char buf[256] = {}; - WOLFSSL_X509 *cert; - int err, depth; - - cert = wolfSSL_X509_STORE_CTX_get_current_cert(chainContext); - err = wolfSSL_X509_STORE_CTX_get_error(chainContext); - depth = wolfSSL_X509_STORE_CTX_get_error_depth(chainContext); - - LogPrintf("TLS: %s: %s():%d - preverify_ok=%d, errCode=%d, depth=%d\n", - __FILE__, __func__, __LINE__, preverify_ok, err, depth); - - // is not useful checking preverify_ok because, after the chain root verification, it is set accordingly - // to the return value of this callback, and we choose to always return 1 - if (err != X509_V_OK ) { - LogPrintf("TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s] at chain depth=%d\n", - __FILE__, __func__, __LINE__, err, wolfSSL_X509_verify_cert_error_string(err), depth); - - if (cert && err == X509_V_ERR_CERT_HAS_EXPIRED) { - char time_buf[MAX_TIME_STRING_SZ]; - ASN1_TIME * at = wolfSSL_X509_get_notAfter(cert); - if (wolfSSL_ASN1_TIME_to_string(at, time_buf, sizeof(time_buf)) != NULL) { - LogPrintf("TLS: %s: %s():%d - expired on=%s\n", - __FILE__, __func__, __LINE__, buf); - } - } - } else if (cert) { - wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(cert), buf, 256); - LogPrintf("TLS: %s: %s():%d - subj name=%s\n", - __FILE__, __func__, __LINE__, buf); - - wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(cert), buf, 256); - LogPrintf("TLS: %s: %s():%d - issuer name=%s\n", - __FILE__, __func__, __LINE__, buf); - - char time_buf[MAX_TIME_STRING_SZ]; - WOLFSSL_ASN1_TIME * at = wolfSSL_X509_get_notAfter(cert); - if (wolfSSL_ASN1_TIME_to_string(at, time_buf, sizeof(time_buf)) != NULL) { - LogPrintf("TLS: %s: %s():%d - expiring on=%s\n", - __FILE__, __func__, __LINE__, buf); - } - } else { - // should never happen - LogPrintf("TLS: %s: %s():%d - invalid cert/err\n", __FILE__, __func__, __LINE__); - } -} - -/** -* @brief If verify_callback always returns 1, the TLS/SSL handshake will not be terminated with respect to verification failures and the connection will be established. -* -* @param preverify_ok -* @param chainContext -* @return int -*/ -int tlsCertVerificationCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* chainContext) -{ - dumpCertificateDebugInfo(preverify_ok, chainContext); - - /* The return value controls the strategy of the further verification process. If it returns 0 - * the verification process is immediately stopped with "verification failed" state. - * If SSL_VERIFY_PEER has been set in set_verify, a verification failure alert is sent to the peer and the TLS/SSL - * handshake is terminated. - * If it returns 1, the verification process is continued. - * Here we choose to continue the verification process by returning 1 and to leave the optional cert - * verification if we call ValidatePeerCertificate(). - */ - return 1; -} -/** - * @brief Wait for a given SSL connection event. - * - * @param eRoutine a SSLConnectionRoutine value which determines the type of the event. - * @param hSocket - * @param ssl pointer to an SSL instance. - * @param timeoutSec timeout in seconds. - * @return int returns nError corresponding to the connection event. - */ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* ssl, int timeoutSec, unsigned long& err_code) { int retOp = 0; err_code = 0; + char err_buffer[1024]; while (true) { @@ -173,9 +95,9 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* retOp = wolfSSL_connect(ssl); if (retOp == 0) { err_code = wolfSSL_ERR_get_error(); - const char* error_str = wolfSSL_ERR_error_string(err_code, NULL); + const char* error_str = wolfSSL_ERR_error_string(err_code, err_buffer); LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_CONNECT err: %s\n", - __FILE__, __func__, __LINE__, error_str); + __FILE__, __func__, __LINE__, err_buffer); return -1; } } @@ -186,9 +108,9 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* retOp = wolfSSL_accept(ssl); if (retOp == 0) { err_code = wolfSSL_ERR_get_error(); - const char* error_str = wolfSSL_ERR_error_string(err_code, NULL); + const char* error_str = wolfSSL_ERR_error_string(err_code, err_buffer); LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_ACCEPT err: %s\n", - __FILE__, __func__, __LINE__, error_str); + __FILE__, __func__, __LINE__, err_buffer); return -1; } } @@ -239,10 +161,10 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* if (sslErr != WOLFSSL_ERROR_WANT_READ && sslErr != WOLFSSL_ERROR_WANT_WRITE) { err_code = wolfSSL_ERR_get_error(); - const char* error_str = wolfSSL_ERR_error_string(err_code, NULL); + const char* error_str = wolfSSL_ERR_error_string(err_code, err_buffer); LogPrint("tls", "TLS: WARNING: %s: %s():%d - routine(%d), sslErr[0x%x], retOp[%d], errno[0x%x], lib[0x%x], func[0x%x], reas[0x%x]-> err: %s\n", __FILE__, __func__, __LINE__, - eRoutine, sslErr, retOp, errno, wolfSSL_ERR_GET_LIB(err_code), ERR_GET_FUNC(err_code), wolfSSL_ERR_GET_REASON(err_code), error_str); + eRoutine, sslErr, retOp, errno, wolfSSL_ERR_GET_LIB(err_code), ERR_GET_FUNC(err_code), wolfSSL_ERR_GET_REASON(err_code), err_buffer); retOp = -1; break; } @@ -302,6 +224,7 @@ WOLFSSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsign LogPrint("tls", "TLS: establishing connection (tid = %X), (peerid = %s)\n", pthread_self(), addrConnect.ToString()); err_code = 0; + char err_buffer[1024]; WOLFSSL* ssl = NULL; bool bConnectedTLS = false; @@ -317,9 +240,9 @@ WOLFSSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsign else { err_code = wolfSSL_ERR_get_error(); - const char* error_str = wolfSSL_ERR_error_string(err_code, NULL); + const char* error_str = wolfSSL_ERR_error_string(err_code, err_buffer); LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n", - __FILE__, __func__, __LINE__, error_str); + __FILE__, __func__, __LINE__, err_buffer); } if (bConnectedTLS) { @@ -346,22 +269,21 @@ WOLFSSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsign * @param trustedDirs trusted directories * @return WOLSSL_CTX* returns the context. */ -WOLFSSL_CTX* TLSManager::initCtx( - TLSContextType ctxType, - const boost::filesystem::path& privateKeyFile, - const boost::filesystem::path& certificateFile, - const std::vector& trustedDirs) +WOLFSSL_CTX* TLSManager::initCtx(TLSContextType ctxType) { LogPrintf("TLS: %s: %s():%d - Initializing %s context\n", __FILE__, __func__, __LINE__, ctxType == SERVER_CONTEXT ? "server" : "client"); - if (!boost::filesystem::exists(privateKeyFile) || !boost::filesystem::exists(certificateFile)) { + if (!mykey || !mycert) { return NULL; } bool bInitialized = false; WOLFSSL_CTX* tlsCtx = NULL; + byte *pem; + int plen = 0; + if ((tlsCtx = wolfSSL_CTX_new(ctxType == SERVER_CONTEXT ? wolfTLSv1_3_server_method() : wolfTLSv1_3_client_method()))) { wolfSSL_CTX_set_mode(tlsCtx, SSL_MODE_AUTO_RETRY); @@ -389,53 +311,40 @@ WOLFSSL_CTX* TLSManager::initCtx( LogPrintf("%s: Setting preferred cipher failed !!!\n", __func__); } } - - // TLSv1.3 has ephemeral Diffie-Hellman as the only key exchange mechanism, so that perfect forward secrecy is ensured. - + if (ctxType == SERVER_CONTEXT) { - // amongst the Cl/Srv mutually-acceptable set, pick the one that the server prefers most instead of the one that - // the client prefers most + // In case server and client prefered ciphers are different, server preference has priority wolfSSL_CTX_set_options(tlsCtx, SSL_OP_CIPHER_SERVER_PREFERENCE); LogPrintf("TLS: %s: %s():%d - setting dh callback\n", __FILE__, __func__, __LINE__); SSL_CTX_set_tmp_dh_callback(tlsCtx, tmp_dh_callback); } + + // No certificate verification, all should be self-signed + wolfSSL_CTX_set_verify(tlsCtx, WOLFSSL_VERIFY_NONE, NULL); - // Fix for Secure Client-Initiated Renegotiation DoS threat: - // In WolfSSL library renegotiation is disabled by default build config + WOLFSSL_EC_KEY *ec_key = NULL; - // Support for TLSv1.3 should be the only one compiled - // ./configure --disable-oldtls --disable-tlsv12 + ec_key = wolfSSL_EVP_PKEY_get0_EC_KEY(mykey); - int rootCertsNum = LoadDefaultRootCertificates(tlsCtx); - int trustedPathsNum = 0; - - for (boost::filesystem::path trustedDir : trustedDirs) - { - if (wolfSSL_CTX_load_verify_locations(tlsCtx, NULL, trustedDir.string().c_str()) == 1) { - trustedPathsNum++; - } - } - - if (rootCertsNum == 0 && trustedPathsNum == 0) { - LogPrintf("TLS: WARNING: %s: %s: failed to set up verified certificates. It will be impossible to verify peer certificates. \n", __FILE__, __func__); - } - - wolfSSL_CTX_set_verify(tlsCtx, WOLFSSL_VERIFY_PEER, tlsCertVerificationCallback); - - if (wolfSSL_CTX_use_certificate_file(tlsCtx, certificateFile.string().c_str(), WOLFSSL_FILETYPE_PEM) > 0) { - if (wolfSSL_CTX_use_PrivateKey_file(tlsCtx, privateKeyFile.string().c_str(), WOLFSSL_FILETYPE_PEM) > 0) { - if (wolfSSL_CTX_check_private_key(tlsCtx)) { - bInitialized = true; + if (ec_key != NULL && wolfSSL_PEM_write_mem_ECPrivateKey(ec_key, NULL, NULL, 0, &pem, &plen)) { + if (wolfSSL_CTX_use_certificate(tlsCtx, mycert) > 0) { + if (wolfSSL_CTX_use_PrivateKey_buffer(tlsCtx, pem, plen, SSL_FILETYPE_PEM) > 0) { + + free(pem); + + if (wolfSSL_CTX_check_private_key(tlsCtx)) { + bInitialized = true; + } else { + LogPrintf("TLS: ERROR: %s: %s: private key does not match the certificate public key\n", __FILE__, __func__); + } } else { - LogPrintf("TLS: ERROR: %s: %s: private key does not match the certificate public key\n", __FILE__, __func__); + LogPrintf("TLS: ERROR: %s: %s: failed to use private key file\n", __FILE__, __func__); } } else { - LogPrintf("TLS: ERROR: %s: %s: failed to use privateKey file\n", __FILE__, __func__); + LogPrintf("TLS: ERROR: %s: %s: failed to use certificate file\n", __FILE__, __func__); + wolfSSL_ERR_dump_errors_fp(stderr); } - } else { - LogPrintf("TLS: ERROR: %s: %s: failed to use certificate file\n", __FILE__, __func__); - wolfSSL_ERR_dump_errors_fp(stderr); } } else { LogPrintf("TLS: ERROR: %s: %s: failed to create TLS context\n", __FILE__, __func__); @@ -451,42 +360,65 @@ WOLFSSL_CTX* TLSManager::initCtx( return tlsCtx; } /** - * @brief load the certificate credentials from file. + * @brief generates certificate credentials. * * @return true returns true is successful. * @return false returns false if an error has occured. */ bool TLSManager::prepareCredentials() { - boost::filesystem::path - defaultKeyPath(GetDataDir() / TLS_KEY_FILE_NAME), - defaultCertPath(GetDataDir() / TLS_CERT_FILE_NAME); + mykey = NULL; + mycert = NULL; - CredentialsStatus credStatus = - VerifyCredentials( - boost::filesystem::path(GetArg("-tlskeypath", defaultKeyPath.string())), - boost::filesystem::path(GetArg("-tlscertpath", defaultCertPath.string())), - GetArg("-tlskeypwd", "")); - - bool bPrepared = (credStatus == credOk); - - if (!bPrepared) { - if (!mapArgs.count("-tlskeypath") && !mapArgs.count("-tlscertpath")) { - // Default paths were used - - if (credStatus == credAbsent) { - // Generate new credentials (key and self-signed certificate on it) only if credentials were absent previously - // - bPrepared = GenerateCredentials( - defaultKeyPath, - defaultCertPath, - GetArg("-tlskeypwd", "")); + // Generating key and the self-signed certificate for it + // + mykey = GenerateEcKey(); + if (mykey) { + mycert = GenerateCertificate(mykey); + if (mycert) { + if (CheckKeyCert()) { + LogPrintStr("TLS: New private key and self-signed certificate were generated successfully\n"); + + return true; } + //wolfSSL_X509_free(mycert); } + //wolfSSL_EVP_PKEY_free(mykey); } - return bPrepared; + return false; } + +bool TLSManager::CheckKeyCert() +{ + if (!mykey) { + LogPrintf("Key is not generated!!!\n"); + return false; + } + + if (!mycert) { + LogPrintf("Certificate is not generated!!!\n"); + return false; + } + + WOLFSSL_EC_KEY *eccKey = wolfSSL_EVP_PKEY_get1_EC_KEY(mykey); + if (eccKey && wc_ecc_check_key((ecc_key*)eccKey->internal) == 0) { + wolfSSL_EC_KEY_free(eccKey); + } else { + LogPrintf("Generated ECC key check failed!!!\n"); + return false; + } + + if (wolfSSL_X509_verify(mycert, mykey) == WOLFSSL_SUCCESS) { + return true; + } + + LogPrintf("Generated key and certificate do not match!!!\n"); + + return false; +} + + /** * @brief accept a TLS connection * @@ -500,6 +432,7 @@ WOLFSSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& LogPrint("tls", "TLS: accepting connection from %s (tid = %X)\n", addr.ToString(), pthread_self()); err_code = 0; + char err_buffer[1024]; WOLFSSL* ssl = NULL; bool bAcceptedTLS = false; @@ -515,9 +448,9 @@ WOLFSSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& else { err_code = wolfSSL_ERR_get_error(); - const char* error_str = wolfSSL_ERR_error_string(err_code, NULL); + const char* error_str = wolfSSL_ERR_error_string(err_code, err_buffer); LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n", - __FILE__, __func__, __LINE__, error_str); + __FILE__, __func__, __LINE__, err_buffer); } if (bAcceptedTLS) { @@ -541,6 +474,7 @@ WOLFSSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& return ssl; } + /** * @brief Determines whether a string exists in the non-TLS address pool. * @@ -555,6 +489,7 @@ bool TLSManager::isNonTLSAddr(const string& strAddr, const vector& vP LOCK(cs); return (find(vPool.begin(), vPool.end(), NODE_ADDR(strAddr)) != vPool.end()); } + /** * @brief Removes non-TLS node addresses based on timeout. * @@ -702,8 +637,10 @@ int TLSManager::threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fds if (lockSend) SocketSendData(pnode); } + return 0; } + /** * @brief Initialization of the server and client contexts * @@ -714,40 +651,17 @@ bool TLSManager::initialize() { bool bInitializationStatus = false; - // Initialization routines for the OpenSSL library + // Initialization routines for the WolfSSL library // wolfSSL_load_error_strings(); wolfSSL_ERR_load_crypto_strings(); wolfSSL_library_init(); - namespace fs = boost::filesystem; - fs::path certFile = GetArg("-tlscertpath", ""); - if (!fs::exists(certFile)) - certFile = (GetDataDir() / TLS_CERT_FILE_NAME); - - fs::path privKeyFile = GetArg("-tlskeypath", ""); - if (!fs::exists(privKeyFile)) { - privKeyFile = (GetDataDir() / TLS_KEY_FILE_NAME); - } - - std::vector trustedDirs; - fs::path trustedDir = GetArg("-tlstrustdir", ""); - if (fs::exists(trustedDir)) { - // Use only the specified trusted directory - trustedDirs.push_back(trustedDir); - } else { - // If specified directory can't be used, then setting the default trusted directories - trustedDirs = GetDefaultTrustedDirectories(); - } - - for (fs::path dir : trustedDirs) - LogPrintf("TLS: trusted directory '%s' will be used\n", dir.string().c_str()); - // Initialization of the server and client contexts // - if ((tls_ctx_server = TLSManager::initCtx(SERVER_CONTEXT, privKeyFile, certFile, trustedDirs))) + if ((tls_ctx_server = TLSManager::initCtx(SERVER_CONTEXT))) { - if ((tls_ctx_client = TLSManager::initCtx(CLIENT_CONTEXT, privKeyFile, certFile, trustedDirs))) + if ((tls_ctx_client = TLSManager::initCtx(CLIENT_CONTEXT))) { LogPrint("tls", "TLS: contexts are initialized\n"); bInitializationStatus = true; diff --git a/src/hush/tlsmanager.h b/src/hush/tlsmanager.h index f6add7e74..01edbe98a 100644 --- a/src/hush/tlsmanager.h +++ b/src/hush/tlsmanager.h @@ -40,25 +40,21 @@ bool operator==(const _NODE_ADDR b) const class TLSManager { public: - /* This is set as a custom error number which is not an error in OpenSSL protocol. - A true (not null) OpenSSL error returned by ERR_get_error() consists of a library number, + /* This is set as a custom error number which is not an error in SSL protocol. + A true (not null) SSL error returned by ERR_get_error() consists of a library number, function code and reason code. */ - static const long SELECT_TIMEDOUT = 0xFFFFFFFF; + static const long SELECT_TIMEDOUT = 0xFFFFFFFF; - int waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* ssl, int timeoutSec, unsigned long& err_code); + int waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* ssl, int timeoutSec, unsigned long& err_code); - WOLFSSL* connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code); - WOLFSSL_CTX* initCtx( - TLSContextType ctxType, - const boost::filesystem::path& privateKeyFile, - const boost::filesystem::path& certificateFile, - const std::vector& trustedDirs); - - bool prepareCredentials(); - WOLFSSL* accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code); - bool isNonTLSAddr(const string& strAddr, const vector& vPool, CCriticalSection& cs); - void cleanNonTLSPool(std::vector& vPool, CCriticalSection& cs); - int threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fdsetSend, fd_set& fdsetError); - bool initialize(); + WOLFSSL* connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code); + WOLFSSL_CTX* initCtx(TLSContextType ctxType); + bool prepareCredentials(); + WOLFSSL* accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code); + bool isNonTLSAddr(const string& strAddr, const vector& vPool, CCriticalSection& cs); + void cleanNonTLSPool(std::vector& vPool, CCriticalSection& cs); + int threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fdsetSend, fd_set& fdsetError); + bool initialize(); + bool CheckKeyCert(); }; } diff --git a/src/hush/utiltls.cpp b/src/hush/utiltls.cpp index f6b7ba171..1f0ea6564 100644 --- a/src/hush/utiltls.cpp +++ b/src/hush/utiltls.cpp @@ -8,96 +8,14 @@ #include #include -#include -#include -#include - #include "../util.h" #include "utiltls.h" namespace hush { -// Set of most common default trusted certificates directories used by OpenSSL -static const char* defaultTrustedDirs[] = -{ -#ifdef WIN32 - "" -#elif MAC_OSX - "/System/Library/OpenSSL/certs" -#else // Linux build - "/etc/ssl/certs", - "/usr/local/ssl/certs", - "/usr/lib/ssl/certs", - "/usr/share/ssl/certs", - "/etc/pki/tls/certs", - "/var/lib/ca-certificates" -#endif -}; - -// Default root certificates (PEM encoded) -static const char defaultRootCerts[] = -{ -// // Example of specifying a certificate -// // -// "-----BEGIN CERTIFICATE-----\n" -// "MIIDYDCCAkigAwIBAgIJAJMakdoBYY67MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" -// "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" -// "aWRnaXRzIFB0eSBMdGQwHhcNMTcwODE0MTc0MTMyWhcNNDQxMjMwMTc0MTMyWjBF\n" -// "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" -// "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" -// "CgKCAQEAzNV+SPRCKSEGlntfpCRMVSfz99NoEo3K1SRyw6GTSb1LNSTQCn1EsCSH\n" -// "cVZTmyfjcTHpwz4aF14yw8lQC42f218AOsG1DV5suCaUXhSmZlajMkvEJVwfBOft\n" -// "xpcqE1fA9wovXlnJLXVgyJGMc896S8tcbrCU/l/BsqKh5QX8N60MQ3w376nSGvVP\n" -// "ussN8bVH3aKRwjhateqx1GRt0GPnM8/u7EkgF8Bc+m8WZYcUfkPC5Am2D0MO1HOA\n" -// "u3IKxXZMs/fYd6nF5DZBwg+D23EP/V8oqenn8ilvrSORq5PguOl1QoDyY66PhmjN\n" -// "L9c4Spxw8HXUDlrfuSQn2NJnw1XhdQIDAQABo1MwUTAdBgNVHQ4EFgQU/KD+n5Bz\n" -// "QLbp09qKzwwyNwOQU4swHwYDVR0jBBgwFoAU/KD+n5BzQLbp09qKzwwyNwOQU4sw\n" -// "DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVtprBxZD6O+WNYUM\n" -// "ksdKiVVoszEJXlt7wajuaPBPK/K3buxE9FLVxS+LiH1PUhPCc6V28guyKWwn109/\n" -// "4WnO51LQjygvd7SaePlbiO7iIatkOk4oETJQZ+tEJ7fv/NITY/GQUfgPNkANmPPz\n" -// "Mz9I6He8XhIpO6NGuDG+74aR1RhvR3PWJJYT0QpL0STVR4qTc/HfnymF5XnnjOYZ\n" -// "mwzT8jXX5dhLYwJmyPBS+uv+oa1quM/FitA63N9anYtRBiPaBtund9Ikjat1hM0h\n" -// "neo2tz7Mfsgjb0aiORtiyaH2OetvwR0QuCSVPnknkfGWPDINdUdkgKyA1PX58Smw\n" -// "vaXEcw==\n" -// "-----END CERTIFICATE-----" - - "" -}; - -// Generates RSA keypair (a private key of 'bits' length for a specified 'uPublicKey') -// obsolete since we use EC instead of RSA -static WOLFSSL_EVP_PKEY* GenerateRsaKey(int bits, WOLFSSL_BN_ULONG uPublicKey) -{ - WOLFSSL_EVP_PKEY *evpPrivKey = NULL; - - WOLFSSL_BIGNUM *pubKey = wolfSSL_BN_new(); - if (pubKey) { - if (wolfSSL_BN_set_word(pubKey, uPublicKey)) { - WOLFSSL_RSA *privKey = wolfSSL_RSA_new(); - if (privKey) { - if (wolfSSL_RAND_poll() && wolfSSL_RSA_generate_key_ex(privKey, bits, pubKey, NULL)) { - if ((evpPrivKey = wolfSSL_EVP_PKEY_new())) { - if (!wolfSSL_EVP_PKEY_assign_RSA(evpPrivKey, privKey)) { - wolfSSL_EVP_PKEY_free(evpPrivKey); - evpPrivKey = NULL; - } - } - } - - if(!evpPrivKey) { - wolfSSL_RSA_free(privKey); - } - } - } - wolfSSL_BN_free(pubKey); - } - - return evpPrivKey; -} - // Generates EC keypair // -static WOLFSSL_EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1) +WOLFSSL_EVP_PKEY* GenerateEcKey(int nid) { WOLFSSL_EVP_PKEY *evpPrivKey = NULL; WOLFSSL_EC_KEY *privKey = wolfSSL_EC_KEY_new_by_curve_name(nid); @@ -114,6 +32,7 @@ static WOLFSSL_EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1) if(!evpPrivKey) { wolfSSL_EC_KEY_free(privKey); + evpPrivKey = NULL; } } @@ -122,7 +41,7 @@ static WOLFSSL_EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1) // Generates certificate for a specified public key using a corresponding private key (both of them should be specified in the 'keypair'). // -static WOLFSSL_X509* GenerateCertificate(WOLFSSL_EVP_PKEY *keypair) +WOLFSSL_X509* GenerateCertificate(WOLFSSL_EVP_PKEY *keypair) { if (!keypair) { return NULL; @@ -149,381 +68,8 @@ static WOLFSSL_X509* GenerateCertificate(WOLFSSL_EVP_PKEY *keypair) cert = NULL; } } - + return cert; } -// Stores key to file, specified by the 'filePath' -// -static bool StoreKey(WOLFSSL_EVP_PKEY *key, const boost::filesystem::path &filePath, const std::string &passphrase) -{ - if (!key) - return false; - - bool bStored = false; - - FILE *keyfd = fopen(filePath.string().c_str(), "wb"); - if (keyfd) - { - WOLFSSL_EC_KEY *ec_key = NULL; - ec_key = wolfSSL_EVP_PKEY_get0_EC_KEY(key); - if (ec_key != NULL) - { - const WOLFSSL_EVP_CIPHER* pCipher = NULL; - - if (passphrase.length() && (pCipher = wolfSSL_EVP_aes_256_cbc())) - bStored = wolfSSL_PEM_write_ECPrivateKey(keyfd, ec_key, pCipher, NULL, 0, NULL, (void*)passphrase.c_str()); - else - bStored = wolfSSL_PEM_write_ECPrivateKey(keyfd, ec_key, NULL, NULL, 0, NULL, NULL); - } - - fclose(keyfd); - } - - return bStored; -} - -// Stores certificate to file, specified by the 'filePath' -// -static bool StoreCertificate(WOLFSSL_X509 *cert, const boost::filesystem::path &filePath) -{ - if (!cert) - return false; - - bool bStored = false; - - FILE *certfd = fopen(filePath.string().c_str(), "wb"); - if (certfd) - { - bStored = wolfSSL_PEM_write_X509(certfd, cert); - fclose(certfd); - } - - return bStored; -} - -// Loads key from file, specified by the 'filePath' -// -static WOLFSSL_EVP_PKEY* old_LoadKey(const boost::filesystem::path &filePath, const std::string &passphrase) -{ - if (!boost::filesystem::exists(filePath)) - return NULL; - - WOLFSSL_EVP_PKEY *key = wolfSSL_EVP_PKEY_new(); - FILE *keyfd = fopen(filePath.string().c_str(), "rb"); - if (keyfd) - { - key = wolfSSL_PEM_read_PrivateKey(keyfd, NULL, NULL, passphrase.length() ? (void*)passphrase.c_str() : NULL); - fclose(keyfd); - } - - return key; -} - -// Loads key from file, specified by the 'filePath' -// -static WOLFSSL_EVP_PKEY* LoadKey(const boost::filesystem::path &filePath, const std::string &passphrase) -{ - if (!boost::filesystem::exists(filePath)) - return NULL; - - WOLFSSL_EVP_PKEY *key = NULL; - FILE *keyfd = fopen(filePath.string().c_str(), "rb"); - byte der[4096]; - byte pem[4096]; - WOLFSSL_EC_KEY *ecKey; - ecKey = wolfSSL_EC_KEY_new(); - word32 idx = 0; - - if (keyfd) - { - int fileSz = fread(pem, 1, 4096, keyfd); - fclose(keyfd); - - if (fileSz > 0) - { - if (ecKey) - { - int derSz = wc_KeyPemToDer(pem, fileSz, der, 4096, passphrase.c_str()); - int ret_decode = wc_EccPrivateKeyDecode(der, &idx, (ecc_key*)ecKey->internal, derSz); - if (ret_decode == 0) - { - if (key = wolfSSL_EVP_PKEY_new()) - { - wolfSSL_EVP_PKEY_assign_EC_KEY(key, ecKey); - } - } - } - } - } - - return key; -} - -// Loads certificate from file, specified by the 'filePath' -// -static WOLFSSL_X509* LoadCertificate(const boost::filesystem::path &filePath) -{ - if (!boost::filesystem::exists(filePath)) - return NULL; - - WOLFSSL_X509 *cert = NULL; - FILE *certfd = fopen(filePath.string().c_str(), "rb"); - if (certfd) - { - cert = wolfSSL_PEM_read_X509(certfd, NULL, NULL, NULL); - fclose(certfd); - } - - return cert; -} - -// Verifies if the private key in 'key' matches the public key in 'cert' -// (Signs random bytes on 'key' and verifies signature correctness on public key from 'cert') -// -static bool IsMatching(WOLFSSL_EVP_PKEY *key, WOLFSSL_X509 *cert) -{ - if (!key || !cert) - return false; - - if (wolfSSL_X509_verify(cert, key) == WOLFSSL_SUCCESS) - { - return true; - } - - LogPrintf("Loaded key and certificate do not match, delete them to generate new credentials!!!\n"); - - return false; -} - -// Checks the correctness of a private-public key pair and the validity of a certificate using public key from key pair -// -static bool CheckCredentials(WOLFSSL_EVP_PKEY *key, WOLFSSL_X509 *cert) -{ - if (!key || !cert) - return false; - - bool bIsOk = false; - - // Validating the correctness of a private-public key pair, depending on a key type - // - switch (wolfSSL_EVP_PKEY_base_id(key)) - { - case EVP_PKEY_RSA: - case EVP_PKEY_RSA2: - { - WOLFSSL_RSA *rsaKey = wolfSSL_EVP_PKEY_get1_RSA(key); - if (rsaKey) - { - bIsOk = (wc_CheckRsaKey((RsaKey*)rsaKey->internal) == 0); - wolfSSL_RSA_free(rsaKey); - } - break; - } - case EVP_PKEY_EC: - { - WOLFSSL_EC_KEY *eccKey = wolfSSL_EVP_PKEY_get1_EC_KEY(key); - if (eccKey) - { - bIsOk = (wc_ecc_check_key((ecc_key*)eccKey->internal) == 0); - wolfSSL_EC_KEY_free(eccKey); - } - break; - } - - default: - bIsOk = false; - } - - // Verifying if the private key matches the public key in certificate - if (bIsOk) - bIsOk = IsMatching(key, cert); - - return bIsOk; -} - -// Verifies credentials (a private key, a certificate for public key and a correspondence between the private and the public key) -// -CredentialsStatus VerifyCredentials( - const boost::filesystem::path &keyPath, - const boost::filesystem::path &certPath, - const std::string &passphrase) -{ - CredentialsStatus status = credAbsent; - - WOLFSSL_EVP_PKEY *key = NULL; - WOLFSSL_X509 *cert = NULL; - - key = LoadKey(keyPath, passphrase); - cert = LoadCertificate(certPath); - - if (key && cert) { - status = CheckCredentials(key, cert) ? credOk : credNonConsistent; - } else if (!key && !cert) { - status = credAbsent; - } else { - status = credPartiallyAbsent; - } - - if (key) { - wolfSSL_EVP_PKEY_free(key); - } - - if (cert) { - wolfSSL_X509_free(cert); - } - - return status; -} - -// Generates public key pair and the self-signed certificate for it, and then stores them by the specified paths 'keyPath' and 'certPath' respectively. -// -bool GenerateCredentials( - const boost::filesystem::path &keyPath, - const boost::filesystem::path &certPath, - const std::string &passphrase) -{ - bool bGenerated = false; - - WOLFSSL_EVP_PKEY *key = NULL; - WOLFSSL_X509 *cert = NULL; - - // Generating key and the self-signed certificate for it - // - //key = GenerateRsaKey(TLS_RSA_KEY_SIZE, RSA_F4); - //key = GenerateEcKey(NID_secp256k1); - key = GenerateEcKey(); - if (key) - { - cert = GenerateCertificate(key); - if (cert) - { - bool bKey = StoreKey(key, keyPath, passphrase); - bool bCert = StoreCertificate(cert, certPath); - - if ( bKey && bCert ) - { - bGenerated = true; - LogPrintStr("TLS: New private key and self-signed certificate were generated successfully\n"); - } - - wolfSSL_X509_free(cert); - } - wolfSSL_EVP_PKEY_free(key); - } - - return bGenerated; -} - -// Checks if certificate of a peer is valid (by internal means of the TLS protocol) -// -// Validates peer certificate using a chain of CA certificates. -// If some of intermediate CA certificates are absent in the trusted certificates store, then validation status will be 'false') -// -bool ValidatePeerCertificate(WOLFSSL *ssl) -{ - if (!ssl) - return false; - - bool bIsOk = false; - - WOLFSSL_X509 *cert = wolfSSL_get_peer_certificate (ssl); - if (cert) { - long errCode = wolfSSL_get_verify_result(ssl); - if (errCode != X509_V_OK) - { - LogPrint("tls", "TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s]\n", - __FILE__, __func__, __LINE__, errCode, wolfSSL_X509_verify_cert_error_string(errCode)); - } else { - bIsOk = true; - - char buf[256]; - wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(cert), buf, 256); - LogPrint("tls", "TLS: %s: %s():%d - subj name=%s\n", - __FILE__, __func__, __LINE__, buf); - - wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(cert), buf, 256); - LogPrint("tls", "TLS: %s: %s():%d - issuer name=%s\n", - __FILE__, __func__, __LINE__, buf); - } - - wolfSSL_X509_free(cert); - } else { - LogPrint("tls", "TLS: %s: %s():%d - WARNING: Peer does not have certificate\n", - __FILE__, __func__, __LINE__); - } - return bIsOk; -} - -// Check if a given context is set up with a cert that can be validated by this context -// -bool ValidateCertificate(WOLFSSL_CTX *ssl_ctx) -{ - if (!ssl_ctx) { - return false; - } - - bool bIsOk = false; - - WOLFSSL_X509_STORE *store = wolfSSL_CTX_get_cert_store(ssl_ctx); - - if (store) { - WOLFSSL_X509_STORE_CTX *ctx = wolfSSL_X509_STORE_CTX_new(); - if (ctx) { - bIsOk = (wolfSSL_X509_verify_cert(ctx) == WOLFSSL_SUCCESS); - wolfSSL_X509_STORE_CTX_free(ctx); - } - } - - return bIsOk; -} - -// Creates the list of available OpenSSL default directories for trusted certificates storage -// -std::vector GetDefaultTrustedDirectories() -{ - namespace fs = boost::filesystem; - std::vector defaultDirectoriesList; - - // Check and set all possible standard default directories - for (const char *dir : defaultTrustedDirs) - { - fs::path defaultDir(dir); - - if (fs::exists(defaultDir)) { - defaultDirectoriesList.push_back(defaultDir); - } - } - - return defaultDirectoriesList; -} - -// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context. -// Returns the number of loaded certificates. -// -int LoadDefaultRootCertificates(WOLFSSL_CTX *ctx) -{ - if (!ctx) { - return 0; - } - - int certsLoaded = 0; - - // Certificate text buffer 'defaultRootCerts' is a C string with certificates in PEM format - WOLFSSL_BIO *memBuf = wolfSSL_BIO_new_mem_buf(defaultRootCerts, -1); - if (memBuf) { - WOLFSSL_X509 *cert = NULL; - while ((cert = wolfSSL_PEM_read_bio_X509(memBuf, NULL, 0, NULL))) - { - if (wolfSSL_X509_STORE_add_cert(wolfSSL_CTX_get_cert_store(ctx), cert) > 0) { - certsLoaded++; - } - - wolfSSL_X509_free(cert); - } - wolfSSL_BIO_free(memBuf); - } - - return certsLoaded; -} } diff --git a/src/hush/utiltls.h b/src/hush/utiltls.h index c47308523..495c112cb 100644 --- a/src/hush/utiltls.h +++ b/src/hush/utiltls.h @@ -6,51 +6,13 @@ #ifndef UTILTLS_H #define UTILTLS_H -#include namespace hush { -#define TLS_KEY_FILE_NAME "key.pem" // default name of a private key -#define TLS_CERT_FILE_NAME "cert.pem" // default name of a certificate - #define CERT_VALIDITY_DAYS (365 * 10) // period of validity, in days, for a self-signed certificate -#define TLS_RSA_KEY_SIZE 2048 // size of a private RSA key, in bits, that will be generated, if no other key is specified +WOLFSSL_EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1); -typedef enum {credOk, credNonConsistent, credAbsent, credPartiallyAbsent} CredentialsStatus; - -// Verifies credentials (a private key, a certificate for public key and a correspondence between the private and the public key) -// -CredentialsStatus VerifyCredentials( - const boost::filesystem::path &keyPath, - const boost::filesystem::path &certPath, - const std::string &passphrase); - -// Generates public key pair and the self-signed certificate for it, and then stores them by the specified paths 'keyPath' and 'certPath' respectively. -// -bool GenerateCredentials( - const boost::filesystem::path &keyPath, - const boost::filesystem::path &certPath, - const std::string &passphrase); - -// Checks if certificate of a peer is valid (by internal means of the TLS protocol) -// -// Validates peer certificate using a chain of CA certificates. -// If some of intermediate CA certificates are absent in the trusted certificates store, then validation status will be 'false') -// -bool ValidatePeerCertificate(WOLFSSL *ssl); - -// Check if a given context is set up with a cert that can be validated by this context -// -bool ValidateCertificate(WOLFSSL_CTX *ssl_ctx); - -// Creates the list of available default directories for trusted certificates storage -// -std::vector GetDefaultTrustedDirectories(); - -// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context. -// Returns the number of loaded certificates. -// -int LoadDefaultRootCertificates(WOLFSSL_CTX *ctx); +WOLFSSL_X509* GenerateCertificate(WOLFSSL_EVP_PKEY *keypair); } diff --git a/src/net.cpp b/src/net.cpp index 33248e391..c9ba84fc4 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -72,7 +72,7 @@ using namespace hush; #if defined(USE_TLS) && !defined(TLS1_3_VERSION) // minimum secure protocol is 1.3 // TLS1_3_VERSION is defined in openssl/tls1.h - #error "ERROR: Your OpenSSL version does not support TLS v1.3" + #error "ERROR: Your WolfSSL version does not support TLS v1.3" #endif @@ -138,8 +138,8 @@ static boost::condition_variable messageHandlerCondition; static CNodeSignals g_signals; CNodeSignals& GetNodeSignals() { return g_signals; } -// OpenSSL server and client contexts -SSL_CTX *tls_ctx_server, *tls_ctx_client; +// WolfSSL server and client contexts +WOLFSSL_CTX *tls_ctx_server, *tls_ctx_client; static bool operator==(_NODE_ADDR a, _NODE_ADDR b) { @@ -442,7 +442,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) addrman.Attempt(addrConnect); - SSL *ssl = NULL; + WOLFSSL *ssl = NULL; #ifdef USE_TLS /* TCP connection is ready. Do client side SSL. */ @@ -509,19 +509,6 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) } } - // certificate validation is disabled by default - if (CNode::GetTlsValidate()) - { - if (ssl && !ValidatePeerCertificate(ssl)) - { - LogPrintf ("TLS: ERROR: Wrong server certificate from %s. Connection will be closed.\n", addrConnect.ToString()); - - SSL_shutdown(ssl); - CloseSocket(hSocket); - SSL_free(ssl); - return NULL; - } - } #endif // USE_TLS // Add node @@ -569,7 +556,7 @@ void CNode::CloseSocketDisconnect() { unsigned long err_code = 0; tlsmanager.waitFor(SSL_SHUTDOWN, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code); - SSL_free(ssl); + wolfSSL_free(ssl); ssl = NULL; } CloseSocket(hSocket); @@ -747,7 +734,6 @@ void CNode::copyStats(CNodeStats &stats, const std::vector &m_asmap) { LOCK(cs_hSocket); stats.fTLSEstablished = (ssl != NULL) && (wolfSSL_is_init_finished(ssl) == 1); - stats.fTLSVerified = (ssl != NULL) && ValidatePeerCertificate(ssl); } } @@ -863,9 +849,9 @@ void SocketSendData(CNode *pnode) if (bIsSSL) { - ERR_clear_error(); // clear the error queue, otherwise we may be reading an old error that occurred previously in the current thread - nBytes = SSL_write(pnode->ssl, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset); - nRet = SSL_get_error(pnode->ssl, nBytes); + wolfSSL_ERR_clear_error(); // clear the error queue, otherwise we may be reading an old error that occurred previously in the current thread + nBytes = wolfSSL_write(pnode->ssl, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset); + nRet = wolfSSL_get_error(pnode->ssl, nBytes); } else { @@ -893,9 +879,9 @@ void SocketSendData(CNode *pnode) // if (bIsSSL) { - if (nRet != SSL_ERROR_WANT_READ && nRet != SSL_ERROR_WANT_WRITE) + if (nRet != WOLFSSL_ERROR_WANT_READ && nRet != WOLFSSL_ERROR_WANT_WRITE) { - LogPrintf("ERROR: SSL_write %s; closing connection\n", ERR_error_string(nRet, NULL)); + LogPrintf("ERROR: SSL_write %s; closing connection\n", wolfSSL_ERR_error_string(nRet, NULL)); pnode->CloseSocketDisconnect(); } else @@ -1194,7 +1180,7 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); #endif - SSL *ssl = NULL; + WOLFSSL *ssl = NULL; SetSocketNonBlocking(hSocket, true); @@ -1260,20 +1246,7 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { return; } } - - // certificate validation is disabled by default - if (CNode::GetTlsValidate()) - { - if (ssl && !ValidatePeerCertificate(ssl)) - { - LogPrintf ("TLS: ERROR: Wrong client certificate from %s. Connection will be closed.\n", addr.ToString()); - - SSL_shutdown(ssl); - CloseSocket(hSocket); - SSL_free(ssl); - return; - } - } + #endif // USE_TLS CNode* pnode = new CNode(hSocket, addr, "", true, ssl); @@ -2090,7 +2063,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (!tlsmanager.prepareCredentials()) { - LogPrintf("TLS: ERROR: %s: %s: Credentials weren't loaded. Node can't be started.\n", __FILE__, __func__); + LogPrintf("TLS: ERROR: %s: %s: Credentials weren't generated. Node can't be started.\n", __FILE__, __func__); return; } @@ -2388,7 +2361,7 @@ bool CAddrDB::Read(CAddrMan& addr) unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } -CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn, SSL *sslIn) : +CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn, WOLFSSL *sslIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), setInventoryKnown(SendBufferSize() / 1000) @@ -2500,7 +2473,7 @@ CNode::~CNode() unsigned long err_code = 0; tlsmanager.waitFor(SSL_SHUTDOWN, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code); - SSL_free(ssl); + wolfSSL_free(ssl); ssl = NULL; } diff --git a/src/net.h b/src/net.h index 5bbd44aef..72a13a7e9 100644 --- a/src/net.h +++ b/src/net.h @@ -104,12 +104,6 @@ X509 *generate_x509(EVP_PKEY *pkey); bool write_to_disk(EVP_PKEY *pkey, X509 *x509); void configure_context(SSL_CTX *ctx, bool server_side); -// OpenSSL related variables for metrics.cpp -static std::string routingsecrecy; -static std::string cipherdescription; -static std::string securitylevel; -static std::string validationdescription; - typedef int NodeId; class CNodeStats; diff --git a/src/util.cpp b/src/util.cpp index 57701bdb5..ed81fe2d8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -994,8 +994,6 @@ std::string LicenseInfo() FormatParagraph(_("This is experimental software!!!")) + "\n" + "\n" + FormatParagraph(_("Distributed under the GPLv3 software license, see the accompanying file COPYING or .")) + "\n" + - "\n" + - FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young.")) + "\n"; }