From 5b9309420cc9721a0d5745b6ad3166a4bdbd1508 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Fri, 10 May 2024 15:45:07 -0400 Subject: build: move chainparamsbase from util to common Move chainparamsbase from util to common, because util library should not depend on the common library and chainparamsbase uses the ArgsManager class in common. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index b749651b72..1fd0cdd7a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -669,6 +669,7 @@ libbitcoin_common_a_SOURCES = \ addresstype.cpp \ base58.cpp \ bech32.cpp \ + chainparamsbase.cpp \ chainparams.cpp \ coins.cpp \ common/args.cpp \ @@ -719,7 +720,6 @@ libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ support/lockedpool.cpp \ - chainparamsbase.cpp \ clientversion.cpp \ logging.cpp \ random.cpp \ -- cgit v1.2.3 From cc5f29fbea15d33e4d1aa95591253c6b86953fe7 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Fri, 10 May 2024 15:45:07 -0400 Subject: build: move memory_cleanse from util to crypto Move memory_cleanse from util to crypto because the crypto library should not depend on other libraries, and it calls memory_cleanse. --- src/Makefile.am | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 1fd0cdd7a8..bb61f2d027 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -587,7 +587,8 @@ crypto_libbitcoin_crypto_base_la_SOURCES = \ crypto/sha512.cpp \ crypto/sha512.h \ crypto/siphash.cpp \ - crypto/siphash.h + crypto/siphash.h \ + support/cleanse.cpp # See explanation for -static in crypto_libbitcoin_crypto_base_la's LDFLAGS and # CXXFLAGS above @@ -725,7 +726,6 @@ libbitcoin_util_a_SOURCES = \ random.cpp \ randomenv.cpp \ streams.cpp \ - support/cleanse.cpp \ sync.cpp \ util/asmap.cpp \ util/batchpriority.cpp \ @@ -968,7 +968,6 @@ libbitcoinkernel_la_SOURCES = \ script/solver.cpp \ signet.cpp \ streams.cpp \ - support/cleanse.cpp \ support/lockedpool.cpp \ sync.cpp \ txdb.cpp \ -- cgit v1.2.3 From 6861f954f8ff42c87ad638037adae86a5bd89600 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Fri, 10 May 2024 15:45:07 -0400 Subject: util: move util/message to common/signmessage Move util/message to common/signmessage so it is named more clearly, and because the util library is not supposed to depend on other libraries besides the crypto library. The signmessage functions use CKey, CPubKey, PKHash, and DecodeDestination functions in the consensus and common libraries. --- src/Makefile.am | 4 +- src/common/signmessage.cpp | 93 ++++++++++++++++++++++++++++++++++++++ src/common/signmessage.h | 77 +++++++++++++++++++++++++++++++ src/interfaces/wallet.h | 2 +- src/qt/signverifymessagedialog.cpp | 2 +- src/rpc/signmessage.cpp | 2 +- src/test/fuzz/message.cpp | 2 +- src/test/util_tests.cpp | 2 +- src/util/message.cpp | 93 -------------------------------------- src/util/message.h | 77 ------------------------------- src/wallet/rpc/signmessage.cpp | 2 +- src/wallet/scriptpubkeyman.h | 2 +- src/wallet/wallet.cpp | 2 +- 13 files changed, 180 insertions(+), 180 deletions(-) create mode 100644 src/common/signmessage.cpp create mode 100644 src/common/signmessage.h delete mode 100644 src/util/message.cpp delete mode 100644 src/util/message.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bb61f2d027..54000a7eb1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -144,6 +144,7 @@ BITCOIN_CORE_H = \ compat/cpuid.h \ compat/endian.h \ common/settings.h \ + common/signmessage.h \ common/system.h \ compressor.h \ consensus/consensus.h \ @@ -308,7 +309,6 @@ BITCOIN_CORE_H = \ util/hasher.h \ util/insert.h \ util/macros.h \ - util/message.h \ util/moneystr.h \ util/overflow.h \ util/overloaded.h \ @@ -680,6 +680,7 @@ libbitcoin_common_a_SOURCES = \ common/interfaces.cpp \ common/run_command.cpp \ common/settings.cpp \ + common/signmessage.cpp \ common/system.cpp \ common/url.cpp \ compressor.cpp \ @@ -742,7 +743,6 @@ libbitcoin_util_a_SOURCES = \ util/hasher.cpp \ util/sock.cpp \ util/syserror.cpp \ - util/message.cpp \ util/moneystr.cpp \ util/rbf.cpp \ util/readwritefile.cpp \ diff --git a/src/common/signmessage.cpp b/src/common/signmessage.cpp new file mode 100644 index 0000000000..1612751e44 --- /dev/null +++ b/src/common/signmessage.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/** + * Text used to signify that a signed message follows and to prevent + * inadvertently signing a transaction. + */ +const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n"; + +MessageVerificationResult MessageVerify( + const std::string& address, + const std::string& signature, + const std::string& message) +{ + CTxDestination destination = DecodeDestination(address); + if (!IsValidDestination(destination)) { + return MessageVerificationResult::ERR_INVALID_ADDRESS; + } + + if (std::get_if(&destination) == nullptr) { + return MessageVerificationResult::ERR_ADDRESS_NO_KEY; + } + + auto signature_bytes = DecodeBase64(signature); + if (!signature_bytes) { + return MessageVerificationResult::ERR_MALFORMED_SIGNATURE; + } + + CPubKey pubkey; + if (!pubkey.RecoverCompact(MessageHash(message), *signature_bytes)) { + return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED; + } + + if (!(PKHash(pubkey) == *std::get_if(&destination))) { + return MessageVerificationResult::ERR_NOT_SIGNED; + } + + return MessageVerificationResult::OK; +} + +bool MessageSign( + const CKey& privkey, + const std::string& message, + std::string& signature) +{ + std::vector signature_bytes; + + if (!privkey.SignCompact(MessageHash(message), signature_bytes)) { + return false; + } + + signature = EncodeBase64(signature_bytes); + + return true; +} + +uint256 MessageHash(const std::string& message) +{ + HashWriter hasher{}; + hasher << MESSAGE_MAGIC << message; + + return hasher.GetHash(); +} + +std::string SigningResultString(const SigningResult res) +{ + switch (res) { + case SigningResult::OK: + return "No error"; + case SigningResult::PRIVATE_KEY_NOT_AVAILABLE: + return "Private key not available"; + case SigningResult::SIGNING_FAILED: + return "Sign failed"; + // no default case, so the compiler can warn about missing cases + } + assert(false); +} diff --git a/src/common/signmessage.h b/src/common/signmessage.h new file mode 100644 index 0000000000..215b563bbb --- /dev/null +++ b/src/common/signmessage.h @@ -0,0 +1,77 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COMMON_SIGNMESSAGE_H +#define BITCOIN_COMMON_SIGNMESSAGE_H + +#include + +#include + +class CKey; + +extern const std::string MESSAGE_MAGIC; + +/** The result of a signed message verification. + * Message verification takes as an input: + * - address (with whose private key the message is supposed to have been signed) + * - signature + * - message + */ +enum class MessageVerificationResult { + //! The provided address is invalid. + ERR_INVALID_ADDRESS, + + //! The provided address is valid but does not refer to a public key. + ERR_ADDRESS_NO_KEY, + + //! The provided signature couldn't be parsed (maybe invalid base64). + ERR_MALFORMED_SIGNATURE, + + //! A public key could not be recovered from the provided signature and message. + ERR_PUBKEY_NOT_RECOVERED, + + //! The message was not signed with the private key of the provided address. + ERR_NOT_SIGNED, + + //! The message verification was successful. + OK +}; + +enum class SigningResult { + OK, //!< No error + PRIVATE_KEY_NOT_AVAILABLE, + SIGNING_FAILED, +}; + +/** Verify a signed message. + * @param[in] address Signer's bitcoin address, it must refer to a public key. + * @param[in] signature The signature in base64 format. + * @param[in] message The message that was signed. + * @return result code */ +MessageVerificationResult MessageVerify( + const std::string& address, + const std::string& signature, + const std::string& message); + +/** Sign a message. + * @param[in] privkey Private key to sign with. + * @param[in] message The message to sign. + * @param[out] signature Signature, base64 encoded, only set if true is returned. + * @return true if signing was successful. */ +bool MessageSign( + const CKey& privkey, + const std::string& message, + std::string& signature); + +/** + * Hashes a message for signing and verification in a manner that prevents + * inadvertently signing a transaction. + */ +uint256 MessageHash(const std::string& message); + +std::string SigningResultString(const SigningResult res); + +#endif // BITCOIN_COMMON_SIGNMESSAGE_H diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index c41f35829d..f1bfffa7d4 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -6,13 +6,13 @@ #define BITCOIN_INTERFACES_WALLET_H #include +#include #include #include #include #include