1175 lines
43 KiB
C++
1175 lines
43 KiB
C++
//
|
|
// 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
|