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