// Copyright (c) 2013 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 "net/android/keystore_openssl.h"

#include <jni.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>

#include "base/android/build_info.h"
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "crypto/openssl_util.h"
#include "net/android/keystore.h"
#include "net/android/legacy_openssl.h"
#include "net/ssl/ssl_client_cert_type.h"

// IMPORTANT NOTE: The following code will currently only work when used
// to implement client certificate support with OpenSSL. That's because
// only the signing operations used in this use case are implemented here.
//
// Generally speaking, OpenSSL provides many different ways to sign
// digests. This code doesn't support all these cases, only the ones that
// are required to sign the digest during the OpenSSL handshake for TLS.
//
// The OpenSSL EVP_PKEY type is a generic wrapper around key pairs.
// Internally, it can hold a pointer to a RSA, DSA or ECDSA structure,
// which model keypair implementations of each respective crypto
// algorithm.
//
// The RSA type has a 'method' field pointer to a vtable-like structure
// called a RSA_METHOD. This contains several function pointers that
// correspond to operations on RSA keys (e.g. decode/encode with public
// key, decode/encode with private key, signing, validation), as well as
// a few flags.
//
// For example, the RSA_sign() function will call "method->rsa_sign()" if
// method->rsa_sign is not NULL, otherwise, it will perform a regular
// signing operation using the other fields in the RSA structure (which
// are used to hold the typical modulus / exponent / parameters for the
// key pair).
//
// This source file thus defines a custom RSA_METHOD structure whose
// fields point to static methods used to implement the corresponding
// RSA operation using platform Android APIs.
//
// However, the platform APIs require a jobject JNI reference to work. It must
// be stored in the RSA instance, or made accessible when the custom RSA
// methods are called. This is done by storing it in a |KeyExData| structure
// that's referenced by the key using |EX_DATA|.

using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;

namespace net {
namespace android {

namespace {

extern const RSA_METHOD android_rsa_method;
extern const ECDSA_METHOD android_ecdsa_method;

// KeyExData contains the data that is contained in the EX_DATA of the RSA, DSA
// and ECDSA objects that are created to wrap Android system keys.
struct KeyExData {
  // private_key contains a reference to a Java, private-key object.
  jobject private_key;
  // legacy_rsa, if not NULL, points to an RSA* in the system's OpenSSL (which
  // might not be ABI compatible with Chromium).
  AndroidRSA* legacy_rsa;
  // cached_size contains the "size" of the key. This is the size of the
  // modulus (in bytes) for RSA, or the group order size for (EC)DSA. This
  // avoids calling into Java to calculate the size.
  size_t cached_size;
};

// ExDataDup is called when one of the RSA, DSA or EC_KEY objects is
// duplicated. We don't support this and it should never happen.
int ExDataDup(CRYPTO_EX_DATA* to,
              const CRYPTO_EX_DATA* from,
              void** from_d,
              int index,
              long argl,
              void* argp) {
  CHECK_EQ((void*)NULL, *from_d);
  return 0;
}

// ExDataFree is called when one of the RSA, DSA or EC_KEY object is freed.
void ExDataFree(void* parent,
                void* ptr,
                CRYPTO_EX_DATA* ad,
                int index,
                long argl,
                void* argp) {
  // Ensure the global JNI reference created with this wrapper is
  // properly destroyed with it.
  KeyExData *ex_data = reinterpret_cast<KeyExData*>(ptr);
  if (ex_data != NULL) {
    ReleaseKey(ex_data->private_key);
    delete ex_data;
  }
}

// BoringSSLEngine is a BoringSSL ENGINE that implements RSA, DSA and ECDSA by
// forwarding the requested operations to the Java libraries.
class BoringSSLEngine {
 public:
  BoringSSLEngine()
      : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
                                        NULL /* argp */,
                                        NULL /* new_func */,
                                        ExDataDup,
                                        ExDataFree)),
        ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
                                              NULL /* argp */,
                                              NULL /* new_func */,
                                              ExDataDup,
                                              ExDataFree)),
        engine_(ENGINE_new()) {
    ENGINE_set_RSA_method(
        engine_, &android_rsa_method, sizeof(android_rsa_method));
    ENGINE_set_ECDSA_method(
        engine_, &android_ecdsa_method, sizeof(android_ecdsa_method));
  }

  int rsa_ex_index() const { return rsa_index_; }
  int ec_key_ex_index() const { return ec_key_index_; }

  const ENGINE* engine() const { return engine_; }

 private:
  const int rsa_index_;
  const int ec_key_index_;
  ENGINE* const engine_;
};

