// 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/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 (iter = validation_cache_.rbegin();
       iter != validation_cache_.rend();
       ++iter) {
    pickle->WriteString(iter->first);
  }

  // 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

