// Copyright (c) 2012 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/cert_verify_proc_mac.h"

#include <CommonCrypto/CommonDigest.h>
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>

#include <algorithm>
#include <string>
#include <vector>

#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
#include "crypto/mac_security_services_lock.h"
#include "crypto/sha2.h"
#include "net/base/hash_value.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/crl_set.h"
#include "net/cert/ev_root_ca_metadata.h"
#include "net/cert/internal/certificate_policies.h"
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/known_roots.h"
#include "net/cert/known_roots_mac.h"
#include "net/cert/test_keychain_search_list_mac.h"
#include "net/cert/test_root_certs.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "net/cert/x509_util_ios_and_mac.h"
#include "net/cert/x509_util_mac.h"
#include "starboard/memory.h"
#include "starboard/types.h"

// CSSM functions are deprecated as of OSX 10.7, but have no replacement.
// https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

using base::ScopedCFTypeRef;

namespace net {

namespace {

typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef,
                                                      CFDictionaryRef*);

int NetErrorFromOSStatus(OSStatus status) {
  switch (status) {
    case noErr:
      return OK;
    case errSecNotAvailable:
    case errSecNoCertificateModule:
    case errSecNoPolicyModule:
      return ERR_NOT_IMPLEMENTED;
    case errSecAuthFailed:
      return ERR_ACCESS_DENIED;
    default: {
      OSSTATUS_LOG(ERROR, status) << "Unknown error mapped to ERR_FAILED";
      return ERR_FAILED;
    }
  }
}

CertStatus CertStatusFromOSStatus(OSStatus status) {
  switch (status) {
    case noErr:
      return 0;

    case CSSMERR_TP_INVALID_ANCHOR_CERT:
    case CSSMERR_TP_NOT_TRUSTED:
    case CSSMERR_TP_INVALID_CERT_AUTHORITY:
      return CERT_STATUS_AUTHORITY_INVALID;

    case CSSMERR_TP_CERT_EXPIRED:
    case CSSMERR_TP_CERT_NOT_VALID_YET:
      // "Expired" and "not yet valid" collapse into a single status.
      return CERT_STATUS_DATE_INVALID;

    case CSSMERR_TP_CERT_REVOKED:
    case CSSMERR_TP_CERT_SUSPENDED:
      return CERT_STATUS_REVOKED;

    case CSSMERR_APPLETP_HOSTNAME_MISMATCH:
      return CERT_STATUS_COMMON_NAME_INVALID;

    case CSSMERR_APPLETP_CRL_NOT_FOUND:
    case CSSMERR_APPLETP_OCSP_UNAVAILABLE:
      return CERT_STATUS_NO_REVOCATION_MECHANISM;

    case CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK:
      // Starting with later 10.12 versions,
      // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK is a catch-all code for
      // failures to check revocation status.
      // However, on pre-10.12 versions, it would also be used on revocation
      // failures. (CERT_STATUS_NO_REVOCATION_MECHANISM isn't really right
      // there either, but that's what the old code has, and it just gets
      // masked off later so has no actual effect.)
      return base::mac::IsAtLeastOS10_12()
                 ? CERT_STATUS_UNABLE_TO_CHECK_REVOCATION
                 : CERT_STATUS_NO_REVOCATION_MECHANISM;

    case CSSMERR_APPLETP_CRL_EXPIRED:
    case CSSMERR_APPLETP_CRL_NOT_VALID_YET:
    case CSSMERR_APPLETP_CRL_SERVER_DOWN:
    case CSSMERR_APPLETP_CRL_NOT_TRUSTED:
    case CSSMERR_APPLETP_CRL_INVALID_ANCHOR_CERT:
    case CSSMERR_APPLETP_CRL_POLICY_FAIL:
    case CSSMERR_APPLETP_OCSP_BAD_RESPONSE:
    case CSSMERR_APPLETP_OCSP_BAD_REQUEST:
    case CSSMERR_APPLETP_OCSP_STATUS_UNRECOGNIZED:
    case CSSMERR_APPLETP_NETWORK_FAILURE:
    case CSSMERR_APPLETP_OCSP_NOT_TRUSTED:
    case CSSMERR_APPLETP_OCSP_INVALID_ANCHOR_CERT:
    case CSSMERR_APPLETP_OCSP_SIG_ERROR:
    case CSSMERR_APPLETP_OCSP_NO_SIGNER:
    case CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ:
    case CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR:
    case CSSMERR_APPLETP_OCSP_RESP_TRY_LATER:
    case CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED:
    case CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED:
    case CSSMERR_APPLETP_OCSP_NONCE_MISMATCH:
      // We asked for a revocation check, but didn't get it.
      return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;

    case CSSMERR_APPLETP_SSL_BAD_EXT_KEY_USE:
      // TODO(wtc): Should we add CERT_STATUS_WRONG_USAGE?
      return CERT_STATUS_INVALID;

    case CSSMERR_APPLETP_CRL_BAD_URI:
    case CSSMERR_APPLETP_IDP_FAIL:
      return CERT_STATUS_INVALID;

    case CSSMERR_CSP_UNSUPPORTED_KEY_SIZE:
      // Mapping UNSUPPORTED_KEY_SIZE to CERT_STATUS_WEAK_KEY is not strictly
      // accurate, as the error may have been returned due to a key size
      // that exceeded the maximum supported. However, within
      // CertVerifyProcMac::VerifyInternal(), this code should only be
      // encountered as a certificate status code, and only when the key size
      // is smaller than the minimum required (1024 bits).
      return CERT_STATUS_WEAK_KEY;

    default: {
      // Failure was due to something Chromium doesn't define a
      // specific status for (such as basic constraints violation, or
      // unknown critical extension)
      OSSTATUS_LOG(WARNING, status)
          << "Unknown error mapped to CERT_STATUS_INVALID";
      return CERT_STATUS_INVALID;
    }
  }
}

// Creates a series of SecPolicyRefs to be added to a SecTrustRef used to
// validate a certificate for an SSL server. |flags| is a bitwise-OR of
// VerifyFlags that can further alter how trust is validated, such as how
// revocation is checked. If successful, returns noErr, and stores the
// resultant array of SecPolicyRefs in |policies|.
OSStatus CreateTrustPolicies(int flags, ScopedCFTypeRef<CFArrayRef>* policies) {
  ScopedCFTypeRef<CFMutableArrayRef> local_policies(
      CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
  if (!local_policies)
    return memFullErr;

  SecPolicyRef ssl_policy;
  OSStatus status =
      x509_util::CreateSSLServerPolicy(std::string(), &ssl_policy);
  if (status)
    return status;
  CFArrayAppendValue(local_policies, ssl_policy);
  CFRelease(ssl_policy);

  // Explicitly add revocation policies, in order to override system
  // revocation checking policies and instead respect the application-level
  // revocation preference.
  status = x509_util::CreateRevocationPolicies(
      (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED), local_policies);
  if (status)
    return status;

  policies->reset(local_policies.release());
  return noErr;
}

// Stores the constructed certificate chain |cert_chain| into
// |*verify_result|. |cert_chain| must not be empty.
void CopyCertChainToVerifyResult(CFArrayRef cert_chain,
                                 CertVerifyResult* verify_result) {
  DCHECK_LT(0, CFArrayGetCount(cert_chain));

  SecCertificateRef verified_cert = NULL;
  std::vector<SecCertificateRef> verified_chain;
  for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
    SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
        const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
    if (i == 0) {
      verified_cert = chain_cert;
    } else {
      verified_chain.push_back(chain_cert);
    }
  }
  if (!verified_cert) {
    NOTREACHED();
    verify_result->cert_status |= CERT_STATUS_INVALID;
    return;
  }

  scoped_refptr<X509Certificate> verified_cert_with_chain =
      x509_util::CreateX509CertificateFromSecCertificate(verified_cert,
                                                         verified_chain);
  if (verified_cert_with_chain)
    verify_result->verified_cert = std::move(verified_cert_with_chain);
  else
    verify_result->cert_status |= CERT_STATUS_INVALID;
}

// Returns true if the certificate uses MD2, MD4, MD5, or SHA1, and false
// otherwise. A return of false also includes the case where the signature
// algorithm couldn't be conclusively labeled as weak.
bool CertUsesWeakHash(SecCertificateRef cert_handle) {
  x509_util::CSSMCachedCertificate cached_cert;
  OSStatus status = cached_cert.Init(cert_handle);
  if (status)
    return false;

  x509_util::CSSMFieldValue signature_field;
  status =
      cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field);
  if (status || !signature_field.field())
    return false;

