Skip to content

Commit 38b9850

Browse files
laanwjjameshilliard
authored andcommitted
qt: cleanup: Move BIP70 functions together in paymentserver
Reduces the number of separate `#ifdefs` spans.
1 parent 9dcf6c0 commit 38b9850

File tree

2 files changed

+148
-159
lines changed

2 files changed

+148
-159
lines changed

src/qt/paymentserver.cpp

Lines changed: 135 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -57,21 +57,6 @@ const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest";
5757
const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment";
5858
const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack";
5959
const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest";
60-
61-
struct X509StoreDeleter {
62-
void operator()(X509_STORE* b) {
63-
X509_STORE_free(b);
64-
}
65-
};
66-
67-
struct X509Deleter {
68-
void operator()(X509* b) { X509_free(b); }
69-
};
70-
71-
namespace // Anon namespace
72-
{
73-
std::unique_ptr<X509_STORE, X509StoreDeleter> certStore;
74-
}
7560
#endif
7661

7762
//
@@ -99,96 +84,6 @@ static QString ipcServerName()
9984

10085
static QList<QString> savedPaymentRequests;
10186

102-
#ifdef ENABLE_BIP70
103-
static void ReportInvalidCertificate(const QSslCertificate& cert)
104-
{
105-
qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
106-
}
107-
108-
//
109-
// Load OpenSSL's list of root certificate authorities
110-
//
111-
void PaymentServer::LoadRootCAs(X509_STORE* _store)
112-
{
113-
// Unit tests mostly use this, to pass in fake root CAs:
114-
if (_store)
115-
{
116-
certStore.reset(_store);
117-
return;
118-
}
119-
120-
// Normal execution, use either -rootcertificates or system certs:
121-
certStore.reset(X509_STORE_new());
122-
123-
// Note: use "-system-" default here so that users can pass -rootcertificates=""
124-
// and get 'I don't like X.509 certificates, don't trust anybody' behavior:
125-
QString certFile = QString::fromStdString(gArgs.GetArg("-rootcertificates", "-system-"));
126-
127-
// Empty store
128-
if (certFile.isEmpty()) {
129-
qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__);
130-
return;
131-
}
132-
133-
QList<QSslCertificate> certList;
134-
135-
if (certFile != "-system-") {
136-
qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile);
137-
138-
certList = QSslCertificate::fromPath(certFile);
139-
// Use those certificates when fetching payment requests, too:
140-
QSslSocket::setDefaultCaCertificates(certList);
141-
} else
142-
certList = QSslSocket::systemCaCertificates();
143-
144-
int nRootCerts = 0;
145-
const QDateTime currentTime = QDateTime::currentDateTime();
146-
147-
for (const QSslCertificate& cert : certList) {
148-
// Don't log NULL certificates
149-
if (cert.isNull())
150-
continue;
151-
152-
// Not yet active/valid, or expired certificate
153-
if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
154-
ReportInvalidCertificate(cert);
155-
continue;
156-
}
157-
158-
// Blacklisted certificate
159-
if (cert.isBlacklisted()) {
160-
ReportInvalidCertificate(cert);
161-
continue;
162-
}
163-
QByteArray certData = cert.toDer();
164-
const unsigned char *data = (const unsigned char *)certData.data();
165-
166-
std::unique_ptr<X509, X509Deleter> x509(d2i_X509(0, &data, certData.size()));
167-
if (x509 && X509_STORE_add_cert(certStore.get(), x509.get()))
168-
{
169-
// Note: X509_STORE increases the reference count to the X509 object,
170-
// we still have to release our reference to it.
171-
++nRootCerts;
172-
}
173-
else
174-
{
175-
ReportInvalidCertificate(cert);
176-
continue;
177-
}
178-
}
179-
qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates";
180-
181-
// Project for another day:
182-
// Fetch certificate revocation lists, and add them to certStore.
183-
// Issues to consider:
184-
// performance (start a thread to fetch in background?)
185-
// privacy (fetch through tor/proxy so IP address isn't revealed)
186-
// would it be easier to just use a compiled-in blacklist?
187-
// or use Qt's blacklist?
188-
// "certificate stapling" with server-side caching is more efficient
189-
}
190-
#endif
191-
19287
//
19388
// Sending to the server is done synchronously, at startup.
19489
// If the server isn't already running, startup continues,
@@ -300,10 +195,10 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
300195
QObject(parent),
301196
saveURIs(true),
302197
uriServer(0),
198+
optionsModel(0)
303199
#ifdef ENABLE_BIP70
304-
netManager(0),
200+
,netManager(0)
305201
#endif
306-
optionsModel(0)
307202
{
308203
#ifdef ENABLE_BIP70
309204
// Verify that the version of the library that we linked against is
@@ -367,32 +262,6 @@ bool PaymentServer::eventFilter(QObject *object, QEvent *event)
367262
return QObject::eventFilter(object, event);
368263
}
369264

370-
#ifdef ENABLE_BIP70
371-
void PaymentServer::initNetManager()
372-
{
373-
if (!optionsModel)
374-
return;
375-
delete netManager;
376-
377-
// netManager is used to fetch paymentrequests given in bitcoin: URIs
378-
netManager = new QNetworkAccessManager(this);
379-
380-
QNetworkProxy proxy;
381-
382-
// Query active SOCKS5 proxy
383-
if (optionsModel->getProxySettings(proxy)) {
384-
netManager->setProxy(proxy);
385-
386-
qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
387-
}
388-
else
389-
qDebug() << "PaymentServer::initNetManager: No active proxy server found.";
390-
391-
connect(netManager, &QNetworkAccessManager::finished, this, &PaymentServer::netRequestFinished);
392-
connect(netManager, &QNetworkAccessManager::sslErrors, this, &PaymentServer::reportSslErrors);
393-
}
394-
#endif
395-
396265
void PaymentServer::uiReady()
397266
{
398267
#ifdef ENABLE_BIP70
@@ -510,7 +379,140 @@ void PaymentServer::handleURIConnection()
510379
handleURIOrFile(msg);
511380
}
512381

