// Copyright 2021 The Pigweed 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 "mbedtls_backend.h"

#include "pw_log/log.h"

namespace {

int MbedtlsWrite(void* ctx, const unsigned char* buf, size_t len) {
  TransportInterface* transport = *static_cast<TransportInterface**>(ctx);
  int status = transport->Write(buf, len);
  return status;
}

int MbedtlsRead(void* ctx, unsigned char* buf, size_t len) {
  TransportInterface* transport = *static_cast<TransportInterface**>(ctx);
  int status = transport->Read(buf, len);
  if (status == 0) {
    return MBEDTLS_ERR_SSL_WANT_READ;
  }
  return status;
}

// A dummy source for generating random bytes for demo purpose only.
// Real applicaiton should provide an implementation.
int DummyEntropySource(void*, unsigned char*, size_t len, size_t* olen) {
  *olen = len;
  return 0;
}

}  // namespace

MbedtlsBackend::MbedtlsBackend() {
  mbedtls_ssl_init(&ssl_);
  mbedtls_ssl_config_init(&conf_);
  mbedtls_x509_crt_init(&cacert_);
  mbedtls_x509_crl_init(&cacrl_);
  mbedtls_ctr_drbg_init(&ctr_drbg_);
  mbedtls_entropy_init(&entropy_);
  mbedtls_ssl_set_bio(&ssl_, &mbedtls_io_ctx_, MbedtlsWrite, MbedtlsRead, NULL);
}

int MbedtlsBackend::SetHostName(const char* host) {
  int ret = 0;
  if ((ret = mbedtls_ssl_set_hostname(&ssl_, host)) != 0) {
    PW_LOG_INFO("Failed to set host name, -0x%x",
                static_cast<unsigned int>(-ret));
    return -1;
  }
  return 0;
}

int MbedtlsBackend::Setup() {
  int ret = 0;
  // Add a dummy entropy source.
  const char* personalization_string = "ssl_client";
  mbedtls_entropy_add_source(
      &entropy_, DummyEntropySource, NULL, 16, MBEDTLS_ENTROPY_SOURCE_STRONG);
  if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg_,
                                   mbedtls_entropy_func,
                                   &entropy_,
                                   (const unsigned char*)personalization_string,
                                   sizeof(personalization_string) - 1)) != 0) {
    PW_LOG_INFO("Failed to add entroy source, -0x%x",
                static_cast<unsigned int>(-ret));
    return -1;
  }

  if ((ret = mbedtls_ssl_config_defaults(&conf_,
                                         MBEDTLS_SSL_IS_CLIENT,
                                         MBEDTLS_SSL_TRANSPORT_STREAM,
                                         MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
    PW_LOG_INFO("Failed to setup default config. -0x%x",
                static_cast<unsigned int>(-ret));
    return -1;
  }

  mbedtls_ssl_conf_authmode(&conf_, MBEDTLS_SSL_VERIFY_OPTIONAL);
  mbedtls_ssl_conf_ca_chain(&conf_, &cacert_, &cacrl_);
  mbedtls_ssl_conf_rng(&conf_, mbedtls_ctr_drbg_random, &ctr_drbg_);

  if ((ret = mbedtls_ssl_setup(&ssl_, &conf_)) != 0) {
    PW_LOG_INFO("Failed to set up ssl. -0x%x", static_cast<unsigned int>(-ret));
    return -1;
  }

  return 0;
}

int MbedtlsBackend::Handshake(TransportInterface* transport) {
  if (Setup() < 0) {
    return -1;
  }
  int ret = 0;
  mbedtls_io_ctx_ = transport;
  while ((ret = mbedtls_ssl_handshake(&ssl_)) != 0) {
    if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
      PW_LOG_INFO("Failed to handshake -0x%x", static_cast<unsigned int>(-ret));
      return -1;
    }
  }

  // Check certificate verification result.
  uint32_t flags = 0;
  if ((flags = mbedtls_ssl_get_verify_result(&ssl_)) != 0) {
    char verify_buf[512];
    mbedtls_x509_crt_verify_info(verify_buf, sizeof(verify_buf), "  ! ", flags);
    PW_LOG_INFO("certificate verification failed, %s", verify_buf);
    return -1;
  }

  return 0;
}