  const CSSM_X509_ALGORITHM_IDENTIFIER* sig_algorithm =
      signature_field.GetAs<CSSM_X509_ALGORITHM_IDENTIFIER>();
  if (!sig_algorithm)
    return false;

  const CSSM_OID* alg_oid = &sig_algorithm->algorithm;

  return (x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithRSA_OIW) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_CMS) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_SHA1WithDSA_JDK) ||
          x509_util::CSSMOIDEqual(alg_oid, &CSSMOID_ECDSA_WithSHA1));
}

// Returns true if the intermediates (excluding trusted certificates) use a
// weak hashing algorithm, but the target does not use a weak hash.
bool IsWeakChainBasedOnHashingAlgorithms(
    CFArrayRef cert_chain,
    CSSM_TP_APPLE_EVIDENCE_INFO* chain_info) {
  DCHECK_LT(0, CFArrayGetCount(cert_chain));

  bool intermediates_contain_weak_hash = false;
  bool leaf_uses_weak_hash = false;

  for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); i < count; ++i) {
    SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>(
        const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));

    if ((chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_IN_ANCHORS) ||
        (chain_info[i].StatusBits & CSSM_CERT_STATUS_IS_ROOT)) {
      // The current certificate is either in the user's trusted store or is
      // a root (self-signed) certificate. Ignore the signature algorithm for
      // these certificates, as it is meaningless for security. We allow
      // self-signed certificates (i == 0 & IS_ROOT), since we accept that
      // any security assertions by such a cert are inherently meaningless.
      continue;
    }

    if (CertUsesWeakHash(chain_cert)) {
      if (i == 0) {
        leaf_uses_weak_hash = true;
      } else {
        intermediates_contain_weak_hash = true;
      }
    }
  }

  return !leaf_uses_weak_hash && intermediates_contain_weak_hash;
}

