// Copyright (c) 2012 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 "base/base64.h"
#include "base/format_macros.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/sys_byteorder.h"
#include "base/time.h"
#include "base/values.h"
#include "crypto/sha2.h"
#include "net/base/crl_set.h"

#if defined(USE_SYSTEM_ZLIB)
#include <zlib.h>
#else
#include "third_party/zlib/zlib.h"
#endif

namespace net {

// Decompress zlib decompressed |in| into |out|. |out_len| is the number of
// bytes at |out| and must be exactly equal to the size of the decompressed
// data.
static bool DecompressZlib(uint8* out, int out_len, base::StringPiece in) {
  z_stream z;
  memset(&z, 0, sizeof(z));

  z.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(in.data()));
  z.avail_in = in.size();
  z.next_out = reinterpret_cast<Bytef*>(out);
  z.avail_out = out_len;

  if (inflateInit(&z) != Z_OK)
    return false;
  bool ret = false;
  int r = inflate(&z, Z_FINISH);
  if (r != Z_STREAM_END)
    goto err;
  if (z.avail_in || z.avail_out)
    goto err;
  ret = true;

 err:
  inflateEnd(&z);
  return ret;
}

CRLSet::CRLSet()
    : sequence_(0),
      not_after_(0) {
}

CRLSet::~CRLSet() {
}

// CRLSet format:
//
// uint16le header_len
// byte[header_len] header_bytes
// repeated {
//   byte[32] parent_spki_sha256
//   uint32le num_serials
//   [num_serials] {
//     uint8 serial_length;
//     byte[serial_length] serial;
//   }
//
// header_bytes consists of a JSON dictionary with the following keys:
//   Version (int): currently 0
//   ContentType (string): "CRLSet" or "CRLSetDelta" (magic value)
//   DeltaFrom (int32): if this is a delta update (see below), then this
//       contains the sequence number of the base CRLSet.
//   Sequence (int32): the monotonic sequence number of this CRL set.
//
// A delta CRLSet is similar to a CRLSet:
//
// struct CompressedChanges {
//    uint32le uncompressed_size
//    uint32le compressed_size
//    byte[compressed_size] zlib_data
// }
//
// uint16le header_len
// byte[header_len] header_bytes
// CompressedChanges crl_changes
// [crl_changes.uncompressed_size] {
//   switch (crl_changes[i]) {
//   case 0:
//     // CRL is the same
//   case 1:
//     // New CRL inserted
//     // See CRL structure from the non-delta format
//   case 2:
//     // CRL deleted
//   case 3:
//     // CRL changed
//     CompressedChanges serials_changes
//     [serials_changes.uncompressed_size] {
//       switch (serials_changes[i]) {
//       case 0:
//         // the serial is the same
//       case 1:
//         // serial inserted
//         uint8 serial_length
//         byte[serial_length] serial
//       case 2:
//         // serial deleted
//       }
//     }
//   }
// }
//
// A delta CRLSet applies to a specific CRL set as given in the
// header's "DeltaFrom" value. The delta describes the changes to each CRL
// in turn with a zlib compressed array of options: either the CRL is the same,
// a new CRL is inserted, the CRL is deleted or the CRL is updated. In the case
// of an update, the serials in the CRL are considered in the same fashion
// except there is no delta update of a serial number: they are either
// inserted, deleted or left the same.

// ReadHeader reads the header (including length prefix) from |data| and
// updates |data| to remove the header on return. Caller takes ownership of the
// returned pointer.
static base::DictionaryValue* ReadHeader(base::StringPiece* data) {
  if (data->size() < 2)
    return NULL;
  uint16 header_len;
  // Data is in little endian format
  memcpy(&header_len, data->data(), 2);
  header_len = base::ByteSwapToLE16(header_len);
  data->remove_prefix(2);

  if (data->size() < header_len)
    return NULL;

  const base::StringPiece header_bytes(data->data(), header_len);
  data->remove_prefix(header_len);

  scoped_ptr<Value> header(base::JSONReader::Read(
      header_bytes, base::JSON_ALLOW_TRAILING_COMMAS));
  if (header.get() == NULL)
    return NULL;

  if (!header->IsType(Value::TYPE_DICTIONARY))
    return NULL;
  return reinterpret_cast<base::DictionaryValue*>(header.release());
}

// kCurrentFileVersion is the version of the CRLSet file format that we
// currently implement.
static const int kCurrentFileVersion = 0;

