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

#include "net/cert/x509_cert_types.h"
#include "net/test/cert_test_util.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)
const char kVerisignPolicy[] = "2.16.840.1.113733.1.7.23.6";
const char kThawtePolicy[] = "2.16.840.1.113733.1.7.48.1";
const char kFakePolicy[] = "2.16.840.1.42";
const SHA1HashValue kVerisignFingerprint =
    { { 0x74, 0x2c, 0x31, 0x92, 0xe6, 0x07, 0xe4, 0x24, 0xeb, 0x45,
        0x49, 0x54, 0x2b, 0xe1, 0xbb, 0xc5, 0x3e, 0x61, 0x74, 0xe2 } };
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
