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.
This commit is contained in:
parent
1985c4efda
commit
85973bcc44
1 changed files with 48 additions and 10 deletions
|
@ -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)
|
QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit)
|
||||||
{
|
{
|
||||||
int numBlocks;
|
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>";
|
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
|
||||||
|
|
||||||
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
|
// 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")
|
if (r.first == "Message")
|
||||||
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
|
strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
|
||||||
|
|
||||||
#ifdef ENABLE_BIP70
|
//
|
||||||
//
|
// PaymentRequest info:
|
||||||
// PaymentRequest info:
|
//
|
||||||
//
|
|
||||||
for (const std::pair<std::string, std::string>& r : orderForm)
|
|
||||||
{
|
|
||||||
if (r.first == "PaymentRequest")
|
if (r.first == "PaymentRequest")
|
||||||
{
|
{
|
||||||
|
QString merchant;
|
||||||
|
#ifdef ENABLE_BIP70
|
||||||
PaymentRequestPlus req;
|
PaymentRequestPlus req;
|
||||||
req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
|
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>";
|
strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (wtx.is_coinbase)
|
if (wtx.is_coinbase)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue