blob: 757a3372c1a660201b245c1796dad284ead81bda [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.
#include "chaps/object_store.h"
#include <map>
#include <string>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/memory/scoped_ptr.h>
#include <chromeos/secure_blob.h>
#include <gtest/gtest_prod.h>
#include <leveldb/db.h>
#include <leveldb/env.h>
namespace chaps {
// An ObjectStore implementation based on SQLite.
class ObjectStoreImpl : public ObjectStore {
virtual ~ObjectStoreImpl();
// Initializes the object store with the given database path. The magic file
// name ":memory:" will cause the store to create a memory-only database which
// is suitable for testing.
bool Init(const base::FilePath& database_path);
// ObjectStore methods.
virtual bool GetInternalBlob(int blob_id, std::string* blob);
virtual bool SetInternalBlob(int blob_id, const std::string& blob);
virtual bool SetEncryptionKey(const chromeos::SecureBlob& key);
virtual bool InsertObjectBlob(const ObjectBlob& blob, int* handle);
virtual bool DeleteObjectBlob(int handle);
virtual bool DeleteAllObjectBlobs();
virtual bool UpdateObjectBlob(int handle, const ObjectBlob& blob);
virtual bool LoadPublicObjectBlobs(std::map<int, ObjectBlob>* blobs);
virtual bool LoadPrivateObjectBlobs(std::map<int, ObjectBlob>* blobs);
enum BlobType {
// Loads all object of a given type.
bool LoadObjectBlobs(BlobType type, std::map<int, ObjectBlob>* blobs);
// Encrypts an object blob with a random IV and appends an HMAC.
bool Encrypt(const ObjectBlob& plain_text,
ObjectBlob* cipher_text);
// Verifies and decrypts an object blob.
bool Decrypt(const ObjectBlob& cipher_text,
ObjectBlob* plain_text);
// Computes an HMAC and appends it to the given input.
std::string AppendHMAC(const std::string& input,
const chromeos::SecureBlob& key);
// Verifies an appended HMAC and strips it from the given input.
bool VerifyAndStripHMAC(const std::string& input,
const chromeos::SecureBlob& key,
std::string* stripped);
// Creates and returns a unique database key for a blob.
std::string CreateBlobKey(BlobType type, int blob_id);
// Given a valid blob key (as created by CreateBlobKey), determines whether
// the blob is internal, public, or private and the blob id. Returns true on
// success.
bool ParseBlobKey(const std::string& key, BlobType* type, int* blob_id);
// Computes and returns the next (unused) blob id;
bool GetNextID(int* next_id);
// Reads a blob from the database. Returns true on success.
bool ReadBlob(const std::string& key, std::string* value);
// Reads an integer from the database. Returns true on success.
bool ReadInt(const std::string& key, int* value);
// Writes a blob to the database. Returns true on success.
bool WriteBlob(const std::string& key, const std::string& value);
// Writes an integer to the database. Returns true on success.
bool WriteInt(const std::string& key, int value);
// Returns the blob type for the specified blob. If 'blob_id' is unknown,
// kInternal is returned.
BlobType GetBlobType(int blob_id);
// These strings are used to construct database keys for blobs. In general the
// format of a blob database key is: <prefix><separator><id>.
static const char kInternalBlobKeyPrefix[];
static const char kPublicBlobKeyPrefix[];
static const char kPrivateBlobKeyPrefix[];
static const char kBlobKeySeparator[];
// The key for the database version. The existence of this value indicates the
// database is not new.
static const char kDatabaseVersionKey[];
// The database key for the ID tracker, which always holds a value larger than
// any object blob ID in use.
static const char kIDTrackerKey[];
static const int kAESKeySizeBytes;
static const int kHMACSizeBytes;
// The leveldb directory.
static const char kDatabaseDirectory[];
// A directory in which to backup a corrupted database before recreating.
static const char kCorruptDatabaseDirectory[];
// An obfuscation key used for public objects.
static const char kObfuscationKey[];
// The current blob format version.
static const int kBlobVersion;
chromeos::SecureBlob key_;
scoped_ptr<leveldb::Env> env_;
scoped_ptr<leveldb::DB> db_;
std::map<int, BlobType> blob_type_map_;
friend class TestObjectStoreEncryption;
FRIEND_TEST(TestObjectStoreEncryption, EncryptionInit);
FRIEND_TEST(TestObjectStoreEncryption, Encryption);
FRIEND_TEST(TestObjectStoreEncryption, CBCMode);
} // namespace chaps