Skip to content

Commit

Permalink
Added support for the content protection profile to AttestationFlow.
Browse files Browse the repository at this point in the history
This change moves all attestation certificate requests to the
new CreateCertRequestByProfile dbus method.

BUG=chromium:260504
TEST=unit, manual

Review URL: https://chromiumcodereview.appspot.com/20873002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217673 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
dkrahn@google.com committed Aug 14, 2013
1 parent 93f9098 commit 64494c3
Show file tree
Hide file tree
Showing 23 changed files with 152 additions and 94 deletions.
3 changes: 2 additions & 1 deletion WATCHLISTS
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@
},
'chromeos_attestation': {
'filepath': 'chromeos/attestation/|'\
'chrome/browser/chromeos/attestation/',
'chrome/browser/chromeos/attestation/|'\
'chrome/browser/extensions/api/enterprise_platform_keys_private/',
},
'chromeos_calculator': {
'filepath': 'chrome/common/extensions/docs/examples/apps/calculator/',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ void AttestationPolicyObserver::GetNewCertificate() {
// We can reuse the dbus callback handler logic.
attestation_flow_->GetCertificate(
PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
std::string(), // Not used.
std::string(), // Not used.
true, // Force a new key to be generated.
base::Bind(DBusStringCallback,
base::Bind(&AttestationPolicyObserver::UploadCertificate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ class AttestationPolicyObserverTest : public ::testing::Test {
// another costly operation and if it gets triggered more than once during
// a single pass this indicates a logical problem in the observer.
if (new_key) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _))
.WillOnce(WithArgs<2>(Invoke(CertCallbackSuccess)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackSuccess)));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mnissler@chromium.org

Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ void EPKPChallengeKeyBase::AskForUserConsentCallback(
// Generate a new key and have it signed by PCA.
attestation_flow_->GetCertificate(
certificate_profile,
std::string(), // Not used.
std::string(), // Not used.
true, // Force a new key to be generated.
base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback, this,
callback));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ void SignChallengeCallbackFalse(

void GetCertificateCallbackTrue(
chromeos::attestation::AttestationCertificateProfile certificate_profile,
const std::string& user_email,
const std::string& request_origin,
bool force_new_key,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
Expand All @@ -103,6 +105,8 @@ void GetCertificateCallbackTrue(

void GetCertificateCallbackFalse(
chromeos::attestation::AttestationCertificateProfile certificate_profile,
const std::string& user_email,
const std::string& request_origin,
bool force_new_key,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
Expand All @@ -121,7 +125,7 @@ class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest {
ON_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _))
.WillByDefault(Invoke(SignChallengeCallbackTrue));
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _))
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
.WillByDefault(Invoke(GetCertificateCallbackTrue));

// Set the Enterprise install attributes.
Expand Down Expand Up @@ -236,7 +240,7 @@ TEST_F(EPKPChallengeMachineKeyTest, DoesKeyExistDbusFailed) {
}

TEST_F(EPKPChallengeMachineKeyTest, GetCertificateFailed) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackFalse));

EXPECT_EQ(base::StringPrintf(
Expand All @@ -257,7 +261,7 @@ TEST_F(EPKPChallengeMachineKeyTest, KeyExists) {
EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _))
.WillRepeatedly(Invoke(DoesKeyExistCallbackTrue));
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
.Times(0);

EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), utils::NONE));
Expand All @@ -268,7 +272,7 @@ TEST_F(EPKPChallengeMachineKeyTest, Success) {
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
_, _))
_, _, _, _))
.Times(1);
// SignEnterpriseChallenge must be called exactly once.
EXPECT_CALL(mock_async_method_caller_,
Expand Down Expand Up @@ -356,7 +360,7 @@ TEST_F(EPKPChallengeUserKeyTest, DoesKeyExistDbusFailed) {
}

TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailed) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackFalse));

