From 96b16225f24a2a2e1a917a58ef859f4efd68ad13 Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 27 Jan 2018 14:29:14 +0100 Subject: [PATCH] Improvement for OSX and Boost Add support Boost 1.66 Add support for OpenSSL over 1.0.0. --with-unsupported-ssl --- configure.ac | 8 +++--- src/bitcloud-cli.cpp | 2 +- src/crypter.cpp | 48 ++++++++++++++++------------------- src/ecwrapper.cpp | 31 +++++++++++++++++++++- src/qt/paymentrequestplus.cpp | 17 +++++++++---- src/rpcserver.cpp | 30 +++++++++++----------- 6 files changed, 84 insertions(+), 52 deletions(-) diff --git a/configure.ac b/configure.ac index 83632e6..ef3af4b 100755 --- a/configure.ac +++ b/configure.ac @@ -766,10 +766,10 @@ else fi AC_CHECK_LIB([crypto],[RAND_egd],[],[ - AC_ARG_WITH([libressl], - [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])], - [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])], - [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])] + AC_ARG_WITH([unsupported-ssl], + [AS_HELP_STRING([--with-unsupported-ssl],[Build with system SSL (default is no; DANGEROUS; NOT SUPPORTED; You should use OpenSSL 1.0)])], + [AC_MSG_WARN([Detected unsupported SSL version: This is NOT supported, and may break consensus compatibility!])], + [AC_MSG_ERROR([Detected unsupported SSL version: This is NOT supported, and may break consensus compatibility!])] ) ]) diff --git a/src/bitcloud-cli.cpp b/src/bitcloud-cli.cpp index 3848f00..90d5b52 100644 --- a/src/bitcloud-cli.cpp +++ b/src/bitcloud-cli.cpp @@ -110,7 +110,7 @@ Object CallRPC(const string& strMethod, const Array& params) // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); asio::io_service io_service; - ssl::context context(io_service, ssl::context::sslv23); + ssl::context context(ssl::context::sslv23); context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); asio::ssl::stream sslStream(io_service, context); SSLIOStreamDevice d(sslStream, fUseSSL); diff --git a/src/crypter.cpp b/src/crypter.cpp index f48257f..b9bb7de 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -57,15 +57,13 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector(nCLen); - EVP_CIPHER_CTX ctx; - bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; - if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0; + if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0; + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; @@ -84,15 +82,13 @@ bool CCrypter::Decrypt(const std::vector& vchCiphertext, CKeyingM vchPlaintext = CKeyingMaterial(nPLen); - EVP_CIPHER_CTX ctx; - bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; - if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0; + if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0; + if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0; + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; @@ -131,15 +127,15 @@ bool EncryptAES256(const SecureString& sKey, const SecureString& sPlaintext, con sCiphertext.resize(nCLen); // Perform the encryption - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX* ctx; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); - if (fOk) fOk = EVP_EncryptUpdate(&ctx, (unsigned char*)&sCiphertext[0], &nCLen, (const unsigned char*)&sPlaintext[0], nLen); - if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (unsigned char*)(&sCiphertext[0]) + nCLen, &nFLen); - EVP_CIPHER_CTX_cleanup(&ctx); + ctx = EVP_CIPHER_CTX_new(); + if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); + if (fOk) fOk = EVP_EncryptUpdate(ctx, (unsigned char*)&sCiphertext[0], &nCLen, (const unsigned char*)&sPlaintext[0], nLen); + if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (unsigned char*)(&sCiphertext[0]) + nCLen, &nFLen); + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; @@ -172,15 +168,15 @@ bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, con sPlaintext.resize(nPLen); - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX* ctx; bool fOk = true; - EVP_CIPHER_CTX_init(&ctx); - if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); - if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen); - if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); - EVP_CIPHER_CTX_cleanup(&ctx); + ctx = EVP_CIPHER_CTX_new(); + if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)&sKey[0], (const unsigned char*)&sIV[0]); + if (fOk) fOk = EVP_DecryptUpdate(ctx, (unsigned char*)&sPlaintext[0], &nPLen, (const unsigned char*)&sCiphertext[0], nLen); + if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (unsigned char*)(&sPlaintext[0]) + nPLen, &nFLen); + EVP_CIPHER_CTX_free(ctx); if (!fOk) return false; diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 7aba237..4c7306e 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -39,6 +39,11 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY* eckey, ECDSA_SIG* ecsig, const unsigned ch int n = 0; int i = recid / 2; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + const BIGNUM *sig_r, *sig_s; + ECDSA_SIG_get0(ecsig, &sig_r, &sig_s); +#endif + const EC_GROUP* group = EC_KEY_get0_group(eckey); if ((ctx = BN_CTX_new()) == NULL) { ret = -1; @@ -59,7 +64,11 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY* eckey, ECDSA_SIG* ecsig, const unsigned ch ret = -1; goto err; } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (!BN_add(x, x, sig_r)) { +#else if (!BN_add(x, x, ecsig->r)) { +#endif ret = -1; goto err; } @@ -115,12 +124,20 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY* eckey, ECDSA_SIG* ecsig, const unsigned ch goto err; } rr = BN_CTX_get(ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (!BN_mod_inverse(rr, sig_r, order, ctx)) { +#else if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { +#endif ret = -1; goto err; } sor = BN_CTX_get(ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (!BN_mod_mul(sor, sig_s, rr, order, ctx)) { +#else if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { +#endif ret = -1; goto err; } @@ -218,8 +235,20 @@ bool CECKey::Recover(const uint256& hash, const unsigned char* p64, int rec) if (rec < 0 || rec >= 3) return false; ECDSA_SIG* sig = ECDSA_SIG_new(); - BN_bin2bn(&p64[0], 32, sig->r); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + BIGNUM *sig_r = NULL; + BIGNUM *sig_s = NULL; + if (!(sig_r = BN_bin2bn(&p64[0], 32, nullptr)) || + !(sig_s = BN_bin2bn(&p64[32], 32, nullptr)) || + !ECDSA_SIG_set0(sig, sig_r, sig_s)) { + BN_free(sig_r); + BN_free(sig_s); + return false; + } +#else + BN_bin2bn(&p64[0], 32, sig->r); BN_bin2bn(&p64[32], 32, sig->s); +#endif bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1; ECDSA_SIG_free(sig); return ret; diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index d76fafc..8a67d5f 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -154,14 +154,21 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); - EVP_MD_CTX ctx; + EVP_MD_CTX* ctx; EVP_PKEY* pubkey = X509_get_pubkey(signing_cert); - EVP_MD_CTX_init(&ctx); - if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) || - !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + ctx = EVP_MD_CTX_new(); +#else + EVP_MD_CTX_init(ctx); +#endif + if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || + !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || + !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { throw SSLVerifyError("Bad signature, invalid PaymentRequest."); } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_MD_CTX_free(ctx); +#endif // OpenSSL API for getting human printable strings from certs is baroque. int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 9ff9430..7dfd837 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -472,20 +472,20 @@ class AcceptedConnectionImpl : public AcceptedConnection void ServiceConnection(AcceptedConnection* conn); //! Forward declaration required for RPCListen -template -static void RPCAcceptHandler(boost::shared_ptr > acceptor, - ssl::context& context, - bool fUseSSL, - boost::shared_ptr conn, +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + bool fUseSSL, + boost::shared_ptr< AcceptedConnection > conn, const boost::system::error_code& error); /** * Sets up I/O resources to accept and handle a new connection. */ -template -static void RPCListen(boost::shared_ptr > acceptor, - ssl::context& context, - const bool fUseSSL) +template +static void RPCListen(boost::shared_ptr< basic_socket_acceptor > acceptor, + ssl::context& context, + const bool fUseSSL) { // Accept connection boost::shared_ptr > conn(new AcceptedConnectionImpl(acceptor->get_io_service(), context, fUseSSL)); @@ -493,7 +493,7 @@ static void RPCListen(boost::shared_ptrasync_accept( conn->sslStream.lowest_layer(), conn->peer, - boost::bind(&RPCAcceptHandler, + boost::bind(&RPCAcceptHandler, acceptor, boost::ref(context), fUseSSL, @@ -505,11 +505,11 @@ static void RPCListen(boost::shared_ptr -static void RPCAcceptHandler(boost::shared_ptr > acceptor, +template +static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor > acceptor, ssl::context& context, const bool fUseSSL, - boost::shared_ptr conn, + boost::shared_ptr< AcceptedConnection > conn, const boost::system::error_code& error) { // Immediately start accepting new connections, except when we're cancelled or our socket is closed. @@ -594,7 +594,7 @@ void StartRPCThreads() assert(rpc_io_service == NULL); rpc_io_service = new asio::io_service(); - rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); + rpc_ssl_context = new ssl::context(ssl::context::sslv23); const bool fUseSSL = GetBoolArg("-rpcssl", false); @@ -616,7 +616,7 @@ void StartRPCThreads() LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); + SSL_CTX_set_cipher_list(rpc_ssl_context->native_handle(), strCiphers.c_str()); } std::vector vEndpoints;