]>
Commit | Line | Data |
---|---|---|
47894585 PK |
1 | #include "signverifymessagedialog.h" |
2 | #include "ui_signverifymessagedialog.h" | |
3 | ||
4 | #include "addressbookpage.h" | |
5 | #include "base58.h" | |
6 | #include "guiutil.h" | |
7 | #include "init.h" | |
8 | #include "main.h" | |
9 | #include "optionsmodel.h" | |
10 | #include "walletmodel.h" | |
11 | #include "wallet.h" | |
12 | ||
13 | #include <string> | |
14 | #include <vector> | |
15 | ||
16 | #include <QClipboard> | |
17 | ||
18 | SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : | |
19 | QDialog(parent), | |
20 | ui(new Ui::SignVerifyMessageDialog), | |
21 | model(0) | |
22 | { | |
23 | ui->setupUi(this); | |
24 | ||
25 | #if (QT_VERSION >= 0x040700) | |
26 | /* Do not move this to the XML file, Qt before 4.7 will choke on it */ | |
27 | ui->addressIn_SM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); | |
28 | ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); | |
29 | ||
30 | ui->addressIn_VM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); | |
31 | ui->signatureIn_VM->setPlaceholderText(tr("Enter Bitcoin signature")); | |
32 | #endif | |
33 | ||
34 | GUIUtil::setupAddressWidget(ui->addressIn_SM, this); | |
35 | GUIUtil::setupAddressWidget(ui->addressIn_VM, this); | |
36 | ||
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 | ||
44 | ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont()); | |
45 | ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); | |
46 | } | |
47 | ||
48 | SignVerifyMessageDialog::~SignVerifyMessageDialog() | |
49 | { | |
50 | delete ui; | |
51 | } | |
52 | ||
53 | void SignVerifyMessageDialog::setModel(WalletModel *model) | |
54 | { | |
55 | this->model = model; | |
56 | } | |
57 | ||
58 | void SignVerifyMessageDialog::setAddress_SM(QString address) | |
59 | { | |
60 | ui->addressIn_SM->setText(address); | |
61 | ui->messageIn_SM->setFocus(); | |
62 | } | |
63 | ||
64 | void SignVerifyMessageDialog::setAddress_VM(QString address) | |
65 | { | |
66 | ui->addressIn_VM->setText(address); | |
67 | ui->messageIn_VM->setFocus(); | |
68 | } | |
69 | ||
70 | void SignVerifyMessageDialog::showTab_SM(bool fShow) | |
71 | { | |
72 | ui->tabWidget->setCurrentIndex(0); | |
73 | ||
74 | if (fShow) | |
75 | this->show(); | |
76 | } | |
77 | ||
78 | void SignVerifyMessageDialog::showTab_VM(bool fShow) | |
79 | { | |
80 | ui->tabWidget->setCurrentIndex(1); | |
81 | if (fShow) | |
82 | this->show(); | |
83 | } | |
84 | ||
85 | void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() | |
86 | { | |
87 | if (model && model->getAddressTableModel()) | |
88 | { | |
89 | AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::ReceivingTab, this); | |
90 | dlg.setModel(model->getAddressTableModel()); | |
91 | if (dlg.exec()) | |
92 | { | |
93 | setAddress_SM(dlg.getReturnValue()); | |
94 | } | |
95 | } | |
96 | } | |
97 | ||
98 | void SignVerifyMessageDialog::on_pasteButton_SM_clicked() | |
99 | { | |
100 | setAddress_SM(QApplication::clipboard()->text()); | |
101 | } | |
102 | ||
103 | void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() | |
104 | { | |
105 | /* Clear old signature to ensure users don't get confused on error with an old signature displayed */ | |
106 | ui->signatureOut_SM->clear(); | |
107 | ||
108 | CBitcoinAddress addr(ui->addressIn_SM->text().toStdString()); | |
109 | if (!addr.IsValid()) | |
110 | { | |
111 | ui->addressIn_SM->setValid(false); | |
112 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
113 | ui->statusLabel_SM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); | |
114 | return; | |
115 | } | |
116 | CKeyID keyID; | |
117 | if (!addr.GetKeyID(keyID)) | |
118 | { | |
119 | ui->addressIn_SM->setValid(false); | |
120 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
121 | ui->statusLabel_SM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); | |
122 | return; | |
123 | } | |
124 | ||
125 | WalletModel::UnlockContext ctx(model->requestUnlock()); | |
126 | if (!ctx.isValid()) | |
127 | { | |
128 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
129 | ui->statusLabel_SM->setText(tr("Wallet unlock was canceled.")); | |
130 | return; | |
131 | } | |
132 | ||
133 | CKey key; | |
134 | if (!pwalletMain->GetKey(keyID, key)) | |
135 | { | |
136 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
137 | ui->statusLabel_SM->setText(tr("Private key for the entered address is not available.")); | |
138 | return; | |
139 | } | |
140 | ||
141 | CDataStream ss(SER_GETHASH, 0); | |
142 | ss << strMessageMagic; | |
143 | ss << ui->messageIn_SM->document()->toPlainText().toStdString(); | |
144 | ||
145 | std::vector<unsigned char> vchSig; | |
146 | if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) | |
147 | { | |
148 | ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); | |
149 | ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>")); | |
150 | return; | |
151 | } | |
152 | ||
153 | ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); | |
154 | ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>")); | |
155 | ||
156 | ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); | |
157 | } | |
158 | ||
159 | void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() | |
160 | { | |
161 | QApplication::clipboard()->setText(ui->signatureOut_SM->text()); | |
162 | } | |
163 | ||
164 | void SignVerifyMessageDialog::on_clearButton_SM_clicked() | |
165 | { | |
166 | ui->addressIn_SM->clear(); | |
167 | ui->messageIn_SM->clear(); | |
168 | ui->signatureOut_SM->clear(); | |
169 | ui->statusLabel_SM->clear(); | |
170 | ||
171 | ui->addressIn_SM->setFocus(); | |
172 | } | |
173 | ||
174 | void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() | |
175 | { | |
176 | if (model && model->getAddressTableModel()) | |
177 | { | |
178 | AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); | |
179 | dlg.setModel(model->getAddressTableModel()); | |
180 | if (dlg.exec()) | |
181 | { | |
182 | setAddress_VM(dlg.getReturnValue()); | |
183 | } | |
184 | } | |
185 | } | |
186 | ||
187 | void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() | |
188 | { | |
189 | CBitcoinAddress addr(ui->addressIn_VM->text().toStdString()); | |
190 | if (!addr.IsValid()) | |
191 | { | |
192 | ui->addressIn_VM->setValid(false); | |
193 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
194 | ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); | |
195 | return; | |
196 | } | |
197 | CKeyID keyID; | |
198 | if (!addr.GetKeyID(keyID)) | |
199 | { | |
200 | ui->addressIn_VM->setValid(false); | |
201 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
202 | ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); | |
203 | return; | |
204 | } | |
205 | ||
206 | bool fInvalid = false; | |
207 | std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid); | |
208 | ||
209 | if (fInvalid) | |
210 | { | |
211 | ui->signatureIn_VM->setValid(false); | |
212 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
213 | ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again.")); | |
214 | return; | |
215 | } | |
216 | ||
217 | CDataStream ss(SER_GETHASH, 0); | |
218 | ss << strMessageMagic; | |
219 | ss << ui->messageIn_VM->document()->toPlainText().toStdString(); | |
220 | ||
221 | CKey key; | |
222 | if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) | |
223 | { | |
224 | ui->signatureIn_VM->setValid(false); | |
225 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
226 | ui->statusLabel_VM->setText(tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again.")); | |
227 | return; | |
228 | } | |
229 | ||
230 | if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr)) | |
231 | { | |
232 | ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); | |
233 | ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>")); | |
234 | return; | |
235 | } | |
236 | ||
237 | ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }"); | |
238 | ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>")); | |
239 | } | |
240 | ||
241 | void SignVerifyMessageDialog::on_clearButton_VM_clicked() | |
242 | { | |
243 | ui->addressIn_VM->clear(); | |
244 | ui->signatureIn_VM->clear(); | |
245 | ui->messageIn_VM->clear(); | |
246 | ui->statusLabel_VM->clear(); | |
247 | ||
248 | ui->addressIn_VM->setFocus(); | |
249 | } | |
250 | ||
251 | bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) | |
252 | { | |
253 | if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn) | |
254 | { | |
255 | if (ui->tabWidget->currentIndex() == 0) | |
256 | { | |
257 | /* Clear status message on focus change */ | |
258 | ui->statusLabel_SM->clear(); | |
259 | ||
260 | /* Select generated signature */ | |
261 | if (object == ui->signatureOut_SM) | |
262 | { | |
263 | ui->signatureOut_SM->selectAll(); | |
264 | return true; | |
265 | } | |
266 | } | |
267 | else if (ui->tabWidget->currentIndex() == 1) | |
268 | { | |
269 | /* Clear status message on focus change */ | |
270 | ui->statusLabel_VM->clear(); | |
271 | } | |
272 | } | |
273 | return QDialog::eventFilter(object, event); | |
274 | } |