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