static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash,
                    std::vector<std::string>* out_serials) {
  if (data->size() < crypto::kSHA256Length)
    return false;
  *out_parent_spki_hash = std::string(data->data(), crypto::kSHA256Length);
  data->remove_prefix(crypto::kSHA256Length);

  if (data->size() < sizeof(uint32))
    return false;
  uint32 num_serials;
  // Data is in little endian format
  memcpy(&num_serials, data->data(), sizeof(uint32));
  num_serials = base::ByteSwapToLE32(num_serials);
  data->remove_prefix(sizeof(uint32));

  for (uint32 i = 0; i < num_serials; ++i) {
    uint8 serial_length;
    if (data->size() < sizeof(uint8))
      return false;
    memcpy(&serial_length, data->data(), sizeof(uint8));
    data->remove_prefix(sizeof(uint8));

    if (data->size() < serial_length)
      return false;
    std::string serial(data->data(), serial_length);
    data->remove_prefix(serial_length);
    out_serials->push_back(serial);
  }

  return true;
}

bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) {
  ListValue* blocked_spkis_list = NULL;
  if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) {
    // BlockedSPKIs is optional, so it's fine if we don't find it.
    return true;
  }

  blocked_spkis_.clear();

  for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) {
    std::string spki_sha256_base64, spki_sha256;
    if (!blocked_spkis_list->GetString(i, &spki_sha256_base64))
      return false;
    if (!base::Base64Decode(spki_sha256_base64, &spki_sha256))
      return false;
    blocked_spkis_.push_back(spki_sha256);
  }

  return true;
}

// static
bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) {
  scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
  if (!header_dict.get())
    return false;

  std::string contents;
  if (!header_dict->GetString("ContentType", &contents))
    return false;
  if (contents != "CRLSet")
    return false;

  int version;
  if (!header_dict->GetInteger("Version", &version) ||
      version != kCurrentFileVersion) {
    return false;
  }

  int sequence;
  if (!header_dict->GetInteger("Sequence", &sequence))
    return false;

  double not_after;
  if (!header_dict->GetDouble("NotAfter", &not_after)) {
    // NotAfter is optional for now.
    not_after = 0;
  }
  if (not_after < 0)
    return false;

  scoped_refptr<CRLSet> crl_set(new CRLSet);
  crl_set->sequence_ = static_cast<uint32>(sequence);
  crl_set->not_after_ = static_cast<uint64>(not_after);

  for (size_t crl_index = 0; !data.empty(); crl_index++) {
    std::string parent_spki_sha256;
    std::vector<std::string> serials;
    if (!ReadCRL(&data, &parent_spki_sha256, &serials))
      return false;

    crl_set->crls_.push_back(std::make_pair(parent_spki_sha256, serials));
    crl_set->crls_index_by_issuer_[parent_spki_sha256] = crl_index;
  }

  if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get()))
    return false;

  *out_crl_set = crl_set;
  return true;
}

// kMaxUncompressedChangesLength is the largest changes array that we'll
// accept. This bounds the number of CRLs in the CRLSet as well as the number
// of serial numbers in a given CRL.
static const unsigned kMaxUncompressedChangesLength = 1024 * 1024;

static bool ReadChanges(base::StringPiece* data,
                        std::vector<uint8>* out_changes) {
  uint32 uncompressed_size, compressed_size;
  if (data->size() < 2 * sizeof(uint32))
    return false;
  // Data is in little endian format
  memcpy(&uncompressed_size, data->data(), sizeof(uint32));
  uncompressed_size = base::ByteSwapToLE32(uncompressed_size);
  data->remove_prefix(4);
  memcpy(&compressed_size, data->data(), sizeof(uint32));
  compressed_size = base::ByteSwapToLE32(compressed_size);
  data->remove_prefix(4);

  if (uncompressed_size > kMaxUncompressedChangesLength)
    return false;
  if (data->size() < compressed_size)
    return false;

  out_changes->clear();
  if (uncompressed_size == 0)
    return true;

  out_changes->resize(uncompressed_size);
  base::StringPiece compressed(data->data(), compressed_size);
  data->remove_prefix(compressed_size);
  return DecompressZlib(&(*out_changes)[0], uncompressed_size, compressed);
}

// These are the range coder symbols used in delta updates.
enum {
  SYMBOL_SAME = 0,
  SYMBOL_INSERT = 1,
  SYMBOL_DELETE = 2,
  SYMBOL_CHANGED = 3,
};

