// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#if !defined(DART_IO_SECURE_SOCKET_DISABLED)

#include "platform/globals.h"
#if defined(DART_HOST_OS_MACOS)

#include "bin/security_context.h"

#include <Availability.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/SecureTransport.h>
#include <Security/Security.h>

#include <openssl/ssl.h>
#include <openssl/x509.h>

#include "bin/secure_socket_filter.h"

namespace dart {
namespace bin {

const intptr_t SSLCertContext::kApproximateSize = sizeof(SSLCertContext);

template <typename T>
class ScopedCFType {
 public:
  explicit ScopedCFType(T obj) : obj_(obj) {}

  ~ScopedCFType() {
    if (obj_ != NULL) {
      CFRelease(obj_);
    }
  }

  T get() { return obj_; }
  T* ptr() { return &obj_; }
  const T get() const { return obj_; }

  DART_WARN_UNUSED_RESULT T release() {
    T temp = obj_;
    obj_ = NULL;
    return temp;
  }

  void set(T obj) { obj_ = obj; }

  bool operator==(T other) { return other == get(); }

  bool operator!=(T other) { return other != get(); }

 private:
  T obj_;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(ScopedCFType);
};

static void releaseObjects(const void* val, void* context) {
  CFRelease(val);
}

template <>
ScopedCFType<CFMutableArrayRef>::~ScopedCFType() {
  if (obj_ != NULL) {
    CFIndex count = 0;
    CFArrayApplyFunction(obj_, CFRangeMake(0, CFArrayGetCount(obj_)),
                         releaseObjects, &count);
    CFRelease(obj_);
  }
}

typedef ScopedCFType<CFMutableArrayRef> ScopedCFMutableArrayRef;
typedef ScopedCFType<CFDataRef> ScopedCFDataRef;
typedef ScopedCFType<CFStringRef> ScopedCFStringRef;
typedef ScopedCFType<SecPolicyRef> ScopedSecPolicyRef;
typedef ScopedCFType<SecCertificateRef> ScopedSecCertificateRef;
typedef ScopedCFType<SecTrustRef> ScopedSecTrustRef;

const int kNumTrustEvaluateRequestParams = 5;

static SecCertificateRef CreateSecCertificateFromX509(X509* cert) {
  if (cert == NULL) {
    return NULL;
  }
  int length = i2d_X509(cert, NULL);
  if (length < 0) {
    return NULL;
  }
  // This can be `std::make_unique<unsigned char[]>(length)` in C++14
  // But the Mac toolchain is still using C++11.
  auto deb_cert = std::unique_ptr<unsigned char[]>(new unsigned char[length]);
  unsigned char* temp = deb_cert.get();
  if (i2d_X509(cert, &temp) != length) {
    return NULL;
  }
  // TODO(bkonyi): we create a copy of the deb_cert here since it's unclear
  // whether or not SecCertificateCreateWithData takes ownership of the CFData.
  // Implementation here:
  // https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.2/lib/SecCertificate.cpp.auto.html
  ScopedCFDataRef cert_buf(CFDataCreate(NULL, deb_cert.get(), length));
  return SecCertificateCreateWithData(NULL, cert_buf.get());
}

static ssl_verify_result_t CertificateVerificationCallback(SSL* ssl,
                                                           uint8_t* out_alert) {
  SSLFilter* filter = static_cast<SSLFilter*>(
      SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
  SSLCertContext* context = static_cast<SSLCertContext*>(
      SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));

  const X509TrustState* certificate_trust_state =
      filter->certificate_trust_state();
  if (certificate_trust_state != nullptr) {
    // Callback have been previously called to explicitly evaluate root_cert.
    STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
    X509* root_cert = nullptr;
    for (uintptr_t i = sk_X509_num(unverified); i > 0; i--) {
      root_cert = sk_X509_shift(unverified);
      if (root_cert == nullptr) {
        break;
      }
    }
    if (certificate_trust_state->x509() == root_cert) {
      return certificate_trust_state->is_trusted() ? ssl_verify_ok
                                                   : ssl_verify_invalid;
    }
  }

  STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));

