// Copyright 2015 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 "components/webcrypto/algorithms/secret_key_util.h"

#include "components/webcrypto/algorithms/util.h"
#include "components/webcrypto/blink_key_handle.h"
#include "components/webcrypto/crypto_data.h"
#include "components/webcrypto/generate_key_result.h"
#include "components/webcrypto/jwk.h"
#include "components/webcrypto/status.h"
#include "crypto/openssl_util.h"
#include "third_party/boringssl/src/include/openssl/rand.h"

namespace webcrypto {

Status GenerateWebCryptoSecretKey(const blink::WebCryptoKeyAlgorithm& algorithm,
                                  bool extractable,
                                  blink::WebCryptoKeyUsageMask usages,
                                  unsigned int keylen_bits,
                                  GenerateKeyResult* result) {
  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);

  unsigned int keylen_bytes = NumBitsToBytes(keylen_bits);
  std::vector<uint8_t> random_bytes(keylen_bytes, 0);

  if (keylen_bytes > 0) {
    if (!RAND_bytes(random_bytes.data(), keylen_bytes))
      return Status::OperationError();
    TruncateToBitLength(keylen_bits, &random_bytes);
  }

  result->AssignSecretKey(blink::WebCryptoKey::Create(
      CreateSymmetricKeyHandle(CryptoData(random_bytes)),
      blink::kWebCryptoKeyTypeSecret, extractable, algorithm, usages));

  return Status::Success();
}

Status CreateWebCryptoSecretKey(const CryptoData& key_data,
                                const blink::WebCryptoKeyAlgorithm& algorithm,
                                bool extractable,
                                blink::WebCryptoKeyUsageMask usages,
                                blink::WebCryptoKey* key) {
  *key = blink::WebCryptoKey::Create(CreateSymmetricKeyHandle(key_data),
                                     blink::kWebCryptoKeyTypeSecret,
                                     extractable, algorithm, usages);
  return Status::Success();
}

void WriteSecretKeyJwk(const CryptoData& raw_key_data,
                       const std::string& algorithm,
                       bool extractable,
                       blink::WebCryptoKeyUsageMask usages,
                       std::vector<uint8_t>* jwk_key_data) {
  JwkWriter writer(algorithm, extractable, usages, "oct");
  writer.SetBytes("k", raw_key_data);
  writer.ToJson(jwk_key_data);
}

Status ReadSecretKeyNoExpectedAlgJwk(
    const CryptoData& key_data,
    bool expected_extractable,
    blink::WebCryptoKeyUsageMask expected_usages,
    std::vector<uint8_t>* raw_key_data,
    JwkReader* jwk) {
  Status status = jwk->Init(key_data, expected_extractable, expected_usages,
                            "oct", std::string());
  if (status.IsError())
    return status;

  std::string jwk_k_value;
  status = jwk->GetBytes("k", &jwk_k_value);
  if (status.IsError())
    return status;
  raw_key_data->assign(jwk_k_value.begin(), jwk_k_value.end());

  return Status::Success();
}

}  // namespace webcrypto
