diff options
author | Vasil Dimov <vd@FreeBSD.org> | 2019-11-19 15:49:35 +0100 |
---|---|---|
committer | Vasil Dimov <vd@FreeBSD.org> | 2020-02-14 10:45:40 +0100 |
commit | 2ce3447eb1e25ec7aec4b300dabf6c1e394f1906 (patch) | |
tree | 34f8785b1b3836e8d8d12b32851f897dd926b1bd /src/util/message.cpp | |
parent | 470664f2b788e2cce9202991d11476a6fef00ef4 (diff) |
Deduplicate the message verifying code
The logic of verifying a message was duplicated in 2 places:
src/qt/signverifymessagedialog.cpp
SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
src/rpc/misc.cpp
verifymessage()
with the only difference being the result handling. Move the logic into
a dedicated
src/util/message.cpp
MessageVerify()
which returns a set of result codes, call it from the 2 places and just
handle the results differently in the callers.
Diffstat (limited to 'src/util/message.cpp')
-rw-r--r-- | src/util/message.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/util/message.cpp b/src/util/message.cpp new file mode 100644 index 0000000000..33e9c3384b --- /dev/null +++ b/src/util/message.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2020 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 <hash.h> // For CHashWriter +#include <key_io.h> // For DecodeDestination() +#include <pubkey.h> // For CPubKey +#include <script/standard.h> // For CTxDestination, IsValidDestination(), PKHash +#include <serialize.h> // For SER_GETHASH +#include <util/message.h> +#include <util/strencodings.h> // For DecodeBase64() + +#include <string> +#include <vector> + +const std::string strMessageMagic = "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 (boost::get<PKHash>(&destination) == nullptr) { + return MessageVerificationResult::ERR_ADDRESS_NO_KEY; + } + + bool invalid = false; + std::vector<unsigned char> signature_bytes = DecodeBase64(signature.c_str(), &invalid); + if (invalid) { + return MessageVerificationResult::ERR_MALFORMED_SIGNATURE; + } + + CHashWriter ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << message; + + CPubKey pubkey; + if (!pubkey.RecoverCompact(ss.GetHash(), signature_bytes)) { + return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED; + } + + if (!(CTxDestination(PKHash(pubkey)) == destination)) { + return MessageVerificationResult::ERR_NOT_SIGNED; + } + + return MessageVerificationResult::OK; +} |