[squid-dev] [PATCH] LockingPointer API update

Amos Jeffries squid3 at treenet.co.nz
Tue Jun 21 10:00:11 UTC 2016


With GnuTLS support it is sometimes more useful to use a TidyPointer
where a LockingPointer is used by OpenSSL.

This patch converts the LockingPointer resetAndLock() to a virtual
reset() so callers can use the right one without needing to care which
type of pointer they are handling.

Doing this has already uncovered two instances of the
TidyPointer::reset() being wrongly used on cert LockingPointer objects.
There may be more hidden away, I only noticed the ones that were being
used near a resetAndLock() on the same variable. That could have been
leading to early unexpected free'ing of those certs in some code paths.

This change needs to be checked by someone with an OpenSSL bumping
installation please.

Amos
-------------- next part --------------
=== modified file 'src/base/TidyPointer.h'
--- src/base/TidyPointer.h	2016-03-31 23:33:45 +0000
+++ src/base/TidyPointer.h	2016-06-20 22:24:54 +0000
@@ -12,53 +12,53 @@
 /**
  * A pointer that deletes the object it points to when the pointer's owner or
  * context is gone. Similar to std::unique_ptr but without confusing assignment
  * and with a customizable cleanup method. Prevents memory leaks in
  * the presence of exceptions and processing short cuts.
 */
 template <typename T, void (*DeAllocator)(T *t)> class TidyPointer
 {
 public:
     /// Delete callback.
     typedef void DCB (T *t);
     TidyPointer(T *t = NULL)
         :   raw(t) {}
 public:
     bool operator !() const { return !raw; }
     explicit operator bool() const { return raw; }
     /// Returns raw and possibly NULL pointer
     T *get() const { return raw; }
 
     /// Reset raw pointer - delete last one and save new one.
-    void reset(T *t) {
+    virtual void reset(T *t) {
         deletePointer();
         raw = t;
     }
 
     /// Forget the raw pointer without freeing it. Become a nil pointer.
     T *release() {
         T *ret = raw;
         raw = NULL;
         return ret;
     }
     /// Deallocate raw pointer.
-    ~TidyPointer() {
+    virtual ~TidyPointer() {
         deletePointer();
     }
 private:
     /// Forbidden copy constructor.
     TidyPointer(TidyPointer<T, DeAllocator> const &);
     /// Forbidden assigment operator.
     TidyPointer <T, DeAllocator> & operator = (TidyPointer<T, DeAllocator> const &);
     /// Deallocate raw pointer. Become a nil pointer.
     void deletePointer() {
         if (raw) {
             DeAllocator(raw);
         }
         raw = NULL;
     }
     T *raw; ///< pointer to T object or NULL
 };
 
 /// DeAllocator for pointers that need free(3) from the std C library
 template<typename T> void tidyFree(T *p)
 {

=== modified file 'src/client_side.cc'
--- src/client_side.cc	2016-05-20 13:20:27 +0000
+++ src/client_side.cc	2016-06-20 22:36:29 +0000
@@ -2879,55 +2879,55 @@
                     SSL_CTX *sslContext = SSL_get_SSL_CTX(ssl);
                     Ssl::configureUnconfiguredSslContext(sslContext, signAlgorithm, *port);
                 } else {
                     auto ctx = Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), *port);
                     getSslContextDone(ctx, true);
                 }
                 return;
             }
         }
     }
     getSslContextDone(NULL);
 }
 
 void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties)
 {
     certProperties.commonName =  sslCommonName_.isEmpty() ? sslConnectHostOrIp.termedBuf() : sslCommonName_.c_str();
 
     // fake certificate adaptation requires bump-server-first mode
     if (!sslServerBump) {
         assert(port->signingCert.get());
-        certProperties.signWithX509.resetAndLock(port->signingCert.get());
+        certProperties.signWithX509.reset(port->signingCert.get());
         if (port->signPkey.get())
-            certProperties.signWithPkey.resetAndLock(port->signPkey.get());
+            certProperties.signWithPkey.reset(port->signPkey.get());
         certProperties.signAlgorithm = Ssl::algSignTrusted;
         return;
     }
 
     // In case of an error while connecting to the secure server, use a fake
     // trusted certificate, with no mimicked fields and no adaptation
     // algorithms. There is nothing we can mimic so we want to minimize the
     // number of warnings the user will have to see to get to the error page.
     assert(sslServerBump->entry);
     if (sslServerBump->entry->isEmpty()) {
         if (X509 *mimicCert = sslServerBump->serverCert.get())
-            certProperties.mimicCert.resetAndLock(mimicCert);
+            certProperties.mimicCert.reset(mimicCert);
 
         ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(),
                                      clientConnection != NULL ? clientConnection->rfc931 : dash_str);
         checklist.sslErrors = cbdataReference(sslServerBump->sslErrors());
 
         for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) {
             // If the algorithm already set, then ignore it.
             if ((ca->alg == Ssl::algSetCommonName && certProperties.setCommonName) ||
                     (ca->alg == Ssl::algSetValidAfter && certProperties.setValidAfter) ||
                     (ca->alg == Ssl::algSetValidBefore && certProperties.setValidBefore) )
                 continue;
 
             if (ca->aclList && checklist.fastCheck(ca->aclList) == ACCESS_ALLOWED) {
                 const char *alg = Ssl::CertAdaptAlgorithmStr[ca->alg];
                 const char *param = ca->param;
 
                 // For parameterless CN adaptation, use hostname from the
                 // CONNECT request.
                 if (ca->alg == Ssl::algSetCommonName) {
                     if (!param)
@@ -2946,48 +2946,48 @@
 
         certProperties.signAlgorithm = Ssl::algSignEnd;
         for (sslproxy_cert_sign *sg = Config.ssl_client.cert_sign; sg != NULL; sg = sg->next) {
             if (sg->aclList && checklist.fastCheck(sg->aclList) == ACCESS_ALLOWED) {
                 certProperties.signAlgorithm = (Ssl::CertSignAlgorithm)sg->alg;
                 break;
             }
         }
     } else {// if (!sslServerBump->entry->isEmpty())
         // Use trusted certificate for a Squid-generated error
         // or the user would have to add a security exception
         // just to see the error page. We will close the connection
         // so that the trust is not extended to non-Squid content.
         certProperties.signAlgorithm = Ssl::algSignTrusted;
     }
 
     assert(certProperties.signAlgorithm != Ssl::algSignEnd);
 
     if (certProperties.signAlgorithm == Ssl::algSignUntrusted) {
         assert(port->untrustedSigningCert.get());
-        certProperties.signWithX509.resetAndLock(port->untrustedSigningCert.get());
-        certProperties.signWithPkey.resetAndLock(port->untrustedSignPkey.get());
+        certProperties.signWithX509.reset(port->untrustedSigningCert.get());
+        certProperties.signWithPkey.reset(port->untrustedSignPkey.get());
     } else {
         assert(port->signingCert.get());
-        certProperties.signWithX509.resetAndLock(port->signingCert.get());
+        certProperties.signWithX509.reset(port->signingCert.get());
 
         if (port->signPkey.get())
-            certProperties.signWithPkey.resetAndLock(port->signPkey.get());
+            certProperties.signWithPkey.reset(port->signPkey.get());
     }
     signAlgorithm = certProperties.signAlgorithm;
 
     certProperties.signHash = Ssl::DefaultSignHash;
 }
 
 void
 ConnStateData::getSslContextStart()
 {
     // XXX starting SSL with a pipeline of requests still waiting for non-SSL replies?
     assert(pipeline.count() < 2); // the CONNECT is okay for now. Anything else is a bug.
     pipeline.terminateAll(0);
     /* careful: terminateAll(0) above frees request, host, etc. */
 
     if (port->generateHostCertificates) {
         Ssl::CertificateProperties certProperties;
         buildSslCertGenerationParams(certProperties);
         sslBumpCertKey = certProperties.dbKey().c_str();
         assert(sslBumpCertKey.size() > 0 && sslBumpCertKey[0] != '\0');
 

=== modified file 'src/security/LockingPointer.h'
--- src/security/LockingPointer.h	2016-03-31 23:33:45 +0000
+++ src/security/LockingPointer.h	2016-06-20 22:54:50 +0000
@@ -32,58 +32,61 @@
         extern "C++" inline void function ## _cpp(argument a) { \
             function(a); \
         }
 
 namespace Security
 {
 
 /**
  * Add SSL locking (a.k.a. reference counting) and assignment to TidyPointer
  */
 template <typename T, void (*DeAllocator)(T *t), int lock>
 class LockingPointer: public TidyPointer<T, DeAllocator>
 {
 public:
     typedef TidyPointer<T, DeAllocator> Parent;
     typedef LockingPointer<T, DeAllocator, lock> SelfType;
 
     explicit LockingPointer(T *t = nullptr): Parent(t) {}
 
     explicit LockingPointer(const SelfType &o): Parent() {
-        resetAndLock(o.get());
+        reset(o.get());
     }
+    virtual ~LockingPointer() = default;
 
     SelfType &operator =(const SelfType & o) {
-        resetAndLock(o.get());
+        reset(o.get());
         return *this;
     }
 
 #if __cplusplus >= 201103L
     explicit LockingPointer(LockingPointer<T, DeAllocator, lock> &&o): Parent(o.release()) {
     }
 
     LockingPointer<T, DeAllocator, lock> &operator =(LockingPointer<T, DeAllocator, lock> &&o) {
         if (o.get() != this->get())
             this->reset(o.release());
         return *this;
     }
 #endif
 
-    void resetAndLock(T *t) {
+    virtual void reset(T *t) override {
         if (t != this->get()) {
-            this->reset(t);
+            // initial part must match TidyPointer::reset
+            this->TidyPointer<T, DeAllocator>::reset(t);
+            // then the locking
 #if USE_OPENSSL
             if (t)
                 CRYPTO_add(&t->references, 1, lock);
 #elif USE_GNUTLS
             // XXX: GnuTLS does not provide locking ?
 #else
             assert(false);
 #endif
         }
     }
 };
 
 } // namespace Security
 
 #endif /* SQUID_SRC_SECURITY_LOCKINGPOINTER_H */
 

=== modified file 'src/ssl/ErrorDetail.cc'
--- src/ssl/ErrorDetail.cc	2016-01-01 00:12:18 +0000
+++ src/ssl/ErrorDetail.cc	2016-06-20 22:39:28 +0000
@@ -611,48 +611,48 @@
         code_len = convert(++p, &t);
         if (code_len)
             errDetailStr.append(t);
         else
             errDetailStr.append("%");
         s = p + code_len;
     }
     errDetailStr.append(s, strlen(s));
 }
 
 const String &Ssl::ErrorDetail::toString() const
 {
     if (errDetailStr.size() == 0)
         buildDetail();
     return errDetailStr;
 }
 
 Ssl::ErrorDetail::ErrorDetail( Ssl::ssl_error_t err_no, X509 *cert, X509 *broken, const char *aReason): error_no (err_no), lib_error_no(SSL_ERROR_NONE), errReason(aReason)
 {
     if (cert)
-        peer_cert.resetAndLock(cert);
+        peer_cert.reset(cert);
 
     if (broken)
-        broken_cert.resetAndLock(broken);
+        broken_cert.reset(broken);
     else
-        broken_cert.resetAndLock(cert);
+        broken_cert.reset(cert);
 
     detailEntry.error_no = SSL_ERROR_NONE;
 }
 
 Ssl::ErrorDetail::ErrorDetail(Ssl::ErrorDetail const &anErrDetail)
 {
     error_no = anErrDetail.error_no;
     request = anErrDetail.request;
 
     if (anErrDetail.peer_cert.get()) {
-        peer_cert.resetAndLock(anErrDetail.peer_cert.get());
+        peer_cert.reset(anErrDetail.peer_cert.get());
     }
 
     if (anErrDetail.broken_cert.get()) {
-        broken_cert.resetAndLock(anErrDetail.broken_cert.get());
+        broken_cert.reset(anErrDetail.broken_cert.get());
     }
 
     detailEntry = anErrDetail.detailEntry;
 
     lib_error_no = anErrDetail.lib_error_no;
 }
 

=== modified file 'src/ssl/PeekingPeerConnector.cc'
--- src/ssl/PeekingPeerConnector.cc	2016-05-18 16:35:36 +0000
+++ src/ssl/PeekingPeerConnector.cc	2016-06-20 22:40:27 +0000
@@ -212,41 +212,41 @@
         }
     }
 
     return ssl;
 }
 
 void
 Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error)
 {
     Security::SessionPtr ssl = fd_table[serverConnection()->fd].ssl.get();
 
     // Check the list error with
     if (!request->clientConnectionManager.valid() || ! ssl)
         return;
 
     // remember the server certificate from the ErrorDetail object
     if (Ssl::ServerBump *serverBump = request->clientConnectionManager->serverBump()) {
         if (!serverBump->serverCert.get()) {
             // remember the server certificate from the ErrorDetail object
             if (error && error->detail && error->detail->peerCert())
-                serverBump->serverCert.resetAndLock(error->detail->peerCert());
+                serverBump->serverCert.reset(error->detail->peerCert());
             else {
                 handleServerCertificate();
             }
         }
 
         if (error) {
             // For intercepted connections, set the host name to the server
             // certificate CN. Otherwise, we just hope that CONNECT is using
             // a user-entered address (a host name or a user-entered IP).
             const bool isConnectRequest = !request->clientConnectionManager->port->flags.isIntercepted();
             if (request->flags.sslPeek && !isConnectRequest) {
                 if (X509 *srvX509 = serverBump->serverCert.get()) {
                     if (const char *name = Ssl::CommonHostName(srvX509)) {
                         request->url.host(name);
                         debugs(83, 3, "reset request host: " << name);
                     }
                 }
             }
         }
     }
@@ -333,41 +333,41 @@
         Security::SessionPtr ssl = fd_table[fd].ssl.get();
         Security::CertPointer serverCert(SSL_get_peer_certificate(ssl));
         if (!serverCert.get())
             return;
 
         serverCertificateHandled = true;
 
         // remember the server certificate for later use
         if (Ssl::ServerBump *serverBump = csd->serverBump()) {
             serverBump->serverCert.reset(serverCert.release());
         }
     }
 }
 
 void
 Ssl::PeekingPeerConnector::serverCertificateVerified()
 {
     if (ConnStateData *csd = request->clientConnectionManager.valid()) {
         Security::CertPointer serverCert;
         if(Ssl::ServerBump *serverBump = csd->serverBump())
-            serverCert.resetAndLock(serverBump->serverCert.get());
+            serverCert.reset(serverBump->serverCert.get());
         else {
             const int fd = serverConnection()->fd;
             Security::SessionPtr ssl = fd_table[fd].ssl.get();
             serverCert.reset(SSL_get_peer_certificate(ssl));
         }
         if (serverCert.get()) {
             csd->resetSslCommonName(Ssl::CommonHostName(serverCert.get()));
             debugs(83, 5, "HTTPS server CN: " << csd->sslCommonName() <<
                    " bumped: " << *serverConnection());
         }
     }
 }
 
 void
 Ssl::PeekingPeerConnector::tunnelInsteadOfNegotiating()
 {
     Must(callback != NULL);
     CbDialer *dialer = dynamic_cast<CbDialer*>(callback->getDialer());
     Must(dialer);
     dialer->answer().tunneled = true;

=== modified file 'src/ssl/ServerBump.cc'
--- src/ssl/ServerBump.cc	2016-02-13 12:12:10 +0000
+++ src/ssl/ServerBump.cc	2016-06-20 22:41:30 +0000
@@ -40,33 +40,33 @@
     // later, but an entry without any client will trim all its contents away.
     sc = storeClientListAdd(entry, this);
 }
 
 Ssl::ServerBump::~ServerBump()
 {
     debugs(33, 4, HERE << "destroying");
     if (entry) {
         debugs(33, 4, HERE << *entry);
         storeUnregister(sc, entry, this);
         entry->unlock("Ssl::ServerBump");
     }
 }
 
 void
 Ssl::ServerBump::attachServerSSL(SSL *ssl)
 {
     if (serverSSL.get())
         return;
 
-    serverSSL.resetAndLock(ssl);
+    serverSSL.reset(ssl);
 }
 
 const Ssl::CertErrors *
 Ssl::ServerBump::sslErrors() const
 {
     if (!serverSSL.get())
         return NULL;
 
     const Ssl::CertErrors *errs = static_cast<const Ssl::CertErrors*>(SSL_get_ex_data(serverSSL.get(), ssl_ex_index_ssl_errors));
     return errs;
 }
 

