blob: 8a16a67413173cde5affcbff6de2850018f5d9e0 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS 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 CRYPTOHOME_ATTESTATION_H_
#define CRYPTOHOME_ATTESTATION_H_
#include <base/file_path.h>
#include <base/synchronization/lock.h>
#include <base/threading/platform_thread.h>
#include <chromeos/secure_blob.h>
#include <openssl/evp.h>
#include "attestation.pb.h"
namespace cryptohome {
class Platform;
class Tpm;
// This class performs tasks which enable attestation enrollment. These tasks
// include creating an AIK and recording all information about the AIK and EK
// that an attestation server will need to issue credentials for this system. If
// a platform does not have a TPM, this class does nothing.
class Attestation : public base::PlatformThread::Delegate {
public:
Attestation(Tpm* tpm, Platform* platform);
virtual ~Attestation();
// Must be called before any other method.
virtual void Initialize();
// Returns true if the attestation enrollment blobs already exist.
virtual bool IsPreparedForEnrollment();
// Returns true if an AIK certificate exists.
virtual bool IsEnrolled();
// Creates attestation enrollment blobs if they do not already exist. This
// includes extracting the EK information from the TPM and generating an AIK
// to be used later during enrollment.
virtual void PrepareForEnrollment();
// Like PrepareForEnrollment(), but asynchronous.
virtual void PrepareForEnrollmentAsync() {
base::PlatformThread::Create(0, this, &thread_);
}
// Verifies all attestation data as an attestation server would. Returns true
// if all data is valid.
virtual bool Verify();
// Verifies the EK certificate.
virtual bool VerifyEK();
// Creates an enrollment request to be sent to the Privacy CA. This request
// is a serialized AttestationEnrollmentRequest protobuf. Attestation
// enrollment is a process by which the Privacy CA verifies the EK certificate
// of a device and issues a certificate for an AIK. The enrollment process can
// be finished by calling Enroll() with the response from the Privacy CA. This
// method can only succeed if IsPreparedForEnrollment() returns true.
//
// Parameters
// pca_request - The request to be sent to the Privacy CA.
//
// Returns true on success.
virtual bool CreateEnrollRequest(chromeos::SecureBlob* pca_request);
// Finishes the enrollment process. On success, IsEnrolled() will return true.
// The response from the Privacy CA is a serialized
// AttestationEnrollmentResponse protobuf. This method recovers the AIK
// certificate by calling TPM_ActivateIdentity and stores this certificate to
// be used later during a certificate request.
//
// Parameters
// pca_response - The Privacy CA's response to an enrollment request as
// returned by CreateEnrollRequest().
//
// Returns true on success.
virtual bool Enroll(const chromeos::SecureBlob& pca_response);
// Creates an attestation certificate request to be sent to the Privacy CA.
// The reuest is a serialized AttestationCertificateRequest protobuf. The
// certificate request process generates and certifies a key in the TPM and
// sends the AIK certificate along with information about the certified key to
// the Privacy CA. The PCA verifies the information and issues a certificate
// for the ceritified key. The certificate request process can be finished by
// calling FinishCertRequest() with the response from the Privacy CA. This
// method can only succeed if IsEnrolled() returns true.
//
// Parameters
// is_cert_for_owner - Whether the certificate is intended for the device
// owner. If this is true, the PCA may put more
// information into the certificate.
// pca_request - The request to be sent to the Privacy CA.
//
// Returns true on success.
virtual bool CreateCertRequest(bool is_cert_for_owner,
chromeos::SecureBlob* pca_request);
// Finishes the certificate request process. On success, the attestation
// certificate generated by the Privacy CA is provided. The response from the
// Privacy CA is a serialized AttestationCertificateResponse protobuf. This
// final step verifies the PCA operation succeeded and extracts the
// certificate for the certified key.
//
// Parameters
// pca_response - The Privacy CA's response to a certificate request as
// returned by CreateCertRequest().
// attestation_cert - The certificate generated by the PCA.
virtual bool FinishCertRequest(const chromeos::SecureBlob& pca_response,
chromeos::SecureBlob* attestation_cert);
// Sets an alternative attestation database location. Useful in testing.
virtual void set_database_path(const char* path) {
database_path_ = FilePath(path);
}
// PlatformThread::Delegate interface.
virtual void ThreadMain() { PrepareForEnrollment(); }
private:
enum FirmwareType {
kUnknown,
kVerified,
kDeveloper
};
static const size_t kQuoteExternalDataSize;
static const size_t kCipherKeySize;
static const size_t kCipherBlockSize;
static const size_t kNonceSize;
static const size_t kDigestSize;
static const char* kDefaultDatabasePath;
static const char* kDefaultPCAPublicKey;
static const struct CertificateAuthority {
const char* issuer;
const char* modulus; // In hex format.
} kKnownEndorsementCA[];
static const struct PCRValue {
bool developer_mode_enabled;
bool recovery_mode_enabled;
FirmwareType firmware_type;
} kKnownPCRValues[];
Tpm* tpm_;
Platform* platform_;
base::Lock database_pb_lock_;
chromeos::SecureBlob database_key_;
FilePath database_path_;
AttestationDatabase database_pb_;
base::PlatformThreadHandle thread_;
// Moves data from a std::string container to a SecureBlob container.
chromeos::SecureBlob ConvertStringToBlob(const std::string& s);
// Moves data from a chromeos::Blob container to a std::string container.
std::string ConvertBlobToString(const chromeos::Blob& blob);
// Concatenates two SecureBlobs.
chromeos::SecureBlob SecureCat(const chromeos::SecureBlob& blob1,
const chromeos::SecureBlob& blob2);
// Serializes and encrypts an attestation database.
bool EncryptDatabase(const AttestationDatabase& db,
EncryptedData* encrypted_db);
// Decrypts and parses an attestation database.
bool DecryptDatabase(const EncryptedData& encrypted_db,
AttestationDatabase* db);
// Computes an encrypted database HMAC.
std::string ComputeHMAC(const EncryptedData& encrypted_data,
const chromeos::SecureBlob& hmac_key);
// Writes an encrypted database to a persistent storage location.
bool StoreDatabase(const EncryptedData& encrypted_db);
// Reads a database from a persistent storage location.
bool LoadDatabase(EncryptedData* encrypted_db);
// Persists any changes made to database_pb_.
bool PersistDatabaseChanges();
// Ensures permissions of the database file are correct.
void CheckDatabasePermissions();
// Verifies an endorsement credential against known Chrome OS issuers.
bool VerifyEndorsementCredential(const chromeos::SecureBlob& credential,
const chromeos::SecureBlob& public_key);
// Verifies identity key binding data.
bool VerifyIdentityBinding(const IdentityBinding& binding);
// Verifies a quote of PCR0.
bool VerifyQuote(const chromeos::SecureBlob& aik_public_key,
const Quote& quote);
// Verifies a certified key.
bool VerifyCertifiedKey(const chromeos::SecureBlob& aik_public_key,
const chromeos::SecureBlob& certified_public_key,
const chromeos::SecureBlob& certified_key_info,
const chromeos::SecureBlob& proof);
// Creates a public key based on a known credential issuer.
EVP_PKEY* GetAuthorityPublicKey(const char* issuer_name);
// Verifies an RSA-PKCS1-SHA1 digital signature.
bool VerifySignature(const chromeos::SecureBlob& public_key,
const chromeos::SecureBlob& signed_data,
const chromeos::SecureBlob& signature);
// Clears the memory of the database protobuf.
void ClearDatabase();
// Clears the memory of a std::string.
void ClearString(std::string* s);
// Performs AIK activation with a fake credential.
bool VerifyActivateIdentity(const chromeos::SecureBlob& delegate_blob,
const chromeos::SecureBlob& delegate_secret,
const chromeos::SecureBlob& identity_key_blob,
const chromeos::SecureBlob& identity_public_key,
const chromeos::SecureBlob& ek_public_key);
// Encrypts the endorsement credential with the Privacy CA public key.
bool EncryptEndorsementCredential(const chromeos::SecureBlob& credential,
EncryptedData* encrypted_credential);
DISALLOW_COPY_AND_ASSIGN(Attestation);
};
} // namespace cryptohome
#endif // CRYPTOHOME__ATTESTATION_H_