// Checks if |*cert| has a Certificate Policies extension containing either
// of |ev_policy_oid| or anyPolicy.
bool HasPolicyOrAnyPolicy(const ParsedCertificate* cert,
                          const der::Input& ev_policy_oid) {
  if (!cert->has_policy_oids())
    return false;

  for (const der::Input& policy_oid : cert->policy_oids()) {
    if (policy_oid == ev_policy_oid || policy_oid == AnyPolicy())
      return true;
  }
  return false;
}

// Looks for known EV policy OIDs in |cert_input|, if one is found it will be
// stored in |*ev_policy_oid| as a DER-encoded OID value (no tag or length).
void GetCandidateEVPolicy(const X509Certificate* cert_input,
                          std::string* ev_policy_oid) {
  ev_policy_oid->clear();

  scoped_refptr<ParsedCertificate> cert(ParsedCertificate::Create(
      bssl::UpRef(cert_input->cert_buffer()), {}, nullptr));
  if (!cert)
    return;

  if (!cert->has_policy_oids())
    return;

  EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
  for (const der::Input& policy_oid : cert->policy_oids()) {
    if (metadata->IsEVPolicyOID(policy_oid)) {
      *ev_policy_oid = policy_oid.AsString();

      // De-prioritize the CA/Browser forum Extended Validation policy
      // (2.23.140.1.1). See crbug.com/705285.
      if (!EVRootCAMetadata::IsCaBrowserForumEvOid(policy_oid))
        break;
    }
  }
}

// Checks that the certificate chain of |cert| has policies consistent with
// |ev_policy_oid_string|. The leaf is not checked, as it is assumed that is
// where the policy came from.
bool CheckCertChainEV(const X509Certificate* cert,
                      const std::string& ev_policy_oid_string) {
  der::Input ev_policy_oid(&ev_policy_oid_string);
  const std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>& cert_chain =
      cert->intermediate_buffers();

  // Root should have matching policy in EVRootCAMetadata.
  if (cert_chain.empty())
    return false;
  SHA256HashValue fingerprint =
      X509Certificate::CalculateFingerprint256(cert_chain.back().get());
  EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
  if (!metadata->HasEVPolicyOID(fingerprint, ev_policy_oid))
    return false;

  // Intermediates should have Certificate Policies extension with the EV policy
  // or AnyPolicy.
  for (size_t i = 0; i < cert_chain.size() - 1; ++i) {
    scoped_refptr<ParsedCertificate> intermediate_cert(
        ParsedCertificate::Create(bssl::UpRef(cert_chain[i].get()), {},
                                  nullptr));
    if (!intermediate_cert)
      return false;
    if (!HasPolicyOrAnyPolicy(intermediate_cert.get(), ev_policy_oid))
      return false;
  }

  return true;
}

void AppendPublicKeyHashesAndUpdateKnownRoot(CFArrayRef chain,
                                             HashValueVector* hashes,
                                             bool* known_root) {
  // Walk the chain in reverse, to optimize for IsKnownRoot checks.
  for (CFIndex i = CFArrayGetCount(chain); i > 0; i--) {
    SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
        const_cast<void*>(CFArrayGetValueAtIndex(chain, i - 1)));

    CSSM_DATA cert_data;
    OSStatus err = SecCertificateGetData(cert, &cert_data);
    DCHECK_EQ(err, noErr);
    base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data),
                               cert_data.Length);
    base::StringPiece spki_bytes;
    if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
      continue;

    HashValue sha256(HASH_VALUE_SHA256);
    CC_SHA256(spki_bytes.data(), spki_bytes.size(), sha256.data());
    hashes->push_back(sha256);

    if (!*known_root) {
      *known_root =
          GetNetTrustAnchorHistogramIdForSPKI(sha256) != 0 || IsKnownRoot(cert);
    }
  }
  // Reverse the hash array, to maintain the leaf-first ordering.
  std::reverse(hashes->begin(), hashes->end());
}

enum CRLSetResult {
  kCRLSetOk,
  kCRLSetRevoked,
  kCRLSetUnknown,
};

