Dash Core  0.12.2.1
P2P Digital Currency
signverifymessagedialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2017 The Dash 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 
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 #if QT_VERSION >= 0x040700
33  ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
34 #endif
35 
36  QString theme = GUIUtil::getThemeName();
37 
38 #ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
39  ui->signMessageButton_SM->setIcon(QIcon());
40  ui->clearButton_SM->setIcon(QIcon());
41  ui->verifyMessageButton_VM->setIcon(QIcon());
42  ui->clearButton_VM->setIcon(QIcon());
43 #else
44  ui->signMessageButton_SM->setIcon(QIcon(":/icons/" + theme + "/edit"));
45  ui->clearButton_SM->setIcon(QIcon(":/icons/" + theme + "/remove"));
46  ui->verifyMessageButton_VM->setIcon(QIcon(":/icons/" + theme + "/transaction_0"));
47  ui->clearButton_VM->setIcon(QIcon(":/icons/" + theme + "/remove"));
48 #endif
49 
50  // These icons are needed on Mac also
51  ui->addressBookButton_SM->setIcon(QIcon(":/icons/" + theme + "/address-book"));
52  ui->pasteButton_SM->setIcon(QIcon(":/icons/" + theme + "/editpaste"));
53  ui->copySignatureButton_SM->setIcon(QIcon(":/icons/" + theme + "/editcopy"));
54  ui->addressBookButton_VM->setIcon(QIcon(":/icons/" + theme + "/address-book"));
55 
56 
59 
60  ui->addressIn_SM->installEventFilter(this);
61  ui->messageIn_SM->installEventFilter(this);
62  ui->signatureOut_SM->installEventFilter(this);
63  ui->addressIn_VM->installEventFilter(this);
64  ui->messageIn_VM->installEventFilter(this);
65  ui->signatureIn_VM->installEventFilter(this);
66 
69 }
70 
72 {
73  delete ui;
74 }
75 
77 {
78  this->model = model;
79 }
80 
81 void SignVerifyMessageDialog::setAddress_SM(const QString &address)
82 {
83  ui->addressIn_SM->setText(address);
84  ui->messageIn_SM->setFocus();
85 }
86 
87 void SignVerifyMessageDialog::setAddress_VM(const QString &address)
88 {
89  ui->addressIn_VM->setText(address);
90  ui->messageIn_VM->setFocus();
91 }
92 
94 {
95  ui->tabWidget->setCurrentIndex(0);
96  if (fShow)
97  this->show();
98 }
99 
101 {
102  ui->tabWidget->setCurrentIndex(1);
103  if (fShow)
104  this->show();
105 }
106 
108 {
109  if (model && model->getAddressTableModel())
110  {
113  if (dlg.exec())
114  {
116  }
117  }
118 }
119 
121 {
122  setAddress_SM(QApplication::clipboard()->text());
123 }
124 
126 {
127  if (!model)
128  return;
129 
130  /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
131  ui->signatureOut_SM->clear();
132 
133  CBitcoinAddress addr(ui->addressIn_SM->text().toStdString());
134  if (!addr.IsValid())
135  {
136  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
137  ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
138  return;
139  }
140  CKeyID keyID;
141  if (!addr.GetKeyID(keyID))
142  {
143  ui->addressIn_SM->setValid(false);
144  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
145  ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
146  return;
147  }
148 
150  if (!ctx.isValid())
151  {
152  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
153  ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
154  return;
155  }
156 
157  CKey key;
158  if (!pwalletMain->GetKey(keyID, key))
159  {
160  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
161  ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
162  return;
163  }
164 
165  CHashWriter ss(SER_GETHASH, 0);
166  ss << strMessageMagic;
167  ss << ui->messageIn_SM->document()->toPlainText().toStdString();
168 
169  std::vector<unsigned char> vchSig;
170  if (!key.SignCompact(ss.GetHash(), vchSig))
171  {
172  ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
173  ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
174  return;
175  }
176 
177  ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
178  ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
179 
180  ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
181 }
182 
184 {
186 }
187 
189 {
190  ui->addressIn_SM->clear();
191  ui->messageIn_SM->clear();
192  ui->signatureOut_SM->clear();
193  ui->statusLabel_SM->clear();
194 
195  ui->addressIn_SM->setFocus();
196 }
197 
199 {
200  if (model && model->getAddressTableModel())
201  {
204  if (dlg.exec())
205  {
207  }
208  }
209 }
210 
212 {
213  CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
214  if (!addr.IsValid())
215  {
216  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
217  ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
218  return;
219  }
220  CKeyID keyID;
221  if (!addr.GetKeyID(keyID))
222  {
223  ui->addressIn_VM->setValid(false);
224  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
225  ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
226  return;
227  }
228 
229  bool fInvalid = false;
230  std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
231 
232  if (fInvalid)
233  {
234  ui->signatureIn_VM->setValid(false);
235  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
236  ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
237  return;
238  }
239 
240  CHashWriter ss(SER_GETHASH, 0);
241  ss << strMessageMagic;
242  ss << ui->messageIn_VM->document()->toPlainText().toStdString();
243 
244  CPubKey pubkey;
245  if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
246  {
247  ui->signatureIn_VM->setValid(false);
248  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
249  ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
250  return;
251  }
252 
253  if (!(CBitcoinAddress(pubkey.GetID()) == addr))
254  {
255  ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
256  ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
257  return;
258  }
259 
260  ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
261  ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
262 }
263 
265 {
266  ui->addressIn_VM->clear();
267  ui->signatureIn_VM->clear();
268  ui->messageIn_VM->clear();
269  ui->statusLabel_VM->clear();
270 
271  ui->addressIn_VM->setFocus();
272 }
273 
274 bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
275 {
276  if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn)
277  {
278  if (ui->tabWidget->currentIndex() == 0)
279  {
280  /* Clear status message on focus change */
281  ui->statusLabel_SM->clear();
282 
283  /* Select generated signature */
284  if (object == ui->signatureOut_SM)
285  {
286  ui->signatureOut_SM->selectAll();
287  return true;
288  }
289  }
290  else if (ui->tabWidget->currentIndex() == 1)
291  {
292  /* Clear status message on focus change */
293  ui->statusLabel_VM->clear();
294  }
295  }
296  return QDialog::eventFilter(object, event);
297 }
void setAddress_VM(const QString &address)
const PlatformStyle * platformStyle
Definition: pubkey.h:27
SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent)
CWallet * pwalletMain
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
Definition: guiutil.cpp:112
string EncodeBase64(const unsigned char *pch, size_t len)
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:187
bool GetKey(const CKeyID &address, CKey &keyOut) const
GetKey implementation that can derive a HD private key on the fly.
Definition: wallet.cpp:216
uint256 GetHash()
Definition: hash.h:254
void setupUi(QDialog *SignVerifyMessageDialog)
bool eventFilter(QObject *object, QEvent *event)
void setClipboard(const QString &str)
Definition: guiutil.cpp:937
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
static secp256k1_context * ctx
Definition: tests.c:42
void setAddress_SM(const QString &address)
Ui::SignVerifyMessageDialog * ui
const QString & getReturnValue() const
void setValid(bool valid)
QString getThemeName()
Definition: guiutil.cpp:902
Definition: pubkey.h:37
void setModel(WalletModel *model)
const string strMessageMagic
Definition: validation.cpp:109
Definition: key.h:35
AddressTableModel * getAddressTableModel()
void setModel(AddressTableModel *model)
UnlockContext requestUnlock(bool fForMixingOnly=false)
QFont fixedPitchFont()
Definition: guiutil.cpp:97