]>
Commit | Line | Data |
---|---|---|
f914f1a7 | 1 | // Copyright (c) 2011-2013 The Bitcoin Core developers |
78253fcb | 2 | // Distributed under the MIT software license, see the accompanying |
e592d43f WL |
3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | ||
47894585 PK |
5 | #include "signverifymessagedialog.h" |
6 | #include "ui_signverifymessagedialog.h" | |
7 | ||
8 | #include "addressbookpage.h" | |
47894585 | 9 | #include "guiutil.h" |
9b7d3fb1 | 10 | #include "scicon.h" |
47894585 | 11 | #include "walletmodel.h" |
47894585 | 12 | |
51ed9ec9 BD |
13 | #include "base58.h" |
14 | #include "init.h" | |
8a893c94 | 15 | #include "main.h" // For strMessageMagic |
50c72f23 | 16 | #include "wallet/wallet.h" |
32af5266 | 17 | |
47894585 PK |
18 | #include <string> |
19 | #include <vector> | |
20 | ||
51ed9ec9 BD |
21 | #include <QClipboard> |
22 | ||
47894585 PK |
23 | SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : |
24 | QDialog(parent), | |
25 | ui(new Ui::SignVerifyMessageDialog), | |
26 | model(0) | |
27 | { | |
28 | ui->setupUi(this); | |
29 | ||
9b7d3fb1 LD |
30 | ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book")); |
31 | ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste")); | |
32 | ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy")); | |
33 | ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit")); | |
34 | ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove")); | |
35 | ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book")); | |
36 | ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0")); | |
37 | ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove")); | |
38 | ||
79fac3f4 | 39 | #if QT_VERSION >= 0x040700 |
47894585 | 40 | ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); |
47894585 PK |
41 | #endif |
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::bitcoinAddressFont()); | |
54 | ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); | |
55 | } | |
56 | ||
57 | SignVerifyMessageDialog::~SignVerifyMessageDialog() | |
58 | { | |
59 | delete ui; | |
60 | } | |
61 | ||
62 | void SignVerifyMessageDialog::setModel(WalletModel *model) | |
63 | { | |
64 | this->model = model; | |
65 | } | |
66 | ||
17c1f7f0 | 67 | void SignVerifyMessageDialog::setAddress_SM(const QString &address) |
47894585 PK |
68 | { |
69 | ui->addressIn_SM->setText(address); | |
70 | ui->messageIn_SM->setFocus(); | |
71 | } | |
72 | ||
17c1f7f0 | 73 | void SignVerifyMessageDialog::setAddress_VM(const QString &address) |
47894585 PK |
74 | { |
75 | ui->addressIn_VM->setText(address); | |
76 | ui->messageIn_VM->setFocus(); | |
77 | } | |
78 | ||
79 | void SignVerifyMessageDialog::showTab_SM(bool fShow) | |
80 | { | |
81 | ui->tabWidget->setCurrentIndex(0); | |
47894585 PK |
82 | if (fShow) |
83 | this->show(); | |
84 | } | |
85 | ||
86 | void SignVerifyMessageDialog::showTab_VM(bool fShow) | |
87 | { | |
88 | ui->tabWidget->setCurrentIndex(1); | |
89 | if (fShow) | |
90 | this->show(); | |
91 | } | |
92 | ||
93 | void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() | |
94 | { | |
95 | if (model && model->getAddressTableModel()) | |
96 | { | |
74fb765e | 97 | AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); |
47894585 PK |
98 | dlg.setModel(model->getAddressTableModel()); |
99 | if (dlg.exec()) | |
100 | { | |
101 | setAddress_SM(dlg.getReturnValue()); | |
102 | } | |
103 | } | |
104 | } | |
105 | ||
106 | void SignVerifyMessageDialog::on_pasteButton_SM_clicked() | |
107 | { | |
108 | setAddress_SM(QApplication::clipboard()->text()); | |
109 | } | |
110 | ||
111 | void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() | |
112 | { | |
6728e007 PK |
113 | if (!model) |
114 | return; | |
115 | ||
47894585 PK |
116 | /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ |
117 | ui->signatureOut_SM->clear(); | |
118 | ||
119 | CBitcoinAddress addr(ui->addressIn_SM->text().toStdString()); | |
120 | if (!addr.IsValid()) | |
121 | { | |
47894585 PK |
122 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); |
123 | ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); | |
124 | return; | |
125 | } | |
126 | CKeyID keyID; | |
127 | if (!addr.GetKeyID(keyID)) | |
128 | { | |
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 | ||
135 | WalletModel::UnlockContext ctx(model->requestUnlock()); | |
136 | if (!ctx.isValid()) | |
137 | { | |
138 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
814efd6f | 139 | ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); |
47894585 PK |
140 | return; |
141 | } | |
142 | ||
143 | CKey key; | |
144 | if (!pwalletMain->GetKey(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 | CDataStream 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(Hash(ss.begin(), ss.end()), 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[0], vchSig.size()))); | |
167 | } | |
168 | ||
169 | void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() | |
170 | { | |
79fac3f4 | 171 | GUIUtil::setClipboard(ui->signatureOut_SM->text()); |
47894585 PK |
172 | } |
173 | ||
174 | void SignVerifyMessageDialog::on_clearButton_SM_clicked() | |
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 | ||
184 | void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() | |
185 | { | |
186 | if (model && model->getAddressTableModel()) | |
187 | { | |
74fb765e | 188 | AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); |
47894585 PK |
189 | dlg.setModel(model->getAddressTableModel()); |
190 | if (dlg.exec()) | |
191 | { | |
192 | setAddress_VM(dlg.getReturnValue()); | |
193 | } | |
194 | } | |
195 | } | |
196 | ||
197 | void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() | |
198 | { | |
199 | CBitcoinAddress addr(ui->addressIn_VM->text().toStdString()); | |
200 | if (!addr.IsValid()) | |
201 | { | |
47894585 PK |
202 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); |
203 | ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); | |
204 | return; | |
205 | } | |
206 | CKeyID keyID; | |
207 | if (!addr.GetKeyID(keyID)) | |
208 | { | |
209 | ui->addressIn_VM->setValid(false); | |
210 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
211 | ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); | |
212 | return; | |
213 | } | |
214 | ||
215 | bool fInvalid = false; | |
216 | std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid); | |
217 | ||
218 | if (fInvalid) | |
219 | { | |
220 | ui->signatureIn_VM->setValid(false); | |
221 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
222 | ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again.")); | |
223 | return; | |
224 | } | |
225 | ||
226 | CDataStream ss(SER_GETHASH, 0); | |
227 | ss << strMessageMagic; | |
228 | ss << ui->messageIn_VM->document()->toPlainText().toStdString(); | |
229 | ||
dfa23b94 PW |
230 | CPubKey pubkey; |
231 | if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig)) | |
47894585 PK |
232 | { |
233 | ui->signatureIn_VM->setValid(false); | |
234 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
235 | ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again.")); | |
236 | return; | |
237 | } | |
238 | ||
dfa23b94 | 239 | if (!(CBitcoinAddress(pubkey.GetID()) == addr)) |
47894585 PK |
240 | { |
241 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
242 | ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>")); | |
243 | return; | |
244 | } | |
245 | ||
246 | ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }"); | |
247 | ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>")); | |
248 | } | |
249 | ||
250 | void SignVerifyMessageDialog::on_clearButton_VM_clicked() | |
251 | { | |
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 | { | |
262 | if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn) | |
263 | { | |
264 | if (ui->tabWidget->currentIndex() == 0) | |
265 | { | |
266 | /* Clear status message on focus change */ | |
267 | ui->statusLabel_SM->clear(); | |
268 | ||
269 | /* Select generated signature */ | |
270 | if (object == ui->signatureOut_SM) | |
271 | { | |
272 | ui->signatureOut_SM->selectAll(); | |
273 | return true; | |
274 | } | |
275 | } | |
276 | else if (ui->tabWidget->currentIndex() == 1) | |
277 | { | |
278 | /* Clear status message on focus change */ | |
279 | ui->statusLabel_VM->clear(); | |
280 | } | |
281 | } | |
282 | return QDialog::eventFilter(object, event); | |
283 | } |