base::LazyInstance<BoringSSLEngine>::Leaky global_boringssl_engine =
    LAZY_INSTANCE_INITIALIZER;


// VectorBignumSize returns the number of bytes needed to represent the bignum
// given in |v|, i.e. the length of |v| less any leading zero bytes.
size_t VectorBignumSize(const std::vector<uint8>& v) {
  size_t size = v.size();
  // Ignore any leading zero bytes.
  for (size_t i = 0; i < v.size() && v[i] == 0; i++) {
    size--;
  }
  return size;
}

KeyExData* RsaGetExData(const RSA* rsa) {
  return reinterpret_cast<KeyExData*>(
      RSA_get_ex_data(rsa, global_boringssl_engine.Get().rsa_ex_index()));
}

size_t RsaMethodSize(const RSA *rsa) {
  const KeyExData *ex_data = RsaGetExData(rsa);
  return ex_data->cached_size;
}

int RsaMethodEncrypt(RSA* rsa,
                     size_t* out_len,
                     uint8_t* out,
                     size_t max_out,
                     const uint8_t* in,
                     size_t in_len,
                     int padding) {
  NOTIMPLEMENTED();
  OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_ALGORITHM_TYPE);
  return 0;
}

int RsaMethodSignRaw(RSA* rsa,
                     size_t* out_len,
                     uint8_t* out,
                     size_t max_out,
                     const uint8_t* in,
                     size_t in_len,
                     int padding) {
  DCHECK_EQ(RSA_PKCS1_PADDING, padding);
  if (padding != RSA_PKCS1_PADDING) {
    // TODO(davidben): If we need to, we can implement RSA_NO_PADDING
    // by using javax.crypto.Cipher and picking either the
    // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as
    // appropriate. I believe support for both of these was added in
    // the same Android version as the "NONEwithRSA"
    // java.security.Signature algorithm, so the same version checks
    // for GetRsaLegacyKey should work.
    OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE);
    return 0;
  }

  // Retrieve private key JNI reference.
  const KeyExData *ex_data = RsaGetExData(rsa);
  if (!ex_data || !ex_data->private_key) {
    LOG(WARNING) << "Null JNI reference passed to RsaMethodPrivEnc!";
    OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  // Pre-4.2 legacy codepath.
  if (ex_data->legacy_rsa) {
    int ret = ex_data->legacy_rsa->meth->rsa_priv_enc(
        in_len, in, out, ex_data->legacy_rsa, ANDROID_RSA_PKCS1_PADDING);
    if (ret < 0) {
      LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!";
      // System OpenSSL will use a separate error queue, so it is still
      // necessary to push a new error.
      //
      // TODO(davidben): It would be good to also clear the system error queue
      // if there were some way to convince Java to do it. (Without going
      // through Java, it's difficult to get a handle on a system OpenSSL
      // function; dlopen loads a second copy.)
      OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    *out_len = ret;
    return 1;
  }

  base::StringPiece from_piece(reinterpret_cast<const char*>(in), in_len);
  std::vector<uint8> result;
  // For RSA keys, this function behaves as RSA_private_encrypt with
  // PKCS#1 padding.
  if (!RawSignDigestWithPrivateKey(ex_data->private_key, from_piece, &result)) {
    LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!";
    OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  size_t expected_size = static_cast<size_t>(RSA_size(rsa));
  if (result.size() > expected_size) {
    LOG(ERROR) << "RSA Signature size mismatch, actual: "
               <<  result.size() << ", expected <= " << expected_size;
    OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (max_out < expected_size) {
    OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_DATA_TOO_LARGE);
    return 0;
  }

  // Copy result to OpenSSL-provided buffer. RawSignDigestWithPrivateKey
  // should pad with leading 0s, but if it doesn't, pad the result.
  size_t zero_pad = expected_size - result.size();
  memset(out, 0, zero_pad);
  memcpy(out + zero_pad, &result[0], result.size());
  *out_len = expected_size;

  return 1;
}

int RsaMethodDecrypt(RSA* rsa,
                     size_t* out_len,
                     uint8_t* out,
                     size_t max_out,
                     const uint8_t* in,
                     size_t in_len,
                     int padding) {
  NOTIMPLEMENTED();
  OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_UNKNOWN_ALGORITHM_TYPE);
  return 0;
}

int RsaMethodVerifyRaw(RSA* rsa,
                       size_t* out_len,
                       uint8_t* out,
                       size_t max_out,
                       const uint8_t* in,
                       size_t in_len,
                       int padding) {
  NOTIMPLEMENTED();
  OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_ALGORITHM_TYPE);
  return 0;
}

