// 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 <errno.h>
#include <string.h>

#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/values.h"
#include "crypto/openssl_util.h"
#include "crypto/scoped_openssl_types.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/test_root_certs.h"
#include "net/dns/host_resolver.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/tcp_client_socket.h"
#include "net/ssl/openssl_client_key_store.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_config_service.h"
#include "net/test/cert_test_util.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace net {

namespace {

// These client auth tests are currently dependent on OpenSSL's struct X509.
#if defined(USE_OPENSSL_CERTS)

// Loads a PEM-encoded private key file into a scoped EVP_PKEY object.
// |filepath| is the private key file path.
// |*pkey| is reset to the new EVP_PKEY on success, untouched otherwise.
// Returns true on success, false on failure.
bool LoadPrivateKeyOpenSSL(
    const base::FilePath& filepath,
    crypto::ScopedEVP_PKEY* pkey) {
  std::string data;
  if (!base::ReadFileToString(filepath, &data)) {
    LOG(ERROR) << "Could not read private key file: "
               << filepath.value() << ": " << strerror(errno);
    return false;
  }
  crypto::ScopedBIO bio(BIO_new_mem_buf(
      const_cast<char*>(reinterpret_cast<const char*>(data.data())),
      static_cast<int>(data.size())));
  if (!bio.get()) {
    LOG(ERROR) << "Could not allocate BIO for buffer?";
    return false;
  }
  EVP_PKEY* result = PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL);
  if (result == NULL) {
    LOG(ERROR) << "Could not decode private key file: "
               << filepath.value();
    return false;
  }
  pkey->reset(result);
  return true;
}

class SSLClientSocketOpenSSLClientAuthTest : public PlatformTest {
 public:
  SSLClientSocketOpenSSLClientAuthTest()
      : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
        cert_verifier_(new MockCertVerifier),
        transport_security_state_(new TransportSecurityState) {
    cert_verifier_->set_default_result(OK);
    context_.cert_verifier = cert_verifier_.get();
    context_.transport_security_state = transport_security_state_.get();
    key_store_ = OpenSSLClientKeyStore::GetInstance();
  }

  ~SSLClientSocketOpenSSLClientAuthTest() override { key_store_->Flush(); }

 protected:
  scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
      scoped_ptr<StreamSocket> transport_socket,
      const HostPortPair& host_and_port,
      const SSLConfig& ssl_config) {
    scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
    connection->SetSocket(transport_socket.Pass());
    return socket_factory_->CreateSSLClientSocket(connection.Pass(),
                                                  host_and_port,
                                                  ssl_config,
                                                  context_);
  }

  // Connect to a HTTPS test server.
  bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) {
    test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTPS,
                                             ssl_options,
                                             base::FilePath()));
    if (!test_server_->Start()) {
      LOG(ERROR) << "Could not start SpawnedTestServer";
      return false;
    }

    if (!test_server_->GetAddressList(&addr_)) {
      LOG(ERROR) << "Could not get SpawnedTestServer address list";
      return false;
    }

    transport_.reset(new TCPClientSocket(
        addr_, &log_, NetLog::Source()));
    int rv = callback_.GetResult(
        transport_->Connect(callback_.callback()));
    if (rv != OK) {
      LOG(ERROR) << "Could not connect to SpawnedTestServer";
      return false;
    }
    return true;
  }

  // Record a certificate's private key to ensure it can be used
  // by the OpenSSL-based SSLClientSocket implementation.
  // |ssl_config| provides a client certificate.
  // |private_key| must be an EVP_PKEY for the corresponding private key.
  // Returns true on success, false on failure.
  bool RecordPrivateKey(SSLConfig& ssl_config,
                        EVP_PKEY* private_key) {
    return key_store_->RecordClientCertPrivateKey(
        ssl_config.client_cert.get(), private_key);
  }

  // Create an SSLClientSocket object and use it to connect to a test
  // server, then wait for connection results. This must be called after
  // a succesful ConnectToTestServer() call.
  // |ssl_config| the SSL configuration to use.
  // |result| will retrieve the ::Connect() result value.
  // Returns true on succes, false otherwise. Success means that the socket
  // could be created and its Connect() was called, not that the connection
  // itself was a success.
  bool CreateAndConnectSSLClientSocket(const SSLConfig& ssl_config,
                                       int* result) {
    sock_ = CreateSSLClientSocket(transport_.Pass(),
                                  test_server_->host_port_pair(),
                                  ssl_config);

    if (sock_->IsConnected()) {
      LOG(ERROR) << "SSL Socket prematurely connected";
      return false;
    }

    *result = callback_.GetResult(sock_->Connect(callback_.callback()));
    return true;
  }


  // Check that the client certificate was sent.
  // Returns true on success.
  bool CheckSSLClientSocketSentCert() {
    SSLInfo ssl_info;
    sock_->GetSSLInfo(&ssl_info);
    return ssl_info.client_cert_sent;
  }

  ClientSocketFactory* socket_factory_;
  scoped_ptr<MockCertVerifier> cert_verifier_;
  scoped_ptr<TransportSecurityState> transport_security_state_;
  SSLClientSocketContext context_;
  OpenSSLClientKeyStore* key_store_;
  scoped_ptr<SpawnedTestServer> test_server_;
  AddressList addr_;
  TestCompletionCallback callback_;
  NetLog log_;
  scoped_ptr<StreamSocket> transport_;
  scoped_ptr<SSLClientSocket> sock_;
};

