// 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/base/ev_root_ca_metadata.h"

#include "net/base/cert_test_util.h"
#include "net/base/x509_cert_types.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(USE_NSS)
#include "crypto/scoped_nss_types.h"
#endif

namespace net {

namespace {

#if defined(USE_NSS) || defined(OS_WIN)
static const char kVerisignPolicy[] = "2.16.840.1.113733.1.7.23.6";
static const char kThawtePolicy[] = "2.16.840.1.113733.1.7.48.1";
static const char kFakePolicy[] = "2.16.840.1.42";
static const SHA1HashValue kVerisignFingerprint =
    { { 0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
        0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2 } };
static const SHA1HashValue kFakeFingerprint =
    { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 } };

class EVOidData {
 public:
  EVOidData();
  bool Init();

  EVRootCAMetadata::PolicyOID verisign_policy;
  EVRootCAMetadata::PolicyOID thawte_policy;
  EVRootCAMetadata::PolicyOID fake_policy;
};

#endif  // defined(USE_NSS) || defined(OS_WIN)

#if defined(USE_NSS)

SECOidTag RegisterOID(PLArenaPool* arena, const char* oid_string) {
  SECOidData oid_data;
  memset(&oid_data, 0, sizeof(oid_data));
  oid_data.offset = SEC_OID_UNKNOWN;
  oid_data.desc = oid_string;
  oid_data.mechanism = CKM_INVALID_MECHANISM;
  oid_data.supportedExtension = INVALID_CERT_EXTENSION;

  SECStatus rv = SEC_StringToOID(arena, &oid_data.oid, oid_string, 0);
  if (rv != SECSuccess)
    return SEC_OID_UNKNOWN;

  return SECOID_AddEntry(&oid_data);
}

EVOidData::EVOidData()
    : verisign_policy(SEC_OID_UNKNOWN),
      thawte_policy(SEC_OID_UNKNOWN),
      fake_policy(SEC_OID_UNKNOWN) {
}

bool EVOidData::Init() {
  crypto::ScopedPLArenaPool pool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
  if (!pool.get())
    return false;

  verisign_policy = RegisterOID(pool.get(), kVerisignPolicy);
  thawte_policy = RegisterOID(pool.get(), kThawtePolicy);
  fake_policy = RegisterOID(pool.get(), kFakePolicy);

  return verisign_policy != SEC_OID_UNKNOWN &&
         thawte_policy != SEC_OID_UNKNOWN &&
         fake_policy != SEC_OID_UNKNOWN;
}

#elif defined(OS_WIN)

EVOidData::EVOidData()
    : verisign_policy(kVerisignPolicy),
      thawte_policy(kThawtePolicy),
      fake_policy(kFakePolicy) {
}

bool EVOidData::Init() {
  return true;
}

#endif

#if defined(USE_NSS) || defined(OS_WIN)

class EVRootCAMetadataTest : public testing::Test {
 protected:
  virtual void SetUp() override {
    ASSERT_TRUE(ev_oid_data.Init());
  }

  EVOidData ev_oid_data;
};

TEST_F(EVRootCAMetadataTest, Basic) {
  EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance());

  EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.verisign_policy));
  EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
  EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
                                          ev_oid_data.verisign_policy));
  EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint,
                                           ev_oid_data.verisign_policy));
  EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
                                           ev_oid_data.fake_policy));
  EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kVerisignFingerprint,
                                           ev_oid_data.thawte_policy));
}

TEST_F(EVRootCAMetadataTest, AddRemove) {
  EVRootCAMetadata* ev_metadata(EVRootCAMetadata::GetInstance());

  EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
  EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint,
                                           ev_oid_data.fake_policy));

  {
    ScopedTestEVPolicy test_ev_policy(ev_metadata, kFakeFingerprint,
                                      kFakePolicy);

    EXPECT_TRUE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
    EXPECT_TRUE(ev_metadata->HasEVPolicyOID(kFakeFingerprint,
                                            ev_oid_data.fake_policy));
  }

  EXPECT_FALSE(ev_metadata->IsEVPolicyOID(ev_oid_data.fake_policy));
  EXPECT_FALSE(ev_metadata->HasEVPolicyOID(kFakeFingerprint,
                                           ev_oid_data.fake_policy));
}

#endif  // defined(USE_NSS) || defined(OS_WIN)

}  // namespace

}  // namespace net
