// Copyright (c) 2017 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 "net/cert/known_roots_mac.h"

#include <Security/Security.h>

#include <algorithm>
#include <vector>

#include "base/lazy_instance.h"
#include "crypto/mac_security_services_lock.h"
#include "net/cert/x509_util_mac.h"
#include "starboard/types.h"

using base::ScopedCFTypeRef;

namespace net {

namespace {

// Helper class for managing the set of OS X Known Roots. This is only safe
// to initialize while the crypto::GetMacSecurityServicesLock() is held, due
// to calling into Security.framework functions; however, once initialized,
// it can be called at any time.
// In practice, due to lazy initialization, it's best to just always guard
// accesses with the lock.
class OSXKnownRootHelper {
 public:
  bool IsKnownRoot(SecCertificateRef cert) {
    // If there are no known roots, then an API failure occurred. For safety,
    // assume that all certificates are issued by known roots.
    if (known_roots_.empty())
      return true;

    HashValue hash(x509_util::CalculateFingerprint256(cert));
    return IsSHA256HashInSortedArray(hash, known_roots_);
  }

 private:
  friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>;

  OSXKnownRootHelper() {
    crypto::GetMacSecurityServicesLock().AssertAcquired();

    CFArrayRef cert_array = NULL;
    OSStatus rv = SecTrustSettingsCopyCertificates(
        kSecTrustSettingsDomainSystem, &cert_array);
    if (rv != noErr) {
      LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
                 << "trusted! Error " << rv;
      return;
    }
    base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);

    known_roots_.reserve(CFArrayGetCount(cert_array));
    for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
      SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
          const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
      known_roots_.push_back(x509_util::CalculateFingerprint256(cert));
    }
    std::sort(known_roots_.begin(), known_roots_.end());
  }

  ~OSXKnownRootHelper() {}

  std::vector<SHA256HashValue> known_roots_;
};

base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

bool IsKnownRoot(SecCertificateRef cert) {
  return g_known_roots.Get().IsKnownRoot(cert);
}

void InitializeKnownRoots() {
  base::AutoLock lock(crypto::GetMacSecurityServicesLock());
  g_known_roots.Get();
}

}  // namespace net