bool ReadDeltaCRL(base::StringPiece* data,
                  const std::vector<std::string>& old_serials,
                  std::vector<std::string>* out_serials) {
  std::vector<uint8> changes;
  if (!ReadChanges(data, &changes))
    return false;

  size_t i = 0;
  for (std::vector<uint8>::const_iterator k = changes.begin();
       k != changes.end(); ++k) {
    if (*k == SYMBOL_SAME) {
      if (i >= old_serials.size())
        return false;
      out_serials->push_back(old_serials[i]);
      i++;
    } else if (*k == SYMBOL_INSERT) {
      uint8 serial_length;
      if (data->size() < sizeof(uint8))
        return false;
      memcpy(&serial_length, data->data(), sizeof(uint8));
      data->remove_prefix(sizeof(uint8));

      if (data->size() < serial_length)
        return false;
      const std::string serial(data->data(), serial_length);
      data->remove_prefix(serial_length);

      out_serials->push_back(serial);
    } else if (*k == SYMBOL_DELETE) {
      if (i >= old_serials.size())
        return false;
      i++;
    } else {
      NOTREACHED();
      return false;
    }
  }

  if (i != old_serials.size())
    return false;
  return true;
}

bool CRLSet::ApplyDelta(const base::StringPiece& in_data,
                        scoped_refptr<CRLSet>* out_crl_set) {
  base::StringPiece data(in_data);
  scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
  if (!header_dict.get())
    return false;

  std::string contents;
  if (!header_dict->GetString("ContentType", &contents))
    return false;
  if (contents != "CRLSetDelta")
    return false;

  int version;
  if (!header_dict->GetInteger("Version", &version) ||
      version != kCurrentFileVersion) {
    return false;
  }

  int sequence, delta_from;
  if (!header_dict->GetInteger("Sequence", &sequence) ||
      !header_dict->GetInteger("DeltaFrom", &delta_from) ||
      delta_from < 0 ||
      static_cast<uint32>(delta_from) != sequence_) {
    return false;
  }

  double not_after;
  if (!header_dict->GetDouble("NotAfter", &not_after)) {
    // NotAfter is optional for now.
    not_after = 0;
  }
  if (not_after < 0)
    return false;

  scoped_refptr<CRLSet> crl_set(new CRLSet);
  crl_set->sequence_ = static_cast<uint32>(sequence);
  crl_set->not_after_ = static_cast<uint64>(not_after);

  if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get()))
    return false;

  std::vector<uint8> crl_changes;

  if (!ReadChanges(&data, &crl_changes))
    return false;

  size_t i = 0, j = 0;
  for (std::vector<uint8>::const_iterator k = crl_changes.begin();
       k != crl_changes.end(); ++k) {
    if (*k == SYMBOL_SAME) {
      if (i >= crls_.size())
        return false;
      crl_set->crls_.push_back(crls_[i]);
      crl_set->crls_index_by_issuer_[crls_[i].first] = j;
      i++;
      j++;
    } else if (*k == SYMBOL_INSERT) {
      std::string parent_spki_hash;
      std::vector<std::string> serials;
      if (!ReadCRL(&data, &parent_spki_hash, &serials))
        return false;
      crl_set->crls_.push_back(std::make_pair(parent_spki_hash, serials));
      crl_set->crls_index_by_issuer_[parent_spki_hash] = j;
      j++;
    } else if (*k == SYMBOL_DELETE) {
      if (i >= crls_.size())
        return false;
      i++;
    } else if (*k == SYMBOL_CHANGED) {
      if (i >= crls_.size())
        return false;
      std::vector<std::string> serials;
      if (!ReadDeltaCRL(&data, crls_[i].second, &serials))
        return false;
      crl_set->crls_.push_back(std::make_pair(crls_[i].first, serials));
      crl_set->crls_index_by_issuer_[crls_[i].first] = j;
      i++;
      j++;
    } else {
      NOTREACHED();
      return false;
    }
  }

  if (!data.empty())
    return false;
  if (i != crls_.size())
    return false;

  *out_crl_set = crl_set;
  return true;
}

// static
bool CRLSet::GetIsDeltaUpdate(const base::StringPiece& in_data,
                              bool* is_delta) {
  base::StringPiece data(in_data);
  scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
  if (!header_dict.get())
    return false;

  std::string contents;
  if (!header_dict->GetString("ContentType", &contents))
    return false;

  if (contents == "CRLSet") {
    *is_delta = false;
  } else if (contents == "CRLSetDelta") {
    *is_delta = true;
  } else {
    return false;
  }

  return true;
}