EXPECT_EQ(base::StringPrintf(
Expand Down Expand Up @@ -385,7 +389,7 @@ TEST_F(EPKPChallengeUserKeyTest, KeyExists) {
EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _))
.WillRepeatedly(Invoke(DoesKeyExistCallbackTrue));
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
.Times(0);

EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(), utils::NONE));
Expand All @@ -412,7 +416,7 @@ TEST_F(EPKPChallengeUserKeyTest, Success) {
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
_, _))
_, _, _, _))
.Times(1);
// SignEnterpriseChallenge must be called exactly once.
EXPECT_CALL(mock_async_method_caller_,
Expand Down
1 change: 1 addition & 0 deletions chromeos/attestation/attestation_constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace attestation {

const char kEnterpriseMachineKey[] = "attest-ent-machine";
const char kEnterpriseUserKey[] = "attest-ent-user";
const char kContentProtectionKeyPrefix[] = "attest-cp-";

} // namespace attestation
} // namespace chromeos
17 changes: 6 additions & 11 deletions chromeos/attestation/attestation_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@
namespace chromeos {
namespace attestation {

// Options available for customizing an attestation certificate.
enum AttestationCertificateOptions {
CERTIFICATE_OPTION_NONE = 0,
// A stable identifier is simply an identifier that is not affected by device
// state changes, including device recovery.
CERTIFICATE_INCLUDE_STABLE_ID = 1,
// Device state information contains a quoted assertion of whether the device
// is in verified mode.
CERTIFICATE_INCLUDE_DEVICE_STATE = 1 << 1,
};

// Key types supported by the Chrome OS attestation subsystem.
enum AttestationKeyType {
// The key will be associated with the device itself and will be available
Expand Down Expand Up @@ -48,6 +37,8 @@ enum AttestationCertificateProfile {
// Uses the following certificate options:
// CERTIFICATE_INCLUDE_DEVICE_STATE
PROFILE_ENTERPRISE_USER_CERTIFICATE,
// A profile for certificates intended for protected content providers.
PROFILE_CONTENT_PROTECTION_CERTIFICATE,
};

// A key name for the Enterprise Machine Key. This key should always be stored
Expand All @@ -58,6 +49,10 @@ CHROMEOS_EXPORT extern const char kEnterpriseMachineKey[];
// a USER_KEY.
CHROMEOS_EXPORT extern const char kEnterpriseUserKey[];

// The key name prefix for content protection keys. This prefix must be
// appended with an origin-specific identifier to form the final key name.
CHROMEOS_EXPORT extern const char kContentProtectionKeyPrefix[];

} // namespace attestation
} // namespace chromeos

Expand Down
34 changes: 18 additions & 16 deletions chromeos/attestation/attestation_flow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,36 +59,27 @@ AttestationKeyType GetKeyTypeForProfile(
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) {
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 "";
}

int GetCertificateOptionsForProfile(
AttestationCertificateProfile profile) {
switch (profile) {
case PROFILE_ENTERPRISE_MACHINE_CERTIFICATE:
return CERTIFICATE_INCLUDE_STABLE_ID | CERTIFICATE_INCLUDE_DEVICE_STATE;
case PROFILE_ENTERPRISE_USER_CERTIFICATE:
return CERTIFICATE_INCLUDE_DEVICE_STATE;
}
NOTREACHED();
return CERTIFICATE_OPTION_NONE;
}

} // namespace

AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller,
Expand All @@ -105,6 +96,8 @@ AttestationFlow::~AttestationFlow() {

void AttestationFlow::GetCertificate(
AttestationCertificateProfile certificate_profile,
const std::string& user_email,
const std::string& request_origin,
bool force_new_key,
const CertificateCallback& callback) {
// If this device has not enrolled with the Privacy CA, we need to do that
Expand All @@ -113,6 +106,8 @@ void AttestationFlow::GetCertificate(
&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(),
certificate_profile,
user_email,
request_origin,
force_new_key,
callback);
base::Closure on_enroll_failure = base::Bind(callback, false, "");
Expand Down Expand Up @@ -196,14 +191,19 @@ void AttestationFlow::OnEnrollComplete(const base::Closure& on_failure,

void AttestationFlow::StartCertificateRequest(
AttestationCertificateProfile certificate_profile,
const std::string& user_email,
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);
std::string key_name = GetKeyNameForProfile(certificate_profile,
request_origin);
if (generate_new_key) {
// Get the attestation service to create a Privacy CA certificate request.
async_caller_->AsyncTpmAttestationCreateCertRequest(
GetCertificateOptionsForProfile(certificate_profile),
certificate_profile,
user_email,
request_origin,
base::Bind(&AttestationFlow::SendCertificateRequestToPCA,
weak_factory_.GetWeakPtr(),
key_type,
Expand All @@ -223,6 +223,8 @@ void AttestationFlow::StartCertificateRequest(
&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(),
certificate_profile,
user_email,
request_origin,
true,
callback);
cryptohome_client_->TpmAttestationDoesKeyExist(
Expand Down
12 changes: 12 additions & 0 deletions chromeos/attestation/attestation_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,21 @@ class CHROMEOS_EXPORT AttestationFlow {
// Parameters
// certificate_profile - Specifies what kind of certificate should be
// requested from the CA.
// user_email - The canonical email address of the currently active user.
// This is ignored when not using the content protection
// profile.
// request_origin - For content protection profiles, certificate requests
// are origin-specific. This string must uniquely identify
// the origin of the request.
// force_new_key - If set to true, a new key will be generated even if a key
// already exists for the profile. The new key will replace
// the existing key on success.
// callback - A callback which will be called when the operation completes.
// On success |result| will be true and |data| will contain the
// PCA-issued certificate chain in PEM format.
virtual void GetCertificate(AttestationCertificateProfile certificate_profile,
const std::string& user_email,
const std::string& request_origin,
bool force_new_key,
const CertificateCallback& callback);

Expand Down Expand Up @@ -134,10 +142,14 @@ class CHROMEOS_EXPORT AttestationFlow {
// Parameters
// certificate_profile - Specifies what kind of certificate should be
// requested from the CA.
// user_email - The active user's canonical email.
// request_origin - An identifier for the origin of this request.
// generate_new_key - If set to true a new key is generated.
// callback - Called when the operation completes.
void StartCertificateRequest(
const AttestationCertificateProfile certificate_profile,
const std::string& user_email,
const std::string& request_origin,
bool generate_new_key,
const CertificateCallback& callback);

Expand Down
Loading

0 comments on commit 64494c3

Please sign in to comment.