This source file includes following definitions.
- DBusBoolRedirectCallback
- DBusDataMethodCallback
- GetKeyTypeForProfile
- GetKeyNameForProfile
- weak_factory_
- GetCertificate
- StartEnroll
- SendEnrollRequestToPCA
- SendEnrollResponseToDaemon
- OnEnrollComplete
- StartCertificateRequest
- SendCertificateRequestToPCA
- SendCertificateResponseToDaemon
- GetExistingCertificate
- GetType
#include "chromeos/attestation/attestation_flow.h"
#include "base/bind.h"
#include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/dbus/cryptohome_client.h"
namespace chromeos {
namespace attestation {
namespace {
void DBusBoolRedirectCallback(const base::Closure& on_true,
const base::Closure& on_false,
const base::Closure& on_fail,
DBusMethodCallStatus status,
bool value) {
if (status != DBUS_METHOD_CALL_SUCCESS) {
LOG(ERROR) << "Attestation: Failed to query enrollment state.";
if (!on_fail.is_null())
on_fail.Run();
return;
}
const base::Closure& task = value ? on_true : on_false;
if (!task.is_null())
task.Run();
}
void DBusDataMethodCallback(
const AttestationFlow::CertificateCallback& callback,
DBusMethodCallStatus status,
bool result,
const std::string& data) {
if (status != DBUS_METHOD_CALL_SUCCESS) {
LOG(ERROR) << "Attestation: DBus data operation failed.";
if (!callback.is_null())
callback.Run(false, "");
return;
}
if (!callback.is_null())
callback.Run(result, data);
}
AttestationKeyType GetKeyTypeForProfile(
AttestationCertificateProfile profile) {
switch (profile) {
case PROFILE_ENTERPRISE_MACHINE_CERTIFICATE:
return KEY_DEVICE;
case PROFILE_ENTERPRISE_USER_CERTIFICATE:
case PROFILE_CONTENT_PROTECTION_CERTIFICATE:
return KEY_USER;
}
NOTREACHED();
return KEY_USER;
}
std::string GetKeyNameForProfile(AttestationCertificateProfile profile,
const std::string& origin) {
switch (profile) {
case PROFILE_ENTERPRISE_MACHINE_CERTIFICATE:
return kEnterpriseMachineKey;
case PROFILE_ENTERPRISE_USER_CERTIFICATE:
return kEnterpriseUserKey;
case PROFILE_CONTENT_PROTECTION_CERTIFICATE:
return std::string(kContentProtectionKeyPrefix) + origin;
}
NOTREACHED();
return "";
}
}
AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller,
CryptohomeClient* cryptohome_client,
scoped_ptr<ServerProxy> server_proxy)
: async_caller_(async_caller),
cryptohome_client_(cryptohome_client),
server_proxy_(server_proxy.Pass()),
weak_factory_(this) {
}
AttestationFlow::~AttestationFlow() {
}
void AttestationFlow::GetCertificate(
AttestationCertificateProfile certificate_profile,
const std::string& user_id,
const std::string& request_origin,
bool force_new_key,
const CertificateCallback& callback) {
base::Closure do_cert_request = base::Bind(
&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(),
certificate_profile,
user_id,
request_origin,
force_new_key,
callback);
base::Closure on_enroll_failure = base::Bind(callback, false, "");
base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll,
weak_factory_.GetWeakPtr(),
on_enroll_failure,
do_cert_request);
cryptohome_client_->TpmAttestationIsEnrolled(base::Bind(
&DBusBoolRedirectCallback,
do_cert_request,
do_enroll,
on_enroll_failure));
}
void AttestationFlow::StartEnroll(const base::Closure& on_failure,
const base::Closure& next_task) {
async_caller_->AsyncTpmAttestationCreateEnrollRequest(
server_proxy_->GetType(),
base::Bind(&AttestationFlow::SendEnrollRequestToPCA,
weak_factory_.GetWeakPtr(),
on_failure,
next_task));
}
void AttestationFlow::SendEnrollRequestToPCA(const base::Closure& on_failure,
const base::Closure& next_task,
bool success,
const std::string& data) {
if (!success) {
LOG(ERROR) << "Attestation: Failed to create enroll request.";
if (!on_failure.is_null())
on_failure.Run();
return;
}
server_proxy_->SendEnrollRequest(
data,
base::Bind(&AttestationFlow::SendEnrollResponseToDaemon,
weak_factory_.GetWeakPtr(),
on_failure,
next_task));
}
void AttestationFlow::SendEnrollResponseToDaemon(
const base::Closure& on_failure,
const base::Closure& next_task,
bool success,
const std::string& data) {
if (!success) {
LOG(ERROR) << "Attestation: Enroll request failed.";
if (!on_failure.is_null())
on_failure.Run();
return;
}
async_caller_->AsyncTpmAttestationEnroll(
server_proxy_->GetType(),
data,
base::Bind(&AttestationFlow::OnEnrollComplete,
weak_factory_.GetWeakPtr(),
on_failure,
next_task));
}
void AttestationFlow::OnEnrollComplete(const base::Closure& on_failure,
const base::Closure& next_task,
bool success,
cryptohome::MountError ) {
if (!success) {
LOG(ERROR) << "Attestation: Failed to complete enrollment.";
if (!on_failure.is_null())
on_failure.Run();
return;
}
if (!next_task.is_null())
next_task.Run();
}
void AttestationFlow::StartCertificateRequest(
AttestationCertificateProfile certificate_profile,
const std::string& user_id,
const std::string& request_origin,
bool generate_new_key,
const CertificateCallback& callback) {
AttestationKeyType key_type = GetKeyTypeForProfile(certificate_profile);
std::string key_name = GetKeyNameForProfile(certificate_profile,
request_origin);
if (generate_new_key) {
async_caller_->AsyncTpmAttestationCreateCertRequest(
server_proxy_->GetType(),
certificate_profile,
user_id,
request_origin,
base::Bind(&AttestationFlow::SendCertificateRequestToPCA,
weak_factory_.GetWeakPtr(),
key_type,
user_id,
key_name,
callback));
} else {
base::Closure on_key_exists = base::Bind(
&AttestationFlow::GetExistingCertificate,
weak_factory_.GetWeakPtr(),
key_type,
user_id,
key_name,
callback);
base::Closure on_key_not_exists = base::Bind(
&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(),
certificate_profile,
user_id,
request_origin,
true,
callback);
cryptohome_client_->TpmAttestationDoesKeyExist(
key_type,
user_id,
key_name,
base::Bind(&DBusBoolRedirectCallback,
on_key_exists,
on_key_not_exists,
base::Bind(callback, false, "")));
}
}
void AttestationFlow::SendCertificateRequestToPCA(
AttestationKeyType key_type,
const std::string& user_id,
const std::string& key_name,
const CertificateCallback& callback,
bool success,
const std::string& data) {
if (!success) {
LOG(ERROR) << "Attestation: Failed to create certificate request.";
if (!callback.is_null())
callback.Run(false, "");
return;
}
server_proxy_->SendCertificateRequest(
data,
base::Bind(&AttestationFlow::SendCertificateResponseToDaemon,
weak_factory_.GetWeakPtr(),
key_type,
user_id,
key_name,
callback));
}
void AttestationFlow::SendCertificateResponseToDaemon(
AttestationKeyType key_type,
const std::string& user_id,
const std::string& key_name,
const CertificateCallback& callback,
bool success,
const std::string& data) {
if (!success) {
LOG(ERROR) << "Attestation: Certificate request failed.";
if (!callback.is_null())
callback.Run(false, "");
return;
}
async_caller_->AsyncTpmAttestationFinishCertRequest(data,
key_type,
user_id,
key_name,
base::Bind(callback));
}
void AttestationFlow::GetExistingCertificate(
AttestationKeyType key_type,
const std::string& user_id,
const std::string& key_name,
const CertificateCallback& callback) {
cryptohome_client_->TpmAttestationGetCertificate(
key_type,
user_id,
key_name,
base::Bind(&DBusDataMethodCallback, callback));
}
ServerProxy::~ServerProxy() {}
PrivacyCAType ServerProxy::GetType() {
return DEFAULT_PCA;
}
}
}