  // Convert BoringSSL formatted certificates to SecCertificate certificates.
  ScopedCFMutableArrayRef cert_chain(NULL);
  X509* root_cert = NULL;
  int num_certs = sk_X509_num(unverified);
  int current_cert = 0;
  cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
  X509* ca;
  // Look for the last certificate in the chain - it's a root certificate.
  while ((ca = sk_X509_shift(unverified)) != NULL) {
    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
    if (cert == NULL) {
      return ssl_verify_invalid;
    }
    CFArrayAppendValue(cert_chain.get(), cert.release());
    ++current_cert;

    if (current_cert == num_certs) {
      break;
    }
  }
  ASSERT(current_cert == num_certs);
  root_cert = ca;
  X509_up_ref(ca);

  SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
  X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
  // Convert all trusted certificates provided by the user via
  // setTrustedCertificatesBytes or the command line into SecCertificates.
  ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
  ASSERT(store != NULL);

  for (const X509_OBJECT* obj : X509_STORE_get0_objects(store)) {
    X509* ca = X509_OBJECT_get0_X509(obj);
    ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
    if (cert == NULL) {
      return ssl_verify_invalid;
    }
    CFArrayAppendValue(trusted_certs.get(), cert.release());
  }

  // Generate a policy for validating chains for SSL.
  CFStringRef cfhostname = NULL;
  if (filter->hostname() != NULL) {
    cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
                                           kCFStringEncodingUTF8);
  }
  ScopedCFStringRef hostname(cfhostname);
  ScopedSecPolicyRef policy(
      SecPolicyCreateSSL(filter->is_client(), hostname.get()));

  // Create the trust object with the certificates provided by the user.
  ScopedSecTrustRef trust(NULL);
  OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
                                                   policy.get(), trust.ptr());
  if (status != noErr) {
    return ssl_verify_invalid;
  }

  // If the user provided any additional CA certificates, add them to the trust
  // object.
  if (CFArrayGetCount(trusted_certs.get()) > 0) {
    status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
    if (status != noErr) {
      return ssl_verify_invalid;
    }
  }

  // Specify whether or not to use the built-in CA certificates for
  // verification.
  status =
      SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
  if (status != noErr) {
    return ssl_verify_invalid;
  }

  // TrustEvaluateHandler should release all handles.
  Dart_CObject dart_cobject_trust;
  dart_cobject_trust.type = Dart_CObject_kInt64;
  dart_cobject_trust.value.as_int64 =
      reinterpret_cast<intptr_t>(trust.release());

  Dart_CObject dart_cobject_cert_chain;
  dart_cobject_cert_chain.type = Dart_CObject_kInt64;
  dart_cobject_cert_chain.value.as_int64 =
      reinterpret_cast<intptr_t>(cert_chain.release());

  Dart_CObject dart_cobject_trusted_certs;
  dart_cobject_trusted_certs.type = Dart_CObject_kInt64;
  dart_cobject_trusted_certs.value.as_int64 =
      reinterpret_cast<intptr_t>(trusted_certs.release());

  Dart_CObject dart_cobject_root_cert;
  dart_cobject_root_cert.type = Dart_CObject_kInt64;
  dart_cobject_root_cert.value.as_int64 = reinterpret_cast<intptr_t>(root_cert);

  Dart_CObject reply_send_port;
  reply_send_port.type = Dart_CObject_kSendPort;
  reply_send_port.value.as_send_port.id = filter->reply_port();

  Dart_CObject array;
  array.type = Dart_CObject_kArray;
  array.value.as_array.length = kNumTrustEvaluateRequestParams;
  Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_cert_chain,
                            &dart_cobject_trusted_certs,
                            &dart_cobject_root_cert, &reply_send_port};
  array.value.as_array.values = values;

  Dart_PostCObject(filter->trust_evaluate_reply_port(), &array);
  return ssl_verify_retry;
}

