You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1175 lines
43 KiB
1175 lines
43 KiB
// |
|
// Copyright (C) 2015 The Android Open Source Project |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
// |
|
|
|
#include <string> |
|
|
|
#include <base/bind.h> |
|
#include <base/callback.h> |
|
#include <base/message_loop/message_loop.h> |
|
#include <base/run_loop.h> |
|
#include <brillo/bind_lambda.h> |
|
#include <brillo/data_encoding.h> |
|
#include <brillo/http/http_transport_fake.h> |
|
#include <brillo/mime_utils.h> |
|
#include <gmock/gmock.h> |
|
#include <gtest/gtest.h> |
|
|
|
#include "attestation/common/attestation_ca.pb.h" |
|
#include "attestation/common/mock_crypto_utility.h" |
|
#include "attestation/common/mock_tpm_utility.h" |
|
#include "attestation/server/attestation_service.h" |
|
#include "attestation/server/mock_database.h" |
|
#include "attestation/server/mock_key_store.h" |
|
|
|
using brillo::http::fake::ServerRequest; |
|
using brillo::http::fake::ServerResponse; |
|
using testing::_; |
|
using testing::DoAll; |
|
using testing::NiceMock; |
|
using testing::Return; |
|
using testing::ReturnRef; |
|
using testing::SetArgumentPointee; |
|
|
|
namespace attestation { |
|
|
|
class AttestationServiceTest : public testing::Test { |
|
public: |
|
enum FakeCAState { |
|
kSuccess, // Valid successful response. |
|
kCommandFailure, // Valid error response. |
|
kHttpFailure, // Responds with an HTTP error. |
|
kBadMessageID, // Valid successful response but a message ID mismatch. |
|
}; |
|
|
|
~AttestationServiceTest() override = default; |
|
void SetUp() override { |
|
service_.reset(new AttestationService); |
|
service_->set_database(&mock_database_); |
|
service_->set_crypto_utility(&mock_crypto_utility_); |
|
fake_http_transport_ = std::make_shared<brillo::http::fake::Transport>(); |
|
service_->set_http_transport(fake_http_transport_); |
|
service_->set_key_store(&mock_key_store_); |
|
service_->set_tpm_utility(&mock_tpm_utility_); |
|
// Setup a fake wrapped EK certificate by default. |
|
mock_database_.GetMutableProtobuf() |
|
->mutable_credentials() |
|
->mutable_default_encrypted_endorsement_credential() |
|
->set_wrapping_key_id("default"); |
|
// Setup a fake Attestation CA for success by default. |
|
SetupFakeCAEnroll(kSuccess); |
|
SetupFakeCASign(kSuccess); |
|
CHECK(service_->Initialize()); |
|
} |
|
|
|
protected: |
|
void SetupFakeCAEnroll(FakeCAState state) { |
|
fake_http_transport_->AddHandler( |
|
service_->attestation_ca_origin() + "/enroll", |
|
brillo::http::request_type::kPost, |
|
base::Bind(&AttestationServiceTest::FakeCAEnroll, |
|
base::Unretained(this), state)); |
|
} |
|
|
|
void SetupFakeCASign(FakeCAState state) { |
|
fake_http_transport_->AddHandler( |
|
service_->attestation_ca_origin() + "/sign", |
|
brillo::http::request_type::kPost, |
|
base::Bind(&AttestationServiceTest::FakeCASign, base::Unretained(this), |
|
state)); |
|
} |
|
|
|
std::string GetFakeCertificateChain() { |
|
const std::string kBeginCertificate = "-----BEGIN CERTIFICATE-----\n"; |
|
const std::string kEndCertificate = "-----END CERTIFICATE-----"; |
|
std::string pem = kBeginCertificate; |
|
pem += brillo::data_encoding::Base64EncodeWrapLines("fake_cert"); |
|
pem += kEndCertificate + "\n" + kBeginCertificate; |
|
pem += brillo::data_encoding::Base64EncodeWrapLines("fake_ca_cert"); |
|
pem += kEndCertificate + "\n" + kBeginCertificate; |
|
pem += brillo::data_encoding::Base64EncodeWrapLines("fake_ca_cert2"); |
|
pem += kEndCertificate; |
|
return pem; |
|
} |
|
|
|
CreateGoogleAttestedKeyRequest GetCreateRequest() { |
|
CreateGoogleAttestedKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); |
|
request.set_username("user"); |
|
request.set_origin("origin"); |
|
return request; |
|
} |
|
|
|
void Run() { run_loop_.Run(); } |
|
|
|
void RunUntilIdle() { run_loop_.RunUntilIdle(); } |
|
|
|
void Quit() { run_loop_.Quit(); } |
|
|
|
std::shared_ptr<brillo::http::fake::Transport> fake_http_transport_; |
|
NiceMock<MockCryptoUtility> mock_crypto_utility_; |
|
NiceMock<MockDatabase> mock_database_; |
|
NiceMock<MockKeyStore> mock_key_store_; |
|
NiceMock<MockTpmUtility> mock_tpm_utility_; |
|
std::unique_ptr<AttestationService> service_; |
|
|
|
private: |
|
void FakeCAEnroll(FakeCAState state, |
|
const ServerRequest& request, |
|
ServerResponse* response) { |
|
AttestationEnrollmentRequest request_pb; |
|
EXPECT_TRUE(request_pb.ParseFromString(request.GetDataAsString())); |
|
if (state == kHttpFailure) { |
|
response->ReplyText(brillo::http::status_code::NotFound, std::string(), |
|
brillo::mime::application::kOctet_stream); |
|
return; |
|
} |
|
AttestationEnrollmentResponse response_pb; |
|
if (state == kCommandFailure) { |
|
response_pb.set_status(SERVER_ERROR); |
|
response_pb.set_detail("fake_enroll_error"); |
|
} else if (state == kSuccess) { |
|
response_pb.set_status(OK); |
|
response_pb.set_detail(""); |
|
response_pb.mutable_encrypted_identity_credential()->set_asym_ca_contents( |
|
"1234"); |
|
response_pb.mutable_encrypted_identity_credential() |
|
->set_sym_ca_attestation("5678"); |
|
} else { |
|
NOTREACHED(); |
|
} |
|
std::string tmp; |
|
response_pb.SerializeToString(&tmp); |
|
response->ReplyText(brillo::http::status_code::Ok, tmp, |
|
brillo::mime::application::kOctet_stream); |
|
} |
|
|
|
void FakeCASign(FakeCAState state, |
|
const ServerRequest& request, |
|
ServerResponse* response) { |
|
AttestationCertificateRequest request_pb; |
|
EXPECT_TRUE(request_pb.ParseFromString(request.GetDataAsString())); |
|
if (state == kHttpFailure) { |
|
response->ReplyText(brillo::http::status_code::NotFound, std::string(), |
|
brillo::mime::application::kOctet_stream); |
|
return; |
|
} |
|
AttestationCertificateResponse response_pb; |
|
if (state == kCommandFailure) { |
|
response_pb.set_status(SERVER_ERROR); |
|
response_pb.set_detail("fake_sign_error"); |
|
} else if (state == kSuccess || state == kBadMessageID) { |
|
response_pb.set_status(OK); |
|
response_pb.set_detail(""); |
|
if (state == kSuccess) { |
|
response_pb.set_message_id(request_pb.message_id()); |
|
} |
|
response_pb.set_certified_key_credential("fake_cert"); |
|
response_pb.set_intermediate_ca_cert("fake_ca_cert"); |
|
*response_pb.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
} |
|
std::string tmp; |
|
response_pb.SerializeToString(&tmp); |
|
response->ReplyText(brillo::http::status_code::Ok, tmp, |
|
brillo::mime::application::kOctet_stream); |
|
} |
|
|
|
base::MessageLoop message_loop_; |
|
base::RunLoop run_loop_; |
|
}; |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeySuccess) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(GetFakeCertificateChain(), reply.certificate_chain()); |
|
EXPECT_FALSE(reply.has_server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeySuccessNoUser) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(GetFakeCertificateChain(), reply.certificate_chain()); |
|
EXPECT_FALSE(reply.has_server_error()); |
|
Quit(); |
|
}; |
|
CreateGoogleAttestedKeyRequest request = GetCreateRequest(); |
|
request.clear_username(); |
|
service_->CreateGoogleAttestedKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithEnrollHttpError) { |
|
SetupFakeCAEnroll(kHttpFailure); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_CA_NOT_AVAILABLE, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithSignHttpError) { |
|
SetupFakeCASign(kHttpFailure); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_CA_NOT_AVAILABLE, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithCAEnrollFailure) { |
|
SetupFakeCAEnroll(kCommandFailure); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_REQUEST_DENIED_BY_CA, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("fake_enroll_error", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithCASignFailure) { |
|
SetupFakeCASign(kCommandFailure); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_EQ(STATUS_REQUEST_DENIED_BY_CA, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("fake_sign_error", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithBadCAMessageID) { |
|
SetupFakeCASign(kBadMessageID); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithNoEKCertificate) { |
|
// Remove the default credential setup. |
|
mock_database_.GetMutableProtobuf()->clear_credentials(); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithRNGFailure) { |
|
EXPECT_CALL(mock_crypto_utility_, GetRandom(_, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithRNGFailure2) { |
|
EXPECT_CALL(mock_crypto_utility_, GetRandom(_, _)) |
|
.WillOnce(Return(true)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithDBFailure) { |
|
EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithDBFailureNoUser) { |
|
EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
CreateGoogleAttestedKeyRequest request = GetCreateRequest(); |
|
request.clear_username(); |
|
service_->CreateGoogleAttestedKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithKeyWriteFailure) { |
|
EXPECT_CALL(mock_key_store_, Write(_, _, _)).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithTpmNotReady) { |
|
EXPECT_CALL(mock_tpm_utility_, IsTpmReady()).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithTpmActivateFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, ActivateIdentity(_, _, _, _, _, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyWithTpmCreateFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, CreateCertifiedKey(_, _, _, _, _, _, _, _, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateGoogleAttestedKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_certificate_chain()); |
|
EXPECT_EQ("", reply.server_error()); |
|
Quit(); |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyAndCancel) { |
|
// Set expectations on the outputs. |
|
int callback_count = 0; |
|
auto callback = [&callback_count](const CreateGoogleAttestedKeyReply& reply) { |
|
callback_count++; |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
// Bring down the service, which should cancel any callbacks. |
|
service_.reset(); |
|
EXPECT_EQ(0, callback_count); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateGoogleAttestedKeyAndCancel2) { |
|
// Set expectations on the outputs. |
|
int callback_count = 0; |
|
auto callback = [&callback_count](const CreateGoogleAttestedKeyReply& reply) { |
|
callback_count++; |
|
}; |
|
service_->CreateGoogleAttestedKey(GetCreateRequest(), base::Bind(callback)); |
|
// Give threads a chance to run. |
|
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); |
|
// Bring down the service, which should cancel any callbacks. |
|
service_.reset(); |
|
// Pump the loop to make sure no callbacks were posted. |
|
RunUntilIdle(); |
|
EXPECT_EQ(0, callback_count); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetKeyInfoSuccess) { |
|
// Setup a certified key in the key store. |
|
CertifiedKey key; |
|
key.set_public_key("public_key"); |
|
key.set_certified_key_credential("fake_cert"); |
|
key.set_intermediate_ca_cert("fake_ca_cert"); |
|
*key.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
key.set_key_name("label"); |
|
key.set_certified_key_info("certify_info"); |
|
key.set_certified_key_proof("signature"); |
|
key.set_key_type(KEY_TYPE_RSA); |
|
key.set_key_usage(KEY_USAGE_SIGN); |
|
std::string key_bytes; |
|
key.SerializeToString(&key_bytes); |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<2>(key_bytes), Return(true))); |
|
|
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(KEY_TYPE_RSA, reply.key_type()); |
|
EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); |
|
EXPECT_EQ("public_key", reply.public_key()); |
|
EXPECT_EQ("certify_info", reply.certify_info()); |
|
EXPECT_EQ("signature", reply.certify_info_signature()); |
|
EXPECT_EQ(GetFakeCertificateChain(), reply.certificate()); |
|
Quit(); |
|
}; |
|
GetKeyInfoRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->GetKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetKeyInfoSuccessNoUser) { |
|
// Setup a certified key in the device key store. |
|
CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys(); |
|
key.set_public_key("public_key"); |
|
key.set_certified_key_credential("fake_cert"); |
|
key.set_intermediate_ca_cert("fake_ca_cert"); |
|
*key.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
key.set_key_name("label"); |
|
key.set_certified_key_info("certify_info"); |
|
key.set_certified_key_proof("signature"); |
|
key.set_key_type(KEY_TYPE_RSA); |
|
key.set_key_usage(KEY_USAGE_SIGN); |
|
|
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(KEY_TYPE_RSA, reply.key_type()); |
|
EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); |
|
EXPECT_EQ("public_key", reply.public_key()); |
|
EXPECT_EQ("certify_info", reply.certify_info()); |
|
EXPECT_EQ("signature", reply.certify_info_signature()); |
|
EXPECT_EQ(GetFakeCertificateChain(), reply.certificate()); |
|
Quit(); |
|
}; |
|
GetKeyInfoRequest request; |
|
request.set_key_label("label"); |
|
service_->GetKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetKeyInfoNoKey) { |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillRepeatedly(Return(false)); |
|
|
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_INVALID_PARAMETER, reply.status()); |
|
Quit(); |
|
}; |
|
GetKeyInfoRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->GetKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetKeyInfoBadPublicKey) { |
|
EXPECT_CALL(mock_crypto_utility_, GetRSASubjectPublicKeyInfo(_, _)) |
|
.WillRepeatedly(Return(false)); |
|
|
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetKeyInfoReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
GetKeyInfoRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->GetKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetEndorsementInfoSuccess) { |
|
AttestationDatabase* database = mock_database_.GetMutableProtobuf(); |
|
database->mutable_credentials()->set_endorsement_public_key("public_key"); |
|
database->mutable_credentials()->set_endorsement_credential("certificate"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetEndorsementInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("public_key", reply.ek_public_key()); |
|
EXPECT_EQ("certificate", reply.ek_certificate()); |
|
Quit(); |
|
}; |
|
GetEndorsementInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetEndorsementInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetEndorsementInfoNoInfo) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetEndorsementInfoReply& reply) { |
|
EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status()); |
|
EXPECT_FALSE(reply.has_ek_public_key()); |
|
EXPECT_FALSE(reply.has_ek_certificate()); |
|
Quit(); |
|
}; |
|
GetEndorsementInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetEndorsementInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetEndorsementInfoNoCert) { |
|
AttestationDatabase* database = mock_database_.GetMutableProtobuf(); |
|
database->mutable_credentials()->set_endorsement_public_key("public_key"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetEndorsementInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("public_key", reply.ek_public_key()); |
|
EXPECT_FALSE(reply.has_ek_certificate()); |
|
Quit(); |
|
}; |
|
GetEndorsementInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetEndorsementInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetAttestationKeyInfoSuccess) { |
|
AttestationDatabase* database = mock_database_.GetMutableProtobuf(); |
|
database->mutable_identity_key()->set_identity_public_key("public_key"); |
|
database->mutable_identity_key()->set_identity_credential("certificate"); |
|
database->mutable_pcr0_quote()->set_quote("pcr0"); |
|
database->mutable_pcr1_quote()->set_quote("pcr1"); |
|
database->mutable_identity_binding()->set_identity_public_key("public_key2"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetAttestationKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("public_key", reply.public_key()); |
|
EXPECT_EQ("public_key2", reply.public_key_tpm_format()); |
|
EXPECT_EQ("certificate", reply.certificate()); |
|
EXPECT_EQ("pcr0", reply.pcr0_quote().quote()); |
|
EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); |
|
Quit(); |
|
}; |
|
GetAttestationKeyInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetAttestationKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetAttestationKeyInfoNoInfo) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetAttestationKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_public_key_tpm_format()); |
|
EXPECT_FALSE(reply.has_certificate()); |
|
EXPECT_FALSE(reply.has_pcr0_quote()); |
|
EXPECT_FALSE(reply.has_pcr1_quote()); |
|
Quit(); |
|
}; |
|
GetAttestationKeyInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetAttestationKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, GetAttestationKeyInfoSomeInfo) { |
|
AttestationDatabase* database = mock_database_.GetMutableProtobuf(); |
|
database->mutable_identity_key()->set_identity_credential("certificate"); |
|
database->mutable_pcr1_quote()->set_quote("pcr1"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const GetAttestationKeyInfoReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_public_key_tpm_format()); |
|
EXPECT_EQ("certificate", reply.certificate()); |
|
EXPECT_FALSE(reply.has_pcr0_quote()); |
|
EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); |
|
Quit(); |
|
}; |
|
GetAttestationKeyInfoRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
service_->GetAttestationKeyInfo(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, ActivateAttestationKeySuccess) { |
|
EXPECT_CALL(mock_database_, SaveChanges()).Times(1); |
|
EXPECT_CALL(mock_tpm_utility_, |
|
ActivateIdentity(_, _, _, "encrypted1", "encrypted2", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<5>(std::string("certificate")), |
|
Return(true))); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const ActivateAttestationKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("certificate", reply.certificate()); |
|
Quit(); |
|
}; |
|
ActivateAttestationKeyRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); |
|
request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); |
|
request.set_save_certificate(true); |
|
service_->ActivateAttestationKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, ActivateAttestationKeySuccessNoSave) { |
|
EXPECT_CALL(mock_database_, GetMutableProtobuf()).Times(0); |
|
EXPECT_CALL(mock_database_, SaveChanges()).Times(0); |
|
EXPECT_CALL(mock_tpm_utility_, |
|
ActivateIdentity(_, _, _, "encrypted1", "encrypted2", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<5>(std::string("certificate")), |
|
Return(true))); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const ActivateAttestationKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("certificate", reply.certificate()); |
|
Quit(); |
|
}; |
|
ActivateAttestationKeyRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); |
|
request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); |
|
request.set_save_certificate(false); |
|
service_->ActivateAttestationKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, ActivateAttestationKeySaveFailure) { |
|
EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const ActivateAttestationKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
ActivateAttestationKeyRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); |
|
request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); |
|
request.set_save_certificate(true); |
|
service_->ActivateAttestationKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, ActivateAttestationKeyActivateFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, |
|
ActivateIdentity(_, _, _, "encrypted1", "encrypted2", _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const ActivateAttestationKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
ActivateAttestationKeyRequest request; |
|
request.set_key_type(KEY_TYPE_RSA); |
|
request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); |
|
request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); |
|
request.set_save_certificate(true); |
|
service_->ActivateAttestationKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeySuccess) { |
|
// Configure a fake TPM response. |
|
EXPECT_CALL( |
|
mock_tpm_utility_, |
|
CreateCertifiedKey(KEY_TYPE_ECC, KEY_USAGE_SIGN, _, _, _, _, _, _, _)) |
|
.WillOnce( |
|
DoAll(SetArgumentPointee<5>(std::string("public_key")), |
|
SetArgumentPointee<7>(std::string("certify_info")), |
|
SetArgumentPointee<8>(std::string("certify_info_signature")), |
|
Return(true))); |
|
// Expect the key to be written exactly once. |
|
EXPECT_CALL(mock_key_store_, Write("user", "label", _)).Times(1); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("public_key", reply.public_key()); |
|
EXPECT_EQ("certify_info", reply.certify_info()); |
|
EXPECT_EQ("certify_info_signature", reply.certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
request.set_username("user"); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeySuccessNoUser) { |
|
// Configure a fake TPM response. |
|
EXPECT_CALL( |
|
mock_tpm_utility_, |
|
CreateCertifiedKey(KEY_TYPE_ECC, KEY_USAGE_SIGN, _, _, _, _, _, _, _)) |
|
.WillOnce( |
|
DoAll(SetArgumentPointee<5>(std::string("public_key")), |
|
SetArgumentPointee<7>(std::string("certify_info")), |
|
SetArgumentPointee<8>(std::string("certify_info_signature")), |
|
Return(true))); |
|
// Expect the key to be written exactly once. |
|
EXPECT_CALL(mock_database_, SaveChanges()).Times(1); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ("public_key", reply.public_key()); |
|
EXPECT_EQ("certify_info", reply.certify_info()); |
|
EXPECT_EQ("certify_info_signature", reply.certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeyRNGFailure) { |
|
EXPECT_CALL(mock_crypto_utility_, GetRandom(_, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_certify_info()); |
|
EXPECT_FALSE(reply.has_certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeyTpmCreateFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, CreateCertifiedKey(_, _, _, _, _, _, _, _, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_certify_info()); |
|
EXPECT_FALSE(reply.has_certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeyDBFailure) { |
|
EXPECT_CALL(mock_key_store_, Write(_, _, _)).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_certify_info()); |
|
EXPECT_FALSE(reply.has_certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
request.set_username("username"); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, CreateCertifiableKeyDBFailureNoUser) { |
|
EXPECT_CALL(mock_database_, SaveChanges()).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const CreateCertifiableKeyReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_public_key()); |
|
EXPECT_FALSE(reply.has_certify_info()); |
|
EXPECT_FALSE(reply.has_certify_info_signature()); |
|
Quit(); |
|
}; |
|
CreateCertifiableKeyRequest request; |
|
request.set_key_label("label"); |
|
request.set_key_type(KEY_TYPE_ECC); |
|
request.set_key_usage(KEY_USAGE_SIGN); |
|
service_->CreateCertifiableKey(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, DecryptSuccess) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const DecryptReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(MockTpmUtility::Transform("Unbind", "data"), |
|
reply.decrypted_data()); |
|
Quit(); |
|
}; |
|
DecryptRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_encrypted_data("data"); |
|
service_->Decrypt(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, DecryptSuccessNoUser) { |
|
mock_database_.GetMutableProtobuf()->add_device_keys()->set_key_name("label"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const DecryptReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(MockTpmUtility::Transform("Unbind", "data"), |
|
reply.decrypted_data()); |
|
Quit(); |
|
}; |
|
DecryptRequest request; |
|
request.set_key_label("label"); |
|
request.set_encrypted_data("data"); |
|
service_->Decrypt(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, DecryptKeyNotFound) { |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const DecryptReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_decrypted_data()); |
|
Quit(); |
|
}; |
|
DecryptRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_encrypted_data("data"); |
|
service_->Decrypt(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, DecryptKeyNotFoundNoUser) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const DecryptReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_decrypted_data()); |
|
Quit(); |
|
}; |
|
DecryptRequest request; |
|
request.set_key_label("label"); |
|
request.set_encrypted_data("data"); |
|
service_->Decrypt(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, DecryptUnbindFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, Unbind(_, _, _)).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const DecryptReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_decrypted_data()); |
|
Quit(); |
|
}; |
|
DecryptRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_encrypted_data("data"); |
|
service_->Decrypt(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, SignSuccess) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const SignReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(MockTpmUtility::Transform("Sign", "data"), reply.signature()); |
|
Quit(); |
|
}; |
|
SignRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_data_to_sign("data"); |
|
service_->Sign(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, SignSuccessNoUser) { |
|
mock_database_.GetMutableProtobuf()->add_device_keys()->set_key_name("label"); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const SignReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(MockTpmUtility::Transform("Sign", "data"), reply.signature()); |
|
Quit(); |
|
}; |
|
SignRequest request; |
|
request.set_key_label("label"); |
|
request.set_data_to_sign("data"); |
|
service_->Sign(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, SignKeyNotFound) { |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const SignReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_signature()); |
|
Quit(); |
|
}; |
|
SignRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_data_to_sign("data"); |
|
service_->Sign(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, SignKeyNotFoundNoUser) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const SignReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_signature()); |
|
Quit(); |
|
}; |
|
SignRequest request; |
|
request.set_key_label("label"); |
|
request.set_data_to_sign("data"); |
|
service_->Sign(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, SignUnbindFailure) { |
|
EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _)).WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const SignReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
EXPECT_FALSE(reply.has_signature()); |
|
Quit(); |
|
}; |
|
SignRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
request.set_data_to_sign("data"); |
|
service_->Sign(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterSuccess) { |
|
// Setup a key in the user key store. |
|
CertifiedKey key; |
|
key.set_key_blob("key_blob"); |
|
key.set_public_key("public_key"); |
|
key.set_certified_key_credential("fake_cert"); |
|
key.set_intermediate_ca_cert("fake_ca_cert"); |
|
*key.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
key.set_key_name("label"); |
|
key.set_key_type(KEY_TYPE_RSA); |
|
key.set_key_usage(KEY_USAGE_SIGN); |
|
std::string key_bytes; |
|
key.SerializeToString(&key_bytes); |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<2>(key_bytes), Return(true))); |
|
// Cardinality is verified here to verify various steps are performed and to |
|
// catch performance regressions. |
|
EXPECT_CALL(mock_key_store_, |
|
Register("user", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN, |
|
"key_blob", "public_key", "fake_cert")) |
|
.Times(1); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate("user", "fake_ca_cert")) |
|
.Times(1); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate("user", "fake_ca_cert2")) |
|
.Times(1); |
|
EXPECT_CALL(mock_key_store_, Delete("user", "label")).Times(1); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterSuccessNoUser) { |
|
// Setup a key in the device_keys field. |
|
CertifiedKey& key = *mock_database_.GetMutableProtobuf()->add_device_keys(); |
|
key.set_key_blob("key_blob"); |
|
key.set_public_key("public_key"); |
|
key.set_certified_key_credential("fake_cert"); |
|
key.set_intermediate_ca_cert("fake_ca_cert"); |
|
*key.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
key.set_key_name("label"); |
|
key.set_key_type(KEY_TYPE_RSA); |
|
key.set_key_usage(KEY_USAGE_SIGN); |
|
// Cardinality is verified here to verify various steps are performed and to |
|
// catch performance regressions. |
|
EXPECT_CALL(mock_key_store_, |
|
Register("", "label", KEY_TYPE_RSA, KEY_USAGE_SIGN, "key_blob", |
|
"public_key", "fake_cert")) |
|
.Times(1); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate("", "fake_ca_cert")) |
|
.Times(1); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate("", "fake_ca_cert2")) |
|
.Times(1); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
|
EXPECT_EQ(0, mock_database_.GetMutableProtobuf()->device_keys_size()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterNoKey) { |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterNoKeyNoUser) { |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterFailure) { |
|
// Setup a key in the user key store. |
|
CertifiedKey key; |
|
key.set_key_name("label"); |
|
std::string key_bytes; |
|
key.SerializeToString(&key_bytes); |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<2>(key_bytes), Return(true))); |
|
EXPECT_CALL(mock_key_store_, Register(_, _, _, _, _, _, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterIntermediateFailure) { |
|
// Setup a key in the user key store. |
|
CertifiedKey key; |
|
key.set_key_name("label"); |
|
key.set_intermediate_ca_cert("fake_ca_cert"); |
|
std::string key_bytes; |
|
key.SerializeToString(&key_bytes); |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<2>(key_bytes), Return(true))); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
TEST_F(AttestationServiceTest, RegisterAdditionalFailure) { |
|
// Setup a key in the user key store. |
|
CertifiedKey key; |
|
key.set_key_name("label"); |
|
*key.add_additional_intermediate_ca_cert() = "fake_ca_cert2"; |
|
std::string key_bytes; |
|
key.SerializeToString(&key_bytes); |
|
EXPECT_CALL(mock_key_store_, Read("user", "label", _)) |
|
.WillOnce(DoAll(SetArgumentPointee<2>(key_bytes), Return(true))); |
|
EXPECT_CALL(mock_key_store_, RegisterCertificate(_, _)) |
|
.WillRepeatedly(Return(false)); |
|
// Set expectations on the outputs. |
|
auto callback = [this](const RegisterKeyWithChapsTokenReply& reply) { |
|
EXPECT_NE(STATUS_SUCCESS, reply.status()); |
|
Quit(); |
|
}; |
|
RegisterKeyWithChapsTokenRequest request; |
|
request.set_key_label("label"); |
|
request.set_username("user"); |
|
service_->RegisterKeyWithChapsToken(request, base::Bind(callback)); |
|
Run(); |
|
} |
|
|
|
} // namespace attestation
|
|
|