/** @file
  Implementation of EFI TLS Configuration Protocol Interfaces.

  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TlsImpl.h"

EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol = {
  TlsConfigurationSetData,
  TlsConfigurationGetData
};

/**
  Set TLS configuration data.

  The SetData() function sets TLS configuration to non-volatile storage or volatile
  storage.

  @param[in]  This                Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
  @param[in]  DataType            Configuration data type.
  @param[in]  Data                Pointer to configuration data.
  @param[in]  DataSize            Total size of configuration data.

  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Data is NULL.
                                  DataSize is 0.
  @retval EFI_UNSUPPORTED         The DataType is unsupported.
  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.

**/
EFI_STATUS
EFIAPI
TlsConfigurationSetData (
  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
  IN     VOID                            *Data,
  IN     UINTN                           DataSize
  )
{
  EFI_STATUS    Status;
  TLS_INSTANCE  *Instance;
  EFI_TPL       OldTpl;

  Status = EFI_SUCCESS;

  if ((This == NULL) ||  (Data == NULL) || (DataSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_CONFIGURATION (This);

  switch (DataType) {
    case EfiTlsConfigDataTypeCACertificate:
      Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeHostPublicCert:
      Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeHostPrivateKey:
      Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeCertRevocationList:
      Status = TlsSetCertRevocationList (Data, DataSize);
      break;
    default:
      Status = EFI_UNSUPPORTED;
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Get TLS configuration data.

  The GetData() function gets TLS configuration.

  @param[in]       This           Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
  @param[in]       DataType       Configuration data type.
  @param[in, out]  Data           Pointer to configuration data.
  @param[in, out]  DataSize       Total size of configuration data. On input, it means
                                  the size of Data buffer. On output, it means the size
                                  of copied Data buffer if EFI_SUCCESS, and means the
                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.

  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  DataSize is NULL.
                                  Data is NULL if *DataSize is not zero.
  @retval EFI_UNSUPPORTED         The DataType is unsupported.
  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
**/
EFI_STATUS
EFIAPI
TlsConfigurationGetData (
  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
  IN OUT VOID                            *Data  OPTIONAL,
  IN OUT UINTN                           *DataSize
  )
{
  EFI_STATUS    Status;
  TLS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  Status = EFI_SUCCESS;

  if ((This == NULL) || (DataSize == NULL) || ((Data == NULL) && (*DataSize != 0))) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = TLS_INSTANCE_FROM_CONFIGURATION (This);

  switch (DataType) {
    case EfiTlsConfigDataTypeCACertificate:
      Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeHostPublicCert:
      Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeHostPrivateKey:
      Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
      break;
    case EfiTlsConfigDataTypeCertRevocationList:
      Status = TlsGetCertRevocationList (Data, DataSize);
      break;
    default:
      Status = EFI_UNSUPPORTED;
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}