const RSA_METHOD android_rsa_method = {
    {
     0 /* references */,
     1 /* is_static */
    } /* common */,
    NULL /* app_data */,

    NULL /* init */,
    NULL /* finish */,
    RsaMethodSize,
    NULL /* sign */,
    NULL /* verify */,
    RsaMethodEncrypt,
    RsaMethodSignRaw,
    RsaMethodDecrypt,
    RsaMethodVerifyRaw,
    NULL /* private_transform */,
    NULL /* mod_exp */,
    NULL /* bn_mod_exp */,
    RSA_FLAG_OPAQUE,
    NULL /* keygen */,
};

// Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object.
// |private_key| is the JNI reference (local or global) to the object.
// |legacy_rsa|, if non-NULL, is a pointer to the system OpenSSL RSA object
// backing |private_key|. This parameter is only used for Android < 4.2 to
// implement key operations not exposed by the platform.
// Returns a new EVP_PKEY on success, NULL otherwise.
// On success, this creates a new global JNI reference to the object
// that is owned by and destroyed with the EVP_PKEY. I.e. caller can
// free |private_key| after the call.
crypto::ScopedEVP_PKEY GetRsaPkeyWrapper(jobject private_key,
                                         AndroidRSA* legacy_rsa) {
  crypto::ScopedRSA rsa(
      RSA_new_method(global_boringssl_engine.Get().engine()));

  ScopedJavaGlobalRef<jobject> global_key;
  global_key.Reset(NULL, private_key);
  if (global_key.is_null()) {
    LOG(ERROR) << "Could not create global JNI reference";
    return crypto::ScopedEVP_PKEY();
  }

  std::vector<uint8> modulus;
  if (!GetRSAKeyModulus(private_key, &modulus)) {
    LOG(ERROR) << "Failed to get private key modulus";
    return crypto::ScopedEVP_PKEY();
  }

  KeyExData* ex_data = new KeyExData;
  ex_data->private_key = global_key.Release();
  ex_data->legacy_rsa = legacy_rsa;
  ex_data->cached_size = VectorBignumSize(modulus);
  RSA_set_ex_data(
      rsa.get(), global_boringssl_engine.Get().rsa_ex_index(), ex_data);

  crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
  if (!pkey ||
      !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) {
    return crypto::ScopedEVP_PKEY();
  }
  return pkey.Pass();
}

// On Android < 4.2, the libkeystore.so ENGINE uses CRYPTO_EX_DATA and is not
// added to the global engine list. If all references to it are dropped, OpenSSL
// will dlclose the module, leaving a dangling function pointer in the RSA
// CRYPTO_EX_DATA class. To work around this, leak an extra reference to the
// ENGINE we extract in GetRsaLegacyKey.
//
// In 4.2, this change avoids the problem:
// https://android.googlesource.com/platform/libcore/+/106a8928fb4249f2f3d4dba1dddbe73ca5cb3d61
//
// https://crbug.com/381465
class KeystoreEngineWorkaround {
 public:
  KeystoreEngineWorkaround() {}

