// Copyright 2015 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/logging.h"
#include "base/numerics/safe_math.h"
#include "net/der/parse_values.h"
#include "net/der/parser.h"

namespace net {

namespace der {

Parser::Parser() : input_(Input()), advance_mark_(Mark::NullMark()) {
}

Parser::Parser(const Input& input)
    : input_(input), advance_mark_(Mark::NullMark()) {
}

bool Parser::PeekTagAndValue(Tag* tag, Input* out) {
  ByteReader reader = input_;

  // Don't support tags > 30.
  uint8_t tag_byte;
  if (!reader.ReadByte(&tag_byte))
    return false;

  // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a
  // tag number no greater than 30. This parser only supports tag numbers up
  // to 30.
  // If the tag number is 31 (0x1F, the largest value that fits in the allotted
  // bytes), then the tag is more than one byte long and the continuation bytes
  // contain the real tag number. We only support tag numbers < 31 (and thus
  // single-byte tags).
  if ((tag_byte & kTagNumberMask) == 31)
    return false;

  // Parse length. The format for the length encoding is specified in
  // ITU-T X.690 section 8.1.3.
  size_t value_len = 0;  // Number of bytes used to encode just the value.

  uint8_t length_first_byte;
  if (!reader.ReadByte(&length_first_byte))
    return false;
  if ((length_first_byte & 0x80) == 0) {
    // Short form for length - it's only one byte long.
    value_len = length_first_byte & 0x7f;
  } else {
    // Long form for length - it's encoded across multiple bytes.
    if (length_first_byte == 0xff) {
      // ITU-T X.690 clause 8.1.3.5.c specifies the value 0xff shall not be
      // used.
      return false;
    }
    // The high bit indicated that this is the long form, while the next 7 bits
    // encode the number of subsequent octets used to encode the length
    // (ITU-T X.690 clause 8.1.3.5.b).
    size_t length_len = length_first_byte & 0x7f;
    if (length_len == 0) {
      // ITU-T X.690 section 10.1 (DER length forms) requires encoding the
      // length with the minimum number of octets. Besides, it makes no sense
      // for the length to be encoded in 0 octets.
      return false;
    }
    if (length_len > sizeof(value_len)) {
      // The length is encoded in multiple octets, with the first octet
      // indicating how many octets follow. Those octets need to be combined
      // to form a size_t, so the number of octets to follow (length_len)
      // must be small enough so that they fit in a size_t.
      return false;
    }
    uint8_t length_byte;
    for (size_t i = 0; i < length_len; i++) {
      if (!reader.ReadByte(&length_byte))
        return false;
      // A first length byte of all zeroes means the length was not encoded in
      // minimum length.
      if (i == 0 && length_byte == 0)
        return false;
      value_len <<= 8;
      value_len += length_byte;
    }
    if (value_len < 0x80) {
      // If value_len is < 0x80, then it could have been encoded in a single
      // byte, meaning it was not encoded in minimum length.
      return false;
    }
  }

  if (!reader.ReadBytes(value_len, out))
    return false;
  advance_mark_ = reader.NewMark();
  *tag = tag_byte;
  return true;
}

bool Parser::Advance() {
  if (advance_mark_.IsEmpty())
    return false;
  if (!input_.AdvanceToMark(advance_mark_))
    return false;
  advance_mark_ = Mark::NullMark();
  return true;
}

bool Parser::HasMore() {
  return input_.HasMore();
}

bool Parser::ReadRawTLV(Input* out) {
  Tag tag;
  Input value;
  if (!PeekTagAndValue(&tag, &value))
    return false;
  if (!input_.ReadToMark(advance_mark_, out))
    return false;
  advance_mark_ = Mark::NullMark();

  return true;
}

bool Parser::ReadTagAndValue(Tag* tag, Input* out) {
  if (!PeekTagAndValue(tag, out))
    return false;
  CHECK(Advance());
  return true;
}

bool Parser::ReadOptionalTag(Tag tag, Input* out, bool* present) {
  if (!HasMore()) {
    *present = false;
    return true;
  }

  Tag read_tag;
  Input value;
  if (!PeekTagAndValue(&read_tag, &value))
    return false;
  *present = false;
  if (read_tag == tag) {
    *present = true;
    *out = value;
    CHECK(Advance());
  } else {
    advance_mark_ = Mark::NullMark();
  }
  return true;
}

bool Parser::SkipOptionalTag(Tag tag, bool* present) {
  Input out;
  return ReadOptionalTag(tag, &out, present);
}

bool Parser::ReadTag(Tag tag, Input* out) {
  bool present;
  return ReadOptionalTag(tag, out, &present) && present;
}

bool Parser::SkipTag(Tag tag) {
  Input out;
  return ReadTag(tag, &out);
}

// Type-specific variants of ReadTag

bool Parser::ReadConstructed(Tag tag, Parser* out) {
  if (!IsConstructed(tag))
    return false;
  Input data;
  if (!ReadTag(tag, &data))
    return false;
  *out = Parser(data);
  return true;
}

bool Parser::ReadSequence(Parser* out) {
  return ReadConstructed(kSequence, out);
}

bool Parser::ReadUint64(uint64_t* out) {
  Input encodedInt;
  if (!ReadTag(kInteger, &encodedInt))
    return false;
  return ParseUint64(encodedInt, out);
}

}  // namespace der

}  // namespace net
