You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

signverifymessagedialog.cpp 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // Copyright (c) 2011-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "signverifymessagedialog.h"
  5. #include "ui_signverifymessagedialog.h"
  6. #include "addressbookpage.h"
  7. #include "guiutil.h"
  8. #include "platformstyle.h"
  9. #include "walletmodel.h"
  10. #include "base58.h"
  11. #include "init.h"
  12. #include "validation.h" // For strMessageMagic
  13. #include "wallet/wallet.h"
  14. #include <string>
  15. #include <vector>
  16. #include <QClipboard>
  17. SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
  18. QDialog(parent),
  19. ui(new Ui::SignVerifyMessageDialog),
  20. model(0),
  21. platformStyle(_platformStyle)
  22. {
  23. ui->setupUi(this);
  24. ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
  25. ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
  26. ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
  27. ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
  28. ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
  29. ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
  30. ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0"));
  31. ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
  32. #if QT_VERSION >= 0x040700
  33. ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
  34. #endif
  35. GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
  36. GUIUtil::setupAddressWidget(ui->addressIn_VM, this);
  37. ui->addressIn_SM->installEventFilter(this);
  38. ui->messageIn_SM->installEventFilter(this);
  39. ui->signatureOut_SM->installEventFilter(this);
  40. ui->addressIn_VM->installEventFilter(this);
  41. ui->messageIn_VM->installEventFilter(this);
  42. ui->signatureIn_VM->installEventFilter(this);
  43. ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont());
  44. ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont());
  45. }
  46. SignVerifyMessageDialog::~SignVerifyMessageDialog()
  47. {
  48. delete ui;
  49. }
  50. void SignVerifyMessageDialog::setModel(WalletModel *_model)
  51. {
  52. this->model = _model;
  53. }
  54. void SignVerifyMessageDialog::setAddress_SM(const QString &address)
  55. {
  56. ui->addressIn_SM->setText(address);
  57. ui->messageIn_SM->setFocus();
  58. }
  59. void SignVerifyMessageDialog::setAddress_VM(const QString &address)
  60. {
  61. ui->addressIn_VM->setText(address);
  62. ui->messageIn_VM->setFocus();
  63. }
  64. void SignVerifyMessageDialog::showTab_SM(bool fShow)
  65. {
  66. ui->tabWidget->setCurrentIndex(0);
  67. if (fShow)
  68. this->show();
  69. }
  70. void SignVerifyMessageDialog::showTab_VM(bool fShow)
  71. {
  72. ui->tabWidget->setCurrentIndex(1);
  73. if (fShow)
  74. this->show();
  75. }
  76. void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
  77. {
  78. if (model && model->getAddressTableModel())
  79. {
  80. AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
  81. dlg.setModel(model->getAddressTableModel());
  82. if (dlg.exec())
  83. {
  84. setAddress_SM(dlg.getReturnValue());
  85. }
  86. }
  87. }
  88. void SignVerifyMessageDialog::on_pasteButton_SM_clicked()
  89. {
  90. setAddress_SM(QApplication::clipboard()->text());
  91. }
  92. void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
  93. {
  94. if (!model)
  95. return;
  96. /* Clear old signature to ensure users don't get confused on error with an old signature displayed */
  97. ui->signatureOut_SM->clear();
  98. CStarwelsAddress addr(ui->addressIn_SM->text().toStdString());
  99. if (!addr.IsValid())
  100. {
  101. ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
  102. ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
  103. return;
  104. }
  105. CKeyID keyID;
  106. if (!addr.GetKeyID(keyID))
  107. {
  108. ui->addressIn_SM->setValid(false);
  109. ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
  110. ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
  111. return;
  112. }
  113. WalletModel::UnlockContext ctx(model->requestUnlock());
  114. if (!ctx.isValid())
  115. {
  116. ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
  117. ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled."));
  118. return;
  119. }
  120. CKey key;
  121. if (!model->getPrivKey(keyID, key))
  122. {
  123. ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
  124. ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
  125. return;
  126. }
  127. CHashWriter ss(SER_GETHASH, 0);
  128. ss << strMessageMagic;
  129. ss << ui->messageIn_SM->document()->toPlainText().toStdString();
  130. std::vector<unsigned char> vchSig;
  131. if (!key.SignCompact(ss.GetHash(), vchSig))
  132. {
  133. ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
  134. ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
  135. return;
  136. }
  137. ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
  138. ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
  139. ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
  140. }
  141. void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
  142. {
  143. GUIUtil::setClipboard(ui->signatureOut_SM->text());
  144. }
  145. void SignVerifyMessageDialog::on_clearButton_SM_clicked()
  146. {
  147. ui->addressIn_SM->clear();
  148. ui->messageIn_SM->clear();
  149. ui->signatureOut_SM->clear();
  150. ui->statusLabel_SM->clear();
  151. ui->addressIn_SM->setFocus();
  152. }
  153. void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
  154. {
  155. if (model && model->getAddressTableModel())
  156. {
  157. AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
  158. dlg.setModel(model->getAddressTableModel());
  159. if (dlg.exec())
  160. {
  161. setAddress_VM(dlg.getReturnValue());
  162. }
  163. }
  164. }
  165. void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
  166. {
  167. CStarwelsAddress addr(ui->addressIn_VM->text().toStdString());
  168. if (!addr.IsValid())
  169. {
  170. ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
  171. ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
  172. return;
  173. }
  174. CKeyID keyID;
  175. if (!addr.GetKeyID(keyID))
  176. {
  177. ui->addressIn_VM->setValid(false);
  178. ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
  179. ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
  180. return;
  181. }
  182. bool fInvalid = false;
  183. std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);
  184. if (fInvalid)
  185. {
  186. ui->signatureIn_VM->setValid(false);
  187. ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
  188. ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
  189. return;
  190. }
  191. CHashWriter ss(SER_GETHASH, 0);
  192. ss << strMessageMagic;
  193. ss << ui->messageIn_VM->document()->toPlainText().toStdString();
  194. CPubKey pubkey;
  195. if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
  196. {
  197. ui->signatureIn_VM->setValid(false);
  198. ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
  199. ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again."));
  200. return;
  201. }
  202. if (!(CStarwelsAddress(pubkey.GetID()) == addr))
  203. {
  204. ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
  205. ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
  206. return;
  207. }
  208. ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
  209. ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
  210. }
  211. void SignVerifyMessageDialog::on_clearButton_VM_clicked()
  212. {
  213. ui->addressIn_VM->clear();
  214. ui->signatureIn_VM->clear();
  215. ui->messageIn_VM->clear();
  216. ui->statusLabel_VM->clear();
  217. ui->addressIn_VM->setFocus();
  218. }
  219. bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
  220. {
  221. if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn)
  222. {
  223. if (ui->tabWidget->currentIndex() == 0)
  224. {
  225. /* Clear status message on focus change */
  226. ui->statusLabel_SM->clear();
  227. /* Select generated signature */
  228. if (object == ui->signatureOut_SM)
  229. {
  230. ui->signatureOut_SM->selectAll();
  231. return true;
  232. }
  233. }
  234. else if (ui->tabWidget->currentIndex() == 1)
  235. {
  236. /* Clear status message on focus change */
  237. ui->statusLabel_VM->clear();
  238. }
  239. }
  240. return QDialog::eventFilter(object, event);
  241. }