// CheckRevocationWithCRLSet attempts to check each element of |cert_list|
// against |crl_set|. It returns:
//   kCRLSetRevoked: if any element of the chain is known to have been revoked.
//   kCRLSetUnknown: if there is no fresh information about the leaf
//       certificate in the chain or if the CRLSet has expired.
//
//       Only the leaf certificate is considered for coverage because some
//       intermediates have CRLs with no revocations (after filtering) and
//       those CRLs are pruned from the CRLSet at generation time. This means
//       that some EV sites would otherwise take the hit of an OCSP lookup for
//       no reason.
//   kCRLSetOk: otherwise.
CRLSetResult CheckRevocationWithCRLSet(CFArrayRef chain, CRLSet* crl_set) {
  if (CFArrayGetCount(chain) == 0)
    return kCRLSetOk;

  // error is set to true if any errors are found. It causes such chains to be
  // considered as not covered.
  bool error = false;
  // last_covered is set to the coverage state of the previous certificate. The
  // certificates are iterated over backwards thus, after the iteration,
  // |last_covered| contains the coverage state of the leaf certificate.
  bool last_covered = false;

  // We iterate from the root certificate down to the leaf, keeping track of
  // the issuer's SPKI at each step.
  std::string issuer_spki_hash;
  for (CFIndex i = CFArrayGetCount(chain); i > 0; i--) {
    SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
        const_cast<void*>(CFArrayGetValueAtIndex(chain, i - 1)));

    CSSM_DATA cert_data;
    OSStatus err = SecCertificateGetData(cert, &cert_data);
    if (err != noErr) {
      NOTREACHED();
      error = true;
      continue;
    }
    base::StringPiece der_bytes(reinterpret_cast<const char*>(cert_data.Data),
                                cert_data.Length);
    base::StringPiece spki, subject;
    if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki) ||
        !asn1::ExtractSubjectFromDERCert(der_bytes, &subject)) {
      NOTREACHED();
      error = true;
      continue;
    }

    const std::string spki_hash = crypto::SHA256HashString(spki);
    x509_util::CSSMCachedCertificate cached_cert;
    if (cached_cert.Init(cert) != CSSM_OK) {
      NOTREACHED();
      error = true;
      continue;
    }
    x509_util::CSSMFieldValue serial_number;
    err = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, &serial_number);
    if (err || !serial_number.field()) {
      NOTREACHED();
      error = true;
      continue;
    }

    base::StringPiece serial(
        reinterpret_cast<const char*>(serial_number.field()->Data),
        serial_number.field()->Length);

    CRLSet::Result result = crl_set->CheckSPKI(spki_hash);

    if (result != CRLSet::REVOKED)
      result = crl_set->CheckSubject(subject, spki_hash);
    if (result != CRLSet::REVOKED && !issuer_spki_hash.empty())
      result = crl_set->CheckSerial(serial, issuer_spki_hash);

    issuer_spki_hash = spki_hash;

    switch (result) {
      case CRLSet::REVOKED:
        return kCRLSetRevoked;
      case CRLSet::UNKNOWN:
        last_covered = false;
        continue;
      case CRLSet::GOOD:
        last_covered = true;
        continue;
      default:
        NOTREACHED();
        error = true;
        continue;
    }
  }

  if (error || !last_covered || crl_set->IsExpired())
    return kCRLSetUnknown;
  return kCRLSetOk;
}

// Builds and evaluates a SecTrustRef for the certificate chain contained
// in |cert_array|, using the verification policies in |trust_policies|. On
// success, returns OK, and updates |trust_ref|, |trust_result|,
// |verified_chain|, and |chain_info| with the verification results. On
// failure, no output parameters are modified.
//
// Note: An OK return does not mean that |cert_array| is trusted, merely that
// verification was performed successfully.
//
// This function should only be called while the Mac Security Services lock is
// held.
int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array,
                                CFArrayRef trust_policies,
                                int flags,
                                CFArrayRef keychain_search_list,
                                ScopedCFTypeRef<SecTrustRef>* trust_ref,
                                SecTrustResultType* trust_result,
                                ScopedCFTypeRef<CFArrayRef>* verified_chain,
                                CSSM_TP_APPLE_EVIDENCE_INFO** chain_info) {
  SecTrustRef tmp_trust = NULL;
  OSStatus status = SecTrustCreateWithCertificates(cert_array, trust_policies,
                                                   &tmp_trust);
  if (status)
    return NetErrorFromOSStatus(status);
  ScopedCFTypeRef<SecTrustRef> scoped_tmp_trust(tmp_trust);

  if (TestRootCerts::HasInstance()) {
    status = TestRootCerts::GetInstance()->FixupSecTrustRef(tmp_trust);
    if (status)
      return NetErrorFromOSStatus(status);
  }

  if (keychain_search_list) {
    status = SecTrustSetKeychains(tmp_trust, keychain_search_list);
    if (status)
      return NetErrorFromOSStatus(status);
  }

  CSSM_APPLE_TP_ACTION_DATA tp_action_data;
  memset(&tp_action_data, 0, sizeof(tp_action_data));
  tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
  // Allow CSSM to download any missing intermediate certificates if an
  // authorityInfoAccess extension or issuerAltName extension is present.
  tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET |
                               CSSM_TP_ACTION_TRUST_SETTINGS;

  // Note: For EV certificates, the Apple TP will handle setting these flags
  // as part of EV evaluation.
  if (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) {
    // Require a positive result from an OCSP responder or a CRL (or both)
    // for every certificate in the chain. The Apple TP automatically
    // excludes the self-signed root from this requirement. If a certificate
    // is missing both a crlDistributionPoints extension and an
    // authorityInfoAccess extension with an OCSP responder URL, then we
    // will get a kSecTrustResultRecoverableTrustFailure back from
    // SecTrustEvaluate(), with a
    // CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case,
    // we'll set our own result to include
    // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are
    // present, and a check fails (server unavailable, OCSP retry later,
    // signature mismatch), then we'll set our own result to include
    // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION.
    tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;

    // Note, even if revocation checking is disabled, SecTrustEvaluate() will
    // modify the OCSP options so as to attempt OCSP checking if it believes a
    // certificate may chain to an EV root. However, because network fetches
    // are disabled in CreateTrustPolicies() when revocation checking is
    // disabled, these will only go against the local cache.
  }

  CFDataRef action_data_ref =
      CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
                                  reinterpret_cast<UInt8*>(&tp_action_data),
                                  sizeof(tp_action_data), kCFAllocatorNull);
  if (!action_data_ref)
    return ERR_OUT_OF_MEMORY;
  ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref);
  status = SecTrustSetParameters(tmp_trust, CSSM_TP_ACTION_DEFAULT,
                                 action_data_ref);
  if (status)
    return NetErrorFromOSStatus(status);

  // Verify the certificate. A non-zero result from SecTrustGetResult()
  // indicates that some fatal error occurred and the chain couldn't be
  // processed, not that the chain contains no errors. We need to examine the
  // output of SecTrustGetResult() to determine that.
  SecTrustResultType tmp_trust_result;
  status = SecTrustEvaluate(tmp_trust, &tmp_trust_result);
  if (status)
    return NetErrorFromOSStatus(status);
  CFArrayRef tmp_verified_chain = NULL;
  CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info;
  status = SecTrustGetResult(tmp_trust, &tmp_trust_result, &tmp_verified_chain,
                             &tmp_chain_info);
  if (status)
    return NetErrorFromOSStatus(status);

  trust_ref->swap(scoped_tmp_trust);
  *trust_result = tmp_trust_result;
  verified_chain->reset(tmp_verified_chain);
  *chain_info = tmp_chain_info;

  return OK;
}

