OpenSSL replaced by WolfSSL
This commit is contained in:
10
configure.ac
10
configure.ac
@@ -664,8 +664,8 @@ if test x$use_pkgconfig = xyes; then
|
|||||||
m4_ifdef(
|
m4_ifdef(
|
||||||
[PKG_CHECK_MODULES],
|
[PKG_CHECK_MODULES],
|
||||||
[
|
[
|
||||||
PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)])
|
PKG_CHECK_MODULES([SSL], [wolfssl],, [AC_MSG_ERROR(WolfSSL not found.)])
|
||||||
PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)])
|
#PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)])
|
||||||
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
|
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
|
||||||
PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)])
|
PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)])
|
||||||
if test x$TARGET_OS != xwindows; then
|
if test x$TARGET_OS != xwindows; then
|
||||||
@@ -688,11 +688,11 @@ else
|
|||||||
# BUG: Fix this:
|
# BUG: Fix this:
|
||||||
echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, gmp'
|
echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, gmp'
|
||||||
|
|
||||||
AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing))
|
AC_CHECK_HEADER([wolfssl/openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing))
|
||||||
AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing))
|
AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing))
|
||||||
|
|
||||||
AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
|
AC_CHECK_HEADER([wolfssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
|
||||||
AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing))
|
AC_CHECK_LIB([wolfssl], [main],SSL_LIBS=-lwolfssl, AC_MSG_ERROR(libwolfssl missing))
|
||||||
|
|
||||||
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
|
if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then
|
||||||
AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),)
|
AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package=libcurl
|
package=libcurl
|
||||||
$(package)_version=7.67.0
|
$(package)_version=7.67.0
|
||||||
$(package)_dependencies=openssl
|
$(package)_dependencies=wolfssl
|
||||||
$(package)_download_path=https://curl.haxx.se/download
|
$(package)_download_path=https://curl.haxx.se/download
|
||||||
$(package)_file_name=curl-$($(package)_version).tar.gz
|
$(package)_file_name=curl-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=52af3361cf806330b88b4fe6f483b6844209d47ae196ac46da4de59bb361ab02
|
$(package)_sha256_hash=52af3361cf806330b88b4fe6f483b6844209d47ae196ac46da4de59bb361ab02
|
||||||
$(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(host)
|
$(package)_config_opts_linux=--disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix) --host=$(host)
|
||||||
$(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32
|
$(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix) --host=x86_64-w64-mingw32
|
||||||
$(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix)
|
$(package)_config_opts_darwin=--disable-shared --enable-static --with-wolfssl --without-ssl --prefix=$(host_prefix)
|
||||||
$(package)_cflags_darwin=-mmacosx-version-min=10.9
|
$(package)_cflags_darwin=-mmacosx-version-min=10.9
|
||||||
$(package)_conf_tool=./configure
|
$(package)_conf_tool=./configure
|
||||||
|
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
package=openssl
|
|
||||||
$(package)_version=1.1.1h
|
|
||||||
$(package)_download_path=https://www.openssl.org/source
|
|
||||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
|
||||||
$(package)_sha256_hash=5c9ca8774bd7b03e5784f26ae9e9e6d749c9da2438545077e6b3d755a06595d9
|
|
||||||
|
|
||||||
define $(package)_set_vars
|
|
||||||
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
|
||||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
|
||||||
$(package)_config_opts+=no-afalgeng
|
|
||||||
$(package)_config_opts+=no-asm
|
|
||||||
$(package)_config_opts+=no-async
|
|
||||||
$(package)_config_opts+=no-bf
|
|
||||||
$(package)_config_opts+=no-blake2
|
|
||||||
$(package)_config_opts+=no-camellia
|
|
||||||
#$(package)_config_opts+=no-capieng
|
|
||||||
$(package)_config_opts+=no-cast
|
|
||||||
#$(package)_config_opts+=no-chacha
|
|
||||||
$(package)_config_opts+=no-cmac
|
|
||||||
$(package)_config_opts+=no-cms
|
|
||||||
#$(package)_config_opts+=no-comp
|
|
||||||
$(package)_config_opts+=no-crypto-mdebug
|
|
||||||
$(package)_config_opts+=no-crypto-mdebug-backtrace
|
|
||||||
#$(package)_config_opts+=no-ct
|
|
||||||
#$(package)_config_opts+=no-des
|
|
||||||
$(package)_config_opts+=no-dgram
|
|
||||||
#$(package)_config_opts+=no-dsa
|
|
||||||
$(package)_config_opts+=no-dso
|
|
||||||
$(package)_config_opts+=no-dtls
|
|
||||||
$(package)_config_opts+=no-dtls1
|
|
||||||
$(package)_config_opts+=no-dtls1-method
|
|
||||||
$(package)_config_opts+=no-dynamic-engine
|
|
||||||
#$(package)_config_opts+=no-ec2m
|
|
||||||
#$(package)_config_opts+=no-ec_nistp_64_gcc_128
|
|
||||||
$(package)_config_opts+=no-egd
|
|
||||||
$(package)_config_opts+=no-engine
|
|
||||||
#$(package)_config_opts+=no-err
|
|
||||||
$(package)_config_opts+=no-gost
|
|
||||||
$(package)_config_opts+=no-heartbeats
|
|
||||||
#$(package)_config_opts+=no-idea
|
|
||||||
$(package)_config_opts+=no-md2
|
|
||||||
$(package)_config_opts+=no-md4
|
|
||||||
$(package)_config_opts+=no-mdc2
|
|
||||||
$(package)_config_opts+=no-multiblock
|
|
||||||
$(package)_config_opts+=no-nextprotoneg
|
|
||||||
$(package)_config_opts+=no-ocb
|
|
||||||
#$(package)_config_opts+=no-ocsp
|
|
||||||
#$(package)_config_opts+=no-poly1305
|
|
||||||
#$(package)_config_opts+=no-posix-io
|
|
||||||
$(package)_config_opts+=no-psk
|
|
||||||
$(package)_config_opts+=no-rc2
|
|
||||||
$(package)_config_opts+=no-rc4
|
|
||||||
$(package)_config_opts+=no-rc5
|
|
||||||
$(package)_config_opts+=no-rdrand
|
|
||||||
$(package)_config_opts+=no-rfc3779
|
|
||||||
$(package)_config_opts+=no-rmd160
|
|
||||||
$(package)_config_opts+=no-scrypt
|
|
||||||
$(package)_config_opts+=no-sctp
|
|
||||||
$(package)_config_opts+=no-seed
|
|
||||||
$(package)_config_opts+=no-shared
|
|
||||||
#$(package)_config_opts+=no-sock
|
|
||||||
$(package)_config_opts+=no-srp
|
|
||||||
$(package)_config_opts+=no-srtp
|
|
||||||
$(package)_config_opts+=no-ssl
|
|
||||||
$(package)_config_opts+=no-ssl3
|
|
||||||
$(package)_config_opts+=no-ssl3-method
|
|
||||||
$(package)_config_opts+=no-ssl-trace
|
|
||||||
#$(package)_config_opts+=no-stdio
|
|
||||||
#$(package)_config_opts+=no-tls
|
|
||||||
#$(package)_config_opts+=no-tls1
|
|
||||||
#$(package)_config_opts+=no-tls1-method
|
|
||||||
$(package)_config_opts+=no-ts
|
|
||||||
$(package)_config_opts+=no-ui
|
|
||||||
$(package)_config_opts+=no-unit-test
|
|
||||||
$(package)_config_opts+=no-weak-ssl-ciphers
|
|
||||||
$(package)_config_opts+=no-whirlpool
|
|
||||||
#$(package)_config_opts+=no-zlib
|
|
||||||
#$(package)_config_opts+=no-zlib-dynamic
|
|
||||||
$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
|
|
||||||
$(package)_config_opts+=-DPURIFY
|
|
||||||
$(package)_config_opts_linux=-fPIC -Wa,--noexecstack
|
|
||||||
$(package)_config_opts_x86_64_linux=linux-x86_64
|
|
||||||
$(package)_config_opts_i686_linux=linux-generic32
|
|
||||||
$(package)_config_opts_arm_linux=linux-generic32
|
|
||||||
$(package)_config_opts_aarch64_linux=linux-generic64
|
|
||||||
$(package)_config_opts_mipsel_linux=linux-generic32
|
|
||||||
$(package)_config_opts_mips_linux=linux-generic32
|
|
||||||
$(package)_config_opts_powerpc_linux=linux-generic32
|
|
||||||
$(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc
|
|
||||||
$(package)_config_opts_x86_64_mingw32=mingw64
|
|
||||||
$(package)_config_opts_i686_mingw32=mingw
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_preprocess_cmds
|
|
||||||
sed -i.old 's/built on: $$$$date/built on: date not available/' util/mkbuildinf.pl && \
|
|
||||||
sed -i.old "s|\"engines\", \"apps\", \"test\"|\"engines\"|" Configure
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_config_cmds
|
|
||||||
./Configure $($(package)_config_opts)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_build_cmds
|
|
||||||
$(MAKE) -j1 build_libs libcrypto.pc libssl.pc openssl.pc
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_stage_cmds
|
|
||||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -j1 install_sw
|
|
||||||
endef
|
|
||||||
|
|
||||||
define $(package)_postprocess_cmds
|
|
||||||
rm -rf share bin etc
|
|
||||||
endef
|
|
||||||
@@ -39,8 +39,8 @@ native_packages := native_ccache
|
|||||||
wallet_packages=bdb
|
wallet_packages=bdb
|
||||||
|
|
||||||
ifeq ($(host_os),linux)
|
ifeq ($(host_os),linux)
|
||||||
packages := boost openssl libevent zeromq $(zcash_packages) googletest libcurl #googlemock
|
packages := boost wolfssl libevent zeromq $(zcash_packages) googletest libcurl #googlemock
|
||||||
else
|
else
|
||||||
packages := boost openssl libevent zeromq $(zcash_packages) libcurl googletest #googlemock
|
packages := boost wolfssl libevent zeromq $(zcash_packages) libcurl googletest #googlemock
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
46
depends/packages/wolfssl.mk
Normal file
46
depends/packages/wolfssl.mk
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package=wolfssl
|
||||||
|
$(package)_version=4.5.0
|
||||||
|
$(package)_download_path=https://github.com/wolfSSL/wolfssl/archive
|
||||||
|
$(package)_download_file=v$($(package)_version)-stable.tar.gz
|
||||||
|
$(package)_file_name=wolfssl-$($(package)_version).tar.gz
|
||||||
|
$(package)_sha256_hash=7de62300ce14daa0051bfefc7c4d6302f96cabc768b6ae49eda77523b118250c
|
||||||
|
|
||||||
|
define $(package)_set_vars
|
||||||
|
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||||
|
$(package)_config_opts=--prefix=$(host_prefix)
|
||||||
|
$(package)_config_opts+=--enable-static
|
||||||
|
$(package)_config_opts+=--disable-shared
|
||||||
|
$(package)_config_opts+=--disable-examples
|
||||||
|
$(package)_config_opts+=--disable-crypttests
|
||||||
|
$(package)_config_opts+=--enable-keygen
|
||||||
|
$(package)_config_opts+=--enable-certgen
|
||||||
|
$(package)_config_opts+=--enable-enckeys
|
||||||
|
$(package)_config_opts+=--enable-opensslall
|
||||||
|
$(package)_config_opts+=--enable-opensslextra
|
||||||
|
$(package)_config_opts+=--enable-harden
|
||||||
|
endef
|
||||||
|
|
||||||
|
define $(package)_preprocess_cmds
|
||||||
|
cd $($(package)_build_subdir); ./autogen.sh
|
||||||
|
endef
|
||||||
|
|
||||||
|
define $(package)_config_cmds
|
||||||
|
./configure $($(package)_config_opts)
|
||||||
|
endef
|
||||||
|
|
||||||
|
#define $(package)_config_cmds
|
||||||
|
# $($(package)_autoconf)
|
||||||
|
#endef
|
||||||
|
|
||||||
|
define $(package)_build_cmds
|
||||||
|
$(MAKE) -j1 src/libwolfssl.la
|
||||||
|
endef
|
||||||
|
|
||||||
|
define $(package)_stage_cmds
|
||||||
|
$(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-nobase_includeHEADERS install-pkgconfigDATA
|
||||||
|
endef
|
||||||
|
|
||||||
|
#define $(package)_postprocess_cmds
|
||||||
|
# rm -rf bin share
|
||||||
|
#endef
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "crosschain.h"
|
#include "crosschain.h"
|
||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
#include "cc/CCinclude.h"
|
#include "cc/CCinclude.h"
|
||||||
#include <openssl/sha.h>
|
#include <wolfssl/wolfcrypt/sha.h>
|
||||||
#include "cc/CCtokens.h"
|
#include "cc/CCtokens.h"
|
||||||
|
|
||||||
#include "key_io.h"
|
#include "key_io.h"
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
// Copyright (c) 2019-2020 The Hush developers
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the GPLv3 software license, see the accompanying
|
// Distributed under the GPLv3 software license, see the accompanying
|
||||||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||||
#include <openssl/conf.h>
|
#include <wolfssl/options.h>
|
||||||
#include <openssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <wolfssl/openssl/dh.h>
|
||||||
|
#include <wolfssl/wolfcrypt/asn.h>
|
||||||
#ifndef HEADER_DH_H
|
|
||||||
#include <openssl/dh.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
@@ -23,7 +20,7 @@ namespace hush
|
|||||||
// it is OK to hard code it (or as an alternative to read it from a file)
|
// it is OK to hard code it (or as an alternative to read it from a file)
|
||||||
// ----
|
// ----
|
||||||
// generated via: openssl dhparam -C 2048
|
// generated via: openssl dhparam -C 2048
|
||||||
static DH *get_dh2048(void)
|
static WOLFSSL_DH *get_dh2048(void)
|
||||||
{
|
{
|
||||||
static unsigned char dhp_2048[] = {
|
static unsigned char dhp_2048[] = {
|
||||||
0xFF, 0x4A, 0xA8, 0x6C, 0x68, 0xD4, 0x4C, 0x41, 0x73, 0x8D,
|
0xFF, 0x4A, 0xA8, 0x6C, 0x68, 0xD4, 0x4C, 0x41, 0x73, 0x8D,
|
||||||
@@ -56,24 +53,20 @@ static DH *get_dh2048(void)
|
|||||||
static unsigned char dhg_2048[] = {
|
static unsigned char dhg_2048[] = {
|
||||||
0x02
|
0x02
|
||||||
};
|
};
|
||||||
DH *dh = DH_new();
|
|
||||||
BIGNUM *p, *g;
|
WOLFSSL_DH *dh = wolfSSL_DH_new();
|
||||||
|
|
||||||
if (dh == NULL)
|
if (dh == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
p = BN_bin2bn(dhp_2048, sizeof(dhp_2048), NULL);
|
|
||||||
g = BN_bin2bn(dhg_2048, sizeof(dhg_2048), NULL);
|
if (wc_DhSetKey((DhKey*)dh->internal, dhp_2048, sizeof(dhp_2048), dhg_2048, sizeof(dhg_2048)) != 0) {
|
||||||
if (p == NULL || g == NULL
|
wolfSSL_DH_free(dh);
|
||||||
|| !DH_set0_pqg(dh, p, NULL, g)) {
|
|
||||||
DH_free(dh);
|
|
||||||
BN_free(p);
|
|
||||||
BN_free(g);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return dh;
|
return dh;
|
||||||
}
|
}
|
||||||
|
|
||||||
DH *tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
DH *tmp_dh_callback(WOLFSSL *ssl, int is_export, int keylength)
|
||||||
{
|
{
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - Using Diffie-Hellman param for PFS: is_export=%d, keylength=%d\n",
|
LogPrint("tls", "TLS: %s: %s():%d - Using Diffie-Hellman param for PFS: is_export=%d, keylength=%d\n",
|
||||||
__FILE__, __func__, __LINE__, is_export, keylength);
|
__FILE__, __func__, __LINE__, is_export, keylength);
|
||||||
@@ -82,64 +75,53 @@ DH *tmp_dh_callback(SSL *ssl, int is_export, int keylength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** if 'tls' debug category is enabled, collect info about certificates relevant to the passed context and print them on logs */
|
/** 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, X509_STORE_CTX* chainContext)
|
static void dumpCertificateDebugInfo(int preverify_ok, WOLFSSL_X509_STORE_CTX* chainContext)
|
||||||
{
|
{
|
||||||
if (!LogAcceptCategory("tls") )
|
if (!LogAcceptCategory("tls")) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char buf[256] = {};
|
char buf[256] = {};
|
||||||
X509 *cert;
|
WOLFSSL_X509 *cert;
|
||||||
int err, depth;
|
int err, depth;
|
||||||
|
|
||||||
cert = X509_STORE_CTX_get_current_cert(chainContext);
|
cert = wolfSSL_X509_STORE_CTX_get_current_cert(chainContext);
|
||||||
err = X509_STORE_CTX_get_error(chainContext);
|
err = wolfSSL_X509_STORE_CTX_get_error(chainContext);
|
||||||
depth = X509_STORE_CTX_get_error_depth(chainContext);
|
depth = wolfSSL_X509_STORE_CTX_get_error_depth(chainContext);
|
||||||
|
|
||||||
LogPrintf("TLS: %s: %s():%d - preverify_ok=%d, errCode=%d, depth=%d\n",
|
LogPrintf("TLS: %s: %s():%d - preverify_ok=%d, errCode=%d, depth=%d\n",
|
||||||
__FILE__, __func__, __LINE__, preverify_ok, err, depth);
|
__FILE__, __func__, __LINE__, preverify_ok, err, depth);
|
||||||
|
|
||||||
// is not useful checking preverify_ok because, after the chain root verification, it is set accordingly
|
// 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
|
// to the return value of this callback, and we choose to always return 1
|
||||||
if (err != X509_V_OK )
|
if (err != X509_V_OK ) {
|
||||||
{
|
|
||||||
LogPrintf("TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s] at chain depth=%d\n",
|
LogPrintf("TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s] at chain depth=%d\n",
|
||||||
__FILE__, __func__, __LINE__, err, X509_verify_cert_error_string(err), depth);
|
__FILE__, __func__, __LINE__, err, wolfSSL_X509_verify_cert_error_string(err), depth);
|
||||||
|
|
||||||
if (cert && err == X509_V_ERR_CERT_HAS_EXPIRED)
|
if (cert && err == X509_V_ERR_CERT_HAS_EXPIRED) {
|
||||||
{
|
char time_buf[MAX_TIME_STRING_SZ];
|
||||||
struct tm t = {};
|
ASN1_TIME * at = wolfSSL_X509_get_notAfter(cert);
|
||||||
const ASN1_TIME * at = X509_get0_notAfter(cert);
|
if (wolfSSL_ASN1_TIME_to_string(at, time_buf, sizeof(time_buf)) != NULL) {
|
||||||
int ret = ASN1_TIME_to_tm(at, &t);
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
(void)strftime(buf, sizeof (buf), "%c", &t);
|
|
||||||
LogPrintf("TLS: %s: %s():%d - expired on=%s\n",
|
LogPrintf("TLS: %s: %s():%d - expired on=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (cert) {
|
||||||
else if (cert)
|
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(cert), buf, 256);
|
||||||
{
|
|
||||||
X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
|
|
||||||
LogPrintf("TLS: %s: %s():%d - subj name=%s\n",
|
LogPrintf("TLS: %s: %s():%d - subj name=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
|
|
||||||
X509_NAME_oneline(X509_get_issuer_name(cert), buf, 256);
|
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(cert), buf, 256);
|
||||||
LogPrintf("TLS: %s: %s():%d - issuer name=%s\n",
|
LogPrintf("TLS: %s: %s():%d - issuer name=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
|
|
||||||
struct tm t = {};
|
char time_buf[MAX_TIME_STRING_SZ];
|
||||||
const ASN1_TIME * at = X509_get0_notAfter(cert);
|
WOLFSSL_ASN1_TIME * at = wolfSSL_X509_get_notAfter(cert);
|
||||||
int ret = ASN1_TIME_to_tm(at, &t);
|
if (wolfSSL_ASN1_TIME_to_string(at, time_buf, sizeof(time_buf)) != NULL) {
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
(void)strftime(buf, sizeof (buf), "%c", &t);
|
|
||||||
LogPrintf("TLS: %s: %s():%d - expiring on=%s\n",
|
LogPrintf("TLS: %s: %s():%d - expiring on=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// should never happen
|
// should never happen
|
||||||
LogPrintf("TLS: %s: %s():%d - invalid cert/err\n", __FILE__, __func__, __LINE__);
|
LogPrintf("TLS: %s: %s():%d - invalid cert/err\n", __FILE__, __func__, __LINE__);
|
||||||
}
|
}
|
||||||
@@ -152,7 +134,7 @@ static void dumpCertificateDebugInfo(int preverify_ok, X509_STORE_CTX* chainCont
|
|||||||
* @param chainContext
|
* @param chainContext
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int tlsCertVerificationCallback(int preverify_ok, X509_STORE_CTX* chainContext)
|
int tlsCertVerificationCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* chainContext)
|
||||||
{
|
{
|
||||||
dumpCertificateDebugInfo(preverify_ok, chainContext);
|
dumpCertificateDebugInfo(preverify_ok, chainContext);
|
||||||
|
|
||||||
@@ -175,23 +157,23 @@ int tlsCertVerificationCallback(int preverify_ok, X509_STORE_CTX* chainContext)
|
|||||||
* @param timeoutSec timeout in seconds.
|
* @param timeoutSec timeout in seconds.
|
||||||
* @return int returns nError corresponding to the connection event.
|
* @return int returns nError corresponding to the connection event.
|
||||||
*/
|
*/
|
||||||
int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl, int timeoutSec, unsigned long& err_code)
|
int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* ssl, int timeoutSec, unsigned long& err_code)
|
||||||
{
|
{
|
||||||
int retOp = 0;
|
int retOp = 0;
|
||||||
err_code = 0;
|
err_code = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true)
|
||||||
|
{
|
||||||
// clear the current thread's error queue
|
// clear the current thread's error queue
|
||||||
ERR_clear_error();
|
wolfSSL_ERR_clear_error();
|
||||||
|
|
||||||
switch (eRoutine) {
|
switch (eRoutine) {
|
||||||
case SSL_CONNECT:
|
case SSL_CONNECT:
|
||||||
{
|
{
|
||||||
retOp = SSL_connect(ssl);
|
retOp = wolfSSL_connect(ssl);
|
||||||
if (retOp == 0)
|
if (retOp == 0) {
|
||||||
{
|
err_code = wolfSSL_ERR_get_error();
|
||||||
err_code = ERR_get_error();
|
const char* error_str = wolfSSL_ERR_error_string(err_code, NULL);
|
||||||
const char* error_str = ERR_error_string(err_code, NULL);
|
|
||||||
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_CONNECT err: %s\n",
|
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_CONNECT err: %s\n",
|
||||||
__FILE__, __func__, __LINE__, error_str);
|
__FILE__, __func__, __LINE__, error_str);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -201,11 +183,10 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl,
|
|||||||
|
|
||||||
case SSL_ACCEPT:
|
case SSL_ACCEPT:
|
||||||
{
|
{
|
||||||
retOp = SSL_accept(ssl);
|
retOp = wolfSSL_accept(ssl);
|
||||||
if (retOp == 0)
|
if (retOp == 0) {
|
||||||
{
|
err_code = wolfSSL_ERR_get_error();
|
||||||
err_code = ERR_get_error();
|
const char* error_str = wolfSSL_ERR_error_string(err_code, NULL);
|
||||||
const char* error_str = ERR_error_string(err_code, NULL);
|
|
||||||
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_ACCEPT err: %s\n",
|
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_ACCEPT err: %s\n",
|
||||||
__FILE__, __func__, __LINE__, error_str);
|
__FILE__, __func__, __LINE__, error_str);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -215,19 +196,17 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl,
|
|||||||
|
|
||||||
case SSL_SHUTDOWN:
|
case SSL_SHUTDOWN:
|
||||||
{
|
{
|
||||||
if (hSocket != INVALID_SOCKET)
|
if (hSocket != INVALID_SOCKET) {
|
||||||
{
|
|
||||||
std::string disconnectedPeer("no info");
|
std::string disconnectedPeer("no info");
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
socklen_t serv_len = sizeof(addr);
|
socklen_t serv_len = sizeof(addr);
|
||||||
int ret = getpeername(hSocket, (struct sockaddr *)&addr, &serv_len);
|
int ret = getpeername(hSocket, (struct sockaddr *)&addr, &serv_len);
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
{
|
|
||||||
disconnectedPeer = std::string(inet_ntoa(addr.sin_addr)) + ":" + std::to_string(ntohs(addr.sin_port));
|
disconnectedPeer = std::string(inet_ntoa(addr.sin_addr)) + ":" + std::to_string(ntohs(addr.sin_port));
|
||||||
}
|
}
|
||||||
LogPrint("tls", "TLS: shutting down fd=%d, peer=%s\n", hSocket, disconnectedPeer);
|
LogPrint("tls", "TLS: shutting down fd=%d, peer=%s\n", hSocket, disconnectedPeer);
|
||||||
}
|
}
|
||||||
retOp = SSL_shutdown(ssl);
|
retOp = wolfSSL_shutdown(ssl);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -236,41 +215,34 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (eRoutine == SSL_SHUTDOWN) {
|
if (eRoutine == SSL_SHUTDOWN) {
|
||||||
if (retOp == 0)
|
if (retOp == 0) {
|
||||||
{
|
|
||||||
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_SHUTDOWN: The close_notify was sent but the peer did not send it back yet.\n",
|
LogPrint("tls", "TLS: WARNING: %s: %s():%d - SSL_SHUTDOWN: The close_notify was sent but the peer did not send it back yet.\n",
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
// do not call SSL_get_error() because it may misleadingly indicate an error even though no error occurred.
|
// do not call SSL_get_error() because it may misleadingly indicate an error even though no error occurred.
|
||||||
break;
|
break;
|
||||||
}
|
} else if (retOp == 1) {
|
||||||
else
|
|
||||||
if (retOp == 1)
|
|
||||||
{
|
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - SSL_SHUTDOWN completed\n", __FILE__, __func__, __LINE__);
|
LogPrint("tls", "TLS: %s: %s():%d - SSL_SHUTDOWN completed\n", __FILE__, __func__, __LINE__);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - SSL_SHUTDOWN failed\n", __FILE__, __func__, __LINE__);
|
LogPrint("tls", "TLS: %s: %s():%d - SSL_SHUTDOWN failed\n", __FILE__, __func__, __LINE__);
|
||||||
// the error will be read afterwards
|
// the error will be read afterwards
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (retOp == 1)
|
if (retOp == 1) {
|
||||||
{
|
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - %s completed\n", __FILE__, __func__, __LINE__,
|
LogPrint("tls", "TLS: %s: %s():%d - %s completed\n", __FILE__, __func__, __LINE__,
|
||||||
eRoutine == SSL_CONNECT ? "SSL_CONNECT" : "SSL_ACCEPT");
|
eRoutine == SSL_CONNECT ? "SSL_CONNECT" : "SSL_ACCEPT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sslErr = SSL_get_error(ssl, retOp);
|
int sslErr = wolfSSL_get_error(ssl, retOp);
|
||||||
|
|
||||||
if (sslErr != SSL_ERROR_WANT_READ && sslErr != SSL_ERROR_WANT_WRITE) {
|
if (sslErr != WOLFSSL_ERROR_WANT_READ && sslErr != WOLFSSL_ERROR_WANT_WRITE) {
|
||||||
err_code = ERR_get_error();
|
err_code = wolfSSL_ERR_get_error();
|
||||||
const char* error_str = ERR_error_string(err_code, NULL);
|
const char* error_str = wolfSSL_ERR_error_string(err_code, NULL);
|
||||||
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",
|
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__,
|
__FILE__, __func__, __LINE__,
|
||||||
eRoutine, sslErr, retOp, errno, ERR_GET_LIB(err_code), ERR_GET_FUNC(err_code), 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), error_str);
|
||||||
retOp = -1;
|
retOp = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -281,7 +253,7 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl,
|
|||||||
|
|
||||||
struct timeval timeout = {timeoutSec, 0};
|
struct timeval timeout = {timeoutSec, 0};
|
||||||
|
|
||||||
if (sslErr == SSL_ERROR_WANT_READ) {
|
if (sslErr == WOLFSSL_ERROR_WANT_READ) {
|
||||||
int result = select(hSocket + 1, &socketSet, NULL, NULL, &timeout);
|
int result = select(hSocket + 1, &socketSet, NULL, NULL, &timeout);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
LogPrint("tls", "TLS: ERROR: %s: %s():%d - WANT_READ timeout on %s\n", __FILE__, __func__, __LINE__,
|
LogPrint("tls", "TLS: ERROR: %s: %s():%d - WANT_READ timeout on %s\n", __FILE__, __func__, __LINE__,
|
||||||
@@ -323,18 +295,18 @@ int TLSManager::waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl,
|
|||||||
* @param hSocket socket
|
* @param hSocket socket
|
||||||
* @param addrConnect the outgoing address
|
* @param addrConnect the outgoing address
|
||||||
* @param tls_ctx_client TLS Client context
|
* @param tls_ctx_client TLS Client context
|
||||||
* @return SSL* returns a ssl* if successful, otherwise returns NULL.
|
* @return WOLFSSL* returns a ssl* if successful, otherwise returns NULL.
|
||||||
*/
|
*/
|
||||||
SSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code)
|
WOLFSSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code)
|
||||||
{
|
{
|
||||||
LogPrint("tls", "TLS: establishing connection (tid = %X), (peerid = %s)\n", pthread_self(), addrConnect.ToString());
|
LogPrint("tls", "TLS: establishing connection (tid = %X), (peerid = %s)\n", pthread_self(), addrConnect.ToString());
|
||||||
|
|
||||||
err_code = 0;
|
err_code = 0;
|
||||||
SSL* ssl = NULL;
|
WOLFSSL* ssl = NULL;
|
||||||
bool bConnectedTLS = false;
|
bool bConnectedTLS = false;
|
||||||
|
|
||||||
if ((ssl = SSL_new(tls_ctx_client))) {
|
if ((ssl = wolfSSL_new(tls_ctx_client))) {
|
||||||
if (SSL_set_fd(ssl, hSocket)) {
|
if (wolfSSL_set_fd(ssl, hSocket)) {
|
||||||
int ret = TLSManager::waitFor(SSL_CONNECT, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code);
|
int ret = TLSManager::waitFor(SSL_CONNECT, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
{
|
{
|
||||||
@@ -344,25 +316,25 @@ SSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsigned l
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err_code = ERR_get_error();
|
err_code = wolfSSL_ERR_get_error();
|
||||||
const char* error_str = ERR_error_string(err_code, NULL);
|
const char* error_str = wolfSSL_ERR_error_string(err_code, NULL);
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n",
|
LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n",
|
||||||
__FILE__, __func__, __LINE__, error_str);
|
__FILE__, __func__, __LINE__, error_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (bConnectedTLS) {
|
if (bConnectedTLS) {
|
||||||
LogPrintf("TLS: connection to %s has been established (tlsv = %s 0x%04x / ssl = %s 0x%x ). Using cipher: %s\n",
|
LogPrintf("TLS: connection to %s has been established (tlsv = %s 0x%04x / ssl = %s 0x%x ). Using cipher: %s\n",
|
||||||
addrConnect.ToString(), SSL_get_version(ssl), SSL_version(ssl), OpenSSL_version(OPENSSL_VERSION), OpenSSL_version_num(), SSL_get_cipher(ssl));
|
addrConnect.ToString(), wolfSSL_get_version(ssl), wolfSSL_version(ssl), wolfSSL_OpenSSL_version(), wolfSSL_lib_version_hex(), wolfSSL_get_cipher_name(ssl));
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: %s: %s():%d - TLS connection to %s failed (err_code 0x%X)\n",
|
LogPrintf("TLS: %s: %s():%d - TLS connection to %s failed (err_code 0x%X)\n",
|
||||||
__FILE__, __func__, __LINE__, addrConnect.ToString(), err_code);
|
__FILE__, __func__, __LINE__, addrConnect.ToString(), err_code);
|
||||||
|
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
SSL_free(ssl);
|
wolfSSL_free(ssl);
|
||||||
ssl = NULL;
|
ssl = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -372,9 +344,9 @@ SSL* TLSManager::connect(SOCKET hSocket, const CAddress& addrConnect, unsigned l
|
|||||||
* @param privateKeyFile private key file path
|
* @param privateKeyFile private key file path
|
||||||
* @param certificateFile certificate key file path
|
* @param certificateFile certificate key file path
|
||||||
* @param trustedDirs trusted directories
|
* @param trustedDirs trusted directories
|
||||||
* @return SSL_CTX* returns the context.
|
* @return WOLSSL_CTX* returns the context.
|
||||||
*/
|
*/
|
||||||
SSL_CTX* TLSManager::initCtx(
|
WOLFSSL_CTX* TLSManager::initCtx(
|
||||||
TLSContextType ctxType,
|
TLSContextType ctxType,
|
||||||
const boost::filesystem::path& privateKeyFile,
|
const boost::filesystem::path& privateKeyFile,
|
||||||
const boost::filesystem::path& certificateFile,
|
const boost::filesystem::path& certificateFile,
|
||||||
@@ -383,90 +355,87 @@ SSL_CTX* TLSManager::initCtx(
|
|||||||
LogPrintf("TLS: %s: %s():%d - Initializing %s context\n",
|
LogPrintf("TLS: %s: %s():%d - Initializing %s context\n",
|
||||||
__FILE__, __func__, __LINE__, ctxType == SERVER_CONTEXT ? "server" : "client");
|
__FILE__, __func__, __LINE__, ctxType == SERVER_CONTEXT ? "server" : "client");
|
||||||
|
|
||||||
if (!boost::filesystem::exists(privateKeyFile) ||
|
if (!boost::filesystem::exists(privateKeyFile) || !boost::filesystem::exists(certificateFile)) {
|
||||||
!boost::filesystem::exists(certificateFile))
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
bool bInitialized = false;
|
bool bInitialized = false;
|
||||||
SSL_CTX* tlsCtx = NULL;
|
WOLFSSL_CTX* tlsCtx = NULL;
|
||||||
|
|
||||||
if ((tlsCtx = SSL_CTX_new(ctxType == SERVER_CONTEXT ? TLS_server_method() : TLS_client_method()))) {
|
if ((tlsCtx = wolfSSL_CTX_new(ctxType == SERVER_CONTEXT ? wolfTLSv1_3_server_method() : wolfTLSv1_3_client_method()))) {
|
||||||
SSL_CTX_set_mode(tlsCtx, SSL_MODE_AUTO_RETRY);
|
wolfSSL_CTX_set_mode(tlsCtx, SSL_MODE_AUTO_RETRY);
|
||||||
|
|
||||||
// Disable TLS < 1.3
|
// Disable TLS < 1.3 ... imho redundant, because v1.3 is required via method
|
||||||
int ret = SSL_CTX_set_min_proto_version(tlsCtx, TLS1_3_VERSION);
|
int ret = wolfSSL_CTX_set_min_proto_version(tlsCtx, TLS1_3_VERSION);
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
{
|
|
||||||
LogPrintf("TLS: WARNING: %s: %s():%d - failed to set min TLS version\n", __FILE__, __func__, __LINE__);
|
LogPrintf("TLS: WARNING: %s: %s():%d - failed to set min TLS version\n", __FILE__, __func__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("TLS: %s: %s():%d - setting cipher list\n", __FILE__, __func__, __LINE__);
|
LogPrintf("TLS: %s: %s():%d - setting cipher list\n", __FILE__, __func__, __LINE__);
|
||||||
|
|
||||||
SSL_CTX_set_cipher_list(tlsCtx, ""); // removes all <= TLS1.2 ciphers
|
// Default TLSv1.3 cipher list is "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
|
||||||
// default is "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
|
// Nodes will randomly choose to prefer first cipher or the second, to create diversity on the network
|
||||||
// Nodes will randomly choose to prefer one suite or the other, to create diversity on the network
|
|
||||||
// and not be in the situation where all nodes have the same list so the first is always used
|
// and not be in the situation where all nodes have the same list so the first is always used
|
||||||
if(GetRand(100) > 50) {
|
if(GetRand(100) > 50) {
|
||||||
if (SSL_CTX_set_ciphersuites(tlsCtx, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256")) {
|
if (wolfSSL_CTX_set_cipher_list(tlsCtx, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256")) {
|
||||||
LogPrintf("%s: Preferring TLS_AES256-GCM-SHA384\n", __func__);
|
LogPrintf("%s: Preferring TLS_AES256-GCM-SHA384\n", __func__);
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("%s: Setting preferred cipher failed !!!\n", __func__);
|
LogPrintf("%s: Setting preferred cipher failed !!!\n", __func__);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (SSL_CTX_set_ciphersuites(tlsCtx, "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384")) {
|
if (wolfSSL_CTX_set_cipher_list(tlsCtx, "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384")) {
|
||||||
LogPrintf("%s: Preferring TLS_AES256-GCM-SHA384\n", __func__);
|
LogPrintf("%s: Preferring TLS_AES256-GCM-SHA384\n", __func__);
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("%s: Setting preferred cipher failed !!!\n", __func__);
|
LogPrintf("%s: Setting preferred cipher failed !!!\n", __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLS 1.3 has ephemeral Diffie-Hellman as the only key exchange mechanism, so that perfect forward
|
// TLSv1.3 has ephemeral Diffie-Hellman as the only key exchange mechanism, so that perfect forward secrecy is ensured.
|
||||||
// secrecy is ensured.
|
|
||||||
|
|
||||||
if (ctxType == SERVER_CONTEXT)
|
if (ctxType == SERVER_CONTEXT) {
|
||||||
{
|
|
||||||
// amongst the Cl/Srv mutually-acceptable set, pick the one that the server prefers most instead of the one that
|
// amongst the Cl/Srv mutually-acceptable set, pick the one that the server prefers most instead of the one that
|
||||||
// the client prefers most
|
// the client prefers most
|
||||||
SSL_CTX_set_options(tlsCtx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
wolfSSL_CTX_set_options(tlsCtx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
|
|
||||||
LogPrintf("TLS: %s: %s():%d - setting dh callback\n", __FILE__, __func__, __LINE__);
|
LogPrintf("TLS: %s: %s():%d - setting dh callback\n", __FILE__, __func__, __LINE__);
|
||||||
SSL_CTX_set_tmp_dh_callback(tlsCtx, tmp_dh_callback);
|
SSL_CTX_set_tmp_dh_callback(tlsCtx, tmp_dh_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix for Secure Client-Initiated Renegotiation DoS threat
|
// Fix for Secure Client-Initiated Renegotiation DoS threat:
|
||||||
SSL_CTX_set_options(tlsCtx, SSL_OP_NO_RENEGOTIATION);
|
// In WolfSSL library renegotiation is disabled by default build config
|
||||||
|
|
||||||
int min_ver = SSL_CTX_get_min_proto_version(tlsCtx);
|
// Support for TLSv1.3 should be the only one compiled
|
||||||
int max_ver = SSL_CTX_get_max_proto_version(tlsCtx); // 0x0 means auto
|
// ./configure --disable-oldtls --disable-tlsv12
|
||||||
int opt_mask = SSL_CTX_get_options(tlsCtx);
|
|
||||||
|
|
||||||
LogPrintf("TLS: proto version: min/max 0x%04x/0x04%x, opt_mask=0x%x\n", min_ver, max_ver, opt_mask);
|
|
||||||
|
|
||||||
int rootCertsNum = LoadDefaultRootCertificates(tlsCtx);
|
int rootCertsNum = LoadDefaultRootCertificates(tlsCtx);
|
||||||
int trustedPathsNum = 0;
|
int trustedPathsNum = 0;
|
||||||
|
|
||||||
for (boost::filesystem::path trustedDir : trustedDirs) {
|
for (boost::filesystem::path trustedDir : trustedDirs)
|
||||||
if (SSL_CTX_load_verify_locations(tlsCtx, NULL, trustedDir.string().c_str()) == 1)
|
{
|
||||||
|
if (wolfSSL_CTX_load_verify_locations(tlsCtx, NULL, trustedDir.string().c_str()) == 1) {
|
||||||
trustedPathsNum++;
|
trustedPathsNum++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rootCertsNum == 0 && trustedPathsNum == 0)
|
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__);
|
LogPrintf("TLS: WARNING: %s: %s: failed to set up verified certificates. It will be impossible to verify peer certificates. \n", __FILE__, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify(tlsCtx, SSL_VERIFY_PEER, tlsCertVerificationCallback);
|
wolfSSL_CTX_set_verify(tlsCtx, WOLFSSL_VERIFY_PEER, tlsCertVerificationCallback);
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_file(tlsCtx, certificateFile.string().c_str(), SSL_FILETYPE_PEM) > 0) {
|
if (wolfSSL_CTX_use_certificate_file(tlsCtx, certificateFile.string().c_str(), WOLFSSL_FILETYPE_PEM) > 0) {
|
||||||
if (SSL_CTX_use_PrivateKey_file(tlsCtx, privateKeyFile.string().c_str(), SSL_FILETYPE_PEM) > 0) {
|
if (wolfSSL_CTX_use_PrivateKey_file(tlsCtx, privateKeyFile.string().c_str(), WOLFSSL_FILETYPE_PEM) > 0) {
|
||||||
if (SSL_CTX_check_private_key(tlsCtx)) {
|
if (wolfSSL_CTX_check_private_key(tlsCtx)) {
|
||||||
bInitialized = true;
|
bInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: private key does not match the certificate public key\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: private key does not match the certificate public key\n", __FILE__, __func__);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: failed to use privateKey file\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: failed to use privateKey file\n", __FILE__, __func__);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: failed to use certificate file\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: failed to use certificate file\n", __FILE__, __func__);
|
||||||
ERR_print_errors_fp(stderr);
|
wolfSSL_ERR_dump_errors_fp(stderr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: failed to create TLS context\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: failed to create TLS context\n", __FILE__, __func__);
|
||||||
@@ -474,7 +443,7 @@ SSL_CTX* TLSManager::initCtx(
|
|||||||
|
|
||||||
if (!bInitialized) {
|
if (!bInitialized) {
|
||||||
if (tlsCtx) {
|
if (tlsCtx) {
|
||||||
SSL_CTX_free(tlsCtx);
|
wolfSSL_CTX_free(tlsCtx);
|
||||||
tlsCtx = NULL;
|
tlsCtx = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,18 +493,18 @@ bool TLSManager::prepareCredentials()
|
|||||||
* @param hSocket the TLS socket.
|
* @param hSocket the TLS socket.
|
||||||
* @param addr incoming address.
|
* @param addr incoming address.
|
||||||
* @param tls_ctx_server TLS server context.
|
* @param tls_ctx_server TLS server context.
|
||||||
* @return SSL* returns pointer to the ssl object if successful, otherwise returns NULL
|
* @return WOLFSSL* returns pointer to the ssl object if successful, otherwise returns NULL
|
||||||
*/
|
*/
|
||||||
SSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code)
|
WOLFSSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code)
|
||||||
{
|
{
|
||||||
LogPrint("tls", "TLS: accepting connection from %s (tid = %X)\n", addr.ToString(), pthread_self());
|
LogPrint("tls", "TLS: accepting connection from %s (tid = %X)\n", addr.ToString(), pthread_self());
|
||||||
|
|
||||||
err_code = 0;
|
err_code = 0;
|
||||||
SSL* ssl = NULL;
|
WOLFSSL* ssl = NULL;
|
||||||
bool bAcceptedTLS = false;
|
bool bAcceptedTLS = false;
|
||||||
|
|
||||||
if ((ssl = SSL_new(tls_ctx_server))) {
|
if ((ssl = wolfSSL_new(tls_ctx_server))) {
|
||||||
if (SSL_set_fd(ssl, hSocket)) {
|
if (wolfSSL_set_fd(ssl, hSocket)) {
|
||||||
int ret = TLSManager::waitFor(SSL_ACCEPT, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code);
|
int ret = TLSManager::waitFor(SSL_ACCEPT, hSocket, ssl, (DEFAULT_CONNECT_TIMEOUT / 1000), err_code);
|
||||||
if (ret == 1)
|
if (ret == 1)
|
||||||
{
|
{
|
||||||
@@ -545,20 +514,20 @@ SSL* TLSManager::accept(SOCKET hSocket, const CAddress& addr, unsigned long& err
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err_code = ERR_get_error();
|
err_code = wolfSSL_ERR_get_error();
|
||||||
const char* error_str = ERR_error_string(err_code, NULL);
|
const char* error_str = wolfSSL_ERR_error_string(err_code, NULL);
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n",
|
LogPrint("tls", "TLS: %s: %s():%d - SSL_new failed err: %s\n",
|
||||||
__FILE__, __func__, __LINE__, error_str);
|
__FILE__, __func__, __LINE__, error_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bAcceptedTLS) {
|
if (bAcceptedTLS) {
|
||||||
LogPrintf("TLS: connection from %s has been accepted (tlsv = %s 0x%04x / ssl = %s 0x%x ). Using cipher: %s\n",
|
LogPrintf("TLS: connection from %s has been accepted (tlsv = %s 0x%04x / ssl = %s 0x%x ). Using cipher: %s\n",
|
||||||
addr.ToString(), SSL_get_version(ssl), SSL_version(ssl), OpenSSL_version(OPENSSL_VERSION), OpenSSL_version_num(), SSL_get_cipher(ssl));
|
addr.ToString(), wolfSSL_get_version(ssl), wolfSSL_version(ssl), wolfSSL_OpenSSL_version(), wolfSSL_lib_version_hex(), wolfSSL_get_cipher(ssl));
|
||||||
|
|
||||||
STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl);
|
WOLFSSL_STACK *sk = wolfSSL_get_ciphers_compat(ssl);
|
||||||
for (int i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
|
for (int i = 0; i < wolfSSL_sk_SSL_CIPHER_num(sk); i++) {
|
||||||
const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
|
const WOLFSSL_CIPHER *c = wolfSSL_sk_SSL_CIPHER_value(sk, i);
|
||||||
LogPrint("tls", "TLS: supporting cipher: %s\n", SSL_CIPHER_get_name(c));
|
LogPrint("tls", "TLS: supporting cipher: %s\n", wolfSSL_CIPHER_get_name(c));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: %s: %s():%d - TLS connection from %s failed (err_code 0x%X)\n",
|
LogPrintf("TLS: %s: %s():%d - TLS connection from %s failed (err_code 0x%X)\n",
|
||||||
@@ -663,9 +632,9 @@ int TLSManager::threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fds
|
|||||||
bIsSSL = (pnode->ssl != NULL);
|
bIsSSL = (pnode->ssl != NULL);
|
||||||
|
|
||||||
if (bIsSSL) {
|
if (bIsSSL) {
|
||||||
ERR_clear_error(); // clear the error queue, otherwise we may be reading an old error that occurred previously in the current thread
|
wolfSSL_ERR_clear_error(); // clear the error queue, otherwise we may be reading an old error that occurred previously in the current thread
|
||||||
nBytes = SSL_read(pnode->ssl, pchBuf, sizeof(pchBuf));
|
nBytes = wolfSSL_read(pnode->ssl, pchBuf, sizeof(pchBuf));
|
||||||
nRet = SSL_get_error(pnode->ssl, nBytes);
|
nRet = wolfSSL_get_error(pnode->ssl, nBytes);
|
||||||
} else {
|
} else {
|
||||||
nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
||||||
nRet = WSAGetLastError();
|
nRet = WSAGetLastError();
|
||||||
@@ -697,7 +666,7 @@ int TLSManager::threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fds
|
|||||||
// error
|
// error
|
||||||
//
|
//
|
||||||
if (bIsSSL) {
|
if (bIsSSL) {
|
||||||
if (nRet != SSL_ERROR_WANT_READ && nRet != SSL_ERROR_WANT_WRITE) // SSL_read() operation has to be repeated because of SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE (https://wiki.openssl.org/index.php/Manual:SSL_read(3)#NOTES)
|
if (nRet != WOLFSSL_ERROR_WANT_READ && nRet != WOLFSSL_ERROR_WANT_WRITE)
|
||||||
{
|
{
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
LogPrintf("TSL: ERROR: SSL_read %s\n", ERR_error_string(nRet, NULL));
|
LogPrintf("TSL: ERROR: SSL_read %s\n", ERR_error_string(nRet, NULL));
|
||||||
@@ -747,10 +716,10 @@ bool TLSManager::initialize()
|
|||||||
|
|
||||||
// Initialization routines for the OpenSSL library
|
// Initialization routines for the OpenSSL library
|
||||||
//
|
//
|
||||||
SSL_load_error_strings();
|
wolfSSL_load_error_strings();
|
||||||
ERR_load_crypto_strings();
|
wolfSSL_ERR_load_crypto_strings();
|
||||||
OpenSSL_add_ssl_algorithms(); // OpenSSL_add_ssl_algorithms() always returns "1", so it is safe to discard the return value.
|
wolfSSL_library_init();
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
fs::path certFile = GetArg("-tlscertpath", "");
|
fs::path certFile = GetArg("-tlscertpath", "");
|
||||||
if (!fs::exists(certFile))
|
if (!fs::exists(certFile))
|
||||||
@@ -784,7 +753,7 @@ bool TLSManager::initialize()
|
|||||||
bInitializationStatus = true;
|
bInitializationStatus = true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: failed to initialize TLS client context\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: failed to initialize TLS client context\n", __FILE__, __func__);
|
||||||
SSL_CTX_free (tls_ctx_server);
|
wolfSSL_CTX_free (tls_ctx_server);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("TLS: ERROR: %s: %s: failed to initialize TLS server context\n", __FILE__, __func__);
|
LogPrintf("TLS: ERROR: %s: %s: failed to initialize TLS server context\n", __FILE__, __func__);
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
// Copyright (c) 2019-2020 The Hush developers
|
// Copyright (c) 2019-2020 The Hush developers
|
||||||
// Distributed under the GPLv3 software license, see the accompanying
|
// Distributed under the GPLv3 software license, see the accompanying
|
||||||
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
||||||
#include <openssl/conf.h>
|
#include <wolfssl/options.h>
|
||||||
#include <openssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
|
||||||
#include "tlsenums.h"
|
#include "tlsenums.h"
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
@@ -46,17 +45,17 @@ public:
|
|||||||
function code and reason code. */
|
function code and reason code. */
|
||||||
static const long SELECT_TIMEDOUT = 0xFFFFFFFF;
|
static const long SELECT_TIMEDOUT = 0xFFFFFFFF;
|
||||||
|
|
||||||
int waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, SSL* ssl, int timeoutSec, unsigned long& err_code);
|
int waitFor(SSLConnectionRoutine eRoutine, SOCKET hSocket, WOLFSSL* ssl, int timeoutSec, unsigned long& err_code);
|
||||||
|
|
||||||
SSL* connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code);
|
WOLFSSL* connect(SOCKET hSocket, const CAddress& addrConnect, unsigned long& err_code);
|
||||||
SSL_CTX* initCtx(
|
WOLFSSL_CTX* initCtx(
|
||||||
TLSContextType ctxType,
|
TLSContextType ctxType,
|
||||||
const boost::filesystem::path& privateKeyFile,
|
const boost::filesystem::path& privateKeyFile,
|
||||||
const boost::filesystem::path& certificateFile,
|
const boost::filesystem::path& certificateFile,
|
||||||
const std::vector<boost::filesystem::path>& trustedDirs);
|
const std::vector<boost::filesystem::path>& trustedDirs);
|
||||||
|
|
||||||
bool prepareCredentials();
|
bool prepareCredentials();
|
||||||
SSL* accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code);
|
WOLFSSL* accept(SOCKET hSocket, const CAddress& addr, unsigned long& err_code);
|
||||||
bool isNonTLSAddr(const string& strAddr, const vector<NODE_ADDR>& vPool, CCriticalSection& cs);
|
bool isNonTLSAddr(const string& strAddr, const vector<NODE_ADDR>& vPool, CCriticalSection& cs);
|
||||||
void cleanNonTLSPool(std::vector<NODE_ADDR>& vPool, CCriticalSection& cs);
|
void cleanNonTLSPool(std::vector<NODE_ADDR>& vPool, CCriticalSection& cs);
|
||||||
int threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fdsetSend, fd_set& fdsetError);
|
int threadSocketHandler(CNode* pnode, fd_set& fdsetRecv, fd_set& fdsetSend, fd_set& fdsetError);
|
||||||
|
|||||||
@@ -6,11 +6,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <openssl/rsa.h>
|
#include <wolfssl/options.h>
|
||||||
#include <openssl/x509.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include <openssl/pem.h>
|
#include <wolfssl/wolfcrypt/rsa.h>
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem/operations.hpp>
|
||||||
|
|
||||||
@@ -67,37 +65,31 @@ static const char defaultRootCerts[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Generates RSA keypair (a private key of 'bits' length for a specified 'uPublicKey')
|
// Generates RSA keypair (a private key of 'bits' length for a specified 'uPublicKey')
|
||||||
//
|
// obsolete since we use EC instead of RSA
|
||||||
static EVP_PKEY* GenerateRsaKey(int bits, BN_ULONG uPublicKey)
|
static WOLFSSL_EVP_PKEY* GenerateRsaKey(int bits, WOLFSSL_BN_ULONG uPublicKey)
|
||||||
{
|
{
|
||||||
EVP_PKEY *evpPrivKey = NULL;
|
WOLFSSL_EVP_PKEY *evpPrivKey = NULL;
|
||||||
|
|
||||||
BIGNUM *pubKey = BN_new();
|
WOLFSSL_BIGNUM *pubKey = wolfSSL_BN_new();
|
||||||
if (pubKey)
|
if (pubKey) {
|
||||||
{
|
if (wolfSSL_BN_set_word(pubKey, uPublicKey)) {
|
||||||
if (BN_set_word(pubKey, uPublicKey))
|
WOLFSSL_RSA *privKey = wolfSSL_RSA_new();
|
||||||
{
|
if (privKey) {
|
||||||
RSA *privKey = RSA_new();
|
if (wolfSSL_RAND_poll() && wolfSSL_RSA_generate_key_ex(privKey, bits, pubKey, NULL)) {
|
||||||
if (privKey)
|
if ((evpPrivKey = wolfSSL_EVP_PKEY_new())) {
|
||||||
{
|
if (!wolfSSL_EVP_PKEY_assign_RSA(evpPrivKey, privKey)) {
|
||||||
if (RAND_poll() && // The pseudo-random number generator must be seeded prior to calling RSA_generate_key_ex(). (https://www.openssl.org/docs/man1.1.0/crypto/RSA_generate_key.html)
|
wolfSSL_EVP_PKEY_free(evpPrivKey);
|
||||||
RSA_generate_key_ex(privKey, bits, pubKey, NULL))
|
|
||||||
{
|
|
||||||
if ((evpPrivKey = EVP_PKEY_new()))
|
|
||||||
{
|
|
||||||
if (!EVP_PKEY_assign_RSA(evpPrivKey, privKey))
|
|
||||||
{
|
|
||||||
EVP_PKEY_free(evpPrivKey);
|
|
||||||
evpPrivKey = NULL;
|
evpPrivKey = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!evpPrivKey) // EVP_PKEY_assign_RSA uses the supplied key internally
|
if(!evpPrivKey) {
|
||||||
RSA_free(privKey);
|
wolfSSL_RSA_free(privKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BN_free(pubKey);
|
wolfSSL_BN_free(pubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return evpPrivKey;
|
return evpPrivKey;
|
||||||
@@ -105,27 +97,24 @@ static EVP_PKEY* GenerateRsaKey(int bits, BN_ULONG uPublicKey)
|
|||||||
|
|
||||||
// Generates EC keypair
|
// Generates EC keypair
|
||||||
//
|
//
|
||||||
static EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1)
|
static WOLFSSL_EVP_PKEY* GenerateEcKey(int nid = NID_X9_62_prime256v1)
|
||||||
{
|
{
|
||||||
EVP_PKEY *evpPrivKey = NULL;
|
WOLFSSL_EVP_PKEY *evpPrivKey = NULL;
|
||||||
EC_KEY *privKey = EC_KEY_new_by_curve_name(nid);
|
WOLFSSL_EC_KEY *privKey = wolfSSL_EC_KEY_new_by_curve_name(nid);
|
||||||
if (privKey)
|
if (privKey) {
|
||||||
{
|
wolfSSL_EC_KEY_set_asn1_flag(privKey, OPENSSL_EC_NAMED_CURVE);
|
||||||
EC_KEY_set_asn1_flag(privKey, OPENSSL_EC_NAMED_CURVE);
|
if (wolfSSL_EC_KEY_generate_key(privKey)) {
|
||||||
if (EC_KEY_generate_key(privKey))
|
if ((evpPrivKey = wolfSSL_EVP_PKEY_new())) {
|
||||||
{
|
if (!wolfSSL_EVP_PKEY_assign_EC_KEY(evpPrivKey, privKey)) {
|
||||||
if ((evpPrivKey = EVP_PKEY_new()))
|
wolfSSL_EVP_PKEY_free(evpPrivKey);
|
||||||
{
|
|
||||||
if (!EVP_PKEY_assign_EC_KEY(evpPrivKey, privKey))
|
|
||||||
{
|
|
||||||
EVP_PKEY_free(evpPrivKey);
|
|
||||||
evpPrivKey = NULL;
|
evpPrivKey = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!evpPrivKey)
|
if(!evpPrivKey) {
|
||||||
EC_KEY_free(privKey);
|
wolfSSL_EC_KEY_free(privKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return evpPrivKey;
|
return evpPrivKey;
|
||||||
@@ -133,42 +122,30 @@ static 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').
|
// Generates certificate for a specified public key using a corresponding private key (both of them should be specified in the 'keypair').
|
||||||
//
|
//
|
||||||
static X509* GenerateCertificate(EVP_PKEY *keypair)
|
static WOLFSSL_X509* GenerateCertificate(WOLFSSL_EVP_PKEY *keypair)
|
||||||
{
|
{
|
||||||
if (!keypair)
|
if (!keypair) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
X509 *cert = X509_new();
|
WOLFSSL_X509 *cert = wolfSSL_X509_new();
|
||||||
if (cert)
|
if (cert) {
|
||||||
{
|
|
||||||
bool bCertSigned = false;
|
bool bCertSigned = false;
|
||||||
long sn = 0;
|
long sn = 0;
|
||||||
|
|
||||||
if (RAND_bytes((unsigned char*)&sn, sizeof sn) &&
|
if (wolfSSL_RAND_bytes((unsigned char*)&sn, sizeof(sn)) &&wolfSSL_ASN1_INTEGER_set(wolfSSL_X509_get_serialNumber(cert), sn)) {
|
||||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), sn))
|
wolfSSL_X509_gmtime_adj(wolfSSL_X509_get_notBefore(cert), 0);
|
||||||
{
|
wolfSSL_X509_gmtime_adj(wolfSSL_X509_get_notAfter(cert), (60 * 60 * 24 * CERT_VALIDITY_DAYS));
|
||||||
X509_gmtime_adj(X509_get_notBefore(cert), 0);
|
|
||||||
X509_gmtime_adj(X509_get_notAfter(cert), (60 * 60 * 24 * CERT_VALIDITY_DAYS));
|
|
||||||
|
|
||||||
// setting a public key from the keypair
|
// setting a public key from the keypair
|
||||||
if (X509_set_pubkey(cert, keypair))
|
if (wolfSSL_X509_set_pubkey(cert, keypair)) {
|
||||||
{
|
// private key from keypair is used; signature will be set inside of the cert
|
||||||
X509_NAME *subjectName = X509_get_subject_name(cert);
|
bCertSigned = wolfSSL_X509_sign(cert, keypair, wolfSSL_EVP_sha512());
|
||||||
if (subjectName)
|
|
||||||
{
|
|
||||||
// an issuer name is the same as a subject name, due to certificate is self-signed
|
|
||||||
if (X509_set_issuer_name(cert, subjectName))
|
|
||||||
{
|
|
||||||
// private key from keypair is used; signature will be set inside of the cert
|
|
||||||
bCertSigned = X509_sign(cert, keypair, EVP_sha512());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bCertSigned)
|
if (!bCertSigned) {
|
||||||
{
|
wolfSSL_X509_free(cert);
|
||||||
X509_free(cert);
|
|
||||||
cert = NULL;
|
cert = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +155,7 @@ static X509* GenerateCertificate(EVP_PKEY *keypair)
|
|||||||
|
|
||||||
// Stores key to file, specified by the 'filePath'
|
// Stores key to file, specified by the 'filePath'
|
||||||
//
|
//
|
||||||
static bool StoreKey(EVP_PKEY *key, const boost::filesystem::path &filePath, const std::string &passphrase)
|
static bool StoreKey(WOLFSSL_EVP_PKEY *key, const boost::filesystem::path &filePath, const std::string &passphrase)
|
||||||
{
|
{
|
||||||
if (!key)
|
if (!key)
|
||||||
return false;
|
return false;
|
||||||
@@ -188,12 +165,17 @@ static bool StoreKey(EVP_PKEY *key, const boost::filesystem::path &filePath, con
|
|||||||
FILE *keyfd = fopen(filePath.string().c_str(), "wb");
|
FILE *keyfd = fopen(filePath.string().c_str(), "wb");
|
||||||
if (keyfd)
|
if (keyfd)
|
||||||
{
|
{
|
||||||
const EVP_CIPHER* pCipher = NULL;
|
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 = EVP_aes_256_cbc()))
|
if (passphrase.length() && (pCipher = wolfSSL_EVP_aes_256_cbc()))
|
||||||
bStored = PEM_write_PrivateKey(keyfd, key, pCipher, NULL, 0, NULL, (void*)passphrase.c_str());
|
bStored = wolfSSL_PEM_write_ECPrivateKey(keyfd, ec_key, pCipher, NULL, 0, NULL, (void*)passphrase.c_str());
|
||||||
else
|
else
|
||||||
bStored = PEM_write_PrivateKey(keyfd, key, NULL, NULL, 0, NULL, NULL);
|
bStored = wolfSSL_PEM_write_ECPrivateKey(keyfd, ec_key, NULL, NULL, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(keyfd);
|
fclose(keyfd);
|
||||||
}
|
}
|
||||||
@@ -203,7 +185,7 @@ static bool StoreKey(EVP_PKEY *key, const boost::filesystem::path &filePath, con
|
|||||||
|
|
||||||
// Stores certificate to file, specified by the 'filePath'
|
// Stores certificate to file, specified by the 'filePath'
|
||||||
//
|
//
|
||||||
static bool StoreCertificate(X509 *cert, const boost::filesystem::path &filePath)
|
static bool StoreCertificate(WOLFSSL_X509 *cert, const boost::filesystem::path &filePath)
|
||||||
{
|
{
|
||||||
if (!cert)
|
if (!cert)
|
||||||
return false;
|
return false;
|
||||||
@@ -213,7 +195,7 @@ static bool StoreCertificate(X509 *cert, const boost::filesystem::path &filePath
|
|||||||
FILE *certfd = fopen(filePath.string().c_str(), "wb");
|
FILE *certfd = fopen(filePath.string().c_str(), "wb");
|
||||||
if (certfd)
|
if (certfd)
|
||||||
{
|
{
|
||||||
bStored = PEM_write_X509(certfd, cert);
|
bStored = wolfSSL_PEM_write_X509(certfd, cert);
|
||||||
fclose(certfd);
|
fclose(certfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,34 +204,74 @@ static bool StoreCertificate(X509 *cert, const boost::filesystem::path &filePath
|
|||||||
|
|
||||||
// Loads key from file, specified by the 'filePath'
|
// Loads key from file, specified by the 'filePath'
|
||||||
//
|
//
|
||||||
static EVP_PKEY* LoadKey(const boost::filesystem::path &filePath, const std::string &passphrase)
|
static WOLFSSL_EVP_PKEY* old_LoadKey(const boost::filesystem::path &filePath, const std::string &passphrase)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::exists(filePath))
|
if (!boost::filesystem::exists(filePath))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
EVP_PKEY *key = NULL;
|
WOLFSSL_EVP_PKEY *key = wolfSSL_EVP_PKEY_new();
|
||||||
FILE *keyfd = fopen(filePath.string().c_str(), "rb");
|
FILE *keyfd = fopen(filePath.string().c_str(), "rb");
|
||||||
if (keyfd)
|
if (keyfd)
|
||||||
{
|
{
|
||||||
key = PEM_read_PrivateKey(keyfd, NULL, NULL, passphrase.length() ? (void*)passphrase.c_str() : NULL);
|
key = wolfSSL_PEM_read_PrivateKey(keyfd, NULL, NULL, passphrase.length() ? (void*)passphrase.c_str() : NULL);
|
||||||
fclose(keyfd);
|
fclose(keyfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
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'
|
// Loads certificate from file, specified by the 'filePath'
|
||||||
//
|
//
|
||||||
static X509* LoadCertificate(const boost::filesystem::path &filePath)
|
static WOLFSSL_X509* LoadCertificate(const boost::filesystem::path &filePath)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::exists(filePath))
|
if (!boost::filesystem::exists(filePath))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
X509 *cert = NULL;
|
WOLFSSL_X509 *cert = NULL;
|
||||||
FILE *certfd = fopen(filePath.string().c_str(), "rb");
|
FILE *certfd = fopen(filePath.string().c_str(), "rb");
|
||||||
if (certfd)
|
if (certfd)
|
||||||
{
|
{
|
||||||
cert = PEM_read_X509(certfd, NULL, NULL, NULL);
|
cert = wolfSSL_PEM_read_X509(certfd, NULL, NULL, NULL);
|
||||||
fclose(certfd);
|
fclose(certfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,59 +281,24 @@ static X509* LoadCertificate(const boost::filesystem::path &filePath)
|
|||||||
// Verifies if the private key in 'key' matches the public key in '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')
|
// (Signs random bytes on 'key' and verifies signature correctness on public key from 'cert')
|
||||||
//
|
//
|
||||||
static bool IsMatching(EVP_PKEY *key, X509 *cert)
|
static bool IsMatching(WOLFSSL_EVP_PKEY *key, WOLFSSL_X509 *cert)
|
||||||
{
|
{
|
||||||
if (!key || !cert)
|
if (!key || !cert)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool bIsMatching = false;
|
if (wolfSSL_X509_verify(cert, key) == WOLFSSL_SUCCESS)
|
||||||
|
|
||||||
EVP_PKEY_CTX *ctxSign = EVP_PKEY_CTX_new(key, NULL);
|
|
||||||
if (ctxSign)
|
|
||||||
{
|
{
|
||||||
if (EVP_PKEY_sign_init(ctxSign) == 1 &&
|
return true;
|
||||||
EVP_PKEY_CTX_set_signature_md(ctxSign, EVP_sha512()) > 0)
|
|
||||||
{
|
|
||||||
unsigned char digest[SHA512_DIGEST_LENGTH] = { 0 };
|
|
||||||
size_t digestSize = sizeof digest, signatureSize = 0;
|
|
||||||
|
|
||||||
if (RAND_bytes((unsigned char*)&digest, digestSize) && // set random bytes as a digest
|
|
||||||
EVP_PKEY_sign(ctxSign, NULL, &signatureSize, digest, digestSize) == 1) // determine buffer length
|
|
||||||
{
|
|
||||||
unsigned char *signature = (unsigned char*)OPENSSL_malloc(signatureSize);
|
|
||||||
if (signature)
|
|
||||||
{
|
|
||||||
if (EVP_PKEY_sign(ctxSign, signature, &signatureSize, digest, digestSize) == 1)
|
|
||||||
{
|
|
||||||
EVP_PKEY *pubkey = X509_get_pubkey(cert);
|
|
||||||
if (pubkey)
|
|
||||||
{
|
|
||||||
EVP_PKEY_CTX *ctxVerif = EVP_PKEY_CTX_new(pubkey, NULL);
|
|
||||||
if (ctxVerif)
|
|
||||||
{
|
|
||||||
if (EVP_PKEY_verify_init(ctxVerif) == 1 &&
|
|
||||||
EVP_PKEY_CTX_set_signature_md(ctxVerif, EVP_sha512()) > 0)
|
|
||||||
{
|
|
||||||
bIsMatching = (EVP_PKEY_verify(ctxVerif, signature, signatureSize, digest, digestSize) == 1);
|
|
||||||
}
|
|
||||||
EVP_PKEY_CTX_free(ctxVerif);
|
|
||||||
}
|
|
||||||
EVP_PKEY_free(pubkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OPENSSL_free(signature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EVP_PKEY_CTX_free(ctxSign);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bIsMatching;
|
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
|
// Checks the correctness of a private-public key pair and the validity of a certificate using public key from key pair
|
||||||
//
|
//
|
||||||
static bool CheckCredentials(EVP_PKEY *key, X509 *cert)
|
static bool CheckCredentials(WOLFSSL_EVP_PKEY *key, WOLFSSL_X509 *cert)
|
||||||
{
|
{
|
||||||
if (!key || !cert)
|
if (!key || !cert)
|
||||||
return false;
|
return false;
|
||||||
@@ -320,31 +307,29 @@ static bool CheckCredentials(EVP_PKEY *key, X509 *cert)
|
|||||||
|
|
||||||
// Validating the correctness of a private-public key pair, depending on a key type
|
// Validating the correctness of a private-public key pair, depending on a key type
|
||||||
//
|
//
|
||||||
switch (EVP_PKEY_base_id(key))
|
switch (wolfSSL_EVP_PKEY_base_id(key))
|
||||||
{
|
{
|
||||||
case EVP_PKEY_RSA:
|
case EVP_PKEY_RSA:
|
||||||
case EVP_PKEY_RSA2:
|
case EVP_PKEY_RSA2:
|
||||||
{
|
{
|
||||||
RSA *rsaKey = EVP_PKEY_get1_RSA(key);
|
WOLFSSL_RSA *rsaKey = wolfSSL_EVP_PKEY_get1_RSA(key);
|
||||||
if (rsaKey)
|
if (rsaKey)
|
||||||
{
|
{
|
||||||
bIsOk = (RSA_check_key(rsaKey) == 1);
|
bIsOk = (wc_CheckRsaKey((RsaKey*)rsaKey->internal) == 0);
|
||||||
RSA_free(rsaKey);
|
wolfSSL_RSA_free(rsaKey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
{
|
{
|
||||||
EC_KEY *eccKey = EVP_PKEY_get1_EC_KEY(key);
|
WOLFSSL_EC_KEY *eccKey = wolfSSL_EVP_PKEY_get1_EC_KEY(key);
|
||||||
if (eccKey)
|
if (eccKey)
|
||||||
{
|
{
|
||||||
bIsOk = (EC_KEY_check_key(eccKey) == 1);
|
bIsOk = (wc_ecc_check_key((ecc_key*)eccKey->internal) == 0);
|
||||||
EC_KEY_free(eccKey);
|
wolfSSL_EC_KEY_free(eccKey);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Currently only RSA & EC keys are supported.
|
|
||||||
// Other key types can be added here in further.
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bIsOk = false;
|
bIsOk = false;
|
||||||
@@ -366,24 +351,28 @@ CredentialsStatus VerifyCredentials(
|
|||||||
{
|
{
|
||||||
CredentialsStatus status = credAbsent;
|
CredentialsStatus status = credAbsent;
|
||||||
|
|
||||||
EVP_PKEY *key = NULL;
|
WOLFSSL_EVP_PKEY *key = NULL;
|
||||||
X509 *cert = NULL;
|
WOLFSSL_X509 *cert = NULL;
|
||||||
|
|
||||||
key = LoadKey(keyPath, passphrase);
|
key = LoadKey(keyPath, passphrase);
|
||||||
cert = LoadCertificate(certPath);
|
cert = LoadCertificate(certPath);
|
||||||
|
|
||||||
if (key && cert)
|
if (key && cert) {
|
||||||
status = CheckCredentials(key, cert) ? credOk : credNonConsistent;
|
status = CheckCredentials(key, cert) ? credOk : credNonConsistent;
|
||||||
else if (!key && !cert)
|
} else if (!key && !cert) {
|
||||||
status = credAbsent;
|
status = credAbsent;
|
||||||
else
|
} else {
|
||||||
status = credPartiallyAbsent;
|
status = credPartiallyAbsent;
|
||||||
|
}
|
||||||
if (key)
|
|
||||||
EVP_PKEY_free(key);
|
if (key) {
|
||||||
if (cert)
|
wolfSSL_EVP_PKEY_free(key);
|
||||||
X509_free(cert);
|
}
|
||||||
|
|
||||||
|
if (cert) {
|
||||||
|
wolfSSL_X509_free(cert);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,10 +385,10 @@ bool GenerateCredentials(
|
|||||||
{
|
{
|
||||||
bool bGenerated = false;
|
bool bGenerated = false;
|
||||||
|
|
||||||
EVP_PKEY *key = NULL;
|
WOLFSSL_EVP_PKEY *key = NULL;
|
||||||
X509 *cert = NULL;
|
WOLFSSL_X509 *cert = NULL;
|
||||||
|
|
||||||
// Generating RSA key and the self-signed certificate for it
|
// Generating key and the self-signed certificate for it
|
||||||
//
|
//
|
||||||
//key = GenerateRsaKey(TLS_RSA_KEY_SIZE, RSA_F4);
|
//key = GenerateRsaKey(TLS_RSA_KEY_SIZE, RSA_F4);
|
||||||
//key = GenerateEcKey(NID_secp256k1);
|
//key = GenerateEcKey(NID_secp256k1);
|
||||||
@@ -409,16 +398,18 @@ bool GenerateCredentials(
|
|||||||
cert = GenerateCertificate(key);
|
cert = GenerateCertificate(key);
|
||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
if (StoreKey(key, keyPath, passphrase) &&
|
bool bKey = StoreKey(key, keyPath, passphrase);
|
||||||
StoreCertificate(cert, certPath))
|
bool bCert = StoreCertificate(cert, certPath);
|
||||||
|
|
||||||
|
if ( bKey && bCert )
|
||||||
{
|
{
|
||||||
bGenerated = true;
|
bGenerated = true;
|
||||||
LogPrintStr("TLS: New private key and self-signed certificate were generated successfully\n");
|
LogPrintStr("TLS: New private key and self-signed certificate were generated successfully\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_free(cert);
|
wolfSSL_X509_free(cert);
|
||||||
}
|
}
|
||||||
EVP_PKEY_free(key);
|
wolfSSL_EVP_PKEY_free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bGenerated;
|
return bGenerated;
|
||||||
@@ -429,42 +420,35 @@ bool GenerateCredentials(
|
|||||||
// Validates peer certificate using a chain of CA certificates.
|
// 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')
|
// If some of intermediate CA certificates are absent in the trusted certificates store, then validation status will be 'false')
|
||||||
//
|
//
|
||||||
bool ValidatePeerCertificate(SSL *ssl)
|
bool ValidatePeerCertificate(WOLFSSL *ssl)
|
||||||
{
|
{
|
||||||
if (!ssl)
|
if (!ssl)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool bIsOk = false;
|
bool bIsOk = false;
|
||||||
|
|
||||||
X509 *cert = SSL_get_peer_certificate (ssl);
|
WOLFSSL_X509 *cert = wolfSSL_get_peer_certificate (ssl);
|
||||||
if (cert)
|
if (cert) {
|
||||||
{
|
long errCode = wolfSSL_get_verify_result(ssl);
|
||||||
// NOTE: SSL_get_verify_result() is only useful in connection with SSL_get_peer_certificate
|
|
||||||
// (https://www.openssl.org/docs/man1.1.1/ssl/SSL_get_verify_result.html)
|
|
||||||
long errCode = SSL_get_verify_result(ssl);
|
|
||||||
if (errCode != X509_V_OK)
|
if (errCode != X509_V_OK)
|
||||||
{
|
{
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s]\n",
|
LogPrint("tls", "TLS: %s: %s():%d - Certificate Verification ERROR=%d: [%s]\n",
|
||||||
__FILE__, __func__, __LINE__, errCode, X509_verify_cert_error_string(errCode));
|
__FILE__, __func__, __LINE__, errCode, wolfSSL_X509_verify_cert_error_string(errCode));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
bIsOk = true;
|
bIsOk = true;
|
||||||
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
|
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(cert), buf, 256);
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - subj name=%s\n",
|
LogPrint("tls", "TLS: %s: %s():%d - subj name=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
|
|
||||||
X509_NAME_oneline(X509_get_issuer_name(cert), buf, 256);
|
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_issuer_name(cert), buf, 256);
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - issuer name=%s\n",
|
LogPrint("tls", "TLS: %s: %s():%d - issuer name=%s\n",
|
||||||
__FILE__, __func__, __LINE__, buf);
|
__FILE__, __func__, __LINE__, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_free(cert);
|
wolfSSL_X509_free(cert);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint("tls", "TLS: %s: %s():%d - WARNING: Peer does not have certificate\n",
|
LogPrint("tls", "TLS: %s: %s():%d - WARNING: Peer does not have certificate\n",
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
}
|
}
|
||||||
@@ -473,24 +457,21 @@ bool ValidatePeerCertificate(SSL *ssl)
|
|||||||
|
|
||||||
// Check if a given context is set up with a cert that can be validated by this context
|
// Check if a given context is set up with a cert that can be validated by this context
|
||||||
//
|
//
|
||||||
bool ValidateCertificate(SSL_CTX *ssl_ctx)
|
bool ValidateCertificate(WOLFSSL_CTX *ssl_ctx)
|
||||||
{
|
{
|
||||||
if (!ssl_ctx)
|
if (!ssl_ctx) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool bIsOk = false;
|
bool bIsOk = false;
|
||||||
|
|
||||||
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
WOLFSSL_X509_STORE *store = wolfSSL_CTX_get_cert_store(ssl_ctx);
|
||||||
|
|
||||||
if (store)
|
if (store) {
|
||||||
{
|
WOLFSSL_X509_STORE_CTX *ctx = wolfSSL_X509_STORE_CTX_new();
|
||||||
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
|
if (ctx) {
|
||||||
if (ctx)
|
bIsOk = (wolfSSL_X509_verify_cert(ctx) == WOLFSSL_SUCCESS);
|
||||||
{
|
wolfSSL_X509_STORE_CTX_free(ctx);
|
||||||
if (X509_STORE_CTX_init(ctx, store, SSL_CTX_get0_certificate(ssl_ctx), NULL) == 1)
|
|
||||||
bIsOk = X509_verify_cert(ctx) == 1;
|
|
||||||
|
|
||||||
X509_STORE_CTX_free(ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,20 +485,14 @@ std::vector<boost::filesystem::path> GetDefaultTrustedDirectories()
|
|||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
std::vector<fs::path> defaultDirectoriesList;
|
std::vector<fs::path> defaultDirectoriesList;
|
||||||
|
|
||||||
// Default certificates directory specified in OpenSSL build
|
|
||||||
fs::path libDefaultDir = X509_get_default_cert_dir();
|
|
||||||
|
|
||||||
if (fs::exists(libDefaultDir))
|
|
||||||
defaultDirectoriesList.push_back(libDefaultDir);
|
|
||||||
|
|
||||||
// Check and set all possible standard default directories
|
// Check and set all possible standard default directories
|
||||||
for (const char *dir : defaultTrustedDirs)
|
for (const char *dir : defaultTrustedDirs)
|
||||||
{
|
{
|
||||||
fs::path defaultDir(dir);
|
fs::path defaultDir(dir);
|
||||||
|
|
||||||
if (defaultDir != libDefaultDir &&
|
if (fs::exists(defaultDir)) {
|
||||||
fs::exists(defaultDir))
|
|
||||||
defaultDirectoriesList.push_back(defaultDir);
|
defaultDirectoriesList.push_back(defaultDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultDirectoriesList;
|
return defaultDirectoriesList;
|
||||||
@@ -526,26 +501,27 @@ std::vector<boost::filesystem::path> GetDefaultTrustedDirectories()
|
|||||||
// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context.
|
// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context.
|
||||||
// Returns the number of loaded certificates.
|
// Returns the number of loaded certificates.
|
||||||
//
|
//
|
||||||
int LoadDefaultRootCertificates(SSL_CTX *ctx)
|
int LoadDefaultRootCertificates(WOLFSSL_CTX *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx)
|
if (!ctx) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int certsLoaded = 0;
|
int certsLoaded = 0;
|
||||||
|
|
||||||
// Certificate text buffer 'defaultRootCerts' is a C string with certificates in PEM format
|
// Certificate text buffer 'defaultRootCerts' is a C string with certificates in PEM format
|
||||||
BIO *memBuf = BIO_new_mem_buf(defaultRootCerts, -1);
|
WOLFSSL_BIO *memBuf = wolfSSL_BIO_new_mem_buf(defaultRootCerts, -1);
|
||||||
if (memBuf)
|
if (memBuf) {
|
||||||
{
|
WOLFSSL_X509 *cert = NULL;
|
||||||
X509 *cert = NULL;
|
while ((cert = wolfSSL_PEM_read_bio_X509(memBuf, NULL, 0, NULL)))
|
||||||
while ((cert = PEM_read_bio_X509(memBuf, NULL, 0, NULL)))
|
|
||||||
{
|
{
|
||||||
if (X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert) > 0)
|
if (wolfSSL_X509_STORE_add_cert(wolfSSL_CTX_get_cert_store(ctx), cert) > 0) {
|
||||||
certsLoaded++;
|
certsLoaded++;
|
||||||
|
}
|
||||||
|
|
||||||
X509_free(cert);
|
wolfSSL_X509_free(cert);
|
||||||
}
|
}
|
||||||
BIO_free(memBuf);
|
wolfSSL_BIO_free(memBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return certsLoaded;
|
return certsLoaded;
|
||||||
|
|||||||
@@ -37,20 +37,20 @@ bool GenerateCredentials(
|
|||||||
// Validates peer certificate using a chain of CA certificates.
|
// 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')
|
// If some of intermediate CA certificates are absent in the trusted certificates store, then validation status will be 'false')
|
||||||
//
|
//
|
||||||
bool ValidatePeerCertificate(SSL *ssl);
|
bool ValidatePeerCertificate(WOLFSSL *ssl);
|
||||||
|
|
||||||
// Check if a given context is set up with a cert that can be validated by this context
|
// Check if a given context is set up with a cert that can be validated by this context
|
||||||
//
|
//
|
||||||
bool ValidateCertificate(SSL_CTX *ssl_ctx);
|
bool ValidateCertificate(WOLFSSL_CTX *ssl_ctx);
|
||||||
|
|
||||||
// Creates the list of available OpenSSL default directories for trusted certificates storage
|
// Creates the list of available default directories for trusted certificates storage
|
||||||
//
|
//
|
||||||
std::vector<boost::filesystem::path> GetDefaultTrustedDirectories();
|
std::vector<boost::filesystem::path> GetDefaultTrustedDirectories();
|
||||||
|
|
||||||
// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context.
|
// Loads default root certificates (placed in the 'defaultRootCerts') into the specified context.
|
||||||
// Returns the number of loaded certificates.
|
// Returns the number of loaded certificates.
|
||||||
//
|
//
|
||||||
int LoadDefaultRootCertificates(SSL_CTX *ctx);
|
int LoadDefaultRootCertificates(WOLFSSL_CTX *ctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,8 @@
|
|||||||
#include <boost/interprocess/sync/file_lock.hpp>
|
#include <boost/interprocess/sync/file_lock.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <openssl/crypto.h>
|
#include <wolfssl/options.h>
|
||||||
|
#include <wolfssl/ssl.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#if ENABLE_ZMQ
|
#if ENABLE_ZMQ
|
||||||
@@ -1435,7 +1436,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
|
|
||||||
if (fPrintToDebugLog)
|
if (fPrintToDebugLog)
|
||||||
OpenDebugLog();
|
OpenDebugLog();
|
||||||
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
|
LogPrintf("Using WolfSSL version %s\n", wolfSSL_lib_version());
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -44,9 +44,8 @@
|
|||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
#include <openssl/conf.h>
|
#include <wolfssl/options.h>
|
||||||
#include <openssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <hush/tlsmanager.cpp>
|
#include <hush/tlsmanager.cpp>
|
||||||
using namespace hush;
|
using namespace hush;
|
||||||
|
|
||||||
@@ -747,7 +746,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
|
|||||||
// If ssl != NULL it means TLS connection was established successfully
|
// If ssl != NULL it means TLS connection was established successfully
|
||||||
{
|
{
|
||||||
LOCK(cs_hSocket);
|
LOCK(cs_hSocket);
|
||||||
stats.fTLSEstablished = (ssl != NULL) && (SSL_get_state(ssl) == TLS_ST_OK);
|
stats.fTLSEstablished = (ssl != NULL) && (wolfSSL_is_init_finished(ssl) == 1);
|
||||||
stats.fTLSVerified = (ssl != NULL) && ValidatePeerCertificate(ssl);
|
stats.fTLSVerified = (ssl != NULL) && ValidatePeerCertificate(ssl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,9 @@
|
|||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/signals2/signal.hpp>
|
#include <boost/signals2/signal.hpp>
|
||||||
|
|
||||||
// Enable OpenSSL Support for Hush
|
// Enable WolfSSL Support for Hush
|
||||||
#include <openssl/bio.h>
|
#include <wolfssl/options.h>
|
||||||
#include <openssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
|
|
||||||
class CAddrMan;
|
class CAddrMan;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
|
|||||||
43
src/util.cpp
43
src/util.cpp
@@ -101,8 +101,6 @@
|
|||||||
#include <boost/program_options/detail/config_file.hpp>
|
#include <boost/program_options/detail/config_file.hpp>
|
||||||
#include <boost/program_options/parsers.hpp>
|
#include <boost/program_options/parsers.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <openssl/conf.h>
|
|
||||||
|
|
||||||
// Work around clang compilation problem in Boost 1.46:
|
// Work around clang compilation problem in Boost 1.46:
|
||||||
// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
|
// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
|
||||||
@@ -133,47 +131,6 @@ bool fLogIPs = DEFAULT_LOGIPS;
|
|||||||
std::atomic<bool> fReopenDebugLog(false);
|
std::atomic<bool> fReopenDebugLog(false);
|
||||||
CTranslationInterface translationInterface;
|
CTranslationInterface translationInterface;
|
||||||
|
|
||||||
/** Init OpenSSL library multithreading support */
|
|
||||||
static CCriticalSection** ppmutexOpenSSL;
|
|
||||||
void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
|
|
||||||
{
|
|
||||||
if (mode & CRYPTO_LOCK) {
|
|
||||||
ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
|
|
||||||
} else {
|
|
||||||
LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init
|
|
||||||
static class CInit
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CInit()
|
|
||||||
{
|
|
||||||
// Init OpenSSL library multithreading support
|
|
||||||
ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
|
|
||||||
for (int i = 0; i < CRYPTO_num_locks(); i++)
|
|
||||||
ppmutexOpenSSL[i] = new CCriticalSection();
|
|
||||||
CRYPTO_set_locking_callback(locking_callback);
|
|
||||||
|
|
||||||
// OpenSSL can optionally load a config file which lists optional loadable modules and engines.
|
|
||||||
// We don't use them so we don't require the config. However some of our libs may call functions
|
|
||||||
// which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
|
|
||||||
// or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
|
|
||||||
// that the config appears to have been loaded and there are no modules/engines available.
|
|
||||||
OPENSSL_no_config();
|
|
||||||
}
|
|
||||||
~CInit()
|
|
||||||
{
|
|
||||||
// Shutdown OpenSSL library multithreading support
|
|
||||||
CRYPTO_set_locking_callback(NULL);
|
|
||||||
for (int i = 0; i < CRYPTO_num_locks(); i++)
|
|
||||||
delete ppmutexOpenSSL[i];
|
|
||||||
OPENSSL_free(ppmutexOpenSSL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instance_of_cinit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LogPrintf() has been broken a couple of times now
|
* LogPrintf() has been broken a couple of times now
|
||||||
* by well-meaning people adding mutexes in the most straightforward way.
|
* by well-meaning people adding mutexes in the most straightforward way.
|
||||||
|
|||||||
Reference in New Issue
Block a user