// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/cert/x509_util_apple.h"

#include <CommonCrypto/CommonDigest.h>

#include <string>

#include "base/check_op.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/include/openssl/pool.h"

namespace net {
namespace x509_util {

namespace {

bssl::UniquePtr<CRYPTO_BUFFER> CertBufferFromSecCertificate(
    SecCertificateRef sec_cert) {
  if (!sec_cert) {
    return nullptr;
  }
  base::ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(sec_cert));
  if (!der_data) {
    return nullptr;
  }
  return CreateCryptoBuffer(
      base::make_span(CFDataGetBytePtr(der_data),
                      base::checked_cast<size_t>(CFDataGetLength(der_data))));
}

}  // namespace

base::ScopedCFTypeRef<SecCertificateRef> CreateSecCertificateFromBytes(
    const uint8_t* data,
    size_t length) {
  base::ScopedCFTypeRef<CFDataRef> cert_data(
      CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
                   base::checked_cast<CFIndex>(length)));
  if (!cert_data)
    return base::ScopedCFTypeRef<SecCertificateRef>();

  return base::ScopedCFTypeRef<SecCertificateRef>(
      SecCertificateCreateWithData(nullptr, cert_data));
}

base::ScopedCFTypeRef<SecCertificateRef>
CreateSecCertificateFromX509Certificate(const X509Certificate* cert) {
  return CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
                                       CRYPTO_BUFFER_len(cert->cert_buffer()));
}

base::ScopedCFTypeRef<CFMutableArrayRef>
CreateSecCertificateArrayForX509Certificate(X509Certificate* cert) {
  return CreateSecCertificateArrayForX509Certificate(
      cert, InvalidIntermediateBehavior::kFail);
}

base::ScopedCFTypeRef<CFMutableArrayRef>
CreateSecCertificateArrayForX509Certificate(
    X509Certificate* cert,
    InvalidIntermediateBehavior invalid_intermediate_behavior) {
  base::ScopedCFTypeRef<CFMutableArrayRef> cert_list(
      CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
  if (!cert_list)
    return base::ScopedCFTypeRef<CFMutableArrayRef>();
  std::string bytes;
  base::ScopedCFTypeRef<SecCertificateRef> sec_cert(
      CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(cert->cert_buffer()),
                                    CRYPTO_BUFFER_len(cert->cert_buffer())));
  if (!sec_cert)
    return base::ScopedCFTypeRef<CFMutableArrayRef>();
  CFArrayAppendValue(cert_list, sec_cert);
  for (const auto& intermediate : cert->intermediate_buffers()) {
    base::ScopedCFTypeRef<SecCertificateRef> intermediate_cert(
        CreateSecCertificateFromBytes(CRYPTO_BUFFER_data(intermediate.get()),
                                      CRYPTO_BUFFER_len(intermediate.get())));
    if (!intermediate_cert) {
      if (invalid_intermediate_behavior == InvalidIntermediateBehavior::kFail)
        return base::ScopedCFTypeRef<CFMutableArrayRef>();
      LOG(WARNING) << "error parsing intermediate";
      continue;
    }
    CFArrayAppendValue(cert_list, intermediate_cert);
  }
  return cert_list;
}

scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
    base::ScopedCFTypeRef<SecCertificateRef> sec_cert,
    const std::vector<base::ScopedCFTypeRef<SecCertificateRef>>& sec_chain) {
  return CreateX509CertificateFromSecCertificate(sec_cert, sec_chain, {});
}

scoped_refptr<X509Certificate> CreateX509CertificateFromSecCertificate(
    base::ScopedCFTypeRef<SecCertificateRef> sec_cert,
    const std::vector<base::ScopedCFTypeRef<SecCertificateRef>>& sec_chain,
    X509Certificate::UnsafeCreateOptions options) {
  bssl::UniquePtr<CRYPTO_BUFFER> cert_handle =
      CertBufferFromSecCertificate(sec_cert);
  if (!cert_handle) {
    return nullptr;
  }
  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
  for (const auto& sec_intermediate : sec_chain) {
    bssl::UniquePtr<CRYPTO_BUFFER> intermediate_cert_handle =
        CertBufferFromSecCertificate(sec_intermediate);
    if (!intermediate_cert_handle) {
      return nullptr;
    }
    intermediates.push_back(std::move(intermediate_cert_handle));
  }
  scoped_refptr<X509Certificate> result(
      X509Certificate::CreateFromBufferUnsafeOptions(
          std::move(cert_handle), std::move(intermediates), options));
  return result;
}

SHA256HashValue CalculateFingerprint256(SecCertificateRef cert) {
  SHA256HashValue sha256;
  memset(sha256.data, 0, sizeof(sha256.data));

  base::ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
  if (!cert_data) {
    return sha256;
  }

  DCHECK(CFDataGetBytePtr(cert_data));
  DCHECK_NE(CFDataGetLength(cert_data), 0);

  CC_SHA256(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data),
            sha256.data);

  return sha256;
}

base::ScopedCFTypeRef<CFArrayRef> CertificateChainFromSecTrust(
    SecTrustRef trust) {
  if (__builtin_available(macOS 12.0, iOS 15.0, *)) {
    return base::ScopedCFTypeRef<CFArrayRef>(
        SecTrustCopyCertificateChain(trust));
  }

// TODO(crbug.com/1426476): Remove code when it is no longer needed.
#if (BUILDFLAG(IS_MAC) &&                                    \
     MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0) || \
    (BUILDFLAG(IS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_15_0)
  base::ScopedCFTypeRef<CFMutableArrayRef> chain(
      CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
  const CFIndex chain_length = SecTrustGetCertificateCount(trust);
  for (CFIndex i = 0; i < chain_length; ++i) {
    CFArrayAppendValue(chain, SecTrustGetCertificateAtIndex(trust, i));
  }
  return base::ScopedCFTypeRef<CFArrayRef>(chain.release());

#else
  // The other logic paths should be used, this is just to make the compiler
  // happy.
  NOTREACHED();
  return base::ScopedCFTypeRef<CFArrayRef>(nullptr);
#endif  // (BUILDFLAG(IS_MAC) && MAC_OS_X_VERSION_MIN_REQUIRED <
        // MAC_OS_VERSION_12_0)
        // || (BUILDFLAG(IS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED <
        // __IPHONE_15_0)
}

}  // namespace x509_util
}  // namespace net
