Raven Core  3.0.0
P2P Digital Currency
signverifymessagedialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
7 #include "ui_signverifymessagedialog.h"
8 
9 #include "addressbookpage.h"
10 #include "guiutil.h"
11 #include "platformstyle.h"
12 #include "walletmodel.h"
13 
14 #include "base58.h"
15 #include "init.h"
16 #include "validation.h" // For strMessageMagic
17 #include "wallet/wallet.h"
18 
19 #include <string>
20 #include <vector>
21 
22 #include <QClipboard>
23 
24 SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
25  QDialog(parent),
26  ui(new Ui::SignVerifyMessageDialog),
27  model(0),
28  platformStyle(_platformStyle)
29 {
30  ui->setupUi(this);
31 
32  ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
33  ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
34  ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
35  ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
36  ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
37  ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
38  ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0"));
39  ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
40 
41 #if QT_VERSION >= 0x040700
42  ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
43 #endif
44 
45  GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
46  GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
47 
48  ui->addressIn_SM->installEventFilter(this);
49  ui->messageIn_SM->installEventFilter(this);
50  ui->signatureOut_SM->installEventFilter(this);
51  ui->addressIn_VM->installEventFilter(this);
52  ui->messageIn_VM->installEventFilter(this);
53  ui->signatureIn_VM->installEventFilter(this);
54 
55  ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
56  ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
57 }
58 
60 {
61  delete ui;
62 }
63 
65 {
66  this->model = _model;
67 }
68 
69 void SignVerifyMessageDialog::setAddress_SM(const QString &address)
70 {
71  ui->addressIn_SM->setText(address);
72  ui->messageIn_SM->setFocus();
73 }
74 
75 void SignVerifyMessageDialog::setAddress_VM(const QString &address)
76 {
77  ui->addressIn_VM->setText(address);
78  ui->messageIn_VM->setFocus();
79 }
80 
82 {
83  ui->tabWidget->setCurrentIndex(0);
84  if (fShow)
85  this->show();
86 }
87 
89 {
90  ui->tabWidget->setCurrentIndex(1);
91  if (fShow)
92  this->show();
93 }
94 
96 {
98  {
101  if (dlg.exec())
102  {
104  }
105  }
106 }
107 
109 {
110  setAddress_SM(QApplication::clipboard()->text());
111 }
112 
114 {
115  if (!model)
116  return;
117 
118  /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
119  ui->signatureOut_SM->clear();
120 
121  CTxDestination destination = DecodeDestination(ui->addressIn_SM->text().toStdString());
122  if (!IsValidDestination(destination)) {
123  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
124  ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
125  return;
126  }
127  const CKeyID* keyID = boost::get<CKeyID>(&destination);
128  if (!keyID) {
129  ui->addressIn_SM->setValid(false);
130  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
131  ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
132  return;
133  }
134 
136  if (!ctx.isValid())
137  {
138  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
139  ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
140  return;
141  }
142 
143  CKey key;
144  if (!model->getPrivKey(*keyID, key))
145  {
146  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
147  ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
148  return;
149  }
150 
151  CHashWriter ss(SER_GETHASH, 0);
152  ss << strMessageMagic;
153  ss << ui->messageIn_SM->document()->toPlainText().toStdString();
154 
155  std::vector<unsigned char> vchSig;
156  if (!key.SignCompact(ss.GetHash(), vchSig))
157  {
158  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
159  ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
160  return;
161  }
162 
163  ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
164  ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
165 
166  ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(vchSig.data(), vchSig.size())));
167 }
168 
170 {
171  GUIUtil::setClipboard(ui->signatureOut_SM->text());
172 }
173 
175 {
176  ui->addressIn_SM->clear();
177  ui->messageIn_SM->clear();
178  ui->signatureOut_SM->clear();
179  ui->statusLabel_SM->clear();
180 
181  ui->addressIn_SM->setFocus();
182 }
183 
185 {
186  if (model && model->getAddressTableModel())
187  {
190  if (dlg.exec())
191  {
193  }
194  }
195 }
196 
198 {
199  CTxDestination destination = DecodeDestination(ui->addressIn_VM->text().toStdString());
200  if (!IsValidDestination(destination)) {
201  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
202  ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
203  return;
204  }
205  if (!boost::get<CKeyID>(&destination)) {
206  ui->addressIn_VM->setValid(false);
207  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
208  ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
209  return;
210  }
211 
212  bool fInvalid = false;
213  std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
214 
215  if (fInvalid)
216  {
217  ui->signatureIn_VM->setValid(false);
218  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
219  ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
220  return;
221  }
222 
223  CHashWriter ss(SER_GETHASH, 0);
224  ss << strMessageMagic;
225  ss << ui->messageIn_VM->document()->toPlainText().toStdString();
226 
227  CPubKey pubkey;
228  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
229  {
230  ui->signatureIn_VM->setValid(false);
231  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
232  ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
233  return;
234  }
235 
236  if (!(CTxDestination(pubkey.GetID()) == destination)) {
237  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
238  ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
239  return;
240  }
241 
242  ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
243  ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
244 }
245 
247 {
248  ui->addressIn_VM->clear();
249  ui->signatureIn_VM->clear();
250  ui->messageIn_VM->clear();
251  ui->statusLabel_VM->clear();
252 
253  ui->addressIn_VM->setFocus();
254 }
255 
256 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
257 {
258  if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn)
259  {
260  if (ui->tabWidget->currentIndex() == 0)
261  {
262  /* Clear status message on focus change */
263  ui->statusLabel_SM->clear();
264 
265  /* Select generated signature */
266  if (object == ui->signatureOut_SM)
267  {
268  ui->signatureOut_SM->selectAll();
269  return true;
270  }
271  }
272  else if (ui->tabWidget->currentIndex() == 1)
273  {
274  /* Clear status message on focus change */
275  ui->statusLabel_VM->clear();
276  }
277  }
278  return QDialog::eventFilter(object, event);
279 }
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
bool eventFilter(QObject *object, QEvent *event)
QFont fixedPitchFont()
Definition: guiutil.cpp:168
std::vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
void setAddress_VM(const QString &address)
void setModel(AddressTableModel *model)
UnlockContext requestUnlock()
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:402
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:333
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
Open address book to pick address.
AddressTableModel * getAddressTableModel()
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:143
const std::string strMessageMagic
Definition: validation.cpp:117
Ui::SignVerifyMessageDialog * ui
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key...
Definition: key.cpp:190
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:201
bool getPrivKey(const CKeyID &address, CKey &vchPrivKeyOut) const
void setClipboard(const QString &str)
Definition: guiutil.cpp:945
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:184
An encapsulated public key.
Definition: pubkey.h:40
Widget that shows a list of sending or receiving addresses.
SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent)
uint256 GetHash()
Definition: hash.h:250
Interface to Raven wallet from Qt view code.
Definition: walletmodel.h:165
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:30
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:231
An encapsulated private key.
Definition: key.h:36
const PlatformStyle * platformStyle
void setModel(WalletModel *model)
std::string EncodeBase64(const unsigned char *pch, size_t len)
const QString & getReturnValue() const
void setAddress_SM(const QString &address)