Commit 90148379 authored by tbarzic's avatar tbarzic Committed by Commit bot

Add unit tests for easyUnlockPrivate API - crypto methods

Also, adds some logic to FakeEasyUnlockClient.

BUG=407996

(note that these would have caught the crashes in bugs 404798 and 405976 :/)

Review URL: https://codereview.chromium.org/513013003

Cr-Commit-Position: refs/heads/master@{#292692}
parent 79597a80
// Copyright 2014 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 "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h"
#include "chrome/browser/extensions/extension_api_unittest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/common/extensions/api/easy_unlock_private.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_easy_unlock_client.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace {
namespace api = extensions::api::easy_unlock_private;
using extensions::api::EasyUnlockPrivateGenerateEcP256KeyPairFunction;
using extensions::api::EasyUnlockPrivatePerformECDHKeyAgreementFunction;
using extensions::api::EasyUnlockPrivateCreateSecureMessageFunction;
using extensions::api::EasyUnlockPrivateUnwrapSecureMessageFunction;
// Converts a string to a base::BinaryValue value whose buffer contains the
// string data without the trailing '\0'.
base::BinaryValue* StringToBinaryValue(const std::string value) {
return base::BinaryValue::CreateWithCopiedBuffer(value.data(),
value.length());
}
// Copies |private_key_source| and |public_key_source| to |private_key_target|
// and |public_key_target|. It is used as a callback for
// |EasyUnlockClient::GenerateEcP256KeyPair| to save the values returned by the
// method.
void CopyKeyPair(std::string* private_key_target,
std::string* public_key_target,
const std::string& private_key_source,
const std::string& public_key_source) {
*private_key_target = private_key_source;
*public_key_target = public_key_source;
}
// Copies |data_source| to |data_target|. Used as a callback to EasyUnlockClient
// methods to save the data returned by the method.
void CopyData(std::string* data_target, const std::string& data_source) {
*data_target = data_source;
}
class EasyUnlockPrivateApiTest : public extensions::ExtensionApiUnittest {
public:
EasyUnlockPrivateApiTest() {}
virtual ~EasyUnlockPrivateApiTest() {}
protected:
virtual void SetUp() OVERRIDE {
chromeos::DBusThreadManager::Initialize();
client_ = chromeos::DBusThreadManager::Get()->GetEasyUnlockClient();
extensions::ExtensionApiUnittest::SetUp();
}
virtual void TearDown() OVERRIDE {
extensions::ExtensionApiUnittest::TearDown();
chromeos::DBusThreadManager::Shutdown();
}
// Extracts a single binary value result from a run extension function
// |function| and converts it to string.
// It will fail if the extension doesn't have exactly one binary value result.
// On failure, an empty string is returned.
std::string GetSingleBinaryResultAsString(
UIThreadExtensionFunction* function) {
const base::ListValue* result_list = function->GetResultList();
if (!result_list) {
LOG(ERROR) << "Function has no result list.";
return "";
}
if (result_list->GetSize() != 1u) {
LOG(ERROR) << "Invalid number of results.";
return "";
}
const base::BinaryValue* result_binary_value;
if (!result_list->GetBinary(0, &result_binary_value) ||
!result_binary_value) {
LOG(ERROR) << "Result not a binary value.";
return "";
}
return std::string(result_binary_value->GetBuffer(),
result_binary_value->GetSize());
}
chromeos::EasyUnlockClient* client_;
};
TEST_F(EasyUnlockPrivateApiTest, GenerateEcP256KeyPair) {
scoped_refptr<EasyUnlockPrivateGenerateEcP256KeyPairFunction> function(
new EasyUnlockPrivateGenerateEcP256KeyPairFunction());
function->set_has_callback(true);
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
"[]",
browser(),
extension_function_test_utils::NONE));
const base::ListValue* result_list = function->GetResultList();
ASSERT_TRUE(result_list);
ASSERT_EQ(2u, result_list->GetSize());
const base::BinaryValue* public_key;
ASSERT_TRUE(result_list->GetBinary(0, &public_key));
ASSERT_TRUE(public_key);
const base::BinaryValue* private_key;
ASSERT_TRUE(result_list->GetBinary(1, &private_key));
ASSERT_TRUE(private_key);
EXPECT_TRUE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
std::string(private_key->GetBuffer(), private_key->GetSize()),
std::string(public_key->GetBuffer(), public_key->GetSize())));
}
TEST_F(EasyUnlockPrivateApiTest, PerformECDHKeyAgreement) {
scoped_refptr<EasyUnlockPrivatePerformECDHKeyAgreementFunction> function(
new EasyUnlockPrivatePerformECDHKeyAgreementFunction());
function->set_has_callback(true);
std::string private_key_1;
std::string public_key_1_unused;
client_->GenerateEcP256KeyPair(
base::Bind(&CopyKeyPair, &private_key_1, &public_key_1_unused));
std::string private_key_2_unused;
std::string public_key_2;
client_->GenerateEcP256KeyPair(
base::Bind(&CopyKeyPair, &private_key_2_unused, &public_key_2));
std::string expected_result;
client_->PerformECDHKeyAgreement(
private_key_1,
public_key_2,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue(private_key_1));
args->Append(StringToBinaryValue(public_key_2));
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, CreateSecureMessage) {
scoped_refptr<EasyUnlockPrivateCreateSecureMessageFunction> function(
new EasyUnlockPrivateCreateSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->CreateSecureMessage(
"PAYLOAD",
"KEY",
"ASSOCIATED_DATA",
"PUBLIC_METADATA",
"VERIFICATION_KEY_ID",
easy_unlock::kEncryptionTypeAES256CBC,
easy_unlock::kSignatureTypeHMACSHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("PAYLOAD"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
options->Set("associatedData", StringToBinaryValue("ASSOCIATED_DATA"));
options->Set("publicMetadata", StringToBinaryValue("PUBLIC_METADATA"));
options->Set("verificationKeyId",
StringToBinaryValue("VERIFICATION_KEY_ID"));
options->SetString(
"encryptType",
api::ToString(api::ENCRYPTION_TYPE_AES_256_CBC));
options->SetString(
"signType",
api::ToString(api::SIGNATURE_TYPE_HMAC_SHA256));
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, CreateSecureMessage_EmptyOptions) {
scoped_refptr<EasyUnlockPrivateCreateSecureMessageFunction> function(
new EasyUnlockPrivateCreateSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->CreateSecureMessage(
"PAYLOAD",
"KEY",
"",
"",
"",
easy_unlock::kEncryptionTypeNone,
easy_unlock::kSignatureTypeHMACSHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("PAYLOAD"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, CreateSecureMessage_AsymmetricSign) {
scoped_refptr<EasyUnlockPrivateCreateSecureMessageFunction> function(
new EasyUnlockPrivateCreateSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->CreateSecureMessage(
"PAYLOAD",
"KEY",
"ASSOCIATED_DATA",
"",
"VERIFICATION_KEY_ID",
easy_unlock::kEncryptionTypeNone,
easy_unlock::kSignatureTypeECDSAP256SHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("PAYLOAD"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
options->Set("associatedData",
StringToBinaryValue("ASSOCIATED_DATA"));
options->Set("verificationKeyId",
StringToBinaryValue("VERIFICATION_KEY_ID"));
options->SetString(
"signType",
api::ToString(api::SIGNATURE_TYPE_ECDSA_P256_SHA256));
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, UnwrapSecureMessage) {
scoped_refptr<EasyUnlockPrivateUnwrapSecureMessageFunction> function(
new EasyUnlockPrivateUnwrapSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->UnwrapSecureMessage(
"PAYLOAD",
"KEY",
"ASSOCIATED_DATA",
easy_unlock::kEncryptionTypeAES256CBC,
easy_unlock::kSignatureTypeHMACSHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("PAYLOAD"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
options->Set("associatedData", StringToBinaryValue("ASSOCIATED_DATA"));
options->SetString(
"encryptType",
api::ToString(api::ENCRYPTION_TYPE_AES_256_CBC));
options->SetString(
"signType",
api::ToString(api::SIGNATURE_TYPE_HMAC_SHA256));
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, UnwrapSecureMessage_EmptyOptions) {
scoped_refptr<EasyUnlockPrivateUnwrapSecureMessageFunction> function(
new EasyUnlockPrivateUnwrapSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->UnwrapSecureMessage(
"MESSAGE",
"KEY",
"",
easy_unlock::kEncryptionTypeNone,
easy_unlock::kSignatureTypeHMACSHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("MESSAGE"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
TEST_F(EasyUnlockPrivateApiTest, UnwrapSecureMessage_AsymmetricSign) {
scoped_refptr<EasyUnlockPrivateUnwrapSecureMessageFunction> function(
new EasyUnlockPrivateUnwrapSecureMessageFunction());
function->set_has_callback(true);
std::string expected_result;
client_->UnwrapSecureMessage(
"MESSAGE",
"KEY",
"ASSOCIATED_DATA",
easy_unlock::kEncryptionTypeNone,
easy_unlock::kSignatureTypeECDSAP256SHA256,
base::Bind(&CopyData, &expected_result));
ASSERT_GT(expected_result.length(), 0u);
scoped_ptr<base::ListValue> args(new base::ListValue);
args->Append(StringToBinaryValue("MESSAGE"));
args->Append(StringToBinaryValue("KEY"));
base::DictionaryValue* options = new base::DictionaryValue();
args->Append(options);
options->Set("associatedData",
StringToBinaryValue("ASSOCIATED_DATA"));
options->SetString(
"signType",
api::ToString(api::SIGNATURE_TYPE_ECDSA_P256_SHA256));
ASSERT_TRUE(extension_function_test_utils::RunFunction(
function.get(),
args.Pass(),
browser(),
extension_function_test_utils::NONE));
EXPECT_EQ(expected_result, GetSingleBinaryResultAsString(function));
}
} // namespace
......@@ -858,6 +858,7 @@
'browser/extensions/api/dial/dial_device_data_unittest.cc',
'browser/extensions/api/dial/dial_registry_unittest.cc',
'browser/extensions/api/dial/dial_service_unittest.cc',
'browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc',
'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc',
'browser/extensions/api/experience_sampling_private/experience_sampling_private_api_unittest.cc',
'browser/extensions/api/extension_action/extension_action_prefs_unittest.cc',
......
......@@ -552,6 +552,7 @@
'dbus/blocking_method_caller_unittest.cc',
'dbus/cros_disks_client_unittest.cc',
'dbus/dbus_client_bundle_unittest.cc',
'dbus/fake_easy_unlock_client_unittest.cc',
'dbus/gsm_sms_client_unittest.cc',
'dbus/introspectable_client_unittest.cc',
'dbus/modem_messaging_client_unittest.cc',
......
......@@ -2,11 +2,55 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/json/json_string_value_serializer.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/fake_easy_unlock_client.h"
namespace {
// Keys generated using |GenerateEcP256KeyPair| are in the following format:
// "{<key_type>: <key_pair_index>}".
// <key_pair_index> is an integer identifying
// the key pair.
// <key_type> specifies whether the key is public or private. It can have one
// of the following valies:
const char kEc256PrivateKeyKey[] = "ec_p256_private_key";
const char kEc256PublicKeyKey[] = "ec_p256_public_key";
// Extracts key pair index from a key in format "<key_type>: <key_pair_index>}".
int ExtractKeyPairIndexFromKey(const std::string& key,
const std::string& key_type) {
JSONStringValueSerializer serializer(key);
scoped_ptr<base::Value> json_value(serializer.Deserialize(NULL, NULL));
if (!json_value)
return -1;
base::DictionaryValue* json_dictionary = NULL;
if (!json_value->GetAsDictionary(&json_dictionary))
return -1;
int key_pair_index = -1;
if (!json_dictionary->GetInteger(key_type, &key_pair_index))
return -1;
return key_pair_index;
}
} // namespace
namespace chromeos {
FakeEasyUnlockClient::FakeEasyUnlockClient() {}
// static
bool FakeEasyUnlockClient::IsEcP256KeyPair(const std::string& private_key,
const std::string& public_key) {
int private_key_index =
ExtractKeyPairIndexFromKey(private_key, kEc256PrivateKeyKey);
int public_key_index =
ExtractKeyPairIndexFromKey(public_key, kEc256PublicKeyKey);
return private_key_index > 0 && public_key_index == private_key_index;
}
FakeEasyUnlockClient::FakeEasyUnlockClient() : generated_keys_count_(0) {}
FakeEasyUnlockClient::~FakeEasyUnlockClient() {}
......@@ -14,32 +58,92 @@ void FakeEasyUnlockClient::Init(dbus::Bus* bus) {}
void FakeEasyUnlockClient::GenerateEcP256KeyPair(
const KeyPairCallback& callback) {
++generated_keys_count_;
callback.Run(
base::StringPrintf("{\"%s\": %d}",
kEc256PrivateKeyKey,
generated_keys_count_),
base::StringPrintf("{\"%s\": %d}",
kEc256PublicKeyKey,
generated_keys_count_));
}
void FakeEasyUnlockClient::PerformECDHKeyAgreement(
const std::string& private_key,
const std::string& public_key,
const DataCallback& callback) {
int private_key_index =
ExtractKeyPairIndexFromKey(private_key, kEc256PrivateKeyKey);
int public_key_index =
ExtractKeyPairIndexFromKey(public_key, kEc256PublicKeyKey);
if (private_key_index < 0 || public_key_index < 0) {
callback.Run("");
return;
}
// ECDH key agreement should be commutative in respect to key pairs to which
// used keys belong, i.e. (key_pair[1].private_key, key_pair[2].public_key)
// and (key_pair[2].private_key, key_pair[1].public_key) should produce the
// same shared key. To achieve this, identify the created key by sum and
// product of the used key pairs.
callback.Run(base::StringPrintf(
"{\"secret_key\": [%d, %d]}",
private_key_index + public_key_index,
private_key_index * public_key_index));
}
void FakeEasyUnlockClient::CreateSecureMessage(
const std::string& payload,
const std::string& secret_key,
const std::string& key,
const std::string& associated_data,
const std::string& public_metadata,
const std::string& verification_key_id,
const std::string& encryption_type,
const std::string& signature_type,
const DataCallback& callback) {
callback.Run(base::StringPrintf(
"{\"securemessage\": {"
"\"payload\": \"%s\","
"\"key\": \"%s\","
"\"associated_data\": \"%s\","
"\"public_metadata\": \"%s\","
"\"verification_key_id\": \"%s\","
"\"encryption_type\": \"%s\","
"\"signature_type\": \"%s\""
"}}",
payload.c_str(),
key.c_str(),
associated_data.c_str(),
public_metadata.c_str(),
verification_key_id.c_str(),
encryption_type.c_str(),
signature_type.c_str()));
}
void FakeEasyUnlockClient::UnwrapSecureMessage(
const std::string& message,
const std::string& secret_key,
const std::string& key,
const std::string& associated_data,
const std::string& encryption_type,
const std::string& signature_type,
const DataCallback& callback) {
// TODO(tbarzic): Verify that |message| is in the format returned by
// |CreateSecureMessage| and extract payload, metadata and
// verification_key_id from there.
callback.Run(base::StringPrintf(
"{\"unwrapped_securemessage\": {"
"\"message\": \"%s\","
"\"key\": \"%s\","
"\"associated_data\": \"%s\","
"\"encryption_type\": \"%s\","
"\"signature_type\": \"%s\""
"}}",
message.c_str(),
key.c_str(),
associated_data.c_str(),
encryption_type.c_str(),
signature_type.c_str()));
}
} // namespace chromeos
......@@ -14,6 +14,11 @@ namespace chromeos {
// A fake implemetation of EasyUnlockClient.
class CHROMEOS_EXPORT FakeEasyUnlockClient : public EasyUnlockClient {
public:
// Tests if the provided keys belong to the same (fake) EC P256 key pair
// generated by |this|.
static bool IsEcP256KeyPair(const std::string& private_key,
const std::string& public_key);
FakeEasyUnlockClient();
virtual ~FakeEasyUnlockClient();
......@@ -24,7 +29,7 @@ class CHROMEOS_EXPORT FakeEasyUnlockClient : public EasyUnlockClient {
const std::string& public_key,
const DataCallback& callback) OVERRIDE;
virtual void CreateSecureMessage(const std::string& payload,
const std::string& secret_key,
const std::string& key,
const std::string& associated_data,
const std::string& public_metadata,
const std::string& verification_key_id,
......@@ -32,13 +37,15 @@ class CHROMEOS_EXPORT FakeEasyUnlockClient : public EasyUnlockClient {
const std::string& signature_type,
const DataCallback& callback) OVERRIDE;
virtual void UnwrapSecureMessage(const std::string& message,
const std::string& secret_key,
const std::string& key,
const std::string& associated_data,
const std::string& encryption_type,
const std::string& signature_type,
const DataCallback& callback) OVERRIDE;
private:
int generated_keys_count_;
DISALLOW_COPY_AND_ASSIGN(FakeEasyUnlockClient);
};
......
// Copyright 2014 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 "chromeos/dbus/fake_easy_unlock_client.h"
#include <string>
#include "base/bind.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// Callback for |GenerateEcP256KeyPair| method. Saves keys returned by the
// method in |private_key_target| and |public_key_target|.
void RecordKeyPair(std::string* private_key_target,
std::string* public_key_target,
const std::string& private_key_source,
const std::string& public_key_source) {
*private_key_target = private_key_source;
*public_key_target = public_key_source;
}
// Callback for |EasyUnlockClient| methods that return a single piece of data.
// It saves the returned data in |data_target|.
void RecordData(std::string* data_target,
const std::string& data_source) {
*data_target = data_source;
}
TEST(FakeEasyUnlockClientTest, GenerateEcP256KeyPair) {
chromeos::FakeEasyUnlockClient client;
std::string private_key_1;
std::string public_key_1;
client.GenerateEcP256KeyPair(
base::Bind(&RecordKeyPair, &private_key_1, &public_key_1));
ASSERT_EQ("{\"ec_p256_private_key\": 1}", private_key_1);
ASSERT_EQ("{\"ec_p256_public_key\": 1}", public_key_1);
std::string private_key_2;
std::string public_key_2;
client.GenerateEcP256KeyPair(
base::Bind(&RecordKeyPair, &private_key_2, &public_key_2));
ASSERT_EQ("{\"ec_p256_private_key\": 2}", private_key_2);
ASSERT_EQ("{\"ec_p256_public_key\": 2}", public_key_2);
EXPECT_NE(private_key_1, private_key_2);
EXPECT_NE(public_key_1, public_key_2);
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair) {
ASSERT_TRUE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_private_key\": 12}",
"{\"ec_p256_public_key\": 12}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeysFromDiffrentPairs) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_private_key\": 12}",
"{\"ec_p256_public_key\": 34}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_KeyOrderSwitched) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_public_key\": 34}",
"{\"ec_p256_private_key\": 34}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidFormat) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"\"ec_p256_private_key\": 12",
"{\"ec_p256_public_key\": 12}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidFormat) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_private_key\": 12}",
"\"ec_p256_public_key\": 12"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PrivateKeyInvalidDictKey) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"invalid\": 12}",
"{\"ec_p256_public_key\": 12}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_PublicKeyInvalidDictKey) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_private_key\": 12}",
"{\"invalid\": 12}"));
}
TEST(FakeEasyUnlockClientTest, IsEcP256KeyPair_InvalidDictValues) {
ASSERT_FALSE(chromeos::FakeEasyUnlockClient::IsEcP256KeyPair(
"{\"ec_p256_private_key\": \"12\"}",
"{\"ec_p256_public_key\": \"12\"}"));
}
// Verifies the fake |PerformECDHKeyAgreement| method is symetric in respect to
// key pairs from which private and public key used in the key agreement
// originate.
TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementSuccess) {
chromeos::FakeEasyUnlockClient client;
// (Fake) key pairs used in the test to generate fake shared keys.
const std::string private_key_1 = "{\"ec_p256_private_key\": 32}";
const std::string public_key_1 = "{\"ec_p256_public_key\": 32}";
const std::string private_key_2 = "{\"ec_p256_private_key\": 352}";
const std::string public_key_2 = "{\"ec_p256_public_key\": 352}";
const std::string private_key_3 = "{\"ec_p256_private_key\": 432}";
const std::string public_key_3 = "{\"ec_p256_public_key\": 432}";
// Generate shared key for key pairs 1 and 2, using private key from the
// second key pair and public key from the first key pair.
std::string shared_key_1;
client.PerformECDHKeyAgreement(private_key_2,
public_key_1,
base::Bind(&RecordData, &shared_key_1));
EXPECT_FALSE(shared_key_1.empty());
// Generate shared key for key pairs 1 and 2, using private key from the
// first key pair and public key from the second key pair.
std::string shared_key_2;
client.PerformECDHKeyAgreement(private_key_1,
public_key_2,
base::Bind(&RecordData, &shared_key_2));
EXPECT_FALSE(shared_key_2.empty());
// The generated keys should be equal. They were generated using keys from
// the same key pairs, even though key pairs from which private and public key
// originate were switched.
EXPECT_EQ(shared_key_1, shared_key_2);
// Generate a key using key pairs 1 and 3.
std::string shared_key_3;
client.PerformECDHKeyAgreement(private_key_1,
public_key_3,
base::Bind(&RecordData, &shared_key_3));
EXPECT_FALSE(shared_key_3.empty());
// The new key should be different from the previously generated ones, since
// the used key pairs are different.
EXPECT_NE(shared_key_3, shared_key_1);
EXPECT_NE(shared_key_3, shared_key_1);
}
TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyOrderSwitched) {
chromeos::FakeEasyUnlockClient client;
const std::string private_key = "{\"ec_p256_private_key\": 415}";
const std::string public_key = "{\"ec_p256_public_key\": 345}";
std::string shared_key;
client.PerformECDHKeyAgreement(public_key,
private_key,
base::Bind(&RecordData, &shared_key));
EXPECT_TRUE(shared_key.empty());
}
TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictKeyInvalid) {
chromeos::FakeEasyUnlockClient client;
const std::string private_key = "{\"ec_p256_private_key_invalid\": 415}";
const std::string public_key = "{\"ec_p256_public_key_invalid\": 345}";
std::string shared_key;
client.PerformECDHKeyAgreement(private_key,
public_key,
base::Bind(&RecordData, &shared_key));
EXPECT_TRUE(shared_key.empty());
}
TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyDictValueInvalid) {
chromeos::FakeEasyUnlockClient client;
const std::string private_key = "{\"ec_p256_private_key\": 415}";
const std::string public_key = "{\"ec_p256_public_key\": \"345__\"}";
std::string shared_key;
client.PerformECDHKeyAgreement(private_key,
public_key,
base::Bind(&RecordData, &shared_key));
EXPECT_TRUE(shared_key.empty());
}
TEST(FakeEasyUnlockClientTest, ECDHKeyAgreementFailsIfKeyFormatInvalid) {
chromeos::FakeEasyUnlockClient client;
const std::string private_key = "invalid";
const std::string public_key = "{\"ec_p256_public_key\": 345}";
std::string shared_key;
client.PerformECDHKeyAgreement(private_key,
public_key,
base::Bind(&RecordData, &shared_key));
EXPECT_TRUE(shared_key.empty());
}
TEST(FakeEasyUnlockClientTest, CreateSecureMessage) {
chromeos::FakeEasyUnlockClient client;
std::string message;
client.CreateSecureMessage(
"PAYLOAD",
"KEY",
"ASSOCIATED_DATA",
"PUBLIC_METADATA",
"VERIFICATION_KEY_ID",
"ENCRYPTION_TYPE",
"SIGNATURE_TYPE",
base::Bind(&RecordData, &message));
const std::string expected_message(
"{\"securemessage\": {"
"\"payload\": \"PAYLOAD\","
"\"key\": \"KEY\","
"\"associated_data\": \"ASSOCIATED_DATA\","
"\"public_metadata\": \"PUBLIC_METADATA\","
"\"verification_key_id\": \"VERIFICATION_KEY_ID\","
"\"encryption_type\": \"ENCRYPTION_TYPE\","
"\"signature_type\": \"SIGNATURE_TYPE\"}"
"}");
ASSERT_EQ(expected_message, message);
}
TEST(FakeEasyUnlockClientTest, UnwrapSecureMessage) {
chromeos::FakeEasyUnlockClient client;
std::string message;
client.UnwrapSecureMessage(
"MESSAGE",
"KEY",
"ASSOCIATED_DATA",
"ENCRYPTION_TYPE",
"SIGNATURE_TYPE",
base::Bind(&RecordData, &message));
const std::string expected_message(
"{\"unwrapped_securemessage\": {"
"\"message\": \"MESSAGE\","
"\"key\": \"KEY\","
"\"associated_data\": \"ASSOCIATED_DATA\","
"\"encryption_type\": \"ENCRYPTION_TYPE\","
"\"signature_type\": \"SIGNATURE_TYPE\"}"
"}");
ASSERT_EQ(expected_message, message);
}
} // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment