@@ -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+
5282QString 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