/*
 *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/ssl_fingerprint.h"

#include <ctype.h>

#include <cstdint>
#include <memory>
#include <string>

#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "rtc_base/logging.h"
#include "rtc_base/message_digest.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/string_encode.h"

namespace rtc {

SSLFingerprint* SSLFingerprint::Create(absl::string_view algorithm,
                                       const rtc::SSLIdentity* identity) {
  return CreateUnique(algorithm, *identity).release();
}

std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUnique(
    absl::string_view algorithm,
    const rtc::SSLIdentity& identity) {
  return Create(algorithm, identity.certificate());
}

std::unique_ptr<SSLFingerprint> SSLFingerprint::Create(
    absl::string_view algorithm,
    const rtc::SSLCertificate& cert) {
  uint8_t digest_val[64];
  size_t digest_len;
  bool ret = cert.ComputeDigest(algorithm, digest_val, sizeof(digest_val),
                                &digest_len);
  if (!ret) {
    return nullptr;
  }
  return std::make_unique<SSLFingerprint>(
      algorithm, ArrayView<const uint8_t>(digest_val, digest_len));
}

SSLFingerprint* SSLFingerprint::CreateFromRfc4572(
    absl::string_view algorithm,
    absl::string_view fingerprint) {
  return CreateUniqueFromRfc4572(algorithm, fingerprint).release();
}

std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUniqueFromRfc4572(
    absl::string_view algorithm,
    absl::string_view fingerprint) {
  if (algorithm.empty() || !rtc::IsFips180DigestAlgorithm(algorithm))
    return nullptr;

  if (fingerprint.empty())
    return nullptr;

  char value[rtc::MessageDigest::kMaxSize];
  size_t value_len = rtc::hex_decode_with_delimiter(
      value, sizeof(value), fingerprint.data(), fingerprint.length(), ':');
  if (!value_len)
    return nullptr;

  return std::make_unique<SSLFingerprint>(
      algorithm,
      ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(value), value_len));
}

std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateFromCertificate(
    const RTCCertificate& cert) {
  std::string digest_alg;
  if (!cert.GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)) {
    RTC_LOG(LS_ERROR)
        << "Failed to retrieve the certificate's digest algorithm";
    return nullptr;
  }

  std::unique_ptr<SSLFingerprint> fingerprint =
      CreateUnique(digest_alg, *cert.identity());
  if (!fingerprint) {
    RTC_LOG(LS_ERROR) << "Failed to create identity fingerprint, alg="
                      << digest_alg;
  }
  return fingerprint;
}

SSLFingerprint::SSLFingerprint(absl::string_view algorithm,
                               ArrayView<const uint8_t> digest_view)
    : algorithm(algorithm), digest(digest_view.data(), digest_view.size()) {}

SSLFingerprint::SSLFingerprint(absl::string_view algorithm,
                               const uint8_t* digest_in,
                               size_t digest_len)
    : SSLFingerprint(algorithm, MakeArrayView(digest_in, digest_len)) {}

bool SSLFingerprint::operator==(const SSLFingerprint& other) const {
  return algorithm == other.algorithm && digest == other.digest;
}

std::string SSLFingerprint::GetRfc4572Fingerprint() const {
  std::string fingerprint =
      rtc::hex_encode_with_delimiter(digest.data<char>(), digest.size(), ':');
  absl::c_transform(fingerprint, fingerprint.begin(), ::toupper);
  return fingerprint;
}

std::string SSLFingerprint::ToString() const {
  std::string fp_str = algorithm;
  fp_str.append(" ");
  fp_str.append(GetRfc4572Fingerprint());
  return fp_str;
}

}  // namespace rtc
