// Copyright 2010 The Chromium Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "pem.h"
#include "string_util.h"

#include <array>
#include <limits>
#include <string_view>

namespace {

constexpr std::string_view kPEMHeaderBeginBlock = "-----BEGIN ";
constexpr std::string_view kPEMHeaderEndBlock = "-----END ";
constexpr std::string_view kPEMHeaderTail = "-----";

}  // namespace

BSSL_NAMESPACE_BEGIN



struct PEMTokenizer::PEMType {
  std::string type;
  std::string header;
  std::string footer;
};

PEMTokenizer::PEMTokenizer(
    std::string_view str, const std::vector<std::string> &allowed_block_types) {
  std::vector<std::string_view> types;
  for (const auto &type : allowed_block_types) {
    types.emplace_back(type);
  }
  Init(str, bssl::Span(types));
}

PEMTokenizer::PEMTokenizer(
    std::string_view str,
    bssl::Span<const std::string_view> allowed_block_types) {
  Init(str, allowed_block_types);
}

PEMTokenizer::~PEMTokenizer() = default;

bool PEMTokenizer::GetNext() {
  while (pos_ != std::string_view::npos) {
    // Scan for the beginning of the next PEM encoded block.
    pos_ = str_.find(kPEMHeaderBeginBlock, pos_);
    if (pos_ == std::string_view::npos) {
      return false;  // No more PEM blocks
    }

    std::vector<PEMType>::const_iterator it;
    // Check to see if it is of an acceptable block type.
    for (it = block_types_.begin(); it != block_types_.end(); ++it) {
      if (!bssl::string_util::StartsWith(str_.substr(pos_), it->header)) {
        continue;
      }

      // Look for a footer matching the header. If none is found, then all
      // data following this point is invalid and should not be parsed.
      std::string_view::size_type footer_pos = str_.find(it->footer, pos_);
      if (footer_pos == std::string_view::npos) {
        pos_ = std::string_view::npos;
        return false;
      }

      // Chop off the header and footer and parse the data in between.
      std::string_view::size_type data_begin = pos_ + it->header.size();
      pos_ = footer_pos + it->footer.size();
      block_type_ = it->type;

      // Arbitrarily limit PEM data to INT_MAX / 2 bytes, which "ought to be
      // enough for anyone". Hardens against possible integer overflows
      // downstream.
      if (footer_pos - data_begin > static_cast<std::string_view::size_type>(
                                        std::numeric_limits<int>::max() / 2)) {
        return false;
      }

      // Remove whitespace from the base64 data.
      std::string_view encoded =
          str_.substr(data_begin, footer_pos - data_begin);
      std::string trimmed;
      trimmed.reserve(encoded.size());
      for (char c : encoded) {
        if (c != '\n' && c != '\r' && c != ' ' && c != '\t') {
          trimmed.push_back(c);
        }
      }

      if (!string_util::Base64Decode(trimmed, &data_)) {
        // The most likely cause for a decode failure is a datatype that
        // includes PEM headers, which are not supported.
        break;
      }

      return true;
    }

    // If the block did not match any acceptable type, move past it and
    // continue the search. Otherwise, `pos_` has been updated to the most
    // appropriate search position to continue searching from and should not
    // be adjusted.
    if (it == block_types_.end()) {
      pos_ += kPEMHeaderBeginBlock.size();
    }
  }

  return false;
}

void PEMTokenizer::Init(std::string_view str,
                        bssl::Span<const std::string_view> allowed_block_types) {
  str_ = str;
  pos_ = 0;

  // Construct PEM header/footer strings for all the accepted types, to
  // reduce parsing later.
  for (const auto &allowed_block_type : allowed_block_types) {
    PEMType allowed_type;
    allowed_type.type = allowed_block_type;
    allowed_type.header = kPEMHeaderBeginBlock;
    allowed_type.header.append(allowed_block_type);
    allowed_type.header.append(kPEMHeaderTail);
    allowed_type.footer = kPEMHeaderEndBlock;
    allowed_type.footer.append(allowed_block_type);
    allowed_type.footer.append(kPEMHeaderTail);
    block_types_.push_back(allowed_type);
  }
}

std::vector<PEMToken> PEMDecode(
    std::string_view data, bssl::Span<const std::string_view> allowed_types) {
  std::vector<PEMToken> results;
  PEMTokenizer tokenizer(data, allowed_types);
  while (tokenizer.GetNext()) {
    results.push_back(PEMToken{tokenizer.block_type(), tokenizer.data()});
  }
  return results;
}

std::optional<std::string> PEMDecodeSingle(
    std::string_view data, std::string_view allowed_type) {
  const std::array<const std::string_view, 1> allowed_types = {allowed_type};
  PEMTokenizer tokenizer(data, allowed_types);
  if (!tokenizer.GetNext()) {
    return std::nullopt;
  }

  std::string result = tokenizer.data();

  // We need exactly one token of the allowed types, so return nullopt if
  // there's more than one.
  if (tokenizer.GetNext()) {
    return std::nullopt;
  }

  return result;
}

std::string PEMEncode(std::string_view data, const std::string &type) {
  std::string b64_encoded;
  string_util::Base64Encode(data, &b64_encoded);

  // Divide the Base-64 encoded data into 64-character chunks, as per
  // 4.3.2.4 of RFC 1421.
  static const size_t kChunkSize = 64;
  size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize;

  std::string pem_encoded;
  pem_encoded.reserve(
      // header & footer
      17 + 15 + type.size() * 2 +
      // encoded data
      b64_encoded.size() +
      // newline characters for line wrapping in encoded data
      chunks);

  pem_encoded = kPEMHeaderBeginBlock;
  pem_encoded.append(type);
  pem_encoded.append(kPEMHeaderTail);
  pem_encoded.append("\n");

  for (size_t i = 0, chunk_offset = 0; i < chunks;
       ++i, chunk_offset += kChunkSize) {
    pem_encoded.append(b64_encoded, chunk_offset, kChunkSize);
    pem_encoded.append("\n");
  }

  pem_encoded.append(kPEMHeaderEndBlock);
  pem_encoded.append(type);
  pem_encoded.append(kPEMHeaderTail);
  pem_encoded.append("\n");
  return pem_encoded;
}

BSSL_NAMESPACE_END