int MbedtlsBackend::Write(const void* buffer,
                          size_t size,
                          TransportInterface* transport) {
  mbedtls_io_ctx_ = transport;
  int ret = 0;
  while ((ret = mbedtls_ssl_write(
              &ssl_, static_cast<const unsigned char*>(buffer), size)) <= 0) {
    if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
      PW_LOG_INFO("Failed to write. -0x%x", static_cast<unsigned int>(-ret));
      return -1;
    }
  }
  return static_cast<int>(size);
}

int MbedtlsBackend::Read(void* buffer,
                         size_t size,
                         TransportInterface* transport) {
  mbedtls_io_ctx_ = transport;
  int ret = 0;
  while (true) {
    ret = mbedtls_ssl_read(&ssl_, static_cast<unsigned char*>(buffer), size);
    if (ret < 0) {
      if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
          ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
        continue;
      }
      PW_LOG_INFO("Failed while reading. -0x%x",
                  static_cast<unsigned int>(-ret));
      return -1;
    }
    return ret;
  }
}

int MbedtlsBackend::LoadCACert(const void* buffer,
                               size_t size,
                               X509LoadFormat format) {
  const unsigned char* data = static_cast<const unsigned char*>(buffer);
  if (format == X509LoadFormat::kPEM || format == X509LoadFormat::kTryAll) {
    int ret = mbedtls_x509_crt_parse(&cacert_, data, size);
    if (ret == 0) {
      return 0;
    } else if (format == X509LoadFormat::kPEM) {
      PW_LOG_INFO("Failed to load CA certificate as PEM. -0x%x",
                  static_cast<unsigned int>(-ret));
      return ret;
    }
  }
  if (format == X509LoadFormat::kDER || format == X509LoadFormat::kTryAll) {
    int ret = mbedtls_x509_crt_parse_der(&cacert_, data, size);
    if (ret == 0) {
      return 0;
    } else if (format == X509LoadFormat::kDER) {
      PW_LOG_INFO("Failed to load CA certificate as DER. -0x%x",
                  static_cast<unsigned int>(-ret));
      return ret;
    }
  }
  return -1;
}

int MbedtlsBackend::LoadCrl(const void* buffer,
                            size_t size,
                            X509LoadFormat format) {
  const unsigned char* data = static_cast<const unsigned char*>(buffer);
  // TODO(zyecheng) mbedtls can't handle any critical extension tag in CRL.
  // However, there is one "X509v3 Issuing Distribution Point" for
  // google CRLs in GTS CA 101. We'll need to find a way to bypass it.
  // For context, see https://github.com/ARMmbed/mbedtls/pull/3564
  if (format == X509LoadFormat::kPEM || format == X509LoadFormat::kTryAll) {
    int ret = mbedtls_x509_crl_parse(&cacrl_, data, size);
    if (ret == 0) {
      return 0;
    } else if (format == X509LoadFormat::kPEM) {
      PW_LOG_INFO("Failed to load crl as PEM. -0x%x",
                  static_cast<unsigned int>(-ret));
      return ret;
    }
  }
  if (format == X509LoadFormat::kDER || format == X509LoadFormat::kTryAll) {
    int ret = mbedtls_x509_crl_parse_der(&cacrl_, data, size);
    if (ret == 0) {
      return 0;
    } else if (format == X509LoadFormat::kDER) {
      PW_LOG_INFO("Failed to load crlas DER. -0x%x",
                  static_cast<unsigned int>(-ret));
      return ret;
    }
  }
  return -1;
}

TlsInterface* CreateTls() { return new MbedtlsBackend(); }
