nacl_validation_cache.cc 3.5 KB

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