.. _module-pw_tls_client:

--------------
pw_tls_client
--------------

This module provides a facade that defines the public APIs for establishing TLS
sessions over arbitrary transports. Two options of backends,
pw_tls_client_mbedtls and pw_tls_client_boringssl, which are based on BoringSSL
and MbedTLS libraries, are under construction.

The facade provides a class ``pw::tls_client::Session`` with Open(), Read(),
Write() and Close() methods for TLS communication. An instance is created by
``pw::tls_client::Session::Create`` method. The method takes a
``pw::tls_client::SessionOptions`` object, which is used to configure TLS
connection options. The list of supported configurations currently include:

1. Host name of the target server. This will be used as the Server Name
Indication(SNI) extension during TLS handshake.

2. User-implemented transport. The underlying transport for the TLS
communication. It is an object that implements the interface of
``pw::stream::ReaderWriter``.

The module will also provide mechanisms/APIs for users to specify sources of
trust anchors, time and entropy. These are under construction.

.. warning::
  This module is under construction, not ready for use, and the documentation
  is incomplete.

Prerequisites
=============
This module requires the following dependencies:

1. Entropy
-----------
TLS requires an entropy source for generating random bytes. Users of this
module should provide one by implementing a backend to the
``pw_tls_client:entropy`` facade.

2. Chromium Verifier
---------------------
BoringSSL backend uses chromium verifier for certication verification. If the
downstream project uses BoringSSL as the backend, the sources of the verifier,
which is part of the chorimum sources, needs to be downloaded in order for
``//third_party/chromium_verifier`` to build. It is recommended to use our
support in pw_package for downloading compatible and tested version:

.. code-block:: sh

  pw package install chromium_verifier

Then follow instruction for setting ``dir_pw_third_party_chromium_verifier`` to
the path of the downloaded repo.

Setup
=====
This module requires the following setup:

  1. Choose a ``pw_tls_client`` backend, or write one yourself.
  2. If using GN build, Specify the ``pw_tls_client_BACKEND`` GN build arg to
     point the library that provides a ``pw_tls_client`` backend.
  3. Provide a `pw_tls_client:entropy` backend. If using GN build, specify the
     backend with variable ``pw_tls_client_ENTROPY_BACKEND``.

Module usage
============
For GN build, add ``//pw_tls_client`` to the dependency list.

The following gives an example code for using the module on host platform.
The example uses a Pigweed socket stream as the transport and performs TLS
connection to www.google.com:

.. code-block:: cpp

  // Host domain name
  constexpr char kHost[] = "www.google.com";

  constexpr int kPort = 443;

  // Server Name Indication.
  constexpr const char* kServerNameIndication = kHost;

  // An example message to send.
  constexpr char kHTTPRequest[] = "GET / HTTP/1.1\r\n\r\n";

  // pw::stream::SocketStream doesn't accept host domain name as input. Thus we
  // introduce this helper function for getting the IP address
  pw::Status GetIPAddrFromHostName(std::string_view host, std::span<char> ip) {
    char null_terminated_host_name[256] = {0};
    auto host_copy_status = pw::string::Copy(host, null_terminated_host_name);
    if (!host_copy_status.ok()) {
      return host_copy_status.status();
    }

    struct hostent* ent = gethostbyname(null_terminated_host_name);
    if (ent == NULL) {
      return PW_STATUS_INTERNAL;
    }

    in_addr** addr_list = reinterpret_cast<in_addr**>(ent->h_addr_list);
    if (addr_list[0] == nullptr) {
      return PW_STATUS_INTERNAL;
    }

    auto ip_copy_status = pw::string::Copy(inet_ntoa(*addr_list[0]), ip);
    if (!ip_copy_status.ok()) {
      return ip_copy_status.status();
    }

    return pw::OkStatus();
  }

  int main() {
    // Get the IP address of the target host.
    char ip_address[64] = {0};
    auto get_ip_status = GetIPAddrFromHostName(kHost, ip_address);
    if (!get_ip_status.ok()) {
      return 1;
    }

    // Use a socket stream as the transport.
    pw::stream::SocketStream socket_stream;

    // Connect the socket to the remote host.
    auto socket_connect_status = socket_stream.Connect(ip_address, kPort);
    if (!socket_connect_status.ok()) {
      return 1;
    }

    // Create a TLS session. Register the transport.
    auto options = pw::tls_client::SessionOptions()
            .set_server_name(kServerNameIndication)
            .set_transport(socket_stream);
    auto tls_conn = pw::tls_client::Session::Create(options);
    if (!tls_conn.ok()) {
      // Handle errors.
      return 1;
    }

    auto open_status = tls_conn.value()->Open();
    if (!open_status.ok()) {
      // Inspect/handle error with open_status.code() and
      // tls_conn.value()->GetLastTLSStatus().
      return 1;
    }

    auto write_status = tls_conn.value()->Write(std::as_bytes(std::span{kHTTPRequest}));
    if (!write_status.ok()) {
      // Inspect/handle error with write_status.code() and
      // tls_conn.value()->GetLastTLSStatus().
      return 0;
    }

    // Listen for incoming data.
    std::array<std::byte, 4096> buffer;
    while (true) {
      auto res = tls_conn.value()->Read(buffer);
      if (!res.ok()) {
        // Inspect/handle error with res.status().code() and
        // tls_conn.value()->GetLastTLSStatus().
        return 1;
      }

      // Process data in |buffer|. res.value() gives the span of read bytes.
      // The following simply print to console.
      if (res.value().size()) {
        auto print_status = pw::sys_io::WriteBytes(res.value());
        if (!print_status.ok()) {
          return 1;
        }
      }

    }
  }

A list of other demos will be provided in ``//pw_tls_client/examples/``

Warning
============

Open()/Read() APIs are synchronous for now. Support for
non-blocking/asynchronous usage will be added in the future.
