// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHAPS_CHAPS_UTILITY_H_
#define CHAPS_CHAPS_UTILITY_H_

#include <string.h>

#include <sstream>
#include <string>
#include <vector>

#include <base/check.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <brillo/secure_blob.h>
#include <crypto/scoped_openssl_types.h>

#include "chaps/chaps.h"
#include "pkcs11/cryptoki.h"

namespace chaps {

enum class DigestAlgorithm {
  MD5 = 0,
  SHA1 = 1,
  SHA256 = 2,
  SHA384 = 3,
  SHA512 = 4,
  // Should be put the last if it is not in kDigestAlgorithmEncoding
  NoDigest
};

enum class RsaPaddingScheme {
  UNKNOWN_PADDING_SCHEME = 0,
  RSASSA_PKCS1_V1_5,
  RSASSA_PSS,
};

// These strings are the DER encodings of the DigestInfo values for the
// supported digest algorithms.  See PKCS #1 v2.1: 9.2.
const struct {
  const char* encoding;
  size_t encoding_len;
} kDigestAlgorithmEncoding[] = {
    {/* MD5 = 0 */
     "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04"
     "\x10",
     18},
    {/* SHA1 = 1 */
     "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14", 15},
    {/* SHA256 = 2 */
     "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04"
     "\x20",
     19},
    {/* SHA384 = 3 */
     "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04"
     "\x30",
     19},
    {/* SHA512 = 4 */
     "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04"
     "\x40",
     19},
};

// Get the algorithm ID for DigestInfo structure
inline std::string GetDigestAlgorithmEncoding(DigestAlgorithm alg) {
  size_t alg_index = static_cast<size_t>(alg);
  if (alg_index >= base::size(kDigestAlgorithmEncoding)) {
    return std::string();
  }
  return std::string(kDigestAlgorithmEncoding[alg_index].encoding,
                     kDigestAlgorithmEncoding[alg_index].encoding_len);
}

// Copy*ToCharBuffer copies to a space-padded CK_UTF8CHAR buffer (not
// NULL-terminated).
inline void CopyStringToCharBuffer(const std::string& source,
                                   CK_UTF8CHAR_PTR buffer,
                                   size_t buffer_size) {
  size_t copy_size = source.length();
  if (copy_size > buffer_size)
    copy_size = buffer_size;
  memset(buffer, ' ', buffer_size);
  if (copy_size > 0)
    memcpy(buffer, source.data(), copy_size);
}

inline void CopyVectorToCharBuffer(const std::vector<uint8_t>& source,
                                   CK_UTF8CHAR_PTR buffer,
                                   size_t buffer_size) {
  size_t copy_size = source.size();
  if (copy_size > buffer_size)
    copy_size = buffer_size;
  memset(buffer, ' ', buffer_size);
  if (copy_size > 0)
    memcpy(buffer, source.data(), copy_size);
}

// RVToString stringifies a PKCS #11 return value.  E.g. CKR_OK --> "CKR_OK".
EXPORT_SPEC const char* CK_RVToString(CK_RV value);

// AttributeToString stringifies a PKCS #11 attribute type.
std::string AttributeToString(CK_ATTRIBUTE_TYPE attribute);

// StringToAttribute tries to parse the input string |attribute_string| into an
// attribute |output|. It'll return true iff the |attribute_string| is parsed
// into attribute.
EXPORT_SPEC bool StringToAttribute(std::string attribute_string,
                                   CK_ATTRIBUTE_TYPE* output);

// ValueToString stringifies a PKCS #11 attribute value.
std::string ValueToString(CK_ATTRIBUTE_TYPE attribute,
                          const std::vector<uint8_t>& value);

// PrintAttributes parses serialized attributes and prints in the form:
// "{attribute1[=value1], attribute2[=value2]}".
std::string PrintAttributes(const std::vector<uint8_t>& serialized,
                            bool is_value_enabled);

// PrintIntVector prints a vector in array literal form.  E.g. "{0, 1, 2}".
// ** A static cast to 'int' must be possible for type T.
template <class T>
std::string PrintIntVector(const std::vector<T>& v) {
  std::stringstream ss;
  ss << "{";
  for (size_t i = 0; i < v.size(); i++) {
    if (i > 0)
      ss << ", ";
    ss << static_cast<int>(v[i]);
  }
  ss << "}";
  return ss.str();
}

// This macro logs the current function name and the CK_RV value provided.
#define LOG_CK_RV(value) \
  LOG(ERROR) << __func__ << " - " << chaps::CK_RVToString(value);

// This macro is a conditional version of LOG_CK_RV which will log only if the
// value is not CKR_OK.
#define LOG_CK_RV_ERR(value)         \
  LOG_IF(ERROR, ((value) != CKR_OK)) \
      << __func__ << " - " << chaps::CK_RVToString(value);

// This macro logs and returns the given CK_RV value.
#define LOG_CK_RV_AND_RETURN(value) \
  {                                 \
    LOG_CK_RV(value);               \
    return (value);                 \
  }

// This macro logs and returns the given CK_RV value if the given condition is
// true.
#define LOG_CK_RV_AND_RETURN_IF(condition, value) \
  if (condition)                                  \
  LOG_CK_RV_AND_RETURN(value)

// This macro logs and returns the given CK_RV value if the value is not CKR_OK.
#define LOG_CK_RV_AND_RETURN_IF_ERR(value) \
  LOG_CK_RV_AND_RETURN_IF((value) != CKR_OK, value)

// This function constructs a string object from a CK_UTF8CHAR array.  The array
// does not need to be NULL-terminated. If buffer is NULL, an empty string will
// be returned.
inline std::string ConvertCharBufferToString(CK_UTF8CHAR_PTR buffer,
                                             size_t buffer_size) {
  if (!buffer)
    return std::string();
  return std::string(reinterpret_cast<char*>(buffer), buffer_size);
}

// This function constructs a string object from a CK_BYTE array.  The array
// does not need to be NULL-terminated. If buffer is NULL, an empty string will
// be returned.
inline std::string ConvertByteBufferToString(CK_BYTE_PTR buffer,
                                             CK_ULONG buffer_size) {
  if (!buffer)
    return std::string();
  return std::string(reinterpret_cast<char*>(buffer), buffer_size);
}

// This function converts a C string to a CK_UTF8CHAR_PTR which points to the
// same buffer.
inline CK_UTF8CHAR_PTR ConvertStringToCharBuffer(const char* str) {
  return reinterpret_cast<CK_UTF8CHAR_PTR>(const_cast<char*>(str));
}

// This function converts a C string to a uint8_t* which points to the same
// buffer.
inline uint8_t* ConvertStringToByteBuffer(const char* str) {
  return reinterpret_cast<uint8_t*>(const_cast<char*>(str));
}

// This function changes the container class for an array of bytes from string
// to vector.
inline std::vector<uint8_t> ConvertByteStringToVector(const std::string& s) {
  const uint8_t* front = reinterpret_cast<const uint8_t*>(s.data());
  return std::vector<uint8_t>(front, front + s.length());
}

// This function changes the container class for an array of bytes from vector
// to string.
inline std::string ConvertByteVectorToString(const std::vector<uint8_t>& v) {
  const char* front = reinterpret_cast<const char*>(v.data());
  return std::string(front, v.size());
}

// This function constructs a vector object from a CK_BYTE array.If buffer is
// NULL, an empty vector will be returned.
inline std::vector<uint8_t> ConvertByteBufferToVector(CK_BYTE_PTR buffer,
                                                      CK_ULONG buffer_size) {
  if (!buffer)
    return std::vector<uint8_t>();
  return std::vector<uint8_t>(buffer, buffer + buffer_size);
}

// This function returns a value composed of the bytes in the given string.
// It only accepts strings whose length is the same as the size of the given
// type. The type must be default-constructible.
template <typename T>
T ExtractFromByteString(const std::string& s) {
  CHECK(s.length() == sizeof(T));
  T ret;
  memcpy(&ret, s.data(), sizeof(ret));
  return ret;
}

// This class preserves a variable that needs to be temporarily converted to
// another type.
template <class PreservedType, class TempType>
class PreservedValue {
 public:
  explicit PreservedValue(PreservedType* value) {
    CHECK(value);
    preserved_ = value;
    temp_ = static_cast<TempType>(*value);
  }
  ~PreservedValue() { *preserved_ = static_cast<PreservedType>(temp_); }
  // Allow an implicit cast to a pointer to the temporary value.
  operator TempType*() { return &temp_; }

