/** @file
  SSL/TLS Process Library Wrapper Implementation over OpenSSL.
  The process includes the TLS handshake and packet I/O.

Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "InternalTlsLib.h"

#define MAX_BUFFER_SIZE   32768

/**
  Checks if the TLS handshake was done.

  This function will check if the specified TLS handshake was done.

  @param[in]  Tls    Pointer to the TLS object for handshake state checking.

  @retval  TRUE     The TLS handshake was done.
  @retval  FALSE    The TLS handshake was not done.

**/
BOOLEAN
EFIAPI
TlsInHandshake (
  IN     VOID                     *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
    return FALSE;
  }

  //
  // Return the status which indicates if the TLS handshake was done.
  //
  return !SSL_is_init_finished (TlsConn->Ssl);
}

/**
  Perform a TLS/SSL handshake.

  This function will perform a TLS/SSL handshake.

  @param[in]       Tls            Pointer to the TLS object for handshake operation.
  @param[in]       BufferIn       Pointer to the most recently received TLS Handshake packet.
  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
                                  Handshake packet.
  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferOutSize  Pointer to the buffer size in bytes. On input, it is
                                  the buffer size provided by the caller. On output, it
                                  is the buffer size in fact needed to contain the
                                  packet.

  @retval EFI_SUCCESS             The required TLS packet is built successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  Tls is NULL.
                                  BufferIn is NULL but BufferInSize is NOT 0.
                                  BufferInSize is 0 but BufferIn is NOT NULL.
                                  BufferOutSize is NULL.
                                  BufferOut is NULL if *BufferOutSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
  @retval EFI_ABORTED             Something wrong during handshake.

**/
EFI_STATUS
EFIAPI
TlsDoHandshake (
  IN     VOID                     *Tls,
  IN     UINT8                    *BufferIn, OPTIONAL
  IN     UINTN                    BufferInSize, OPTIONAL
     OUT UINT8                    *BufferOut, OPTIONAL
  IN OUT UINTN                    *BufferOutSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;
  INTN            Ret;
  UINTN           ErrorCode;

  TlsConn           = (TLS_CONNECTION *) Tls;
  PendingBufferSize = 0;
  Ret               = 1;

  if (TlsConn == NULL || \
    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
    BufferOutSize == NULL || \
    (BufferIn == NULL && BufferInSize != 0) || \
    (BufferIn != NULL && BufferInSize == 0) || \
    (BufferOut == NULL && *BufferOutSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if(BufferIn == NULL && BufferInSize == 0) {
    //
    // If RequestBuffer is NULL and RequestSize is 0, and TLS session
    // status is EfiTlsSessionNotStarted, the TLS session will be initiated
    // and the response packet needs to be ClientHello.
    //
    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
    if (PendingBufferSize == 0) {
      SSL_set_connect_state (TlsConn->Ssl);
      Ret = SSL_do_handshake (TlsConn->Ssl);
      PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
    }
  } else {
    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
    if (PendingBufferSize == 0) {
      BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
      Ret = SSL_do_handshake (TlsConn->Ssl);
      PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
    }
  }

  if (Ret < 1) {
    Ret = SSL_get_error (TlsConn->Ssl, (int) Ret);
    if (Ret == SSL_ERROR_SSL ||
        Ret == SSL_ERROR_SYSCALL ||
        Ret == SSL_ERROR_ZERO_RETURN) {
      DEBUG ((
        DEBUG_ERROR,
        "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
        __FUNCTION__,
        SSL_get_state (TlsConn->Ssl),
        Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN"
        ));
      DEBUG_CODE_BEGIN ();
        while (TRUE) {
          ErrorCode = ERR_get_error ();
          if (ErrorCode == 0) {
            break;
          }
          DEBUG ((
            DEBUG_ERROR,
            "%a ERROR 0x%x=L%x:F%x:R%x\n",
            __FUNCTION__,
            ErrorCode,
            ERR_GET_LIB (ErrorCode),
            ERR_GET_FUNC (ErrorCode),
            ERR_GET_REASON (ErrorCode)
            ));
        }
      DEBUG_CODE_END ();
      return EFI_ABORTED;
    }
  }

  if (PendingBufferSize > *BufferOutSize) {
    *BufferOutSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
  } else {
    *BufferOutSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Handle Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
  TLS session has errors and the response packet needs to be Alert message based on error type.

  @param[in]       Tls            Pointer to the TLS object for state checking.
  @param[in]       BufferIn       Pointer to the most recently received TLS Alert packet.
  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
                                  Alert packet.
  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferOutSize  Pointer to the buffer size in bytes. On input, it is
                                  the buffer size provided by the caller. On output, it
                                  is the buffer size in fact needed to contain the
                                  packet.

  @retval EFI_SUCCESS             The required TLS packet is built successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  Tls is NULL.
                                  BufferIn is NULL but BufferInSize is NOT 0.
                                  BufferInSize is 0 but BufferIn is NOT NULL.
                                  BufferOutSize is NULL.
                                  BufferOut is NULL if *BufferOutSize is not zero.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.

**/
EFI_STATUS
EFIAPI
TlsHandleAlert (
  IN     VOID                     *Tls,
  IN     UINT8                    *BufferIn, OPTIONAL
  IN     UINTN                    BufferInSize, OPTIONAL
     OUT UINT8                    *BufferOut, OPTIONAL
  IN OUT UINTN                    *BufferOutSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;
  UINT8           *TempBuffer;
  INTN            Ret;

  TlsConn           = (TLS_CONNECTION *) Tls;
  PendingBufferSize = 0;
  TempBuffer        = NULL;
  Ret               = 0;

  if (TlsConn == NULL || \
    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
    BufferOutSize == NULL || \
    (BufferIn == NULL && BufferInSize != 0) || \
    (BufferIn != NULL && BufferInSize == 0) || \
    (BufferOut == NULL && *BufferOutSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  if (PendingBufferSize == 0 && BufferIn != NULL && BufferInSize != 0) {
    Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
    if (Ret != (INTN) BufferInSize) {
      return EFI_ABORTED;
    }

    TempBuffer = (UINT8 *) OPENSSL_malloc (MAX_BUFFER_SIZE);

    //
    // ssl3_send_alert() will be called in ssl3_read_bytes() function.
    // TempBuffer is invalid since it's a Alert message, so just ignore it.
    //
    SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);

    OPENSSL_free (TempBuffer);

    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  }

  if (PendingBufferSize > *BufferOutSize) {
    *BufferOutSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
  } else {
    *BufferOutSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Build the CloseNotify packet.

  @param[in]       Tls            Pointer to the TLS object for state checking.
  @param[in, out]  Buffer         Pointer to the buffer to hold the built packet.
  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
                                  the buffer size provided by the caller. On output, it
                                  is the buffer size in fact needed to contain the
                                  packet.

  @retval EFI_SUCCESS             The required TLS packet is built successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  Tls is NULL.
                                  BufferSize is NULL.
                                  Buffer is NULL if *BufferSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.

**/
EFI_STATUS
EFIAPI
TlsCloseNotify (
  IN     VOID                     *Tls,
  IN OUT UINT8                    *Buffer,
  IN OUT UINTN                    *BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           PendingBufferSize;

  TlsConn           = (TLS_CONNECTION *) Tls;
  PendingBufferSize = 0;

  if (TlsConn == NULL || \
    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
    BufferSize == NULL || \
    (Buffer == NULL && *BufferSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  if (PendingBufferSize == 0) {
    //
    // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
    //
    SSL_shutdown (TlsConn->Ssl);
    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
  }

  if (PendingBufferSize > *BufferSize) {
    *BufferSize = PendingBufferSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (PendingBufferSize > 0) {
    *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32) PendingBufferSize);
  } else {
    *BufferSize = 0;
  }

  return EFI_SUCCESS;
}

/**
  Attempts to read bytes from one TLS object and places the data in Buffer.

  This function will attempt to read BufferSize bytes from the TLS object
  and places the data in Buffer.

  @param[in]      Tls           Pointer to the TLS object.
  @param[in,out]  Buffer        Pointer to the buffer to store the data.
  @param[in]      BufferSize    The size of Buffer in bytes.

  @retval  >0    The amount of data successfully read from the TLS object.
  @retval  <=0   No data was successfully read.

**/
INTN
EFIAPI
TlsCtrlTrafficOut (
  IN     VOID                     *Tls,
  IN OUT VOID                     *Buffer,
  IN     UINTN                    BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->OutBio == 0) {
    return -1;
  }

  //
  // Read and return the amount of data from the BIO.
  //
  return BIO_read (TlsConn->OutBio, Buffer, (UINT32) BufferSize);
}

/**
  Attempts to write data from the buffer to TLS object.

  This function will attempt to write BufferSize bytes data from the Buffer
  to the TLS object.

  @param[in]  Tls           Pointer to the TLS object.
  @param[in]  Buffer        Pointer to the data buffer.
  @param[in]  BufferSize    The size of Buffer in bytes.

  @retval  >0    The amount of data successfully written to the TLS object.
  @retval <=0    No data was successfully written.

**/
INTN
EFIAPI
TlsCtrlTrafficIn (
  IN     VOID                     *Tls,
  IN     VOID                     *Buffer,
  IN     UINTN                    BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->InBio == 0) {
    return -1;
  }

  //
  // Write and return the amount of data to the BIO.
  //
  return BIO_write (TlsConn->InBio, Buffer, (UINT32) BufferSize);
}
/**
  Attempts to read bytes from the specified TLS connection into the buffer.

  This function tries to read BufferSize bytes data from the specified TLS
  connection into the Buffer.

  @param[in]      Tls           Pointer to the TLS connection for data reading.
  @param[in,out]  Buffer        Pointer to the data buffer.
  @param[in]      BufferSize    The size of Buffer in bytes.

  @retval  >0    The read operation was successful, and return value is the
                 number of bytes actually read from the TLS connection.
  @retval  <=0   The read operation was not successful.

**/
INTN
EFIAPI
TlsRead (
  IN     VOID                     *Tls,
  IN OUT VOID                     *Buffer,
  IN     UINTN                    BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
    return -1;
  }

  //
  // Read bytes from the specified TLS connection.
  //
  return SSL_read (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
}

/**
  Attempts to write data to a TLS connection.

  This function tries to write BufferSize bytes data from the Buffer into the
  specified TLS connection.

  @param[in]  Tls           Pointer to the TLS connection for data writing.
  @param[in]  Buffer        Pointer to the data buffer.
  @param[in]  BufferSize    The size of Buffer in bytes.

  @retval  >0    The write operation was successful, and return value is the
                 number of bytes actually written to the TLS connection.
  @retval <=0    The write operation was not successful.

**/
INTN
EFIAPI
TlsWrite (
  IN     VOID                     *Tls,
  IN     VOID                     *Buffer,
  IN     UINTN                    BufferSize
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *) Tls;
  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
    return -1;
  }

  //
  // Write bytes to the specified TLS connection.
  //
  return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
}

