blob: 7fd06bf91119bf004167cb5411152bc2b7d00828 [file] [log] [blame]
// Copyright 2019 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 "chrome/browser/sharing/vapid_key_manager.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/sharing/features.h"
#include "chrome/browser/sharing/sharing_sync_preference.h"
#include "components/sync/driver/test_sync_service.h"
#include "components/sync_device_info/fake_device_info_sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "crypto/ec_private_key.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class VapidKeyManagerTest : public testing::Test {
protected:
VapidKeyManagerTest()
: sharing_sync_preference_(&prefs_, &fake_device_info_sync_service_),
vapid_key_manager_(&sharing_sync_preference_, &test_sync_service_) {
SharingSyncPreference::RegisterProfilePrefs(prefs_.registry());
}
base::test::ScopedFeatureList scoped_feature_list_;
sync_preferences::TestingPrefServiceSyncable prefs_;
syncer::FakeDeviceInfoSyncService fake_device_info_sync_service_;
SharingSyncPreference sharing_sync_preference_;
syncer::TestSyncService test_sync_service_;
VapidKeyManager vapid_key_manager_;
};
} // namespace
TEST_F(VapidKeyManagerTest, CreateKeyFlow) {
scoped_feature_list_.InitAndDisableFeature(kSharingDeriveVapidKey);
// No keys stored in preferences.
EXPECT_EQ(base::nullopt, sharing_sync_preference_.GetVapidKey());
// Expected to create new keys and store in preferences.
crypto::ECPrivateKey* key_1 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_1);
std::vector<uint8_t> key_info;
EXPECT_TRUE(key_1->ExportPrivateKey(&key_info));
EXPECT_EQ(key_info, sharing_sync_preference_.GetVapidKey());
// Expected to return same key when called again.
crypto::ECPrivateKey* key_2 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_2);
std::vector<uint8_t> key_info_2;
EXPECT_TRUE(key_2->ExportPrivateKey(&key_info_2));
EXPECT_EQ(key_info, key_info_2);
}
TEST_F(VapidKeyManagerTest, ReadFromPreferenceFlow) {
scoped_feature_list_.InitAndDisableFeature(kSharingDeriveVapidKey);
// VAPID key already stored in preferences.
auto preference_key_1 = crypto::ECPrivateKey::Create();
ASSERT_TRUE(preference_key_1);
std::vector<uint8_t> preference_key_info_1;
ASSERT_TRUE(preference_key_1->ExportPrivateKey(&preference_key_info_1));
sharing_sync_preference_.SetVapidKey(preference_key_info_1);
// Expected to return key stored in preferences.
crypto::ECPrivateKey* key_1 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_1);
std::vector<uint8_t> key_info_1;
EXPECT_TRUE(key_1->ExportPrivateKey(&key_info_1));
EXPECT_EQ(preference_key_info_1, key_info_1);
// Change VAPID key in sync prefernece.
auto preference_key_2 = crypto::ECPrivateKey::Create();
ASSERT_TRUE(preference_key_2);
std::vector<uint8_t> preference_key_info_2;
ASSERT_TRUE(preference_key_2->ExportPrivateKey(&preference_key_info_2));
sharing_sync_preference_.SetVapidKey(preference_key_info_2);
// Refresh local cache with new key in sync preference.
EXPECT_TRUE(vapid_key_manager_.RefreshCachedKey());
crypto::ECPrivateKey* key_2 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_2);
std::vector<uint8_t> key_info_2;
EXPECT_TRUE(key_2->ExportPrivateKey(&key_info_2));
EXPECT_EQ(preference_key_info_2, key_info_2);
}
TEST_F(VapidKeyManagerTest, DeriveKeyFlow) {
scoped_feature_list_.InitAndEnableFeature(kSharingDeriveVapidKey);
test_sync_service_.SetExperimentalAuthenticationKey(
crypto::ECPrivateKey::Create());
// No keys stored in preferences.
EXPECT_EQ(base::nullopt, sharing_sync_preference_.GetVapidKey());
// Expected to derive key from sync secret and store in sync preferences.
crypto::ECPrivateKey* key_1 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_1);
std::vector<uint8_t> key_info_1;
EXPECT_TRUE(key_1->ExportPrivateKey(&key_info_1));
EXPECT_EQ(key_info_1, sharing_sync_preference_.GetVapidKey());
// Change sync secret.
test_sync_service_.SetExperimentalAuthenticationKey(
crypto::ECPrivateKey::Create());
// Refresh local cache with new sync secret.
EXPECT_TRUE(vapid_key_manager_.RefreshCachedKey());
crypto::ECPrivateKey* key_2 = vapid_key_manager_.GetOrCreateKey();
EXPECT_TRUE(key_2);
std::vector<uint8_t> key_info_2;
EXPECT_TRUE(key_2->ExportPrivateKey(&key_info_2));
EXPECT_NE(key_info_1, key_info_2);
}