static void postReply(Dart_Port reply_port_id,
                      bool success,
                      X509* certificate = nullptr) {
  Dart_CObject dart_cobject_success;
  dart_cobject_success.type = Dart_CObject_kBool;
  dart_cobject_success.value.as_bool = success;

  Dart_CObject dart_cobject_certificate;
  dart_cobject_certificate.type = Dart_CObject_kInt64;
  dart_cobject_certificate.value.as_int64 =
      reinterpret_cast<intptr_t>(certificate);

  Dart_CObject array;
  array.type = Dart_CObject_kArray;
  array.value.as_array.length = 2;
  Dart_CObject* values[] = {&dart_cobject_success, &dart_cobject_certificate};
  array.value.as_array.values = values;

  Dart_PostCObject(reply_port_id, &array);
}

static void TrustEvaluateHandler(Dart_Port dest_port_id,
                                 Dart_CObject* message) {
  // This is used for testing to confirm that trust evaluation doesn't block
  // dart isolate.
  // First sleep exposes problem where ssl data structures are released/freed
  // by main isolate before this handler had a chance to access them.
  // Second sleep(below) is there to maintain same long delay of certificate
  // verification.
  if (SSLCertContext::long_ssl_cert_evaluation()) {
    usleep(2000 * 1000 /* 2 s*/);
  }

  CObjectArray request(message);
  if (request.Length() != kNumTrustEvaluateRequestParams) {
    FATAL2("Malformed trust evaluate message: got %" Pd
           " parameters "
           "expected %d\n",
           request.Length(), kNumTrustEvaluateRequestParams);
  }
  CObjectIntptr trust_cobject(request[0]);
  ScopedSecTrustRef trust(reinterpret_cast<SecTrustRef>(trust_cobject.Value()));
  CObjectIntptr cert_chain_cobject(request[1]);
  ScopedCFMutableArrayRef cert_chain(
      reinterpret_cast<CFMutableArrayRef>(cert_chain_cobject.Value()));
  CObjectIntptr trusted_certs_cobject(request[2]);
  ScopedCFMutableArrayRef trusted_certs(
      reinterpret_cast<CFMutableArrayRef>(trusted_certs_cobject.Value()));
  CObjectIntptr root_cert_cobject(request[3]);
  X509* root_cert = reinterpret_cast<X509*>(root_cert_cobject.Value());
  CObjectSendPort reply_port(request[4]);
  Dart_Port reply_port_id = reply_port.Value();

  SecTrustResultType trust_result;
  if (SSLCertContext::long_ssl_cert_evaluation()) {
    usleep(3000 * 1000 /* 3 s*/);
  }

  OSStatus status = noErr;
  // Perform the certificate verification.
  if (__builtin_available(iOS 12.0, macOS 10.14, *)) {
    // SecTrustEvaluateWithError available as of OSX 10.14 and iOS 12.
    // The result is ignored as we get more information from the following call
    // to SecTrustGetTrustResult which also happens to match the information we
    // get from calling SecTrustEvaluate.
    bool res = SecTrustEvaluateWithError(trust.get(), NULL);
    USE(res);
    status = SecTrustGetTrustResult(trust.get(), &trust_result);
  } else {
    // SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
    status = SecTrustEvaluate(trust.get(), &trust_result);
  }

  postReply(reply_port_id,
            status == noErr && (trust_result == kSecTrustResultProceed ||
                                trust_result == kSecTrustResultUnspecified),
            root_cert);
}

void SSLCertContext::RegisterCallbacks(SSL* ssl) {
  SSL_set_custom_verify(ssl, SSL_VERIFY_PEER, CertificateVerificationCallback);
}

TrustEvaluateHandlerFunc SSLCertContext::GetTrustEvaluateHandler() const {
  return &TrustEvaluateHandler;
}

void SSLCertContext::TrustBuiltinRoots() {
  // First, try to use locations specified on the command line.
  if (root_certs_file() != NULL) {
    LoadRootCertFile(root_certs_file());
    return;
  }
  if (root_certs_cache() != NULL) {
    LoadRootCertCache(root_certs_cache());
    return;
  }
  set_trust_builtin(true);
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_MACOS)

#endif  // !defined(DART_IO_SECURE_SOCKET_DISABLED)
