Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / nacl / browser / nacl_validation_cache.cc
blobe956cb1815dd1533c8e34131aea2cf90f0db9962
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/nacl/browser/nacl_validation_cache.h"
7 #include "base/pickle.h"
8 #include "base/rand_util.h"
10 namespace nacl {
12 // For the moment, choose an arbitrary cache size.
13 const size_t kValidationCacheCacheSize = 500;
14 // Key size is equal to the block size (not the digest size) of SHA256.
15 const size_t kValidationCacheKeySize = 64;
16 // Entry size is equal to the digest size of SHA256.
17 const size_t kValidationCacheEntrySize = 32;
19 const char kValidationCacheBeginMagic[] = "NaCl";
20 const char kValidationCacheEndMagic[] = "Done";
22 NaClValidationCache::NaClValidationCache()
23 : validation_cache_(kValidationCacheCacheSize) {
24 // Make sure the cache key is unpredictable, even if the cache has not
25 // been loaded.
26 Reset();
29 NaClValidationCache::~NaClValidationCache() {
30 // Make clang's style checking happy by adding a destructor.
33 bool NaClValidationCache::QueryKnownToValidate(const std::string& signature,
34 bool reorder) {
35 if (signature.length() == kValidationCacheEntrySize) {
36 ValidationCacheType::iterator iter;
37 if (reorder) {
38 iter = validation_cache_.Get(signature);
39 } else {
40 iter = validation_cache_.Peek(signature);
42 if (iter != validation_cache_.end()) {
43 return iter->second;
46 return false;
49 void NaClValidationCache::SetKnownToValidate(const std::string& signature) {
50 if (signature.length() == kValidationCacheEntrySize) {
51 validation_cache_.Put(signature, true);
55 void NaClValidationCache::Serialize(base::Pickle* pickle) const {
56 // Mark the beginning of the data stream.
57 pickle->WriteString(kValidationCacheBeginMagic);
58 pickle->WriteString(validation_cache_key_);
59 pickle->WriteInt(validation_cache_.size());
61 // Serialize the cache in reverse order so that deserializing it can easily
62 // preserve the MRU order. (Last item deserialized => most recently used.)
63 ValidationCacheType::const_reverse_iterator iter;
64 for (iter = validation_cache_.rbegin();
65 iter != validation_cache_.rend();
66 ++iter) {
67 pickle->WriteString(iter->first);
70 // Mark the end of the data stream.
71 pickle->WriteString(kValidationCacheEndMagic);
74 void NaClValidationCache::Reset() {
75 validation_cache_key_ = base::RandBytesAsString(kValidationCacheKeySize);
76 validation_cache_.Clear();
79 bool NaClValidationCache::Deserialize(const base::Pickle* pickle) {
80 bool success = DeserializeImpl(pickle);
81 if (!success) {
82 Reset();
84 return success;
87 bool NaClValidationCache::DeserializeImpl(const base::Pickle* pickle) {
88 base::PickleIterator iter(*pickle);
89 std::string buffer;
90 int count;
92 // Magic
93 if (!iter.ReadString(&buffer))
94 return false;
95 if (0 != buffer.compare(kValidationCacheBeginMagic))
96 return false;
98 // Key
99 if (!iter.ReadString(&buffer))
100 return false;
101 if (buffer.size() != kValidationCacheKeySize)
102 return false;
104 validation_cache_key_ = buffer;
105 validation_cache_.Clear();
107 // Cache entries
108 if (!iter.ReadInt(&count))
109 return false;
110 for (int i = 0; i < count; ++i) {
111 if (!iter.ReadString(&buffer))
112 return false;
113 if (buffer.size() != kValidationCacheEntrySize)
114 return false;
115 validation_cache_.Put(buffer, true);
118 // Magic
119 if (!iter.ReadString(&buffer))
120 return false;
121 if (0 != buffer.compare(kValidationCacheEndMagic))
122 return false;
124 // Success!
125 return true;
128 } // namespace nacl