  void LeakEngine(jobject private_key) {
    if (!engine_.is_null())
      return;
    ScopedJavaLocalRef<jobject> engine =
        GetOpenSSLEngineForPrivateKey(private_key);
    if (engine.is_null()) {
      NOTREACHED();
      return;
    }
    engine_.Reset(engine);
  }

 private:
  ScopedJavaGlobalRef<jobject> engine_;
};

void LeakEngine(jobject private_key) {
  static base::LazyInstance<KeystoreEngineWorkaround>::Leaky s_instance =
      LAZY_INSTANCE_INITIALIZER;
  s_instance.Get().LeakEngine(private_key);
}

// Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object
// for Android 4.0 to 4.1.x. Must only be used on Android < 4.2.
// |private_key| is a JNI reference (local or global) to the object.
// |pkey| is the EVP_PKEY to setup as a wrapper.
// Returns true on success, false otherwise.
crypto::ScopedEVP_PKEY GetRsaLegacyKey(jobject private_key) {
  AndroidEVP_PKEY* sys_pkey =
      GetOpenSSLSystemHandleForPrivateKey(private_key);
  if (sys_pkey != NULL) {
    if (sys_pkey->type != ANDROID_EVP_PKEY_RSA) {
      LOG(ERROR) << "Private key has wrong type!";
      return crypto::ScopedEVP_PKEY();
    }

    AndroidRSA* sys_rsa = sys_pkey->pkey.rsa;
    if (sys_rsa->engine) {
      // |private_key| may not have an engine if the PrivateKey did not come
      // from the key store, such as in unit tests.
      if (strcmp(sys_rsa->engine->id, "keystore") == 0) {
        LeakEngine(private_key);
      } else {
        NOTREACHED();
      }
    }

    return GetRsaPkeyWrapper(private_key, sys_rsa);
  }

  // GetOpenSSLSystemHandleForPrivateKey() will fail on Android 4.0.3 and
  // earlier. However, it is possible to get the key content with
  // PrivateKey.getEncoded() on these platforms.  Note that this method may
  // return NULL on 4.0.4 and later.
  std::vector<uint8> encoded;
  if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) {
    LOG(ERROR) << "Can't get private key data!";
    return crypto::ScopedEVP_PKEY();
  }
  const unsigned char* p =
      reinterpret_cast<const unsigned char*>(&encoded[0]);
  int len = static_cast<int>(encoded.size());
  crypto::ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, len));
  if (!pkey) {
    LOG(ERROR) << "Can't convert private key data!";
    return crypto::ScopedEVP_PKEY();
  }
  return pkey.Pass();
}

// Custom ECDSA_METHOD that uses the platform APIs.
// Note that for now, only signing through ECDSA_sign() is really supported.
// all other method pointers are either stubs returning errors, or no-ops.

jobject EcKeyGetKey(const EC_KEY* ec_key) {
  KeyExData* ex_data = reinterpret_cast<KeyExData*>(EC_KEY_get_ex_data(
      ec_key, global_boringssl_engine.Get().ec_key_ex_index()));
  return ex_data->private_key;
}

size_t EcdsaMethodGroupOrderSize(const EC_KEY* ec_key) {
  KeyExData* ex_data = reinterpret_cast<KeyExData*>(EC_KEY_get_ex_data(
      ec_key, global_boringssl_engine.Get().ec_key_ex_index()));
  return ex_data->cached_size;
}

int EcdsaMethodSign(const uint8_t* digest,
                    size_t digest_len,
                    uint8_t* sig,
                    unsigned int* sig_len,
                    EC_KEY* ec_key) {
  // Retrieve private key JNI reference.
  jobject private_key = EcKeyGetKey(ec_key);
  if (!private_key) {
    LOG(WARNING) << "Null JNI reference passed to EcdsaMethodSign!";
    return 0;
  }
  // Sign message with it through JNI.
  std::vector<uint8> signature;
  base::StringPiece digest_sp(reinterpret_cast<const char*>(digest),
                              digest_len);
  if (!RawSignDigestWithPrivateKey(private_key, digest_sp, &signature)) {
    LOG(WARNING) << "Could not sign message in EcdsaMethodSign!";
    return 0;
  }

  // Note: With ECDSA, the actual signature may be smaller than
  // ECDSA_size().
  size_t max_expected_size = ECDSA_size(ec_key);
  if (signature.size() > max_expected_size) {
    LOG(ERROR) << "ECDSA Signature size mismatch, actual: "
               <<  signature.size() << ", expected <= "
               << max_expected_size;
    return 0;
  }

  memcpy(sig, &signature[0], signature.size());
  *sig_len = signature.size();
  return 1;
}