// Runs path building & verification loop for |cert|, given |flags|. This is
// split into a separate function so verification can be repeated with different
// flags. This function does not handle EV.
int VerifyWithGivenFlags(X509Certificate* cert,
                         const std::string& hostname,
                         const int flags,
                         CRLSet* crl_set,
                         CertVerifyResult* verify_result,
                         CRLSetResult* completed_chain_crl_result) {
  ScopedCFTypeRef<CFArrayRef> trust_policies;
  OSStatus status = CreateTrustPolicies(flags, &trust_policies);
  if (status)
    return NetErrorFromOSStatus(status);

  *completed_chain_crl_result = kCRLSetUnknown;

  // Serialize all calls that may use the Keychain, to work around various
  // issues in OS X 10.6+ with multi-threaded access to Security.framework.
  base::AutoLock lock(crypto::GetMacSecurityServicesLock());

  ScopedCFTypeRef<SecTrustRef> trust_ref;
  SecTrustResultType trust_result = kSecTrustResultDeny;
  ScopedCFTypeRef<CFArrayRef> completed_chain;
  CSSM_TP_APPLE_EVIDENCE_INFO* chain_info = NULL;
  bool candidate_untrusted = true;
  bool candidate_weak = false;

  // OS X lacks proper path discovery; it will take the input certs and never
  // backtrack the graph attempting to discover valid paths.
  // This can create issues in some situations:
  // - When OS X changes the trust store, there may be a chain
  //     A -> B -> C -> D
  //   where OS X trusts D (on some versions) and trusts C (on some versions).
  //   If a server supplies a chain A, B, C (cross-signed by D), then this chain
  //   will successfully validate on systems that trust D, but fail for systems
  //   that trust C. If the server supplies a chain of A -> B, then it forces
  //   all clients to fetch C (via AIA) if they trust D, and not all clients
  //   (notably, Firefox and Android) will do this, thus breaking them.
  //   An example of this is the Verizon Business Services root - GTE CyberTrust
  //   and Baltimore CyberTrust roots represent old and new roots that cause
  //   issues depending on which version of OS X being used.
  //
  // - A server may be (misconfigured) to send an expired intermediate
  //   certificate. On platforms with path discovery, the graph traversal
  //   will back up to immediately before this intermediate, and then
  //   attempt an AIA fetch or retrieval from local store. However, OS X
  //   does not do this, and thus prevents access. While this is ostensibly
  //   a server misconfiguration issue, the fact that it works on other
  //   platforms is a jarring inconsistency for users.
  //
  // - When OS X trusts both C and D (simultaneously), it's possible that the
  //   version of C signed by D is signed using a weak algorithm (e.g. SHA-1),
  //   while the version of C in the trust store's signature doesn't matter.
  //   Since a 'strong' chain exists, it would be desirable to prefer this
  //   chain.
  //
  // - A variant of the above example, it may be that the version of B sent by
  //   the server is signed using a weak algorithm, but the version of B
  //   present in the AIA of A is signed using a strong algorithm. Since a
  //   'strong' chain exists, it would be desirable to prefer this chain.
  //
  // - A user keychain may contain a less desirable intermediate or root.
  //   OS X gives the user keychains higher priority than the system keychain,
  //   so it may build a weak chain.
  //
  // Because of this, the code below first attempts to validate the peer's
  // identity using the supplied chain. If it is not trusted (e.g. the OS only
  // trusts C, but the version of C signed by D was sent, and D is not trusted),
  // or if it contains a weak chain, it will begin lopping off certificates
  // from the end of the chain and attempting to verify. If a stronger, trusted
  // chain is found, it is used, otherwise, the algorithm continues until only
  // the peer's certificate remains.
  //
  // If the loop does not find a trusted chain, the loop will be repeated with
  // the keychain search order altered to give priority to the System Roots
  // keychain.
  //
  // This does cause a performance hit for these users, but only in cases where
  // OS X is building weaker chains than desired, or when it would otherwise
  // fail the connection.
  for (bool try_reordered_keychain : {false, true}) {
    ScopedCFTypeRef<CFArrayRef> scoped_alternate_keychain_search_list;
    if (TestKeychainSearchList::HasInstance()) {
      // Unit tests need to be able to hermetically simulate situations where a
      // user has an undesirable certificate in a per-user keychain.
      // Adding/Removing a Keychain using SecKeychainCreate/SecKeychainDelete
      // has global side effects, which would break other tests and processes
      // running on the same machine, so instead tests may load pre-created
      // keychains using SecKeychainOpen and then inject them through
      // TestKeychainSearchList.
      CFArrayRef keychain_search_list;
      status = TestKeychainSearchList::GetInstance()->CopySearchList(
          &keychain_search_list);
      if (status)
        return NetErrorFromOSStatus(status);
      scoped_alternate_keychain_search_list.reset(keychain_search_list);
    }
    if (try_reordered_keychain) {
      // If a TestKeychainSearchList is present, it will have already set
      // |scoped_alternate_keychain_search_list|, which will be used as the
      // basis for reordering the keychain. Otherwise, get the current keychain
      // search list and use that.
      if (!scoped_alternate_keychain_search_list) {
        CFArrayRef keychain_search_list;
        status = SecKeychainCopySearchList(&keychain_search_list);
        if (status)
          return NetErrorFromOSStatus(status);
        scoped_alternate_keychain_search_list.reset(keychain_search_list);
      }
      CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy(
          kCFAllocatorDefault,
          CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1,
          scoped_alternate_keychain_search_list.get());
      if (!mutable_keychain_search_list)
        return ERR_OUT_OF_MEMORY;
      scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list);

      SecKeychainRef keychain;
      // Get a reference to the System Roots keychain. The System Roots
      // keychain is not normally present in the keychain search list, but is
      // implicitly checked after the keychains in the search list. By
      // including it directly, force it to be checked first.  This is a gross
      // hack, but the path is known to be valid on OS X 10.9-10.11.
      status = SecKeychainOpen(
          "/System/Library/Keychains/SystemRootCertificates.keychain",
          &keychain);
      if (status)
        return NetErrorFromOSStatus(status);
      ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);

      CFArrayInsertValueAtIndex(mutable_keychain_search_list, 0, keychain);
    }

    ScopedCFTypeRef<CFMutableArrayRef> cert_array(
        x509_util::CreateSecCertificateArrayForX509Certificate(
            cert, x509_util::InvalidIntermediateBehavior::kIgnore));
    if (!cert_array) {
      verify_result->cert_status |= CERT_STATUS_INVALID;
      return ERR_CERT_INVALID;
    }

    // Beginning with the certificate chain as supplied by the server, attempt
    // to verify the chain. If a failure is encountered, trim a certificate
    // from the end (so long as one remains) and retry, in the hope of forcing
    // OS X to find a better path.
    while (CFArrayGetCount(cert_array) > 0) {
      ScopedCFTypeRef<SecTrustRef> temp_ref;
      SecTrustResultType temp_trust_result = kSecTrustResultDeny;
      ScopedCFTypeRef<CFArrayRef> temp_chain;
      CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL;

      int rv = BuildAndEvaluateSecTrustRef(
          cert_array, trust_policies, flags,
          scoped_alternate_keychain_search_list.get(), &temp_ref,
          &temp_trust_result, &temp_chain, &temp_chain_info);
      if (rv != OK)
        return rv;

      // Check to see if the path |temp_chain| has been revoked. This is less
      // than ideal to perform after path building, rather than during, because
      // there may be multiple paths to trust anchors, and only some of them
      // are revoked. Ideally, CRLSets would be part of path building, which
      // they are when using NSS (Linux) or CryptoAPI (Windows).
      //
      // The CRLSet checking is performed inside the loop in the hope that if a
      // path is revoked, it's an older path, and the only reason it was built
      // is because the server forced it (by supplying an older or less
      // desirable intermediate) or because the user had installed a
      // certificate in their Keychain forcing this path. However, this means
      // its still possible for a CRLSet block of an intermediate to prevent
      // access, even when there is a 'good' chain. To fully remedy this, a
      // solution might be to have CRLSets contain enough knowledge about what
      // the 'desired' path might be, but for the time being, the
      // implementation is kept as 'simple' as it can be.
      CRLSetResult crl_result = kCRLSetUnknown;
      if (crl_set)
        crl_result = CheckRevocationWithCRLSet(temp_chain, crl_set);
      bool untrusted = (temp_trust_result != kSecTrustResultUnspecified &&
                        temp_trust_result != kSecTrustResultProceed) ||
                       crl_result == kCRLSetRevoked;
      bool weak_chain = false;
      if (CFArrayGetCount(temp_chain) == 0) {
        // If the chain is empty, it cannot be trusted or have recoverable
        // errors.
        DCHECK(untrusted);
        DCHECK_NE(kSecTrustResultRecoverableTrustFailure, temp_trust_result);
      } else {
        weak_chain =
            IsWeakChainBasedOnHashingAlgorithms(temp_chain, temp_chain_info);
      }
      // Set the result to the current chain if:
      // - This is the first verification attempt. This ensures that if
      //   everything is awful (e.g. it may just be an untrusted cert), that
      //   what is reported is exactly what was sent by the server
      // - If the current chain is trusted, and the old chain was not trusted,
      //   then prefer this chain. This ensures that if there is at least a
      //   valid path to a trust anchor, it's preferred over reporting an error.
      // - If the current chain is trusted, and the old chain is trusted, but
      //   the old chain contained weak algorithms while the current chain only
      //   contains strong algorithms, then prefer the current chain over the
      //   old chain.
      //
      // Note: If the leaf certificate itself is weak, then the only
      // consideration is whether or not there is a trusted chain. That's
      // because no amount of path discovery will fix a weak leaf.
      if (!trust_ref || (!untrusted && (candidate_untrusted ||
                                        (candidate_weak && !weak_chain)))) {
        trust_ref = temp_ref;
        trust_result = temp_trust_result;
        completed_chain = temp_chain;
        *completed_chain_crl_result = crl_result;
        chain_info = temp_chain_info;

        candidate_untrusted = untrusted;
        candidate_weak = weak_chain;
      }
      // Short-circuit when a current, trusted chain is found.
      if (!untrusted && !weak_chain)
        break;
      CFArrayRemoveValueAtIndex(cert_array, CFArrayGetCount(cert_array) - 1);
    }
    // Short-circuit when a current, trusted chain is found.
    if (!candidate_untrusted && !candidate_weak)
      break;
  }

  if (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED)
    verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;

  if (*completed_chain_crl_result == kCRLSetRevoked)
    verify_result->cert_status |= CERT_STATUS_REVOKED;

  if (CFArrayGetCount(completed_chain) > 0) {
    CopyCertChainToVerifyResult(completed_chain, verify_result);
  }

  // As of Security Update 2012-002/OS X 10.7.4, when an RSA key < 1024 bits
  // is encountered, CSSM returns CSSMERR_TP_VERIFY_ACTION_FAILED and adds
  // CSSMERR_CSP_UNSUPPORTED_KEY_SIZE as a certificate status. Avoid mapping
  // the CSSMERR_TP_VERIFY_ACTION_FAILED to CERT_STATUS_INVALID if the only
  // error was due to an unsupported key size.
  bool policy_failed = false;
  bool policy_fail_already_mapped = false;
  bool weak_key_or_signature_algorithm = false;

  // Evaluate the results
  OSStatus cssm_result;
  switch (trust_result) {
    case kSecTrustResultUnspecified:
    case kSecTrustResultProceed:
      // Certificate chain is valid and trusted ("unspecified" indicates that
      // the user has not explicitly set a trust setting)
      break;

    // According to SecTrust.h, kSecTrustResultConfirm isn't returned on 10.5+,
    // and it is marked deprecated in the 10.9 SDK.
    case kSecTrustResultDeny:
      // Certificate chain is explicitly untrusted.
      verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
      break;

    case kSecTrustResultRecoverableTrustFailure:
      // Certificate chain has a failure that can be overridden by the user.
      status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
      if (status)
        return NetErrorFromOSStatus(status);
      if (cssm_result == CSSMERR_TP_VERIFY_ACTION_FAILED) {
        policy_failed = true;
      } else {
        verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
      }
      // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO
      // structure which can catch multiple errors from each certificate.
      for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain);
           index < chain_count; ++index) {
        if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED ||
            chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET)
          verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
        if (!IsCertStatusError(verify_result->cert_status) &&
            chain_info[index].NumStatusCodes == 0) {
          LOG(WARNING) << "chain_info[" << index << "].NumStatusCodes is 0"
                          ", chain_info[" << index << "].StatusBits is "
                       << chain_info[index].StatusBits;
        }
        for (uint32_t status_code_index = 0;
             status_code_index < chain_info[index].NumStatusCodes;
             ++status_code_index) {
          // As of OS X 10.9, attempting to verify a certificate chain that
          // contains a weak signature algorithm (MD2, MD5) in an intermediate
          // or leaf cert will be treated as a (recoverable) policy validation
          // failure, with the status code CSSMERR_TP_INVALID_CERTIFICATE
          // added to the Status Codes. Don't treat this code as an invalid
          // certificate; instead, map it to a weak key. Any truly invalid
          // certificates will have the major error (cssm_result) set to
          // CSSMERR_TP_INVALID_CERTIFICATE, rather than
          // CSSMERR_TP_VERIFY_ACTION_FAILED.
          CertStatus mapped_status = 0;
          if (policy_failed &&
              chain_info[index].StatusCodes[status_code_index] ==
                  CSSMERR_TP_INVALID_CERTIFICATE) {
            mapped_status = CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
            weak_key_or_signature_algorithm = true;
            policy_fail_already_mapped = true;
          } else if (policy_failed &&
                     (flags & CertVerifyProc::VERIFY_REV_CHECKING_ENABLED) &&
                     chain_info[index].StatusCodes[status_code_index] ==
                         CSSMERR_TP_VERIFY_ACTION_FAILED &&
                     base::mac::IsOS10_12()) {
            // On early versions of 10.12, using
            // kSecRevocationRequirePositiveResponse flag causes a
            // CSSMERR_TP_VERIFY_ACTION_FAILED status if revocation couldn't be
            // checked. (Note: even if the cert had no crlDistributionPoints or
            // OCSP AIA.) This isn't needed on later 10.12 versions, but it
            // should be mostly harmless.
            mapped_status = CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
            policy_fail_already_mapped = true;
          } else {
            mapped_status = CertStatusFromOSStatus(
                chain_info[index].StatusCodes[status_code_index]);
            if (mapped_status == CERT_STATUS_WEAK_KEY) {
              weak_key_or_signature_algorithm = true;
              policy_fail_already_mapped = true;
            }
          }
          verify_result->cert_status |= mapped_status;
        }
      }
      if (policy_failed && !policy_fail_already_mapped) {
        // If CSSMERR_TP_VERIFY_ACTION_FAILED wasn't returned due to a weak
        // key or problem checking revocation, map it back to an appropriate
        // error code.
        verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
      }
      if (!IsCertStatusError(verify_result->cert_status)) {
        LOG(ERROR) << "cssm_result=" << cssm_result;
        verify_result->cert_status |= CERT_STATUS_INVALID;
        NOTREACHED();
      }
      break;

    default:
      status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
      if (status)
        return NetErrorFromOSStatus(status);
      verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
      if (!IsCertStatusError(verify_result->cert_status)) {
        LOG(WARNING) << "trust_result=" << trust_result;
        verify_result->cert_status |= CERT_STATUS_INVALID;
      }
      break;
  }

  // Hostname validation is handled by CertVerifyProc, so mask off any errors
  // that SecTrustEvaluate may have set, as its results are not used.
  verify_result->cert_status &= ~CERT_STATUS_COMMON_NAME_INVALID;

  // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
  // compatible with Windows, which in turn implements this behavior to be
  // compatible with WinHTTP, which doesn't report this error (bug 3004).
  verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;

  AppendPublicKeyHashesAndUpdateKnownRoot(
      completed_chain, &verify_result->public_key_hashes,
      &verify_result->is_issued_by_known_root);

  if (IsCertStatusError(verify_result->cert_status))
    return MapCertStatusToNetError(verify_result->cert_status);

  return OK;
}

}  // namespace

