123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // 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 "components/nacl/browser/nacl_validation_cache.h"
- #include "base/containers/adapters.h"
- #include "base/pickle.h"
- #include "base/rand_util.h"
- namespace nacl {
- // For the moment, choose an arbitrary cache size.
- const size_t kValidationCacheCacheSize = 500;
- // Key size is equal to the block size (not the digest size) of SHA256.
- const size_t kValidationCacheKeySize = 64;
- // Entry size is equal to the digest size of SHA256.
- const size_t kValidationCacheEntrySize = 32;
- const char kValidationCacheBeginMagic[] = "NaCl";
- const char kValidationCacheEndMagic[] = "Done";
- NaClValidationCache::NaClValidationCache()
- : validation_cache_(kValidationCacheCacheSize) {
- // Make sure the cache key is unpredictable, even if the cache has not
- // been loaded.
- Reset();
- }
- NaClValidationCache::~NaClValidationCache() {
- // Make clang's style checking happy by adding a destructor.
- }
- bool NaClValidationCache::QueryKnownToValidate(const std::string& signature,
- bool reorder) {
- if (signature.length() == kValidationCacheEntrySize) {
- ValidationCacheType::iterator iter;
- if (reorder) {
- iter = validation_cache_.Get(signature);
- } else {
- iter = validation_cache_.Peek(signature);
- }
- if (iter != validation_cache_.end()) {
- return iter->second;
- }
- }
- return false;
- }
- void NaClValidationCache::SetKnownToValidate(const std::string& signature) {
- if (signature.length() == kValidationCacheEntrySize) {
- validation_cache_.Put(signature, true);
- }
- }
- void NaClValidationCache::Serialize(base::Pickle* pickle) const {
- // Mark the beginning of the data stream.
- pickle->WriteString(kValidationCacheBeginMagic);
- pickle->WriteString(validation_cache_key_);
- pickle->WriteInt(validation_cache_.size());
- // Serialize the cache in reverse order so that deserializing it can easily
- // preserve the MRU order. (Last item deserialized => most recently used.)
- ValidationCacheType::const_reverse_iterator iter;
- for (const auto& [signature, value] : base::Reversed(validation_cache_)) {
- pickle->WriteString(signature);
- }
- // Mark the end of the data stream.
- pickle->WriteString(kValidationCacheEndMagic);
- }
- void NaClValidationCache::Reset() {
- validation_cache_key_ = base::RandBytesAsString(kValidationCacheKeySize);
- validation_cache_.Clear();
- }
- bool NaClValidationCache::Deserialize(const base::Pickle* pickle) {
- bool success = DeserializeImpl(pickle);
- if (!success) {
- Reset();
- }
- return success;
- }
- bool NaClValidationCache::DeserializeImpl(const base::Pickle* pickle) {
- base::PickleIterator iter(*pickle);
- std::string buffer;
- int count;
- // Magic
- if (!iter.ReadString(&buffer))
- return false;
- if (0 != buffer.compare(kValidationCacheBeginMagic))
- return false;
- // Key
- if (!iter.ReadString(&buffer))
- return false;
- if (buffer.size() != kValidationCacheKeySize)
- return false;
- validation_cache_key_ = buffer;
- validation_cache_.Clear();
- // Cache entries
- if (!iter.ReadInt(&count))
- return false;
- for (int i = 0; i < count; ++i) {
- if (!iter.ReadString(&buffer))
- return false;
- if (buffer.size() != kValidationCacheEntrySize)
- return false;
- validation_cache_.Put(buffer, true);
- }
- // Magic
- if (!iter.ReadString(&buffer))
- return false;
- if (0 != buffer.compare(kValidationCacheEndMagic))
- return false;
- // Success!
- return true;
- }
- } // namespace nacl
|