int EcdsaMethodVerify(const uint8_t* digest,
                      size_t digest_len,
                      const uint8_t* sig,
                      size_t sig_len,
                      EC_KEY* ec_key) {
  NOTIMPLEMENTED();
  OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED);
  return 0;
}

// Setup an EVP_PKEY to wrap an existing platform PrivateKey object.
// |private_key| is the JNI reference (local or global) to the object.
// Returns a new EVP_PKEY on success, NULL otherwise.
// On success, this creates a global JNI reference to the object that
// is owned by and destroyed with the EVP_PKEY. I.e. the caller shall
// always free |private_key| after the call.
crypto::ScopedEVP_PKEY GetEcdsaPkeyWrapper(jobject private_key) {
  crypto::ScopedEC_KEY ec_key(
      EC_KEY_new_method(global_boringssl_engine.Get().engine()));

  ScopedJavaGlobalRef<jobject> global_key;
  global_key.Reset(NULL, private_key);
  if (global_key.is_null()) {
    LOG(ERROR) << "Can't create global JNI reference";
    return crypto::ScopedEVP_PKEY();
  }

  std::vector<uint8> order;
  if (!GetECKeyOrder(private_key, &order)) {
    LOG(ERROR) << "Can't extract order parameter from EC private key";
    return crypto::ScopedEVP_PKEY();
  }

  KeyExData* ex_data = new KeyExData;
  ex_data->private_key = global_key.Release();
  ex_data->legacy_rsa = NULL;
  ex_data->cached_size = VectorBignumSize(order);

  EC_KEY_set_ex_data(
      ec_key.get(), global_boringssl_engine.Get().ec_key_ex_index(), ex_data);

  crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
  if (!pkey ||
      !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) {
    return crypto::ScopedEVP_PKEY();
  }
  return pkey.Pass();
}

const ECDSA_METHOD android_ecdsa_method = {
    {
     0 /* references */,
     1 /* is_static */
    } /* common */,
    NULL /* app_data */,

    NULL /* init */,
    NULL /* finish */,
    EcdsaMethodGroupOrderSize,
    EcdsaMethodSign,
    EcdsaMethodVerify,
    ECDSA_FLAG_OPAQUE,
};

}  // namespace

crypto::ScopedEVP_PKEY GetOpenSSLPrivateKeyWrapper(jobject private_key) {
  const int kAndroid42ApiLevel = 17;

  // Create sub key type, depending on private key's algorithm type.
  PrivateKeyType key_type = GetPrivateKeyType(private_key);
  switch (key_type) {
    case PRIVATE_KEY_TYPE_RSA:
      // Route around platform bug: if Android < 4.2, then
      // base::android::RawSignDigestWithPrivateKey() cannot work, so
      // instead, obtain a raw EVP_PKEY* to the system object
      // backing this PrivateKey object.
      if (base::android::BuildInfo::GetInstance()->sdk_int() <
          kAndroid42ApiLevel) {
        return GetRsaLegacyKey(private_key);
      } else {
        // Running on Android 4.2.
        return GetRsaPkeyWrapper(private_key, NULL);
      }
    case PRIVATE_KEY_TYPE_ECDSA:
      return GetEcdsaPkeyWrapper(private_key);
    default:
      LOG(WARNING)
          << "GetOpenSSLPrivateKeyWrapper() called with invalid key type";
      return crypto::ScopedEVP_PKEY();
  }
}

}  // namespace android
}  // namespace net
