blob: ca97034aea6c05331930e6fcbfa8199db534ed30 [file] [log] [blame]
// 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/default_server_bound_cert_store.h"
#include <map>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
class MockPersistentStore
: public DefaultServerBoundCertStore::PersistentStore {
public:
MockPersistentStore();
// DefaultServerBoundCertStore::PersistentStore implementation.
virtual bool Load(
std::vector<DefaultServerBoundCertStore::ServerBoundCert*>* certs)
override;
virtual void AddServerBoundCert(
const DefaultServerBoundCertStore::ServerBoundCert& cert) override;
virtual void DeleteServerBoundCert(
const DefaultServerBoundCertStore::ServerBoundCert& cert) override;
virtual void SetForceKeepSessionState() override;
virtual void Flush(const base::Closure& completion_task) override;
protected:
virtual ~MockPersistentStore();
private:
typedef std::map<std::string, DefaultServerBoundCertStore::ServerBoundCert>
ServerBoundCertMap;
ServerBoundCertMap origin_certs_;
};
MockPersistentStore::MockPersistentStore() {}
bool MockPersistentStore::Load(
std::vector<DefaultServerBoundCertStore::ServerBoundCert*>* certs) {
ServerBoundCertMap::iterator it;
for (it = origin_certs_.begin(); it != origin_certs_.end(); ++it) {
certs->push_back(
new DefaultServerBoundCertStore::ServerBoundCert(it->second));
}
return true;
}
void MockPersistentStore::AddServerBoundCert(
const DefaultServerBoundCertStore::ServerBoundCert& cert) {
origin_certs_[cert.server_identifier()] = cert;
}
void MockPersistentStore::DeleteServerBoundCert(
const DefaultServerBoundCertStore::ServerBoundCert& cert) {
origin_certs_.erase(cert.server_identifier());
}
void MockPersistentStore::SetForceKeepSessionState() {}
void MockPersistentStore::Flush(const base::Closure& completion_task) {
NOTREACHED();
}
MockPersistentStore::~MockPersistentStore() {}
TEST(DefaultServerBoundCertStoreTest, TestLoading) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
persistent_store->AddServerBoundCert(
DefaultServerBoundCertStore::ServerBoundCert(
"google.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"a", "b"));
persistent_store->AddServerBoundCert(
DefaultServerBoundCertStore::ServerBoundCert(
"verisign.com",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
base::Time(),
"c", "d"));
// Make sure certs load properly.
DefaultServerBoundCertStore store(persistent_store.get());
EXPECT_EQ(2, store.GetCertCount());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"e", "f");
EXPECT_EQ(2, store.GetCertCount());
store.SetServerBoundCert(
"twitter.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"g", "h");
EXPECT_EQ(3, store.GetCertCount());
}
TEST(DefaultServerBoundCertStoreTest, TestSettingAndGetting) {
DefaultServerBoundCertStore store(NULL);
SSLClientCertType type;
base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
EXPECT_FALSE(store.GetServerBoundCert("verisign.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_TRUE(private_key.empty());
EXPECT_TRUE(cert.empty());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time::FromInternalValue(123),
base::Time::FromInternalValue(456),
"i", "j");
EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type);
EXPECT_EQ(123, creation_time.ToInternalValue());
EXPECT_EQ(456, expiration_time.ToInternalValue());
EXPECT_EQ("i", private_key);
EXPECT_EQ("j", cert);
}
TEST(DefaultServerBoundCertStoreTest, TestDuplicateCerts) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
DefaultServerBoundCertStore store(persistent_store.get());
SSLClientCertType type;
base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time::FromInternalValue(123),
base::Time::FromInternalValue(1234),
"a", "b");
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_ECDSA_SIGN,
base::Time::FromInternalValue(456),
base::Time::FromInternalValue(4567),
"c", "d");
EXPECT_EQ(1, store.GetCertCount());
EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type);
EXPECT_EQ(456, creation_time.ToInternalValue());
EXPECT_EQ(4567, expiration_time.ToInternalValue());
EXPECT_EQ("c", private_key);
EXPECT_EQ("d", cert);
}
TEST(DefaultServerBoundCertStoreTest, TestDeleteAll) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
DefaultServerBoundCertStore store(persistent_store.get());
EXPECT_EQ(0, store.GetCertCount());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"a", "b");
store.SetServerBoundCert(
"google.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"c", "d");
store.SetServerBoundCert(
"harvard.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"e", "f");
EXPECT_EQ(3, store.GetCertCount());
store.DeleteAll();
EXPECT_EQ(0, store.GetCertCount());
}
TEST(DefaultServerBoundCertStoreTest, TestDelete) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
DefaultServerBoundCertStore store(persistent_store.get());
SSLClientCertType type;
base::Time creation_time;
base::Time expiration_time;
std::string private_key, cert;
EXPECT_EQ(0, store.GetCertCount());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"a", "b");
store.SetServerBoundCert(
"google.com",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
base::Time(),
"c", "d");
EXPECT_EQ(2, store.GetCertCount());
store.DeleteServerBoundCert("verisign.com");
EXPECT_EQ(1, store.GetCertCount());
EXPECT_FALSE(store.GetServerBoundCert("verisign.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
EXPECT_TRUE(store.GetServerBoundCert("google.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
store.DeleteServerBoundCert("google.com");
EXPECT_EQ(0, store.GetCertCount());
EXPECT_FALSE(store.GetServerBoundCert("google.com",
&type,
&creation_time,
&expiration_time,
&private_key,
&cert));
}
TEST(DefaultServerBoundCertStoreTest, TestGetAll) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
DefaultServerBoundCertStore store(persistent_store.get());
EXPECT_EQ(0, store.GetCertCount());
store.SetServerBoundCert(
"verisign.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"a", "b");
store.SetServerBoundCert(
"google.com",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
base::Time(),
"c", "d");
store.SetServerBoundCert(
"harvard.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"e", "f");
store.SetServerBoundCert(
"mit.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"g", "h");
EXPECT_EQ(4, store.GetCertCount());
ServerBoundCertStore::ServerBoundCertList certs;
store.GetAllServerBoundCerts(&certs);
EXPECT_EQ(4u, certs.size());
}
TEST(DefaultServerBoundCertStoreTest, TestInitializeFrom) {
scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
DefaultServerBoundCertStore store(persistent_store.get());
store.SetServerBoundCert(
"preexisting.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"a", "b");
store.SetServerBoundCert(
"both.com",
CLIENT_CERT_ECDSA_SIGN,
base::Time(),
base::Time(),
"c", "d");
EXPECT_EQ(2, store.GetCertCount());
ServerBoundCertStore::ServerBoundCertList source_certs;
source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
"both.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
// Key differs from above to test that existing entries are overwritten.
"e", "f"));
source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
"copied.com",
CLIENT_CERT_RSA_SIGN,
base::Time(),
base::Time(),
"g", "h"));
store.InitializeFrom(source_certs);
EXPECT_EQ(3, store.GetCertCount());
ServerBoundCertStore::ServerBoundCertList certs;
store.GetAllServerBoundCerts(&certs);
ASSERT_EQ(3u, certs.size());
ServerBoundCertStore::ServerBoundCertList::iterator cert = certs.begin();
EXPECT_EQ("both.com", cert->server_identifier());
EXPECT_EQ("e", cert->private_key());
++cert;
EXPECT_EQ("copied.com", cert->server_identifier());
EXPECT_EQ("g", cert->private_key());
++cert;
EXPECT_EQ("preexisting.com", cert->server_identifier());
EXPECT_EQ("a", cert->private_key());
}
} // namespace net