// 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 <openssl/cpu.h>

#include "base/logging.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"

#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
#include <cpu-features.h>
#include "base/cpu.h"
#endif

namespace crypto {

namespace {

void CurrentThreadId(CRYPTO_THREADID* id) {
  CRYPTO_THREADID_set_numeric(
      id, 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_THREADID_set_callback(CurrentThreadId);

#if defined(OS_ANDROID) && defined(ARCH_CPU_ARMEL)
    const bool has_neon =
        (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
    if (has_neon)
      CRYPTO_set_NEON_capable(1);
    // See https://code.google.com/p/chromium/issues/detail?id=341598
    base::CPU cpu;
    CRYPTO_set_NEON_functional(!cpu.has_broken_neon());
#endif
  }

  ~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
