// 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_WINDOWS)

#include "bin/security_context.h"

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

#include "bin/directory.h"
#include "bin/file.h"
#include "bin/secure_socket_filter.h"
#include "bin/secure_socket_utils.h"
#include "platform/syslog.h"

#ifndef DART_TARGET_OS_WINDOWS_UWP
#pragma comment(lib, "crypt32.lib")
#endif

namespace dart {
namespace bin {

// The security context won't necessarily use the compiled-in root certificates,
// but since there is no way to update the size of the allocation after creating
// the weak persistent handle, we assume that it will. Note that when the
// root certs aren't compiled in, |root_certificates_pem_length| is 0.
const intptr_t SSLCertContext::kApproximateSize =
    sizeof(SSLCertContext) + root_certificates_pem_length;

static void PrintSSLErr(const char* str) {
  int error = ERR_get_error();
  char error_string[SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE];
  ERR_error_string_n(error, error_string,
                     SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE);
  Syslog::PrintErr("%s %s\n", str, error_string);
}

#ifndef DART_TARGET_OS_WINDOWS_UWP
static bool AddCertificatesFromNamedSystemStore(const wchar_t* name,
                                                DWORD store_type,
                                                X509_STORE* store) {
  ASSERT(store_type == CERT_SYSTEM_STORE_CURRENT_USER ||
         store_type == CERT_SYSTEM_STORE_LOCAL_MACHINE);

  if (SSL_LOG_STATUS) {
    Syslog::Print("AddCertificatesFromNamedSystemStore %ls type: %s\n", name,
                  store_type == CERT_SYSTEM_STORE_CURRENT_USER
                      ? "Current User"
                      : "Local Machine");
  }

  HCERTSTORE cert_store =
      CertOpenStore(CERT_STORE_PROV_SYSTEM,
                    0,     // the encoding type is not needed
                    NULL,  // use the default HCRYPTPROV
                    store_type | CERT_STORE_READONLY_FLAG, name);

  if (cert_store == NULL) {
    if (SSL_LOG_STATUS) {
      DWORD error = GetLastError();
      Syslog::PrintErr(
          "Failed to open Windows root store %ls type %d due to %d\n", name,
          store_type, error);
    }
    return false;
  }

  // Iterating through all certificates in the store. A NULL is required to
  // start iteration.
  PCCERT_CONTEXT cert_context = NULL;
  do {
    cert_context = CertEnumCertificatesInStore(cert_store, cert_context);
    if (cert_context == NULL) {
      // reach the end of store.
      break;
    }
    BIO* root_cert_bio =
        BIO_new_mem_buf(const_cast<unsigned char*>(cert_context->pbCertEncoded),
                        cert_context->cbCertEncoded);
    // `root_cert` has to be initialized to NULL, otherwise, it will be
    // considerred as an existing X509 and cause segmentation fault.
    X509* root_cert = NULL;
    if (d2i_X509_bio(root_cert_bio, &root_cert) == NULL) {
      if (SSL_LOG_STATUS) {
        PrintSSLErr("Fail to read certificate");
      }
      BIO_free(root_cert_bio);
      continue;
    }
    BIO_free(root_cert_bio);

    if (SSL_LOG_STATUS) {
      auto s_name = X509_get_subject_name(root_cert);
      auto s_issuer_name = X509_get_issuer_name(root_cert);
      auto serial_number = X509_get_serialNumber(root_cert);
      BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr);
      char* hex = BN_bn2hex(bn);
      Syslog::Print("Considering root certificate serial: %s subject name: ",
                    hex);
      OPENSSL_free(hex);
      X509_NAME_print_ex_fp(stdout, s_name, 4, 0);
      Syslog::Print(" issuer:");
      X509_NAME_print_ex_fp(stdout, s_issuer_name, 4, 0);
      Syslog::Print("\n");
    }

    int status = X509_STORE_add_cert(store, root_cert);
    if (status == 0) {
      int error = ERR_get_error();
      if (ERR_GET_REASON(error) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
        if (SSL_LOG_STATUS) {
          Syslog::Print("...duplicate\n");
        }
        X509_free(root_cert);
        continue;
      }
      if (SSL_LOG_STATUS) {
        PrintSSLErr("Failed to add certificate to x509 trust store");
      }
      X509_free(root_cert);
      CertFreeCertificateContext(cert_context);
      CertCloseStore(cert_store, 0);
      return false;
    }
  } while (cert_context != NULL);

  // It always returns non-zero.
  CertFreeCertificateContext(cert_context);
  if (!CertCloseStore(cert_store, 0)) {
    if (SSL_LOG_STATUS) {
      PrintSSLErr("Fail to close system root store");
    }
    return false;
  }
  return true;
}

static bool AddCertificatesFromSystemStore(DWORD store_type,
                                           X509_STORE* store) {
  if (!AddCertificatesFromNamedSystemStore(L"ROOT", store_type, store)) {
    return false;
  }
  if (!AddCertificatesFromNamedSystemStore(L"CA", store_type, store)) {
    return false;
  }
  if (!AddCertificatesFromNamedSystemStore(L"TRUST", store_type, store)) {
    return false;
  }
  if (!AddCertificatesFromNamedSystemStore(L"MY", store_type, store)) {
    return false;
  }
  return true;
}
#endif  // ifdef DART_TARGET_OS_WINDOWS_UWP

// Add certificates from Windows trusted root store.
static bool AddCertificatesFromRootStore(X509_STORE* store) {
// The UWP platform doesn't support CertEnumCertificatesInStore hence
// this function cannot work when compiled in UWP mode.
#ifdef DART_TARGET_OS_WINDOWS_UWP
  return false;
#else
  if (!AddCertificatesFromSystemStore(CERT_SYSTEM_STORE_CURRENT_USER, store)) {
    return false;
  }

  if (!AddCertificatesFromSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, store)) {
    return false;
  }

  return true;
#endif  // ifdef DART_TARGET_OS_WINDOWS_UWP
}

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;
  }

  if (bypass_trusting_system_roots()) {
    if (SSL_LOG_STATUS) {
      Syslog::Print("Bypass trusting Windows built-in roots\n");
    }
  } else {
    if (SSL_LOG_STATUS) {
      Syslog::Print("Trusting Windows built-in roots\n");
    }
    X509_STORE* store = SSL_CTX_get_cert_store(context());
    if (AddCertificatesFromRootStore(store)) {
      return;
    }
  }
  // Reset store. SSL_CTX_set_cert_store will take ownership of store. A manual
  // free is not needed.
  SSL_CTX_set_cert_store(context(), X509_STORE_new());
  // Fall back on the compiled-in certs if the standard locations don't exist,
  // or fail to load certificates from Windows root store.
  if (SSL_LOG_STATUS) {
    Syslog::Print("Trusting compiled-in roots\n");
  }
  AddCompiledInCerts();
}

void SSLCertContext::RegisterCallbacks(SSL* ssl) {
  // No callbacks to register for implementations using BoringSSL's built-in
  // verification mechanism.
}

TrustEvaluateHandlerFunc SSLCertContext::GetTrustEvaluateHandler() const {
  return nullptr;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_WINDOWS)

#endif  // !defined(DART_IO_SECURE_SOCKET_DISABLED)