CertVerifyProcMac::CertVerifyProcMac() {}

CertVerifyProcMac::~CertVerifyProcMac() {}

bool CertVerifyProcMac::SupportsAdditionalTrustAnchors() const {
  return false;
}

int CertVerifyProcMac::VerifyInternal(
    X509Certificate* cert,
    const std::string& hostname,
    const std::string& ocsp_response,
    int flags,
    CRLSet* crl_set,
    const CertificateList& additional_trust_anchors,
    CertVerifyResult* verify_result) {
  // Save the input state of |*verify_result|, which may be needed to re-do
  // verification with different flags.
  const CertVerifyResult input_verify_result(*verify_result);

  // Check for EV policy in leaf cert.
  std::string candidate_ev_policy_oid;
  GetCandidateEVPolicy(cert, &candidate_ev_policy_oid);

  CRLSetResult completed_chain_crl_result;
  int rv = VerifyWithGivenFlags(cert, hostname, flags, crl_set, verify_result,
                                &completed_chain_crl_result);
  if (rv != OK)
    return rv;

  if (!candidate_ev_policy_oid.empty() &&
      CheckCertChainEV(verify_result->verified_cert.get(),
                       candidate_ev_policy_oid)) {
    // EV policies check out and the verification succeeded. See if revocation
    // checking still needs to be done before it can be marked as EV.
    if (completed_chain_crl_result == kCRLSetUnknown &&
        !(flags & VERIFY_REV_CHECKING_ENABLED)) {
      // If this is an EV cert and it wasn't covered by CRLSets and revocation
      // checking wasn't already on, try again with revocation forced on.
      //
      // Restore the input state of |*verify_result|, so that the
      // re-verification starts with a clean slate.
      *verify_result = input_verify_result;
      int tmp_rv =
          VerifyWithGivenFlags(verify_result->verified_cert.get(), hostname,
                               flags | VERIFY_REV_CHECKING_ENABLED, crl_set,
                               verify_result, &completed_chain_crl_result);
      // If re-verification failed, return those results without setting EV
      // status.
      if (tmp_rv != OK)
        return tmp_rv;
      // Otherwise, fall through and add the EV status flag.
    }
    // EV cert and it was covered by CRLSets or revocation checking passed.
    verify_result->cert_status |= CERT_STATUS_IS_EV;
  }

  return OK;
}

}  // namespace net

#pragma clang diagnostic pop  // "-Wdeprecated-declarations"
