Index: crypto/openssl_util.cc |
=================================================================== |
--- crypto/openssl_util.cc (revision 0) |
+++ crypto/openssl_util.cc (revision 0) |
@@ -0,0 +1,113 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "crypto/openssl_util.h" |
+ |
+#include <openssl/err.h> |
+#include <openssl/ssl.h> |
+ |
+#include "base/logging.h" |
+#include "base/memory/scoped_vector.h" |
+#include "base/memory/singleton.h" |
+#include "base/string_piece.h" |
+#include "base/synchronization/lock.h" |
+ |
+namespace crypto { |
+ |
+namespace { |
+ |
+unsigned long CurrentThreadId() { |
+ return static_cast<unsigned long>(base::PlatformThread::CurrentId()); |
+} |
+ |
+// Singleton for initializing and cleaning up the OpenSSL library. |
+class OpenSSLInitSingleton { |
+ public: |
+ static OpenSSLInitSingleton* GetInstance() { |
+ // We allow the SSL environment to leak for multiple reasons: |
+ // - it is used from a non-joinable worker thread that is not stopped on |
+ // shutdown, hence may still be using OpenSSL library after the AtExit |
+ // runner has completed. |
+ // - There are other OpenSSL related singletons (e.g. the client socket |
+ // context) who's cleanup depends on the global environment here, but |
+ // we can't control the order the AtExit handlers will run in so |
+ // allowing the global environment to leak at least ensures it is |
+ // available for those other singletons to reliably cleanup. |
+ return base::Singleton<OpenSSLInitSingleton, |
+ base::LeakySingletonTraits<OpenSSLInitSingleton> >::get(); |
+ } |
+ private: |
+ friend struct DefaultSingletonTraits<OpenSSLInitSingleton>; |
+ OpenSSLInitSingleton() { |
+ SSL_load_error_strings(); |
+ SSL_library_init(); |
+ OpenSSL_add_all_algorithms(); |
+ int num_locks = CRYPTO_num_locks(); |
+ locks_.reserve(num_locks); |
+ for (int i = 0; i < num_locks; ++i) |
+ locks_.push_back(new base::Lock()); |
+ CRYPTO_set_locking_callback(LockingCallback); |
+ CRYPTO_set_id_callback(CurrentThreadId); |
+ } |
+ |
+ ~OpenSSLInitSingleton() { |
+ CRYPTO_set_locking_callback(NULL); |
+ EVP_cleanup(); |
+ ERR_free_strings(); |
+ } |
+ |
+ static void LockingCallback(int mode, int n, const char* file, int line) { |
+ OpenSSLInitSingleton::GetInstance()->OnLockingCallback(mode, n, file, line); |
+ } |
+ |
+ void OnLockingCallback(int mode, int n, const char* file, int line) { |
+ CHECK_LT(static_cast<size_t>(n), locks_.size()); |
+ if (mode & CRYPTO_LOCK) |
+ locks_[n]->Acquire(); |
+ else |
+ locks_[n]->Release(); |
+ } |
+ |
+ // These locks are used and managed by OpenSSL via LockingCallback(). |
+ ScopedVector<base::Lock> locks_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(OpenSSLInitSingleton); |
+}; |
+ |
+// Callback routine for OpenSSL to print error messages. |str| is a |
+// NULL-terminated string of length |len| containing diagnostic information |
+// such as the library, function and reason for the error, the file and line |
+// where the error originated, plus potentially any context-specific |
+// information about the error. |context| contains a pointer to user-supplied |
+// data, which is currently unused. |
+// If this callback returns a value <= 0, OpenSSL will stop processing the |
+// error queue and return, otherwise it will continue calling this function |
+// until all errors have been removed from the queue. |
+int OpenSSLErrorCallback(const char* str, size_t len, void* context) { |
+ DVLOG(1) << "\t" << StringPiece(str, len); |
+ return 1; |
+} |
+ |
+} // namespace |
+ |
+void EnsureOpenSSLInit() { |
+ (void)OpenSSLInitSingleton::GetInstance(); |
+} |
+ |
+void ClearOpenSSLERRStack(const tracked_objects::Location& location) { |
+ if (logging::DEBUG_MODE && VLOG_IS_ON(1)) { |
+ int error_num = ERR_peek_error(); |
+ if (error_num == 0) |
+ return; |
+ |
+ std::string message; |
+ location.Write(true, true, &message); |
+ DVLOG(1) << "OpenSSL ERR_get_error stack from " << message; |
+ ERR_print_errors_cb(&OpenSSLErrorCallback, NULL); |
+ } else { |
+ ERR_clear_error(); |
+ } |
+} |
+ |
+} // namespace crypto |
Property changes on: crypto\openssl_util.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |