Skip to content

Commit cd6e9b3

Browse files
committed
Merge #16852: gui: When BIP70 is disabled, get PaymentRequest merchant using string search
85973bc When BIP70 is disabled, get PaymentRequest merchant using string search (Andrew Chow) Pull request description: The merchant name is stored in the X.509 certificate embedded in a PaymentRequest. Use some string searching to locate it so that it can be shown to the user in the transaction details when BIP70 support was not configured. An additional notice is added to the merchant string that indicates the certificate was not verified. When BIP70 is enabled, the certificate would be verified and the merchant name not shown if the certificate was invalid. ACKs for top commit: laanwj: ACK 85973bc Tree-SHA512: 50fdb60d418e2f9eb65a4b52477be16189f00bfc30493adb27d9fb62100fd5bca33b98b8db6caa8485db424838d3b7a1da802c14ff4917943464401f47391616
2 parents a54e52b + 85973bc commit cd6e9b3

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

src/qt/transactiondesc.cpp

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,36 @@ QString TransactionDesc::FormatTxStatus(const interfaces::WalletTx& wtx, const i
4949
}
5050
}
5151

52+
#ifndef ENABLE_BIP70
53+
// Takes an encoded PaymentRequest as a string and tries to find the Common Name of the X.509 certificate
54+
// used to sign the PaymentRequest.
55+
bool GetPaymentRequestMerchant(const std::string& pr, QString& merchant)
56+
{
57+
// Search for the supported pki type strings
58+
if (pr.find(std::string({0x12, 0x0b}) + "x509+sha256") != std::string::npos || pr.find(std::string({0x12, 0x09}) + "x509+sha1") != std::string::npos) {
59+
// We want the common name of the Subject of the cert. This should be the second occurrence
60+
// of the bytes 0x0603550403. The first occurrence of those is the common name of the issuer.
61+
// After those bytes will be either 0x13 or 0x0C, then length, then either the ascii or utf8
62+
// string with the common name which is the merchant name
63+
size_t cn_pos = pr.find({0x06, 0x03, 0x55, 0x04, 0x03});
64+
if (cn_pos != std::string::npos) {
65+
cn_pos = pr.find({0x06, 0x03, 0x55, 0x04, 0x03}, cn_pos + 5);
66+
if (cn_pos != std::string::npos) {
67+
cn_pos += 5;
68+
if (pr[cn_pos] == 0x13 || pr[cn_pos] == 0x0c) {
69+
cn_pos++; // Consume the type
70+
int str_len = pr[cn_pos];
71+
cn_pos++; // Consume the string length
72+
merchant = QString::fromUtf8(pr.data() + cn_pos, str_len);
73+
return true;
74+
}
75+
}
76+
}
77+
}
78+
return false;
79+
}
80+
#endif
81+
5282
QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit)
5383
{
5484
int numBlocks;
@@ -255,26 +285,34 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall
255285
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
256286

257287
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
258-
for (const std::pair<std::string, std::string>& r : orderForm)
288+
for (const std::pair<std::string, std::string>& r : orderForm) {
259289
if (r.first == "Message")
260290
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
261291

262-
#ifdef ENABLE_BIP70
263-
//
264-
// PaymentRequest info:
265-
//
266-
for (const std::pair<std::string, std::string>& r : orderForm)
267-
{
292+
//
293+
// PaymentRequest info:
294+
//
268295
if (r.first == "PaymentRequest")
269296
{
297+
QString merchant;
298+
#ifdef ENABLE_BIP70
270299
PaymentRequestPlus req;
271300
req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
272-
QString merchant;
273-
if (req.getMerchant(PaymentServer::getCertStore(), merchant))
301+
if (!req.getMerchant(PaymentServer::getCertStore(), merchant)) {
302+
merchant.clear();
303+
}
304+
#else
305+
if (!GetPaymentRequestMerchant(r.second, merchant)) {
306+
merchant.clear();
307+
} else {
308+
merchant += tr(" (Certificate was not verified)");
309+
}
310+
#endif
311+
if (!merchant.isNull()) {
274312
strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
313+
}
275314
}
276315
}
277-
#endif
278316

279317
if (wtx.is_coinbase)
280318
{

0 commit comments

Comments
 (0)