// Copyright 2014 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 "net/quic/crypto/channel_id_chromium.h"

#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/strings/string_util.h"
#include "crypto/ec_private_key.h"
#include "crypto/ec_signature_creator.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/ssl/channel_id_service.h"
#include "starboard/client_porting/poem/string_poem.h"
#include "starboard/memory.h"
#include "starboard/string.h"

namespace net {

ChannelIDKeyChromium::ChannelIDKeyChromium(
    std::unique_ptr<crypto::ECPrivateKey> ec_private_key)
    : ec_private_key_(std::move(ec_private_key)) {}

ChannelIDKeyChromium::~ChannelIDKeyChromium() {}

bool ChannelIDKeyChromium::Sign(quic::QuicStringPiece signed_data,
                                std::string* out_signature) const {
  std::unique_ptr<crypto::ECSignatureCreator> sig_creator(
      crypto::ECSignatureCreator::Create(ec_private_key_.get()));
  if (!sig_creator) {
    return false;
  }
  const size_t len1 =
      strlen(quic::ChannelIDVerifier::kContextStr) + 1;
  const size_t len2 =
      strlen(quic::ChannelIDVerifier::kClientToServerStr) + 1;
  std::vector<uint8_t> data(len1 + len2 + signed_data.size());
  memcpy(&data[0], quic::ChannelIDVerifier::kContextStr, len1);
  memcpy(&data[len1], quic::ChannelIDVerifier::kClientToServerStr, len2);
  memcpy(&data[len1 + len2], signed_data.data(), signed_data.size());
  std::vector<uint8_t> der_signature;
  if (!sig_creator->Sign(&data[0], data.size(), &der_signature)) {
    return false;
  }
  std::vector<uint8_t> raw_signature;
  if (!sig_creator->DecodeSignature(der_signature, &raw_signature)) {
    return false;
  }
  memcpy(base::WriteInto(out_signature, raw_signature.size() + 1),
               &raw_signature[0], raw_signature.size());
  return true;
}

std::string ChannelIDKeyChromium::SerializeKey() const {
  std::string out_key;
  if (!ec_private_key_->ExportRawPublicKey(&out_key)) {
    return std::string();
  }
  return out_key;
}

// A Job handles the lookup of a single channel ID.  It is owned by the
// quic::ChannelIDSource. If the operation can not complete synchronously, it
// will notify the quic::ChannelIDSource upon completion.
class ChannelIDSourceChromium::Job {
 public:
  Job(ChannelIDSourceChromium* channel_id_source,
      ChannelIDService* channel_id_service);

  // Starts the channel ID lookup.  If |quic::QUIC_PENDING| is returned, then
  // |callback| will be invoked asynchronously when the operation completes.
  quic::QuicAsyncStatus GetChannelIDKey(
      const std::string& hostname,
      std::unique_ptr<quic::ChannelIDKey>* channel_id_key,
      quic::ChannelIDSourceCallback* callback);

 private:
  enum State {
    STATE_NONE,
    STATE_GET_CHANNEL_ID_KEY,
    STATE_GET_CHANNEL_ID_KEY_COMPLETE,
  };

  int DoLoop(int last_io_result);
  void OnIOComplete(int result);
  int DoGetChannelIDKey(int result);
  int DoGetChannelIDKeyComplete(int result);

  // Channel ID source to notify when this jobs completes.
  ChannelIDSourceChromium* const channel_id_source_;

  ChannelIDService* const channel_id_service_;

  std::unique_ptr<crypto::ECPrivateKey> channel_id_crypto_key_;
  ChannelIDService::Request channel_id_request_;

  // |hostname| specifies the hostname for which we need a channel ID.
  std::string hostname_;

  std::unique_ptr<quic::ChannelIDSourceCallback> callback_;

  std::unique_ptr<quic::ChannelIDKey> channel_id_key_;

  State next_state_;

