@@ -58,14 +58,19 @@ const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest"
5858// BIP70 max payment request size in bytes (DoS protection)
5959const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000 ;
6060
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
6372{
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;
6974}
7075
7176//
@@ -107,20 +112,15 @@ static void ReportInvalidCertificate(const QSslCertificate& cert)
107112//
108113void PaymentServer::LoadRootCAs (X509_STORE* _store)
109114{
110- if (PaymentServer::certStore == NULL )
111- atexit (PaymentServer::freeCertStore);
112- else
113- freeCertStore ();
114-
115115 // Unit tests mostly use this, to pass in fake root CAs:
116116 if (_store)
117117 {
118- PaymentServer:: certStore = _store;
118+ certStore. reset ( _store) ;
119119 return ;
120120 }
121121
122122 // Normal execution, use either -rootcertificates or system certs:
123- PaymentServer:: certStore = X509_STORE_new ();
123+ certStore. reset ( X509_STORE_new () );
124124
125125 // Note: use "-system-" default here so that users can pass -rootcertificates=""
126126 // and get 'I don't like X.509 certificates, don't trust anybody' behavior:
@@ -167,11 +167,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
167167 QByteArray certData = cert.toDer ();
168168 const unsigned char *data = (const unsigned char *)certData.data ();
169169
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 () ))
172172 {
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.
175175 ++nRootCerts;
176176 }
177177 else
@@ -550,7 +550,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen
550550 recipient.paymentRequest = request;
551551 recipient.message = GUIUtil::HtmlEscape (request.getDetails ().memo ());
552552
553- request.getMerchant (PaymentServer:: certStore, recipient.authenticatedMerchant );
553+ request.getMerchant (certStore. get () , recipient.authenticatedMerchant );
554554
555555 QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo ();
556556 QStringList addresses;
@@ -807,3 +807,8 @@ bool PaymentServer::verifyAmount(const CAmount& requestAmount)
807807 }
808808 return fVerified ;
809809}
810+
811+ X509_STORE* PaymentServer::getCertStore ()
812+ {
813+ return certStore.get ();
814+ }
0 commit comments