Bitcoin ABC  0.24.7
P2P Digital Currency
signverifymessagedialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <qt/forms/ui_signverifymessagedialog.h>
7 
8 #include <key_io.h>
9 #include <qt/addressbookpage.h>
10 #include <qt/guiutil.h>
11 #include <qt/platformstyle.h>
12 #include <qt/walletmodel.h>
13 #include <util/message.h> // For MessageSign(), MessageVerify()
14 #include <wallet/wallet.h>
15 
16 #include <QClipboard>
17 
18 #include <vector>
19 
21  const PlatformStyle *_platformStyle, QWidget *parent)
22  : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(nullptr),
23  platformStyle(_platformStyle) {
24  ui->setupUi(this);
25 
26  ui->addressBookButton_SM->setIcon(
27  platformStyle->SingleColorIcon(":/icons/address-book"));
28  ui->pasteButton_SM->setIcon(
29  platformStyle->SingleColorIcon(":/icons/editpaste"));
30  ui->copySignatureButton_SM->setIcon(
31  platformStyle->SingleColorIcon(":/icons/editcopy"));
32  ui->signMessageButton_SM->setIcon(
33  platformStyle->SingleColorIcon(":/icons/edit"));
34  ui->clearButton_SM->setIcon(
35  platformStyle->SingleColorIcon(":/icons/remove"));
36  ui->addressBookButton_VM->setIcon(
37  platformStyle->SingleColorIcon(":/icons/address-book"));
38  ui->verifyMessageButton_VM->setIcon(
39  platformStyle->SingleColorIcon(":/icons/transaction_0"));
40  ui->clearButton_VM->setIcon(
41  platformStyle->SingleColorIcon(":/icons/remove"));
42 
43  GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
44  GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
45 
46  ui->addressIn_SM->installEventFilter(this);
47  ui->messageIn_SM->installEventFilter(this);
48  ui->signatureOut_SM->installEventFilter(this);
49  ui->addressIn_VM->installEventFilter(this);
50  ui->messageIn_VM->installEventFilter(this);
51  ui->signatureIn_VM->installEventFilter(this);
52 
53  ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
54  ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
55 
57 }
58 
60  delete ui;
61 }
62 
64  this->model = _model;
65 }
66 
67 void SignVerifyMessageDialog::setAddress_SM(const QString &address) {
68  ui->addressIn_SM->setText(address);
69  ui->messageIn_SM->setFocus();
70 }
71 
72 void SignVerifyMessageDialog::setAddress_VM(const QString &address) {
73  ui->addressIn_VM->setText(address);
74  ui->messageIn_VM->setFocus();
75 }
76 
78  ui->tabWidget->setCurrentIndex(0);
79  if (fShow) {
80  this->show();
81  }
82 }
83 
85  ui->tabWidget->setCurrentIndex(1);
86  if (fShow) {
87  this->show();
88  }
89 }
90 
92  if (model && model->getAddressTableModel()) {
96  if (dlg.exec()) {
98  }
99  }
100 }
101 
103  setAddress_SM(QApplication::clipboard()->text());
104 }
105 
107  if (!model) {
108  return;
109  }
110 
111  /* Clear old signature to ensure users don't get confused on error with an
112  * old signature displayed */
113  ui->signatureOut_SM->clear();
114 
115  CTxDestination destination = DecodeDestination(
116  ui->addressIn_SM->text().toStdString(), model->getChainParams());
117  if (!IsValidDestination(destination)) {
118  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
119  ui->statusLabel_SM->setText(
120  tr("The entered address is invalid.") + QString(" ") +
121  tr("Please check the address and try again."));
122  return;
123  }
124  const PKHash *pkhash = boost::get<PKHash>(&destination);
125  if (!pkhash) {
126  ui->addressIn_SM->setValid(false);
127  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
128  ui->statusLabel_SM->setText(
129  tr("The entered address does not refer to a key.") + QString(" ") +
130  tr("Please check the address and try again."));
131  return;
132  }
133 
135  if (!ctx.isValid()) {
136  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
137  ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
138  return;
139  }
140 
141  const std::string &message =
142  ui->messageIn_SM->document()->toPlainText().toStdString();
143  std::string signature;
144  SigningResult res =
145  model->wallet().signMessage(message, *pkhash, signature);
146 
147  QString error;
148  switch (res) {
149  case SigningResult::OK:
150  error = tr("No error");
151  break;
153  error = tr("Private key for the entered address is not available.");
154  break;
156  error = tr("Message signing failed.");
157  break;
158  // no default case, so the compiler can warn about missing cases
159  }
160 
161  if (res != SigningResult::OK) {
162  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
163  ui->statusLabel_SM->setText(QString("<nobr>") + error +
164  QString("</nobr>"));
165  return;
166  }
167 
168  ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
169  ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") +
170  QString("</nobr>"));
171 
172  ui->signatureOut_SM->setText(QString::fromStdString(signature));
173 }
174 
176  GUIUtil::setClipboard(ui->signatureOut_SM->text());
177 }
178 
180  ui->addressIn_SM->clear();
181  ui->messageIn_SM->clear();
182  ui->signatureOut_SM->clear();
183  ui->statusLabel_SM->clear();
184 
185  ui->addressIn_SM->setFocus();
186 }
187 
189  if (model && model->getAddressTableModel()) {
193  if (dlg.exec()) {
195  }
196  }
197 }
198 
200  const std::string &address = ui->addressIn_VM->text().toStdString();
201  const std::string &signature = ui->signatureIn_VM->text().toStdString();
202  const std::string &message =
203  ui->messageIn_VM->document()->toPlainText().toStdString();
204 
205  const auto result =
206  MessageVerify(model->getChainParams(), address, signature, message);
207 
208  if (result == MessageVerificationResult::OK) {
209  ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
210  } else {
211  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
212  }
213 
214  switch (result) {
216  ui->statusLabel_VM->setText(QString("<nobr>") +
217  tr("Message verified.") +
218  QString("</nobr>"));
219  return;
221  ui->statusLabel_VM->setText(
222  tr("The entered address is invalid.") + QString(" ") +
223  tr("Please check the address and try again."));
224  return;
226  ui->addressIn_VM->setValid(false);
227  ui->statusLabel_VM->setText(
228  tr("The entered address does not refer to a key.") +
229  QString(" ") + tr("Please check the address and try again."));
230  return;
232  ui->signatureIn_VM->setValid(false);
233  ui->statusLabel_VM->setText(
234  tr("The signature could not be decoded.") + QString(" ") +
235  tr("Please check the signature and try again."));
236  return;
238  ui->signatureIn_VM->setValid(false);
239  ui->statusLabel_VM->setText(
240  tr("The signature did not match the message digest.") +
241  QString(" ") + tr("Please check the signature and try again."));
242  return;
244  ui->statusLabel_VM->setText(QString("<nobr>") +
245  tr("Message verification failed.") +
246  QString("</nobr>"));
247  return;
248  }
249 }
250 
252  ui->addressIn_VM->clear();
253  ui->signatureIn_VM->clear();
254  ui->messageIn_VM->clear();
255  ui->statusLabel_VM->clear();
256 
257  ui->addressIn_VM->setFocus();
258 }
259 
260 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) {
261  if (event->type() == QEvent::MouseButtonPress ||
262  event->type() == QEvent::FocusIn) {
263  if (ui->tabWidget->currentIndex() == 0) {
264  /* Clear status message on focus change */
265  ui->statusLabel_SM->clear();
266 
267  /* Select generated signature */
268  if (object == ui->signatureOut_SM) {
269  ui->signatureOut_SM->selectAll();
270  return true;
271  }
272  } else if (ui->tabWidget->currentIndex() == 1) {
273  /* Clear status message on focus change */
274  ui->statusLabel_VM->clear();
275  }
276  }
277  return QDialog::eventFilter(object, event);
278 }
signverifymessagedialog.h
AddressBookPage::setModel
void setModel(AddressTableModel *model)
Definition: addressbookpage.cpp:162
AddressBookPage::SendingTab
@ SendingTab
Definition: addressbookpage.h:29
MessageVerificationResult::ERR_MALFORMED_SIGNATURE
@ ERR_MALFORMED_SIGNATURE
The provided signature couldn't be parsed (maybe invalid base64).
MessageVerify
MessageVerificationResult MessageVerify(const CChainParams &params, const std::string &address, const std::string &signature, const std::string &message)
Verify a signed message.
Definition: message.cpp:24
SigningResult::OK
@ OK
No error.
SignVerifyMessageDialog::on_signMessageButton_SM_clicked
void on_signMessageButton_SM_clicked()
Definition: signverifymessagedialog.cpp:106
wallet.h
WalletModel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:47
SignVerifyMessageDialog::setAddress_VM
void setAddress_VM(const QString &address)
Definition: signverifymessagedialog.cpp:72
key_io.h
PlatformStyle::SingleColorIcon
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
Definition: platformstyle.cpp:97
addressbookpage.h
SignVerifyMessageDialog::showTab_VM
void showTab_VM(bool fShow)
Definition: signverifymessagedialog.cpp:84
walletmodel.h
WalletModel::getAddressTableModel
AddressTableModel * getAddressTableModel()
Definition: walletmodel.cpp:319
interfaces::Wallet::signMessage
virtual SigningResult signMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig)=0
Sign message.
MessageVerificationResult::ERR_NOT_SIGNED
@ ERR_NOT_SIGNED
The message was not signed with the private key of the provided address.
SignVerifyMessageDialog::setModel
void setModel(WalletModel *model)
Definition: signverifymessagedialog.cpp:63
WalletModel::requestUnlock
UnlockContext requestUnlock()
Definition: walletmodel.cpp:465
SignVerifyMessageDialog
Definition: signverifymessagedialog.h:17
SigningResult
SigningResult
Definition: message.h:47
GUIUtil::setClipboard
void setClipboard(const QString &str)
Definition: guiutil.cpp:766
GUIUtil::fixedPitchFont
QFont fixedPitchFont()
Definition: guiutil.cpp:76
WalletModel::wallet
interfaces::Wallet & wallet() const
Definition: walletmodel.h:150
SignVerifyMessageDialog::model
WalletModel * model
Definition: signverifymessagedialog.h:37
IsValidDestination
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:263
SignVerifyMessageDialog::on_addressBookButton_VM_clicked
void on_addressBookButton_VM_clicked()
Definition: signverifymessagedialog.cpp:188
message.h
SignVerifyMessageDialog::ui
Ui::SignVerifyMessageDialog * ui
Definition: signverifymessagedialog.h:36
SigningResult::PRIVATE_KEY_NOT_AVAILABLE
@ PRIVATE_KEY_NOT_AVAILABLE
WalletModel::getChainParams
const CChainParams & getChainParams() const
Definition: walletmodel.cpp:531
MessageVerificationResult::ERR_INVALID_ADDRESS
@ ERR_INVALID_ADDRESS
The provided address is invalid.
AddressBookPage
Widget that shows a list of sending or receiving addresses.
Definition: addressbookpage.h:25
guiutil.h
SignVerifyMessageDialog::platformStyle
const PlatformStyle * platformStyle
Definition: signverifymessagedialog.h:38
MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED
@ ERR_PUBKEY_NOT_RECOVERED
A public key could not be recovered from the provided signature and message.
SignVerifyMessageDialog::~SignVerifyMessageDialog
~SignVerifyMessageDialog()
Definition: signverifymessagedialog.cpp:59
SignVerifyMessageDialog::on_copySignatureButton_SM_clicked
void on_copySignatureButton_SM_clicked()
Definition: signverifymessagedialog.cpp:175
SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked
void on_verifyMessageButton_VM_clicked()
Definition: signverifymessagedialog.cpp:199
MessageVerificationResult::ERR_ADDRESS_NO_KEY
@ ERR_ADDRESS_NO_KEY
The provided address is valid but does not refer to a public key.
SignVerifyMessageDialog::setAddress_SM
void setAddress_SM(const QString &address)
Definition: signverifymessagedialog.cpp:67
SignVerifyMessageDialog::eventFilter
bool eventFilter(QObject *object, QEvent *event) override
Definition: signverifymessagedialog.cpp:260
ctx
secp256k1_context * ctx
Definition: bench_multiset.c:12
platformstyle.h
PKHash
Definition: standard.h:106
Ui
Definition: addressbookpage.h:14
SignVerifyMessageDialog::on_pasteButton_SM_clicked
void on_pasteButton_SM_clicked()
Definition: signverifymessagedialog.cpp:102
WalletModel::UnlockContext
Definition: walletmodel.h:115
SignVerifyMessageDialog::SignVerifyMessageDialog
SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent)
Definition: signverifymessagedialog.cpp:20
SignVerifyMessageDialog::on_addressBookButton_SM_clicked
void on_addressBookButton_SM_clicked()
Definition: signverifymessagedialog.cpp:91
SigningResult::SIGNING_FAILED
@ SIGNING_FAILED
MessageVerificationResult::OK
@ OK
The message verification was successful.
SignVerifyMessageDialog::on_clearButton_VM_clicked
void on_clearButton_VM_clicked()
Definition: signverifymessagedialog.cpp:251
AddressBookPage::getReturnValue
const QString & getReturnValue() const
Definition: addressbookpage.h:41
GUIUtil::handleCloseWindowShortcut
void handleCloseWindowShortcut(QWidget *w)
Definition: guiutil.cpp:396
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
PlatformStyle
Definition: platformstyle.h:13
DecodeDestination
CTxDestination DecodeDestination(const std::string &addr, const CChainParams &params)
Definition: key_io.cpp:177
GUIUtil::setupAddressWidget
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:119
SignVerifyMessageDialog::showTab_SM
void showTab_SM(bool fShow)
Definition: signverifymessagedialog.cpp:77
SignVerifyMessageDialog::on_clearButton_SM_clicked
void on_clearButton_SM_clicked()
Definition: signverifymessagedialog.cpp:179
CTxDestination
boost::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:132
AddressBookPage::ForSelection
@ ForSelection
Open address book to pick address.
Definition: addressbookpage.h:32
AddressBookPage::ReceivingTab
@ ReceivingTab
Definition: addressbookpage.h:29