382+
void PaymentServer::setOptionsModel(OptionsModel *_optionsModel)
383+
{
384+
this->optionsModel = _optionsModel;
385+
}
386+
513387
#ifdef ENABLE_BIP70
388+
struct X509StoreDeleter {
389+
void operator()(X509_STORE* b) {
390+
X509_STORE_free(b);
391+
}
392+
};
393+
394+
struct X509Deleter {
395+
void operator()(X509* b) { X509_free(b); }
396+
};
397+
398+
namespace // Anon namespace
399+
{
400+
std::unique_ptr<X509_STORE, X509StoreDeleter> certStore;
401+
}
402+
403+
static void ReportInvalidCertificate(const QSslCertificate& cert)
404+
{
405+
qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
406+
}
407+
408+
//
409+
// Load OpenSSL's list of root certificate authorities
410+
//
411+
void PaymentServer::LoadRootCAs(X509_STORE* _store)
412+
{
413+
// Unit tests mostly use this, to pass in fake root CAs:
414+
if (_store)
415+
{
416+
certStore.reset(_store);
417+
return;
418+
}
419+
420+
// Normal execution, use either -rootcertificates or system certs:
421+
certStore.reset(X509_STORE_new());
422+
423+
// Note: use "-system-" default here so that users can pass -rootcertificates=""
424+
// and get 'I don't like X.509 certificates, don't trust anybody' behavior:
425+
QString certFile = QString::fromStdString(gArgs.GetArg("-rootcertificates", "-system-"));
426+
427+
// Empty store
428+
if (certFile.isEmpty()) {
429+
qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__);
430+
return;
431+
}
432+
433+
QList<QSslCertificate> certList;
434+
435+
if (certFile != "-system-") {
436+
qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile);
437+
438+
certList = QSslCertificate::fromPath(certFile);
439+
// Use those certificates when fetching payment requests, too:
440+
QSslSocket::setDefaultCaCertificates(certList);
441+
} else
442+
certList = QSslSocket::systemCaCertificates();
443+
444+
int nRootCerts = 0;
445+
const QDateTime currentTime = QDateTime::currentDateTime();
446+
447+
for (const QSslCertificate& cert : certList) {
448+
// Don't log NULL certificates
449+
if (cert.isNull())
450+
continue;
451+
452+
// Not yet active/valid, or expired certificate
453+
if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
454+
ReportInvalidCertificate(cert);
455+
continue;
456+
}
457+
458+
// Blacklisted certificate
459+
if (cert.isBlacklisted()) {
460+
ReportInvalidCertificate(cert);
461+
continue;
462+
}
463+
464+
QByteArray certData = cert.toDer();
465+
const unsigned char *data = (const unsigned char *)certData.data();
466+
467+
std::unique_ptr<X509, X509Deleter> x509(d2i_X509(0, &data, certData.size()));
468+
if (x509 && X509_STORE_add_cert(certStore.get(), x509.get()))
469+
{
470+
// Note: X509_STORE increases the reference count to the X509 object,
471+
// we still have to release our reference to it.
472+
++nRootCerts;
473+
}
474+
else
475+
{
476+
ReportInvalidCertificate(cert);
477+
continue;
478+
}
479+
}
480+
qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates";
481+
482+
// Project for another day:
483+
// Fetch certificate revocation lists, and add them to certStore.
484+
// Issues to consider:
485+
// performance (start a thread to fetch in background?)
486+
// privacy (fetch through tor/proxy so IP address isn't revealed)
487+
// would it be easier to just use a compiled-in blacklist?
488+
// or use Qt's blacklist?
489+
// "certificate stapling" with server-side caching is more efficient
490+
}
491+
492+
void PaymentServer::initNetManager()
493+
{
494+
if (!optionsModel)
495+
return;
496+
delete netManager;
497+
498+
// netManager is used to fetch paymentrequests given in bitcoin: URIs
499+
netManager = new QNetworkAccessManager(this);
500+
501+
QNetworkProxy proxy;
502+
503+
// Query active SOCKS5 proxy
504+
if (optionsModel->getProxySettings(proxy)) {
505+
netManager->setProxy(proxy);
506+
507+
qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
508+
}
509+
else
510+
qDebug() << "PaymentServer::initNetManager: No active proxy server found.";
511+
512+
connect(netManager, &QNetworkAccessManager::finished, this, &PaymentServer::netRequestFinished);
513+
connect(netManager, &QNetworkAccessManager::sslErrors, this, &PaymentServer::reportSslErrors);
514+
}
515+
514516
//
515517
// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
516518
// so don't use "Q_EMIT message()", but "QMessageBox::"!
@@ -760,14 +762,7 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError>
760762
}
761763
Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
762764
}
763-
#endif
764-
765-
void PaymentServer::setOptionsModel(OptionsModel *_optionsModel)
766-
{
767-
this->optionsModel = _optionsModel;
768-
}
769765

770-
#ifdef ENABLE_BIP70
771766
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
772767
{
773768
// currently we don't further process or store the paymentACK message

0 commit comments

Comments
 (0)