// Connect to a server requesting client authentication, do not send
// any client certificates. It should refuse the connection.
TEST_F(SSLClientSocketOpenSSLClientAuthTest, NoCert) {
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.request_client_certificate = true;

  ASSERT_TRUE(ConnectToTestServer(ssl_options));

  base::FilePath certs_dir = GetTestCertsDirectory();

  int rv;
  ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));

  EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
  EXPECT_FALSE(sock_->IsConnected());
}

// Connect to a server requesting client authentication, and send it
// an empty certificate. It should refuse the connection.
TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendEmptyCert) {
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.request_client_certificate = true;
  ssl_options.client_authorities.push_back(
      GetTestClientCertsDirectory().AppendASCII("client_1_ca.pem"));

  ASSERT_TRUE(ConnectToTestServer(ssl_options));

  base::FilePath certs_dir = GetTestCertsDirectory();
  SSLConfig ssl_config;
  ssl_config.send_client_cert = true;
  ssl_config.client_cert = NULL;

  int rv;
  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));

  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(sock_->IsConnected());
}

// Connect to a server requesting client authentication. Send it a
// matching certificate. It should allow the connection.
TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendGoodCert) {
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.request_client_certificate = true;
  ssl_options.client_authorities.push_back(
      GetTestClientCertsDirectory().AppendASCII("client_1_ca.pem"));

  ASSERT_TRUE(ConnectToTestServer(ssl_options));

  base::FilePath certs_dir = GetTestCertsDirectory();
  SSLConfig ssl_config;
  ssl_config.send_client_cert = true;
  ssl_config.client_cert = ImportCertFromFile(certs_dir, "client_1.pem");

  // This is required to ensure that signing works with the client
  // certificate's private key.
  crypto::ScopedEVP_PKEY client_private_key;
  ASSERT_TRUE(LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"),
                                    &client_private_key));
  EXPECT_TRUE(RecordPrivateKey(ssl_config, client_private_key.get()));

  int rv;
  ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));

  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(sock_->IsConnected());

  EXPECT_TRUE(CheckSSLClientSocketSentCert());

  sock_->Disconnect();
  EXPECT_FALSE(sock_->IsConnected());
}
#endif  // defined(USE_OPENSSL_CERTS)

}  // namespace
}  // namespace net
