@@ -58,14 +58,19 @@ const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest"
58
58
// BIP70 max payment request size in bytes (DoS protection)
59
59
const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000 ;
60
60
61
- X509_STORE* PaymentServer::certStore = NULL ;
62
- void PaymentServer::freeCertStore ()
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
63
72
{
64
- if (PaymentServer::certStore != NULL )
65
- {
66
- X509_STORE_free (PaymentServer::certStore);
67
- PaymentServer::certStore = NULL ;
68
- }
73
+ std::unique_ptr<X509_STORE, X509StoreDeleter> certStore;
69
74
}
70
75
71
76
//
@@ -107,20 +112,15 @@ static void ReportInvalidCertificate(const QSslCertificate& cert)
107
112
//
108
113
void PaymentServer::LoadRootCAs (X509_STORE* _store)
109
114
{
110
- if (PaymentServer::certStore == NULL )
111
- atexit (PaymentServer::freeCertStore);
112
- else
113
- freeCertStore ();
114
-
115
115
// Unit tests mostly use this, to pass in fake root CAs:
116
116
if (_store)
117
117
{
118
- PaymentServer:: certStore = _store;
118
+ certStore. reset ( _store) ;
119
119
return ;
120
120
}
121
121
122
122
// Normal execution, use either -rootcertificates or system certs:
123
- PaymentServer:: certStore = X509_STORE_new ();
123
+ certStore. reset ( X509_STORE_new () );
124
124
125
125
// Note: use "-system-" default here so that users can pass -rootcertificates=""
126
126
// and get 'I don't like X.509 certificates, don't trust anybody' behavior:
@@ -167,11 +167,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
167
167
QByteArray certData = cert.toDer ();
168
168
const unsigned char *data = (const unsigned char *)certData.data ();
169
169
170
- X509* x509 = d2i_X509 (0 , &data, certData.size ());
171
- if (x509 && X509_STORE_add_cert (PaymentServer:: certStore, x509))
170
+ std::unique_ptr< X509, X509Deleter> x509 ( d2i_X509 (0 , &data, certData.size () ));
171
+ if (x509 && X509_STORE_add_cert (certStore. get () , x509. get () ))
172
172
{
173
- // Note: X509_STORE_free will free the X509* objects when
174
- // the PaymentServer is destroyed
173
+ // Note: X509_STORE increases the reference count to the X509 object,
174
+ // we still have to release our reference to it.
175
175
++nRootCerts;
176
176
}
177
177
else
@@ -550,7 +550,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen
550
550
recipient.paymentRequest = request;
551
551
recipient.message = GUIUtil::HtmlEscape (request.getDetails ().memo ());
552
552
553
- request.getMerchant (PaymentServer:: certStore, recipient.authenticatedMerchant );
553
+ request.getMerchant (certStore. get () , recipient.authenticatedMerchant );
554
554
555
555
QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo ();
556
556
QStringList addresses;
@@ -807,3 +807,8 @@ bool PaymentServer::verifyAmount(const CAmount& requestAmount)
807
807
}
808
808
return fVerified ;
809
809
}
810
+
811
+ X509_STORE* PaymentServer::getCertStore ()
812
+ {
813
+ return certStore.get ();
814
+ }
0 commit comments