=== modified file 'src/ssl/cert_validate_message.cc'
--- src/ssl/cert_validate_message.cc	2016-01-05 10:55:14 +0000
+++ src/ssl/cert_validate_message.cc	2016-06-20 22:41:38 +0000
@@ -199,52 +199,52 @@
     id = old.id;
     error_no = old.error_no;
     error_reason = old.error_reason;
     error_depth = old.error_depth;
     setCert(old.cert.get());
 }
 
 Ssl::CertValidationResponse::RecvdError & Ssl::CertValidationResponse::RecvdError::operator = (const RecvdError &old)
 {
     id = old.id;
     error_no = old.error_no;
     error_reason = old.error_reason;
     error_depth = old.error_depth;
     setCert(old.cert.get());
     return *this;
 }
 
 void
 Ssl::CertValidationResponse::RecvdError::setCert(X509 *aCert)
 {
-    cert.resetAndLock(aCert);
+    cert.reset(aCert);
 }
 
 Ssl::CertValidationMsg::CertItem::CertItem(const CertItem &old)
 {
     name = old.name;
     setCert(old.cert.get());
 }
 
 Ssl::CertValidationMsg::CertItem & Ssl::CertValidationMsg::CertItem::operator = (const CertItem &old)
 {
     name = old.name;
     setCert(old.cert.get());
     return *this;
 }
 
 void
 Ssl::CertValidationMsg::CertItem::setCert(X509 *aCert)
 {
-    cert.resetAndLock(aCert);
+    cert.reset(aCert);
 }
 
 const std::string Ssl::CertValidationMsg::code_cert_validate("cert_validate");
 const std::string Ssl::CertValidationMsg::param_domain("domain");
 const std::string Ssl::CertValidationMsg::param_cert("cert_");
 const std::string Ssl::CertValidationMsg::param_error_name("error_name_");
 const std::string Ssl::CertValidationMsg::param_error_reason("error_reason_");
 const std::string Ssl::CertValidationMsg::param_error_cert("error_cert_");
 const std::string Ssl::CertValidationMsg::param_error_depth("error_depth_");
 const std::string Ssl::CertValidationMsg::param_proto_version("proto_version");
 const std::string Ssl::CertValidationMsg::param_cipher("cipher");
 

