diff options
author | Andrew Chow <achow101-github@achow101.com> | 2019-09-11 03:37:44 -0400 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2019-09-30 11:31:58 -0400 |
commit | 85973bcc44f60fe3bbc952557ebf578dd4c475d2 (patch) | |
tree | 606320f5872fe5a5f8774ac81a6c983d3b962fee | |
parent | 1985c4efda56b48f6f9c04f39d69268ee8f0b40a (diff) |
When BIP70 is disabled, get PaymentRequest merchant using string search
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.
-rw-r--r-- | src/qt/transactiondesc.cpp | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index ebe7925368..648fdb7673 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -49,6 +49,36 @@ QString TransactionDesc::FormatTxStatus(const interfaces::WalletTx& wtx, const i } } +#ifndef ENABLE_BIP70 +// Takes an encoded PaymentRequest as a string and tries to find the Common Name of the X.509 certificate +// used to sign the PaymentRequest. +bool GetPaymentRequestMerchant(const std::string& pr, QString& merchant) +{ + // Search for the supported pki type strings + if (pr.find(std::string({0x12, 0x0b}) + "x509+sha256") != std::string::npos || pr.find(std::string({0x12, 0x09}) + "x509+sha1") != std::string::npos) { + // We want the common name of the Subject of the cert. This should be the second occurrence + // of the bytes 0x0603550403. The first occurrence of those is the common name of the issuer. + // After those bytes will be either 0x13 or 0x0C, then length, then either the ascii or utf8 + // string with the common name which is the merchant name + size_t cn_pos = pr.find({0x06, 0x03, 0x55, 0x04, 0x03}); + if (cn_pos != std::string::npos) { + cn_pos = pr.find({0x06, 0x03, 0x55, 0x04, 0x03}, cn_pos + 5); + if (cn_pos != std::string::npos) { + cn_pos += 5; + if (pr[cn_pos] == 0x13 || pr[cn_pos] == 0x0c) { + cn_pos++; // Consume the type + int str_len = pr[cn_pos]; + cn_pos++; // Consume the string length + merchant = QString::fromUtf8(pr.data() + cn_pos, str_len); + return true; + } + } + } + } + return false; +} +#endif + QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit) { int numBlocks; @@ -255,26 +285,34 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>"; // Message from normal bitcoin:URI (bitcoin:123...?message=example) - for (const std::pair<std::string, std::string>& r : orderForm) + for (const std::pair<std::string, std::string>& r : orderForm) { if (r.first == "Message") strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>"; -#ifdef ENABLE_BIP70 - // - // PaymentRequest info: - // - for (const std::pair<std::string, std::string>& r : orderForm) - { + // + // PaymentRequest info: + // if (r.first == "PaymentRequest") { + QString merchant; +#ifdef ENABLE_BIP70 PaymentRequestPlus req; req.parse(QByteArray::fromRawData(r.second.data(), r.second.size())); - QString merchant; - if (req.getMerchant(PaymentServer::getCertStore(), merchant)) + if (!req.getMerchant(PaymentServer::getCertStore(), merchant)) { + merchant.clear(); + } +#else + if (!GetPaymentRequestMerchant(r.second, merchant)) { + merchant.clear(); + } else { + merchant += tr(" (Certificate was not verified)"); + } +#endif + if (!merchant.isNull()) { strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>"; + } } } -#endif if (wtx.is_coinbase) { |