diff options
author | dkrahn@chromium.org <dkrahn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 13:52:46 +0000 |
---|---|---|
committer | dkrahn@chromium.org <dkrahn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-13 13:52:46 +0000 |
commit | 77e3163e1ee1ca690ee255bb9d69dad9e70b4344 (patch) | |
tree | bd2b951558af9987f10b849637c3349cb879ffa4 | |
parent | d2b3e58c42497b19a89176ca225caeee01f3e35b (diff) | |
download | chromium_src-77e3163e1ee1ca690ee255bb9d69dad9e70b4344.zip chromium_src-77e3163e1ee1ca690ee255bb9d69dad9e70b4344.tar.gz chromium_src-77e3163e1ee1ca690ee255bb9d69dad9e70b4344.tar.bz2 |
Handle expired platform key certificates.
Platform keys and certificates are retained until they are manually
cleared or the account is removed from the device. If a certificate
expires, a new key is now generated and certified as a replacement.
BUG=chromium:322683
TEST=unit
Review URL: https://codereview.chromium.org/110883010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240622 0039d316-1c4b-4281-b951-d872f2087c98
7 files changed, 173 insertions, 83 deletions
diff --git a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc index 1268d10..31037da 100644 --- a/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc +++ b/chrome/browser/chromeos/attestation/attestation_policy_observer_unittest.cc @@ -9,6 +9,7 @@ #include "base/run_loop.h" #include "chrome/browser/chromeos/attestation/attestation_key_payload.pb.h" #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h" +#include "chrome/browser/chromeos/attestation/fake_certificate.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" @@ -17,9 +18,6 @@ #include "chromeos/settings/cros_settings_names.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "content/public/test/test_browser_thread.h" -#include "crypto/rsa_private_key.h" -#include "net/cert/x509_certificate.h" -#include "net/cert/x509_util.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -32,38 +30,9 @@ namespace attestation { namespace { -// A test key encoded as ASN.1 PrivateKeyInfo from PKCS #8. -const uint8 kTestKeyData[] = { - 0x30, 0x82, 0x01, 0x55, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x01, 0x3f, 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, - 0xd9, 0xcd, 0xca, 0xcd, 0xc3, 0xea, 0xbe, 0x72, 0x79, 0x1c, 0x29, 0x37, - 0x39, 0x99, 0x1f, 0xd4, 0xb3, 0x0e, 0xf0, 0x7b, 0x78, 0x77, 0x0e, 0x05, - 0x3b, 0x65, 0x34, 0x12, 0x62, 0xaf, 0xa6, 0x8d, 0x33, 0xce, 0x78, 0xf8, - 0x47, 0x05, 0x1d, 0x98, 0xaa, 0x1b, 0x1f, 0x50, 0x05, 0x5b, 0x3c, 0x19, - 0x3f, 0x80, 0x83, 0x63, 0x63, 0x3a, 0xec, 0xcb, 0x2e, 0x90, 0x4f, 0xf5, - 0x26, 0x76, 0xf1, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x64, - 0x29, 0xc2, 0xd9, 0x6b, 0xfe, 0xf9, 0x84, 0x75, 0x73, 0xe0, 0xf4, 0x77, - 0xb5, 0x96, 0xb0, 0xdf, 0x83, 0xc0, 0x4e, 0x57, 0xf1, 0x10, 0x6e, 0x91, - 0x89, 0x12, 0x30, 0x5e, 0x57, 0xff, 0x14, 0x59, 0x5f, 0x18, 0x86, 0x4e, - 0x4b, 0x17, 0x56, 0xfc, 0x8d, 0x40, 0xdd, 0x74, 0x65, 0xd3, 0xff, 0x67, - 0x64, 0xcb, 0x9c, 0xb4, 0x14, 0x8a, 0x06, 0xb7, 0x13, 0x45, 0x94, 0x16, - 0x7d, 0x3f, 0xe1, 0x02, 0x21, 0x00, 0xf6, 0x0f, 0x31, 0x6d, 0x06, 0xcc, - 0x3b, 0xa0, 0x44, 0x1f, 0xf5, 0xc2, 0x45, 0x2b, 0x10, 0x6c, 0xf9, 0x6f, - 0x8f, 0x87, 0x3d, 0xc0, 0x3b, 0x55, 0x13, 0x37, 0x80, 0xcd, 0x9f, 0xe1, - 0xb7, 0xd9, 0x02, 0x21, 0x00, 0xe2, 0x9a, 0x5f, 0xbf, 0x95, 0x74, 0xb5, - 0x7a, 0x6a, 0xa6, 0x97, 0xbd, 0x75, 0x8c, 0x97, 0x18, 0x24, 0xd6, 0x09, - 0xcd, 0xdc, 0xb5, 0x94, 0xbf, 0xe2, 0x78, 0xaa, 0x20, 0x47, 0x9f, 0x68, - 0x5d, 0x02, 0x21, 0x00, 0xaf, 0x8f, 0x97, 0x8c, 0x5a, 0xd5, 0x4d, 0x95, - 0xc4, 0x05, 0xa9, 0xab, 0xba, 0xfe, 0x46, 0xf1, 0xf9, 0xe7, 0x07, 0x59, - 0x4f, 0x4d, 0xe1, 0x07, 0x8a, 0x76, 0x87, 0x88, 0x2f, 0x13, 0x35, 0xc1, - 0x02, 0x20, 0x24, 0xc3, 0xd9, 0x2f, 0x13, 0x47, 0x99, 0x3e, 0x20, 0x59, - 0xa1, 0x1a, 0xeb, 0x1c, 0x81, 0x53, 0x38, 0x7e, 0xc5, 0x9e, 0x71, 0xe5, - 0xc0, 0x19, 0x95, 0xdb, 0xef, 0xf6, 0x46, 0xc8, 0x95, 0x3d, 0x02, 0x21, - 0x00, 0xaa, 0xb1, 0xff, 0x8a, 0xa2, 0xb2, 0x2b, 0xef, 0x9a, 0x83, 0x3f, - 0xc5, 0xbc, 0xd4, 0x6a, 0x07, 0xe8, 0xc7, 0x0b, 0x2e, 0xd4, 0x0f, 0xf8, - 0x98, 0x68, 0xe1, 0x04, 0xa8, 0x92, 0xd0, 0x10, 0xaa, -}; +const int64 kCertValid = 90; +const int64 kCertExpiringSoon = 20; +const int64 kCertExpired = -20; void DBusCallbackFalse(const BoolDBusMethodCallback& callback) { base::MessageLoop::current()->PostTask( @@ -130,12 +99,6 @@ class AttestationPolicyObserverTest : public ::testing::Test { } protected: - enum CertExpiryOptions { - CERT_VALID, - CERT_EXPIRING_SOON, - CERT_EXPIRED - }; - enum MockOptions { MOCK_KEY_EXISTS = 1, // Configure so a certified key exists. MOCK_KEY_UPLOADED = (1 << 1), // Configure so an upload has occurred. @@ -204,37 +167,6 @@ class AttestationPolicyObserverTest : public ::testing::Test { return serialized; } - bool CreateCertificate(CertExpiryOptions options, std::string* certificate) { - base::Time valid_start = base::Time::Now() - base::TimeDelta::FromDays(90); - base::Time valid_expiry; - switch (options) { - case CERT_VALID: - valid_expiry = base::Time::Now() + base::TimeDelta::FromDays(90); - break; - case CERT_EXPIRING_SOON: - valid_expiry = base::Time::Now() + base::TimeDelta::FromDays(20); - break; - case CERT_EXPIRED: - valid_expiry = base::Time::Now() - base::TimeDelta::FromDays(20); - break; - default: - NOTREACHED(); - } - scoped_ptr<crypto::RSAPrivateKey> test_key( - crypto::RSAPrivateKey::CreateFromPrivateKeyInfo( - std::vector<uint8>(&kTestKeyData[0], - &kTestKeyData[arraysize(kTestKeyData)]))); - if (!test_key.get()) - return false; - return net::x509_util::CreateSelfSignedCert(test_key.get(), - net::x509_util::DIGEST_SHA256, - "CN=subject", - 12345, - valid_start, - valid_expiry, - certificate); - } - base::MessageLoop message_loop_; content::TestBrowserThread ui_thread_; ScopedTestDeviceSettingsService test_device_settings_service_; @@ -264,28 +196,32 @@ TEST_F(AttestationPolicyObserverTest, NewCertificate) { TEST_F(AttestationPolicyObserverTest, KeyExistsNotUploaded) { std::string certificate; - ASSERT_TRUE(CreateCertificate(CERT_VALID, &certificate)); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(kCertValid), + &certificate)); SetupMocks(MOCK_KEY_EXISTS, certificate); Run(); } TEST_F(AttestationPolicyObserverTest, KeyExistsAlreadyUploaded) { std::string certificate; - ASSERT_TRUE(CreateCertificate(CERT_VALID, &certificate)); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(kCertValid), + &certificate)); SetupMocks(MOCK_KEY_EXISTS | MOCK_KEY_UPLOADED, certificate); Run(); } TEST_F(AttestationPolicyObserverTest, KeyExistsCertExpiringSoon) { std::string certificate; - ASSERT_TRUE(CreateCertificate(CERT_EXPIRING_SOON, &certificate)); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(kCertExpiringSoon), + &certificate)); SetupMocks(MOCK_KEY_EXISTS | MOCK_KEY_UPLOADED | MOCK_NEW_KEY, certificate); Run(); } TEST_F(AttestationPolicyObserverTest, KeyExistsCertExpired) { std::string certificate; - ASSERT_TRUE(CreateCertificate(CERT_EXPIRED, &certificate)); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(kCertExpired), + &certificate)); SetupMocks(MOCK_KEY_EXISTS | MOCK_KEY_UPLOADED | MOCK_NEW_KEY, certificate); Run(); } diff --git a/chrome/browser/chromeos/attestation/fake_certificate.cc b/chrome/browser/chromeos/attestation/fake_certificate.cc new file mode 100644 index 0000000..b1e8a82 --- /dev/null +++ b/chrome/browser/chromeos/attestation/fake_certificate.cc @@ -0,0 +1,74 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fake_certificate.h" + +#include "base/time/time.h" +#include "crypto/rsa_private_key.h" +#include "net/cert/x509_certificate.h" +#include "net/cert/x509_util.h" + +namespace chromeos { +namespace attestation { + +namespace { + +// A test key encoded as ASN.1 PrivateKeyInfo from PKCS #8. +const uint8 kTestKeyData[] = { + 0x30, 0x82, 0x01, 0x55, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x01, 0x3f, 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, + 0xd9, 0xcd, 0xca, 0xcd, 0xc3, 0xea, 0xbe, 0x72, 0x79, 0x1c, 0x29, 0x37, + 0x39, 0x99, 0x1f, 0xd4, 0xb3, 0x0e, 0xf0, 0x7b, 0x78, 0x77, 0x0e, 0x05, + 0x3b, 0x65, 0x34, 0x12, 0x62, 0xaf, 0xa6, 0x8d, 0x33, 0xce, 0x78, 0xf8, + 0x47, 0x05, 0x1d, 0x98, 0xaa, 0x1b, 0x1f, 0x50, 0x05, 0x5b, 0x3c, 0x19, + 0x3f, 0x80, 0x83, 0x63, 0x63, 0x3a, 0xec, 0xcb, 0x2e, 0x90, 0x4f, 0xf5, + 0x26, 0x76, 0xf1, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x64, + 0x29, 0xc2, 0xd9, 0x6b, 0xfe, 0xf9, 0x84, 0x75, 0x73, 0xe0, 0xf4, 0x77, + 0xb5, 0x96, 0xb0, 0xdf, 0x83, 0xc0, 0x4e, 0x57, 0xf1, 0x10, 0x6e, 0x91, + 0x89, 0x12, 0x30, 0x5e, 0x57, 0xff, 0x14, 0x59, 0x5f, 0x18, 0x86, 0x4e, + 0x4b, 0x17, 0x56, 0xfc, 0x8d, 0x40, 0xdd, 0x74, 0x65, 0xd3, 0xff, 0x67, + 0x64, 0xcb, 0x9c, 0xb4, 0x14, 0x8a, 0x06, 0xb7, 0x13, 0x45, 0x94, 0x16, + 0x7d, 0x3f, 0xe1, 0x02, 0x21, 0x00, 0xf6, 0x0f, 0x31, 0x6d, 0x06, 0xcc, + 0x3b, 0xa0, 0x44, 0x1f, 0xf5, 0xc2, 0x45, 0x2b, 0x10, 0x6c, 0xf9, 0x6f, + 0x8f, 0x87, 0x3d, 0xc0, 0x3b, 0x55, 0x13, 0x37, 0x80, 0xcd, 0x9f, 0xe1, + 0xb7, 0xd9, 0x02, 0x21, 0x00, 0xe2, 0x9a, 0x5f, 0xbf, 0x95, 0x74, 0xb5, + 0x7a, 0x6a, 0xa6, 0x97, 0xbd, 0x75, 0x8c, 0x97, 0x18, 0x24, 0xd6, 0x09, + 0xcd, 0xdc, 0xb5, 0x94, 0xbf, 0xe2, 0x78, 0xaa, 0x20, 0x47, 0x9f, 0x68, + 0x5d, 0x02, 0x21, 0x00, 0xaf, 0x8f, 0x97, 0x8c, 0x5a, 0xd5, 0x4d, 0x95, + 0xc4, 0x05, 0xa9, 0xab, 0xba, 0xfe, 0x46, 0xf1, 0xf9, 0xe7, 0x07, 0x59, + 0x4f, 0x4d, 0xe1, 0x07, 0x8a, 0x76, 0x87, 0x88, 0x2f, 0x13, 0x35, 0xc1, + 0x02, 0x20, 0x24, 0xc3, 0xd9, 0x2f, 0x13, 0x47, 0x99, 0x3e, 0x20, 0x59, + 0xa1, 0x1a, 0xeb, 0x1c, 0x81, 0x53, 0x38, 0x7e, 0xc5, 0x9e, 0x71, 0xe5, + 0xc0, 0x19, 0x95, 0xdb, 0xef, 0xf6, 0x46, 0xc8, 0x95, 0x3d, 0x02, 0x21, + 0x00, 0xaa, 0xb1, 0xff, 0x8a, 0xa2, 0xb2, 0x2b, 0xef, 0x9a, 0x83, 0x3f, + 0xc5, 0xbc, 0xd4, 0x6a, 0x07, 0xe8, 0xc7, 0x0b, 0x2e, 0xd4, 0x0f, 0xf8, + 0x98, 0x68, 0xe1, 0x04, 0xa8, 0x92, 0xd0, 0x10, 0xaa, +}; + +} // namespace + +bool GetFakeCertificate(const base::TimeDelta& expiry, + std::string* certificate) { + base::Time valid_start = base::Time::Now() - base::TimeDelta::FromDays(1); + base::Time valid_expiry = base::Time::Now() + expiry; + if (valid_expiry <= valid_start) + valid_start = valid_expiry - base::TimeDelta::FromDays(1); + scoped_ptr<crypto::RSAPrivateKey> test_key( + crypto::RSAPrivateKey::CreateFromPrivateKeyInfo( + std::vector<uint8>(&kTestKeyData[0], + &kTestKeyData[arraysize(kTestKeyData)]))); + if (!test_key.get()) + return false; + return net::x509_util::CreateSelfSignedCert(test_key.get(), + net::x509_util::DIGEST_SHA256, + "CN=subject", + 12345, + valid_start, + valid_expiry, + certificate); +} + +} // namespace attestation +} // namespace chromeos diff --git a/chrome/browser/chromeos/attestation/fake_certificate.h b/chrome/browser/chromeos/attestation/fake_certificate.h new file mode 100644 index 0000000..2979d93 --- /dev/null +++ b/chrome/browser/chromeos/attestation/fake_certificate.h @@ -0,0 +1,26 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ATTESTATION_FAKE_CERTIFICATE_H_ +#define CHROME_BROWSER_CHROMEOS_ATTESTATION_FAKE_CERTIFICATE_H_ + +#include <string> + +#include "base/time/time.h" + +namespace chromeos { +namespace attestation { + +// Creates a self-signed |certificate| based on constant key material. The +// certificate |expiry| is relative to the current time. The certificate will +// be (or have been) valid from sometime before the current time or expiry, +// whichever is first. This is designed for use in unit tests and runs quickly. +// Returns true on success. +bool GetFakeCertificate(const base::TimeDelta& expiry, + std::string* certificate); + +} // namespace attestation +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_ATTESTATION_FAKE_CERTIFICATE_H_ diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.cc b/chrome/browser/chromeos/attestation/platform_verification_flow.cc index f741263..95767a8 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow.cc @@ -31,6 +31,7 @@ #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" +#include "net/cert/x509_certificate.h" namespace { @@ -143,7 +144,6 @@ void PlatformVerificationFlow::ChallengePlatformKey( return; } if (!IsAttestationEnabled(web_contents)) { - LOG(INFO) << "PlatformVerificationFlow: Feature disabled."; ReportError(callback, POLICY_REJECTED); return; } @@ -208,7 +208,6 @@ void PlatformVerificationFlow::OnConsentResponse( return; } if (consent_response == CONSENT_RESPONSE_DENY) { - LOG(INFO) << "PlatformVerificationFlow: User rejected request."; content::RecordAction( content::UserMetricsAction("PlatformVerificationRejected")); ReportError(context.callback, USER_REJECTED); @@ -228,6 +227,12 @@ void PlatformVerificationFlow::OnConsentResponse( return; } + GetCertificate(context, user->email(), false /* Don't force a new key */); +} + +void PlatformVerificationFlow::GetCertificate(const ChallengeContext& context, + const std::string& user_id, + bool force_new_key) { scoped_ptr<base::Timer> timer(new base::Timer(false, // Don't retain. false)); // Don't repeat. base::Closure timeout_callback = base::Bind( @@ -240,13 +245,13 @@ void PlatformVerificationFlow::OnConsentResponse( &PlatformVerificationFlow::OnCertificateReady, this, context, - user->email(), + user_id, base::Passed(&timer)); attestation_flow_->GetCertificate( PROFILE_CONTENT_PROTECTION_CERTIFICATE, - user->email(), + user_id, context.service_id, - false, // Don't force a new key. + force_new_key, certificate_callback); } @@ -271,6 +276,10 @@ void PlatformVerificationFlow::OnCertificateReady( ReportError(context.callback, PLATFORM_NOT_VERIFIED); return; } + if (IsExpired(certificate)) { + GetCertificate(context, user_id, true /* Force a new key */); + return; + } cryptohome::AsyncMethodCaller::DataCallback cryptohome_callback = base::Bind( &PlatformVerificationFlow::OnChallengeReady, this, @@ -311,7 +320,6 @@ void PlatformVerificationFlow::OnChallengeReady( signed_data_pb.data(), signed_data_pb.signature(), certificate); - LOG(INFO) << "PlatformVerificationFlow: Platform successfully verified."; } PrefService* PlatformVerificationFlow::GetPrefs( @@ -442,5 +450,16 @@ void PlatformVerificationFlow::RecordDomainConsent( } } +bool PlatformVerificationFlow::IsExpired(const std::string& certificate) { + scoped_refptr<net::X509Certificate> x509( + net::X509Certificate::CreateFromBytes(certificate.data(), + certificate.length())); + if (!x509.get() || x509->valid_expiry().is_null()) { + LOG(WARNING) << "Failed to parse certificate, cannot check expiry."; + return false; + } + return (base::Time::Now() > x509->valid_expiry()); +} + } // namespace attestation } // namespace chromeos diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow.h b/chrome/browser/chromeos/attestation/platform_verification_flow.h index 0e4e169..e21c024 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow.h +++ b/chrome/browser/chromeos/attestation/platform_verification_flow.h @@ -180,6 +180,15 @@ class PlatformVerificationFlow bool consent_required, ConsentResponse consent_response); + // Initiates the flow to get a platform key certificate. The arguments to + // ChallengePlatformKey are in |context|. |user_id| identifies the user for + // which to get a certificate. If |force_new_key| is true then any existing + // key for the same user and service will be ignored and a new key will be + // generated and certified. + void GetCertificate(const ChallengeContext& context, + const std::string& user_id, + bool force_new_key); + // A callback called when an attestation certificate request operation // completes. The arguments to ChallengePlatformKey are in |context|. // |user_id| identifies the user for which the certificate was requested. @@ -252,6 +261,9 @@ class PlatformVerificationFlow const GURL& url, bool allow_domain); + // Returns true iff |certificate| is an expired X.509 certificate. + bool IsExpired(const std::string& certificate); + void set_testing_prefs(PrefService* testing_prefs) { testing_prefs_ = testing_prefs; } diff --git a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc index b817405..a46081d 100644 --- a/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc +++ b/chrome/browser/chromeos/attestation/platform_verification_flow_unittest.cc @@ -10,6 +10,7 @@ #include "base/prefs/testing_pref_service.h" #include "base/run_loop.h" #include "chrome/browser/chromeos/attestation/attestation_signed_data.pb.h" +#include "chrome/browser/chromeos/attestation/fake_certificate.h" #include "chrome/browser/chromeos/attestation/platform_verification_flow.h" #include "chrome/browser/chromeos/login/mock_user_manager.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -123,6 +124,7 @@ class PlatformVerificationFlowTest : public ::testing::Test { : message_loop_(base::MessageLoop::TYPE_UI), ui_thread_(content::BrowserThread::UI, &message_loop_), certificate_success_(true), + fake_certificate_index_(0), sign_challenge_success_(true), result_(PlatformVerificationFlow::INTERNAL_ERROR) {} @@ -265,10 +267,14 @@ class PlatformVerificationFlowTest : public ::testing::Test { void FakeGetCertificate( const AttestationFlow::CertificateCallback& callback) { + std::string certificate = + (fake_certificate_index_ < fake_certificate_list_.size()) ? + fake_certificate_list_[fake_certificate_index_] : kTestCertificate; base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, certificate_success_, - kTestCertificate)); + certificate)); + ++fake_certificate_index_; } void FakeSignChallenge( @@ -317,6 +323,8 @@ class PlatformVerificationFlowTest : public ::testing::Test { // Controls result of FakeGetCertificate. bool certificate_success_; + std::vector<std::string> fake_certificate_list_; + size_t fake_certificate_index_; // Controls result of FakeSignChallenge. bool sign_challenge_success_; @@ -459,5 +467,18 @@ TEST_F(PlatformVerificationFlowTest, Timeout) { EXPECT_EQ(PlatformVerificationFlow::TIMEOUT, result_); } +TEST_F(PlatformVerificationFlowTest, ExpiredCert) { + ExpectAttestationFlow(); + fake_certificate_list_.resize(2); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(-1), + &fake_certificate_list_[0])); + ASSERT_TRUE(GetFakeCertificate(base::TimeDelta::FromDays(1), + &fake_certificate_list_[1])); + verifier_->ChallengePlatformKey(NULL, kTestID, kTestChallenge, callback_); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(PlatformVerificationFlow::SUCCESS, result_); + EXPECT_EQ(certificate_, fake_certificate_list_[1]); +} + } // namespace attestation } // namespace chromeos diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index d07dba3..62789c4 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -599,6 +599,8 @@ 'browser/chromeos/accessibility/magnification_manager_unittest.cc', 'browser/chromeos/attestation/attestation_ca_client_unittest.cc', 'browser/chromeos/attestation/attestation_policy_observer_unittest.cc', + 'browser/chromeos/attestation/fake_certificate.cc', + 'browser/chromeos/attestation/fake_certificate.h', 'browser/chromeos/attestation/platform_verification_flow_unittest.cc', 'browser/chromeos/contacts/contact_database_unittest.cc', 'browser/chromeos/contacts/contact_manager_stub.cc', |