=== modified file 'src/ssl/gadgets.cc'
--- src/ssl/gadgets.cc	2016-06-14 18:12:14 +0000
+++ src/ssl/gadgets.cc	2016-06-20 22:41:58 +0000
@@ -492,41 +492,41 @@
                 if (X509_add_ext(cert.get(), ext, -1))
                     ++addedExtensions;
             }
         }
 
         addedExtensions += mimicExtensions(cert, properties.mimicCert, properties.signWithX509);
 
         // According to RFC 5280, using extensions requires v3 certificate.
         if (addedExtensions)
             X509_set_version(cert.get(), 2); // value 2 means v3
     }
 
     return true;
 }
 
 static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties,  Ssl::BIGNUM_Pointer const &serial)
 {
     Ssl::EVP_PKEY_Pointer pkey;
     // Use signing certificates private key as generated certificate private key
     if (properties.signWithPkey.get())
-        pkey.resetAndLock(properties.signWithPkey.get());
+        pkey.reset(properties.signWithPkey.get());
     else // if not exist generate one
         pkey.reset(Ssl::createSslPrivateKey());
 
     if (!pkey)
         return false;
 
     Security::CertPointer cert(X509_new());
     if (!cert)
         return false;
 
     // Set pub key and serial given by the caller
     if (!X509_set_pubkey(cert.get(), pkey.get()))
         return false;
     if (!setSerialNumber(X509_get_serialNumber(cert.get()), serial.get()))
         return false;
 
     // Fill the certificate with the required properties
     if (!buildCertificate(cert, properties))
         return false;
 

=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc	2016-06-02 09:52:43 +0000
+++ src/ssl/support.cc	2016-06-20 22:43:17 +0000
@@ -289,41 +289,41 @@
             if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_errors,  (void *)errs)) {
                 debugs(83, 2, "Failed to set ssl error_no in ssl_verify_cb: Certificate " << buffer);
                 delete errs;
                 errs = NULL;
             }
         } else // remember another error number
             errs->push_back_unique(Ssl::CertError(error_no, broken_cert));
 
         if (const char *err_descr = Ssl::GetErrorDescr(error_no))
             debugs(83, 5, err_descr << ": " << buffer);
         else
             debugs(83, DBG_IMPORTANT, "SSL unknown certificate error " << error_no << " in " << buffer);
 
         // Check if the certificate error can be bypassed.
         // Infinity validation loop errors can not bypassed.
         if (error_no != SQUID_X509_V_ERR_INFINITE_VALIDATION) {
             if (check) {
                 ACLFilledChecklist *filledCheck = Filled(check);
                 assert(!filledCheck->sslErrors);
                 filledCheck->sslErrors = new Ssl::CertErrors(Ssl::CertError(error_no, broken_cert));
-                filledCheck->serverCert.resetAndLock(peer_cert);
+                filledCheck->serverCert.reset(peer_cert);
                 if (check->fastCheck() == ACCESS_ALLOWED) {
                     debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer);
                     ok = 1;
                 } else {
                     debugs(83, 5, "confirming SSL error " << error_no);
                 }
                 delete filledCheck->sslErrors;
                 filledCheck->sslErrors = NULL;
                 filledCheck->serverCert.reset(NULL);
             }
             // If the certificate validator is used then we need to allow all errors and
             // pass them to certficate validator for more processing
             else if (Ssl::TheConfig.ssl_crt_validator) {
                 ok = 1;
             }
         }
     }
 
     if (Ssl::TheConfig.ssl_crt_validator) {
         // Check if we have stored certificates chain. Store if not.
@@ -1282,42 +1282,42 @@
 }
 
 bool Ssl::generateUntrustedCert(Security::CertPointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, Security::CertPointer const  &cert, EVP_PKEY_Pointer const & pkey)
 {
     // Generate the self-signed certificate, using a hard-coded subject prefix
     Ssl::CertificateProperties certProperties;
     if (const char *cn = CommonHostName(cert.get())) {
         certProperties.commonName = "Not trusted by \"";
         certProperties.commonName += cn;
         certProperties.commonName += "\"";
     } else if (const char *org = getOrganization(cert.get())) {
         certProperties.commonName =  "Not trusted by \"";
         certProperties.commonName += org;
         certProperties.commonName += "\"";
     } else
         certProperties.commonName =  "Not trusted";
     certProperties.setCommonName = true;
     // O, OU, and other CA subject fields will be mimicked
     // Expiration date and other common properties will be mimicked
     certProperties.signAlgorithm = Ssl::algSignSelf;
-    certProperties.signWithPkey.resetAndLock(pkey.get());
-    certProperties.mimicCert.resetAndLock(cert.get());
+    certProperties.signWithPkey.reset(pkey.get());
+    certProperties.mimicCert.reset(cert.get());
     return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
 }
 
 SSL *
 SslCreate(Security::ContextPtr sslContext, const int fd, Ssl::Bio::Type type, const char *squidCtx)
 {
     if (fd < 0) {
         debugs(83, DBG_IMPORTANT, "Gone connection");
         return NULL;
     }
 
     const char *errAction = NULL;
     int errCode = 0;
     if (auto ssl = SSL_new(sslContext)) {
         // without BIO, we would call SSL_set_fd(ssl, fd) instead
         if (BIO *bio = Ssl::Bio::Create(fd, type)) {
             Ssl::Bio::Link(ssl, bio); // cannot fail
 
             fd_table[fd].ssl.reset(ssl);
             fd_table[fd].read_method = &ssl_read_method;
@@ -1335,53 +1335,53 @@
 
     debugs(83, DBG_IMPORTANT, "ERROR: " << squidCtx << ' ' << errAction <<
            ": " << ERR_error_string(errCode, NULL));
     return NULL;
 }
 
 SSL *
 Ssl::CreateClient(Security::ContextPtr sslContext, const int fd, const char *squidCtx)
 {
     return SslCreate(sslContext, fd, Ssl::Bio::BIO_TO_SERVER, squidCtx);
 }
 
 SSL *
 Ssl::CreateServer(Security::ContextPtr sslContext, const int fd, const char *squidCtx)
 {
     return SslCreate(sslContext, fd, Ssl::Bio::BIO_TO_CLIENT, squidCtx);
 }
 
 Ssl::CertError::CertError(ssl_error_t anErr, X509 *aCert, int aDepth): code(anErr), depth(aDepth)
 {
-    cert.resetAndLock(aCert);
+    cert.reset(aCert);
 }
 
 Ssl::CertError::CertError(CertError const &err): code(err.code), depth(err.depth)
 {
-    cert.resetAndLock(err.cert.get());
+    cert.reset(err.cert.get());
 }
 
 Ssl::CertError &
 Ssl::CertError::operator = (const CertError &old)
 {
     code = old.code;
-    cert.resetAndLock(old.cert.get());
+    cert.reset(old.cert.get());
     return *this;
 }
 
 bool
 Ssl::CertError::operator == (const CertError &ce) const
 {
     return code == ce.code && cert.get() == ce.cert.get();
 }
 
 bool
 Ssl::CertError::operator != (const CertError &ce) const
 {
     return code != ce.code || cert.get() != ce.cert.get();
 }
 
 static int
 store_session_cb(SSL *ssl, SSL_SESSION *session)
 {
     if (!Ssl::SessionCache)
         return 0;



More information about the squid-dev mailing list