// 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 Singleton<OpenSSLInitSingleton,
               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" << base::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
