Add License::Policy::play_start_grace_period_seconds

[ Merge of http://go/wvgerrit/22565 ]

When using the grace period, the CDM will need to override the values
given to use by the TEE (through OEMCrypto).  Normally the first (and
last) decrypt times are stored securely by the TEE.  To avoid extra
complexity in OEMCrypto, we will simply ignore the values given to us
by the TEE when using this feature.

However, the TEE will still enforce the (hard) license duration.  So
only the rental/playback durations will be affected by malicious
editing of files.

b/34211676

Test: Reran unittests including newly added tests. All tests other than
some oemcrypto, request_license_test passed. Those tests failed with
or without this CL.

Change-Id: I6d7b5bfb669fd8603b474b68c2f7175b0c30901d
This commit is contained in:
Rahul Frias
2017-01-16 18:17:01 -08:00
parent b492f7b73b
commit 826c91ba26
10 changed files with 252 additions and 56 deletions

View File

@@ -118,6 +118,7 @@ struct LicenseInfo {
std::string key_release_url;
int64_t playback_start_time;
int64_t last_playback_time;
int64_t grace_period_end_time;
std::string app_parameters;
std::string file_data;
};
@@ -225,9 +226,9 @@ LicenseInfo license_test_data[] = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, "",
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
a2bs_hex(
"0AA8150802100122A1150801121408011210303132333435363738394142434445461"
"0AAA150802100122A3150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -306,8 +307,8 @@ LicenseInfo license_test_data[] = {
"106B63746C0000000000ECDCBE0000000020DBDFA68F051A20182F029E35047A3841F"
"A176C74E5B387350E8D58DEA6878FF0BEA6CABACA1C2C3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"365400048001220CD0599C2B85D9F2D573AC7893CE77CB5A10B326828BA8C89047505"
"A8C9B606AC")},
"365400048005800122066F4FFF1CB2C0F978149A9402F3E4FF8D49B19635E646A0678"
"71AA08E7A8FDC3")},
// license 1
{"ksidC8EAA2579A282EB0", DeviceFiles::kLicenseStateReleasing,
@@ -406,9 +407,9 @@ LicenseInfo license_test_data[] = {
"A68F051A20BDA6A56F7CBFD0942198F87C23A34AA5CBD64AFEB134277774"
"CCF8E789D815DD"),
"https://test.google.com/license/GetCencLicense", 0x12345678, 0x12348765,
"Name1 Value1",
0x0, "Name1 Value1",
a2bs_hex(
"0AC1150802100122BA150802121408011210303132333435363738394142434445461"
"0AC3150802100122BC150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -487,8 +488,8 @@ LicenseInfo license_test_data[] = {
"106B63746C00000000CA3A6A75000000002083E5A68F051A20BDA6A56F7CBFD094219"
"8F87C23A34AA5CBD64AFEB134277774CCF8E789D815DD3A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C7565311220BE69"
"AAB25B481BCAF57B741518D9F9DB8E3A7A6911D10C53D4F4649D78393C65")},
"36540F8ACD1910148E58ED29101520F0A054E616D6531120656616C75653158001220"
"9C0315FC1812C6A0E5936E36D04ECE2FA56AF4AB544ECDF3C9135D54B4A26167")},
// license 2
{"ksidE8C37662C88DC673", DeviceFiles::kLicenseStateReleasing,
@@ -587,9 +588,9 @@ LicenseInfo license_test_data[] = {
"A68F051A2041EF0A9267D613D17AA90E1D1DA5BE091860E5E296D41D6D0F"
"75E73660C279B3"),
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, "Name1 Value1 Name2 Param2",
0x123456789abfedc, 0x0, "Name1 Value1 Name2 Param2",
a2bs_hex(
"0AE7150802100122E0150802121408011210303132333435363738394142434445461"
"0AE9150802100122E2150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D507618A5D3A68F05228E023082010A0282010100A947904B8DBD55FB685FDB302"
"5574517CCCC74EE4FEAF6629D5179A52FF85CE7409528EFFA0E5DFC3DE9A34BA5F08B"
@@ -669,9 +670,9 @@ LicenseInfo license_test_data[] = {
"90E1D1DA5BE091860E5E296D41D6D0F75E73660C279B33A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910152150A054E616D6531120C5661"
"6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D321"
"2203653BA57F16FE28D66D9F7A76128B7AD7F33680815FF70A3684617DE1FBB0F9"
"F")}};
"6C756531204E616D653252160A0C4E616D653220506172616D321206506172616D325"
"8001220616E6AC4AF6EB4F7147E98CF7302425E2390B293BBC01F9F8E89B49F653EA3"
"45")}};
// Sample license data and related data for storage and use for offline
// playback. The license data and URLs in this test are not real.
@@ -774,9 +775,9 @@ LicenseInfo license_update_test_data[] = {
"B68F051A2000351030900858FCFD6977B67803ADFD1280AA661E6B0BD30B"
"08B2C467355129"),
"https://test.google.com/license/GetCencLicense", 0x0123456789abcdef,
0x123456789abfedc, "Name1 Value1 Name2 Value2 Name3 Value3",
0x123456789abfedc, 0x0, "Name1 Value1 Name2 Value2 Name3 Value3",
a2bs_hex(
"0AB8150802100122B1150801121408011210303132333435363738394142434445461"
"0ABA150802100122B3150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -855,13 +856,14 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191011220C7ACA00F6877DAAE2E8F50"
"126C3222C2E584A50D08EFA75BC4FC091E7034E1DD")},
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122051F15CDA5B9414919D"
"B67769A781CC4F43138D314DAFFCBFBD620E53167E4AF2")},
// license being released. all fields are identical except for license
// state and hashed file data
{"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, "",
{"", DeviceFiles::kLicenseStateReleasing, "", "", "", "", "", "", 0, 0, 0,
"",
a2bs_hex(
"0AB8150802100122B1150802121408011210303132333435363738394142434445461"
"0ABA150802100122B3150802121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
"7A7D5076189EDFB68F05228E023082010A0282010100CC1715C81AD3F6F279C686F82"
"6E6D7C8961EB13318367D06B4061BBC57E3C616A226A10F042CAD54D44C6484C725CD"
@@ -940,8 +942,8 @@ LicenseInfo license_update_test_data[] = {
"106B63746C0000000071FEF30B0000000020F4DFB68F051A2000351030900858FCFD6"
"977B67803ADFD1280AA661E6B0BD30B08B2C4673551293A2E68747470733A2F2F7465"
"73742E676F6F676C652E636F6D2F6C6963656E73652F47657443656E634C6963656E7"
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD1910112203D8933A735A22FE27AA956"
"802B597529E8FFCB91A5F3CBBB3CE0C38E4AF3DC88")}};
"36540EF9BAFCDF8ACD1910148DCFDAFCDF8ACD191015800122093FDE0D42BC60D3932"
"02E0D5A49775E08093BF01560EF72C298321E921716E24")}};
// Application parameters were added to the License message. This data
// is used to verify that a License saved without application parameters can
@@ -1043,7 +1045,7 @@ LicenseInfo license_app_parameters_backwards_compatibility_test_data = {
"0112001A16200342120A106B63746C0000000000ECDCBE0000000020DBDF"
"A68F051A20182F029E35047A3841FA176C74E5B387350E8D58DEA6878FF0"
"BEA6CABACA1C2C"),
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, "",
"https://test.google.com/license/GetCencLicense", 0x0, 0x0, 0x0, "",
a2bs_hex(
"0AA8150802100122A1150801121408011210303132333435363738394142434445461"
"A9D0E080112950C0AD70B080112EF090AB002080212103E560EC5335E346F591BC4D0"
@@ -1489,7 +1491,7 @@ class DeviceFilesTest : public ::testing::Test {
return sizeof(DeviceFiles::LicenseState) + data.pssh_data.size() +
data.key_request.size() + data.key_response.size() +
data.key_renewal_request.size() + data.key_renewal_response.size() +
data.key_release_url.size() + 2 * sizeof(int64_t);
data.key_release_url.size() + 3 * sizeof(int64_t);
}
CdmAppParameterMap GetAppParameters(std::string str) {
@@ -1747,7 +1749,8 @@ TEST_P(DeviceFilesStoreTest, StoreLicense) {
license_test_data[license_num].key_renewal_response,
license_test_data[license_num].key_release_url,
license_test_data[license_num].playback_start_time,
license_test_data[license_num].last_playback_time, app_parameters));
license_test_data[license_num].last_playback_time,
license_test_data[license_num].grace_period_end_time, app_parameters));
}
INSTANTIATE_TEST_CASE_P(StoreLicense, DeviceFilesStoreTest, ::testing::Bool());
@@ -1794,7 +1797,8 @@ TEST_F(DeviceFilesTest, StoreLicenses) {
license_test_data[i].key_renewal_response,
license_test_data[i].key_release_url,
license_test_data[i].playback_start_time,
license_test_data[i].last_playback_time, app_parameters));
license_test_data[i].last_playback_time,
license_test_data[i].grace_period_end_time, app_parameters));
}
}
@@ -1832,6 +1836,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response;
int64_t playback_start_time, last_playback_time;
int64_t grace_period_end_time;
std::string release_server_url;
CdmAppParameterMap app_parameters;
@@ -1841,7 +1846,7 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
license_test_data[i].key_set_id, &license_state, &pssh_data,
&key_request, &key_response, &key_renewal_request,
&key_renewal_response, &release_server_url, &playback_start_time,
&last_playback_time, &app_parameters));
&last_playback_time, &grace_period_end_time, &app_parameters));
EXPECT_EQ(license_test_data[i].license_state, license_state);
EXPECT_EQ(license_test_data[i].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[i].key_request, key_request);
@@ -1850,6 +1855,8 @@ TEST_F(DeviceFilesTest, RetrieveLicenses) {
EXPECT_EQ(license_test_data[i].key_response, key_response);
EXPECT_EQ(license_test_data[i].playback_start_time, playback_start_time);
EXPECT_EQ(license_test_data[i].last_playback_time, last_playback_time);
EXPECT_EQ(license_test_data[i].grace_period_end_time,
grace_period_end_time);
std::map<std::string, std::string>::iterator itr;
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
@@ -1894,6 +1901,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response;
int64_t playback_start_time, last_playback_time;
int64_t grace_period_end_time;
std::string release_server_url;
CdmAppParameterMap app_parameters;
@@ -1901,7 +1909,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
test_data->key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time,
&app_parameters));
&grace_period_end_time, &app_parameters));
EXPECT_EQ(test_data->license_state, license_state);
EXPECT_EQ(test_data->pssh_data, pssh_data);
EXPECT_EQ(test_data->key_request, key_request);
@@ -1910,6 +1918,7 @@ TEST_F(DeviceFilesTest, AppParametersBackwardCompatibility) {
EXPECT_EQ(test_data->key_response, key_response);
EXPECT_EQ(test_data->playback_start_time, playback_start_time);
EXPECT_EQ(test_data->last_playback_time, last_playback_time);
EXPECT_EQ(test_data->grace_period_end_time, grace_period_end_time);
EXPECT_EQ(0u, app_parameters.size());
}
@@ -1945,6 +1954,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].key_release_url,
license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters)));
EXPECT_TRUE(device_files.StoreLicense(
@@ -1958,6 +1968,7 @@ TEST_F(DeviceFilesTest, UpdateLicenseState) {
license_update_test_data[0].key_release_url,
license_update_test_data[0].playback_start_time,
license_update_test_data[0].last_playback_time,
license_update_test_data[0].grace_period_end_time,
GetAppParameters(license_test_data[0].app_parameters)));
}
@@ -1996,14 +2007,14 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
CdmKeyMessage key_renewal_request;
CdmKeyResponse key_renewal_response;
std::string release_server_url;
int64_t playback_start_time, last_playback_time;
int64_t playback_start_time, last_playback_time, grace_period_end_time;
CdmAppParameterMap app_parameters;
EXPECT_TRUE(device_files.RetrieveLicense(
license_test_data[0].key_set_id, &license_state, &pssh_data, &key_request,
&key_response, &key_renewal_request, &key_renewal_response,
&release_server_url, &playback_start_time, &last_playback_time,
&app_parameters));
&grace_period_end_time, &app_parameters));
EXPECT_EQ(license_test_data[0].license_state, license_state);
EXPECT_EQ(license_test_data[0].pssh_data, pssh_data);
EXPECT_EQ(license_test_data[0].key_request, key_request);
@@ -2012,6 +2023,7 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
EXPECT_EQ(license_test_data[0].key_response, key_response);
EXPECT_EQ(license_test_data[0].playback_start_time, playback_start_time);
EXPECT_EQ(license_test_data[0].last_playback_time, last_playback_time);
EXPECT_EQ(license_test_data[0].grace_period_end_time, grace_period_end_time);
std::map<std::string, std::string>::iterator itr;
for (itr = app_parameters.begin(); itr != app_parameters.end(); ++itr) {
EXPECT_NE(license_test_data[0].app_parameters.find(itr->first),

View File

@@ -1093,7 +1093,8 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadBeforeExpire) {
OnExpirationUpdate(_, kLicenseStartTime + kLicenseDuration));
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
@@ -1117,12 +1118,147 @@ TEST_F(PolicyEngineTest, LicenseExpired_SoftEnforceLoadAfterExpire) {
ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriod) {
const int64_t kGracePeriod = 300; // 5 minutes
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod - 5))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod + 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kPlaybackStartTime + kPlaybackDuration + 5));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithLoad) {
const int64_t kGracePeriod = 300; // 5 minutes
const int64_t kNewPlaybackStartTime = kPlaybackStartTime + kPlaybackDuration;
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime + kGracePeriod - 5))
.WillOnce(Return(kNewPlaybackStartTime + kGracePeriod + 5))
.WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration - 5))
.WillOnce(Return(kNewPlaybackStartTime + kPlaybackDuration + 5));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(check_, Call(1));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kNewPlaybackStartTime + kPlaybackDuration));
EXPECT_CALL(check_, Call(2));
EXPECT_CALL(check_, Call(3));
ExpectSessionKeysChange(kKeyStatusExpired, false);
EXPECT_CALL(check_, Call(4));
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
0);
policy_engine_->BeginDecryption();
for (int i = 1; i <= 4; ++i) {
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId));
policy_engine_->OnTimerEvent();
check_.Call(i);
}
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_GracePeriodWithExpiredLoad) {
const int64_t kGracePeriod = 300; // 5 minutes
const int64_t kNewPlaybackStartTime =
kPlaybackStartTime + kPlaybackDuration + 5;
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kNewPlaybackStartTime))
.WillOnce(Return(kNewPlaybackStartTime));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
ExpectSessionKeysChange(kKeyStatusExpired, false);
policy_engine_->SetLicense(license_);
policy_engine_->RestorePlaybackTimes(kPlaybackStartTime, kPlaybackStartTime,
kPlaybackStartTime);
policy_engine_->OnTimerEvent();
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId));
}
TEST_F(PolicyEngineTest, PlaybackOk_CanStoreGracePeriod) {
const int64_t kGracePeriod = 300; // 5 minutes
License_Policy* policy = license_.mutable_policy();
policy->set_play_start_grace_period_seconds(kGracePeriod);
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(kLicenseStartTime + 1))
.WillOnce(Return(kPlaybackStartTime))
.WillOnce(Return(kPlaybackStartTime + 50))
.WillOnce(Return(kPlaybackStartTime + kGracePeriod + 2));
InSequence seq;
ExpectSessionKeysChange(kKeyStatusUsable, true);
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kLicenseStartTime + kRentalDuration));
EXPECT_CALL(mock_event_listener_,
OnExpirationUpdate(_, kPlaybackStartTime + kPlaybackDuration));
policy_engine_->SetLicense(license_);
policy_engine_->BeginDecryption();
policy_engine_->OnTimerEvent();
EXPECT_EQ(0, policy_engine_->GetGracePeriodEndTime());
policy_engine_->OnTimerEvent();
EXPECT_EQ(kPlaybackStartTime, policy_engine_->GetGracePeriodEndTime());
}
class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
protected:
enum KeyFlag {