std::string CRLSet::Serialize() const {
  std::string header = StringPrintf(
      "{"
      "\"Version\":0,"
      "\"ContentType\":\"CRLSet\","
      "\"Sequence\":%u,"
      "\"DeltaFrom\":0,"
      "\"NumParents\":%u,"
      "\"BlockedSPKIs\":[",
      static_cast<unsigned>(sequence_),
      static_cast<unsigned>(crls_.size()));

  for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin();
       i != blocked_spkis_.end(); ++i) {
    std::string spki_hash_base64;
    base::Base64Encode(*i, &spki_hash_base64);

    if (i != blocked_spkis_.begin())
      header += ",";
    header += "\"" + spki_hash_base64 + "\"";
  }
  header += "]";
  if (not_after_ != 0)
    header += StringPrintf(",\"NotAfter\":%" PRIu64, not_after_);
  header += "}";

  size_t len = 2 /* header len */ + header.size();

  for (CRLList::const_iterator i = crls_.begin(); i != crls_.end(); ++i) {
    len += i->first.size() + 4 /* num serials */;
    for (std::vector<std::string>::const_iterator j = i->second.begin();
         j != i->second.end(); ++j) {
      len += 1 /* serial length */ + j->size();
    }
  }

  std::string ret;
  char* out = WriteInto(&ret, len + 1 /* to include final NUL */);
  size_t off = 0;
  out[off++] = header.size();
  out[off++] = header.size() >> 8;
  memcpy(out + off, header.data(), header.size());
  off += header.size();

  for (CRLList::const_iterator i = crls_.begin(); i != crls_.end(); ++i) {
    memcpy(out + off, i->first.data(), i->first.size());
    off += i->first.size();
    // num_serials is stored in little endian format
    const uint32 num_serials = base::ByteSwapToLE32(i->second.size());
    memcpy(out + off, &num_serials, sizeof(num_serials));
    off += sizeof(num_serials);

    for (std::vector<std::string>::const_iterator j = i->second.begin();
         j != i->second.end(); ++j) {
      out[off++] = j->size();
      memcpy(out + off, j->data(), j->size());
      off += j->size();
    }
  }

  CHECK_EQ(off, len);
  return ret;
}

CRLSet::Result CRLSet::CheckSPKI(const base::StringPiece& spki_hash) const {
  for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin();
       i != blocked_spkis_.end(); ++i) {
    if (spki_hash.size() == i->size() &&
        memcmp(spki_hash.data(), i->data(), i->size()) == 0) {
      return REVOKED;
    }
  }

  return GOOD;
}

CRLSet::Result CRLSet::CheckSerial(
    const base::StringPiece& serial_number,
    const base::StringPiece& issuer_spki_hash) const {
  base::StringPiece serial(serial_number);

  if (!serial.empty() && (serial[0] & 0x80) != 0) {
    // This serial number is negative but the process which generates CRL sets
    // will reject any certificates with negative serial numbers as invalid.
    return UNKNOWN;
  }

  // Remove any leading zero bytes.
  while (serial.size() > 1 && serial[0] == 0x00)
    serial.remove_prefix(1);

  std::map<std::string, size_t>::const_iterator i =
      crls_index_by_issuer_.find(issuer_spki_hash.as_string());
  if (i == crls_index_by_issuer_.end())
    return UNKNOWN;
  const std::vector<std::string>& serials = crls_[i->second].second;

  for (std::vector<std::string>::const_iterator i = serials.begin();
       i != serials.end(); ++i) {
    if (base::StringPiece(*i) == serial)
      return REVOKED;
  }

  return GOOD;
}

bool CRLSet::IsExpired() const {
  if (not_after_ == 0)
    return false;

  uint64 now = base::Time::Now().ToTimeT();
  return now > not_after_;
}

uint32 CRLSet::sequence() const {
  return sequence_;
}

const CRLSet::CRLList& CRLSet::crls() const {
  return crls_;
}

// static
CRLSet* CRLSet::EmptyCRLSetForTesting() {
  return new CRLSet;
}

CRLSet* CRLSet::ExpiredCRLSetForTesting() {
  CRLSet* crl_set = new CRLSet;
  crl_set->not_after_ = 1;
  return crl_set;
}

}  // namespace net
