// 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 "net/socket/ssl_client_socket.h"

#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_util.h"
#include "crypto/ec_private_key.h"
#include "net/base/connection_type_histograms.h"
#include "net/base/net_errors.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_connection_status_flags.h"

namespace net {

SSLClientSocket::SSLClientSocket()
    : signed_cert_timestamps_received_(false),
      stapled_ocsp_response_received_(false),
      negotiation_extension_(kExtensionUnknown) {
}

// static
NextProto SSLClientSocket::NextProtoFromString(
    const std::string& proto_string) {
  if (proto_string == "http1.1" || proto_string == "http/1.1") {
    return kProtoHTTP11;
  } else if (proto_string == "spdy/2") {
    return kProtoDeprecatedSPDY2;
  } else if (proto_string == "spdy/3") {
    return kProtoSPDY3;
  } else if (proto_string == "spdy/3.1") {
    return kProtoSPDY31;
  } else if (proto_string == "h2-14") {
    // For internal consistency, HTTP/2 is named SPDY4 within Chromium.
    // This is the HTTP/2 draft-14 identifier.
    return kProtoSPDY4_14;
  } else if (proto_string == "h2") {
    return kProtoSPDY4;
  } else if (proto_string == "quic/1+spdy/3") {
    return kProtoQUIC1SPDY3;
  } else {
    return kProtoUnknown;
  }
}

// static
const char* SSLClientSocket::NextProtoToString(NextProto next_proto) {
  switch (next_proto) {
    case kProtoHTTP11:
      return "http/1.1";
    case kProtoDeprecatedSPDY2:
      return "spdy/2";
    case kProtoSPDY3:
      return "spdy/3";
    case kProtoSPDY31:
      return "spdy/3.1";
    case kProtoSPDY4_14:
      // For internal consistency, HTTP/2 is named SPDY4 within Chromium.
      // This is the HTTP/2 draft-14 identifier.
      return "h2-14";
    case kProtoSPDY4:
      return "h2";
    case kProtoQUIC1SPDY3:
      return "quic/1+spdy/3";
    case kProtoUnknown:
      break;
  }
  return "unknown";
}

// static
const char* SSLClientSocket::NextProtoStatusToString(
    const SSLClientSocket::NextProtoStatus status) {
  switch (status) {
    case kNextProtoUnsupported:
      return "unsupported";
    case kNextProtoNegotiated:
      return "negotiated";
    case kNextProtoNoOverlap:
      return "no-overlap";
  }
  return NULL;
}

bool SSLClientSocket::WasNpnNegotiated() const {
  std::string unused_proto;
  return GetNextProto(&unused_proto) == kNextProtoNegotiated;
}

NextProto SSLClientSocket::GetNegotiatedProtocol() const {
  std::string proto;
  if (GetNextProto(&proto) != kNextProtoNegotiated)
    return kProtoUnknown;
  return NextProtoFromString(proto);
}

bool SSLClientSocket::IgnoreCertError(int error, int load_flags) {
  if (error == OK)
    return true;
  return (load_flags & LOAD_IGNORE_ALL_CERT_ERRORS) &&
         IsCertificateError(error);
}

void SSLClientSocket::RecordNegotiationExtension() {
  if (negotiation_extension_ == kExtensionUnknown)
    return;
  std::string proto;
  SSLClientSocket::NextProtoStatus status = GetNextProto(&proto);
  if (status == kNextProtoUnsupported)
    return;
  // Convert protocol into numerical value for histogram.
  NextProto protocol_negotiated = SSLClientSocket::NextProtoFromString(proto);
  base::HistogramBase::Sample sample =
      static_cast<base::HistogramBase::Sample>(protocol_negotiated);
  // In addition to the protocol negotiated, we want to record which TLS
  // extension was used, and in case of NPN, whether there was overlap between
  // server and client list of supported protocols.
  if (negotiation_extension_ == kExtensionNPN) {
    if (status == kNextProtoNoOverlap) {
      sample += 1000;
    } else {
      sample += 500;
    }
  } else {
    DCHECK_EQ(kExtensionALPN, negotiation_extension_);
  }
  UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample);
}

// static
void SSLClientSocket::RecordChannelIDSupport(
    ChannelIDService* channel_id_service,
    bool negotiated_channel_id,
    bool channel_id_enabled,
    bool supports_ecc) {
  // Since this enum is used for a histogram, do not change or re-use values.
  enum {
    DISABLED = 0,
    CLIENT_ONLY = 1,
    CLIENT_AND_SERVER = 2,
    CLIENT_NO_ECC = 3,
    CLIENT_BAD_SYSTEM_TIME = 4,
    CLIENT_NO_CHANNEL_ID_SERVICE = 5,
    CHANNEL_ID_USAGE_MAX
  } supported = DISABLED;
  if (negotiated_channel_id) {
    supported = CLIENT_AND_SERVER;
  } else if (channel_id_enabled) {
    if (!channel_id_service)
      supported = CLIENT_NO_CHANNEL_ID_SERVICE;
    else if (!supports_ecc)
      supported = CLIENT_NO_ECC;
    else if (!channel_id_service->IsSystemTimeValid())
      supported = CLIENT_BAD_SYSTEM_TIME;
    else
      supported = CLIENT_ONLY;
  }
  UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
                            CHANNEL_ID_USAGE_MAX);
}

// static
bool SSLClientSocket::IsChannelIDEnabled(
    const SSLConfig& ssl_config,
    ChannelIDService* channel_id_service) {
  if (!ssl_config.channel_id_enabled)
    return false;
  if (!channel_id_service) {
    DVLOG(1) << "NULL channel_id_service_, not enabling channel ID.";
    return false;
  }
  if (!crypto::ECPrivateKey::IsSupported()) {
    DVLOG(1) << "Elliptic Curve not supported, not enabling channel ID.";
    return false;
  }
  if (!channel_id_service->IsSystemTimeValid()) {
    DVLOG(1) << "System time is not within the supported range for certificate "
                "generation, not enabling channel ID.";
    return false;
  }
  return true;
}

// static
bool SSLClientSocket::HasCipherAdequateForHTTP2(
    const std::vector<uint16>& cipher_suites) {
  for (uint16 cipher : cipher_suites) {
    if (IsSecureTLSCipherSuite(cipher))
      return true;
  }
  return false;
}

// static
bool SSLClientSocket::IsTLSVersionAdequateForHTTP2(
    const SSLConfig& ssl_config) {
  return ssl_config.version_max >= SSL_PROTOCOL_VERSION_TLS1_2;
}

// static
std::vector<uint8_t> SSLClientSocket::SerializeNextProtos(
    const NextProtoVector& next_protos,
    bool can_advertise_http2) {
  std::vector<uint8_t> wire_protos;
  for (const NextProto next_proto : next_protos) {
    if (!can_advertise_http2 && kProtoSPDY4MinimumVersion <= next_proto &&
        next_proto <= kProtoSPDY4MaximumVersion) {
      continue;
    }
    const std::string proto = NextProtoToString(next_proto);
    if (proto.size() > 255) {
      LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << proto;
      continue;
    }
    if (proto.size() == 0) {
      LOG(WARNING) << "Ignoring empty NPN/ALPN protocol";
      continue;
    }
    wire_protos.push_back(proto.size());
    for (const char ch : proto) {
      wire_protos.push_back(static_cast<uint8_t>(ch));
    }
  }

  return wire_protos;
}

}  // namespace net