  DISALLOW_COPY_AND_ASSIGN(Job);
};

ChannelIDSourceChromium::Job::Job(ChannelIDSourceChromium* channel_id_source,
                                  ChannelIDService* channel_id_service)
    : channel_id_source_(channel_id_source),
      channel_id_service_(channel_id_service),
      next_state_(STATE_NONE) {}

quic::QuicAsyncStatus ChannelIDSourceChromium::Job::GetChannelIDKey(
    const std::string& hostname,
    std::unique_ptr<quic::ChannelIDKey>* channel_id_key,
    quic::ChannelIDSourceCallback* callback) {
  DCHECK(channel_id_key);
  DCHECK(callback);

  if (STATE_NONE != next_state_) {
    DLOG(DFATAL) << "GetChannelIDKey has begun";
    return quic::QUIC_FAILURE;
  }

  channel_id_key_.reset();

  hostname_ = hostname;

  next_state_ = STATE_GET_CHANNEL_ID_KEY;
  switch (DoLoop(OK)) {
    case OK:
      *channel_id_key = std::move(channel_id_key_);
      return quic::QUIC_SUCCESS;
    case ERR_IO_PENDING:
      callback_.reset(callback);
      return quic::QUIC_PENDING;
    default:
      channel_id_key->reset();
      return quic::QUIC_FAILURE;
  }
}

int ChannelIDSourceChromium::Job::DoLoop(int last_result) {
  int rv = last_result;
  do {
    State state = next_state_;
    next_state_ = STATE_NONE;
    switch (state) {
      case STATE_GET_CHANNEL_ID_KEY:
        DCHECK(rv == OK);
        rv = DoGetChannelIDKey(rv);
        break;
      case STATE_GET_CHANNEL_ID_KEY_COMPLETE:
        rv = DoGetChannelIDKeyComplete(rv);
        break;
      case STATE_NONE:
      default:
        rv = ERR_UNEXPECTED;
        LOG(DFATAL) << "unexpected state " << state;
        break;
    }
  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
  return rv;
}

void ChannelIDSourceChromium::Job::OnIOComplete(int result) {
  int rv = DoLoop(result);
  if (rv != ERR_IO_PENDING) {
    std::unique_ptr<quic::ChannelIDSourceCallback> callback(
        callback_.release());
    callback->Run(&channel_id_key_);
    // Will delete |this|.
    channel_id_source_->OnJobComplete(this);
  }
}

int ChannelIDSourceChromium::Job::DoGetChannelIDKey(int result) {
  next_state_ = STATE_GET_CHANNEL_ID_KEY_COMPLETE;

  return channel_id_service_->GetOrCreateChannelID(
      hostname_, &channel_id_crypto_key_,
      base::Bind(&ChannelIDSourceChromium::Job::OnIOComplete,
                 base::Unretained(this)),
      &channel_id_request_);
}

int ChannelIDSourceChromium::Job::DoGetChannelIDKeyComplete(int result) {
  DCHECK_EQ(STATE_NONE, next_state_);
  if (result != OK) {
    DLOG(WARNING) << "Failed to look up channel ID: " << ErrorToString(result);
    return result;
  }

  DCHECK(channel_id_crypto_key_);
  channel_id_key_.reset(
      new ChannelIDKeyChromium(std::move(channel_id_crypto_key_)));
  return result;
}

ChannelIDSourceChromium::ChannelIDSourceChromium(
    ChannelIDService* channel_id_service)
    : channel_id_service_(channel_id_service) {}

ChannelIDSourceChromium::~ChannelIDSourceChromium() {}

quic::QuicAsyncStatus ChannelIDSourceChromium::GetChannelIDKey(
    const std::string& hostname,
    std::unique_ptr<quic::ChannelIDKey>* channel_id_key,
    quic::ChannelIDSourceCallback* callback) {
  std::unique_ptr<Job> job = std::make_unique<Job>(this, channel_id_service_);
  quic::QuicAsyncStatus status =
      job->GetChannelIDKey(hostname, channel_id_key, callback);
  if (status == quic::QUIC_PENDING) {
    Job* job_ptr = job.get();
    active_jobs_[job_ptr] = std::move(job);
  }
  return status;
}

void ChannelIDSourceChromium::OnJobComplete(Job* job) {
  active_jobs_.erase(job);
}

}  // namespace net