 private:
  PreservedType* preserved_;
  TempType temp_;
};

typedef PreservedValue<CK_ULONG, uint64_t> PreservedCK_ULONG;
typedef PreservedValue<uint64_t, CK_ULONG> PreservedUint64_t;

class PreservedByteVector {
 public:
  explicit PreservedByteVector(std::vector<uint8_t>* value) {
    CHECK(value);
    preserved_ = value;
    temp_ = ConvertByteVectorToString(*value);
  }
  ~PreservedByteVector() { *preserved_ = ConvertByteStringToVector(temp_); }
  // Allow an implicit cast to a string pointer.
  operator std::string*() { return &temp_; }

 private:
  std::vector<uint8_t>* preserved_;
  std::string temp_;
};

// Computes and returns a SHA-1 hash of the given input.
std::string Sha1(const std::string& input);
brillo::SecureBlob Sha1(const brillo::SecureBlob& input);

// Computes and returns a SHA-256 hash of the given input.
brillo::SecureBlob Sha256(const brillo::SecureBlob& input);

// Computes and returns a SHA-512 hash of the given input.
brillo::SecureBlob Sha512(const brillo::SecureBlob& input);

// Initializes the OpenSSL library on construction and terminates the library on
// destruction.
class ScopedOpenSSL {
 public:
  ScopedOpenSSL();
  ~ScopedOpenSSL();
};

// Returns a description of the OpenSSL error stack.
std::string GetOpenSSLError();

// Computes a message authentication code using HMAC and SHA-512.
std::string HmacSha512(const std::string& input, const brillo::SecureBlob& key);

// Performs AES-256 encryption / decryption in CBC mode with PKCS padding. If
// 'iv' is left empty, a random IV will be generated and appended to the cipher-
// text on encryption.
bool RunCipher(bool is_encrypt,
               const brillo::SecureBlob& key,
               const std::string& iv,
               const std::string& input,
               std::string* output);

// Returns true if the given attribute type has an integral value.
bool IsIntegralAttribute(CK_ATTRIBUTE_TYPE type);

// TODO(crbug/916023): Move pure OpenSSL conversion wrappers to a cross daemon
// library.
//
// OpenSSL type <--> raw data string
//

// Convert OpenSSL BIGNUM |bignum| to string.
// Padding the result to at least |pad_to_length| bytes long.
// Return empty string on error.
std::string ConvertFromBIGNUM(const BIGNUM* bignum, int pad_to_length = 0);

// Convert string |big_integer| into pre-allocated OpenSSL BIGNUM.
// Returns false if big_integer is empty, b is nullptr, or conversion fails.
bool ConvertToBIGNUM(const std::string& big_integer, BIGNUM* b);

// Convert the public key consisting of |modulus| and |exponent| to an RSA
// object and return it on success, otherwise, return nullptr.
crypto::ScopedRSA NumberToScopedRsa(const std::string& modulus,
                                    const std::string& exponent);

//
// OpenSSL type <--> DER-encoded string
//

// Get the ECParamters from |key| and DER-encode to a string.
std::string GetECParametersAsString(const EC_KEY* key);
// Get the EC_Point from |key| and DER-encode to a string.
std::string GetECPointAsString(const EC_KEY* key);

//
// OpenSSL type <--> PKCS #11 Attributes
//

// Create a OpenSSL EC_KEY from a CKA_EC_PARAMS string (which is compatible
// with DER-encoded OpenSSL ECParameters)
crypto::ScopedEC_KEY CreateECCKeyFromEC_PARAMS(const std::string& ec_params);

// In OpenSSL 1.1, i2o_ECPublicKey now takes a const EC_KEY *, which breaks
// the function signature expectation of ConvertOpenSSLObjectToString, so
// wrap it with a helper that still takes a non-const pointer.
static inline int i2o_ECPublicKey_nc(EC_KEY* key, unsigned char** buf) {
  return i2o_ECPublicKey(key, buf);
}

// Get the chaps internal digest algorithm type from PKCS#11 mechanism type.
chaps::DigestAlgorithm GetDigestAlgorithm(CK_MECHANISM_TYPE mechanism);

// Return the OpenSSL Digest associated with the given DigestAlgorithm.
const EVP_MD* GetOpenSSLDigest(DigestAlgorithm alg);

// Return the OpenSSL Digest associated with the given PKCS#11 Mechanism.
const EVP_MD* GetOpenSSLDigestForMechanism(CK_MECHANISM_TYPE mechanism);

// Return the RSA padding scheme for the given |mechanism|.
RsaPaddingScheme GetSigningSchemeForMechanism(
    const CK_MECHANISM_TYPE mechanism);

// Return the OpenSSL Digest associated with the given PKCS#11 MGF function
// identifier.
const EVP_MD* GetOpenSSLDigestForMGF(const CK_RSA_PKCS_MGF_TYPE mgf);

// This method parse the PKCS#11 mechanism parameters specified in
// |mechanism_parameter| and interpret it as CK_RSA_PKCS_PSS_PARAMS and check
// its sanity. Return false on error. Otherwise, return true and set the 3
// output parameters if the check is successful.
bool ParseRSAPSSParams(CK_MECHANISM_TYPE signing_mechanism,
                       const std::string& mechanism_parameter,
                       const CK_RSA_PKCS_PSS_PARAMS** pss_params_out,
                       const EVP_MD** mgf1_hash_out,
                       DigestAlgorithm* digest_algorithm_out);

}  // namespace chaps

#endif  // CHAPS_CHAPS_UTILITY_H_
