/** @file
  SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.

Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalTlsLib.h"

typedef struct {
  //
  // TLS Algorithm
  //
  UINT8          Algo;
  //
  // TLS Algorithm name
  //
  CONST CHAR8    *Name;
} TLS_ALGO_TO_NAME;

STATIC CONST TLS_ALGO_TO_NAME  TlsHashAlgoToName[] = {
  { TlsHashAlgoNone,   NULL     },
  { TlsHashAlgoMd5,    "MD5"    },
  { TlsHashAlgoSha1,   "SHA1"   },
  { TlsHashAlgoSha224, "SHA224" },
  { TlsHashAlgoSha256, "SHA256" },
  { TlsHashAlgoSha384, "SHA384" },
  { TlsHashAlgoSha512, "SHA512" },
};

STATIC CONST TLS_ALGO_TO_NAME  TlsSignatureAlgoToName[] = {
  { TlsSignatureAlgoAnonymous, NULL    },
  { TlsSignatureAlgoRsa,       "RSA"   },
  { TlsSignatureAlgoDsa,       "DSA"   },
  { TlsSignatureAlgoEcdsa,     "ECDSA" },
};

/**
  Set a new TLS/SSL method for a particular TLS object.

  This function sets a new TLS/SSL method for a particular TLS object.

  @param[in]  Tls         Pointer to a TLS object.
  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.
  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.

  @retval  EFI_SUCCESS           The TLS/SSL method was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL method.

**/
EFI_STATUS
EFIAPI
TlsSetVersion (
  IN     VOID   *Tls,
  IN     UINT8  MajorVer,
  IN     UINT8  MinorVer
  )
{
  TLS_CONNECTION  *TlsConn;
  UINT16          ProtoVersion;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ProtoVersion = (MajorVer << 8) | MinorVer;

  //
  // Bound TLS method to the particular specified version.
  //
  switch (ProtoVersion) {
    case TLS1_VERSION:
      //
      // TLS 1.0
      //
      SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);
      SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);
      break;
    case TLS1_1_VERSION:
      //
      // TLS 1.1
      //
      SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
      SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
      break;
    case TLS1_2_VERSION:
      //
      // TLS 1.2
      //
      SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
      SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
      break;
    default:
      //
      // Unsupported Protocol Version
      //
      return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Set TLS object to work in client or server mode.

  This function prepares a TLS object to work in client or server mode.

  @param[in]  Tls         Pointer to a TLS object.
  @param[in]  IsServer    Work in server mode.

  @retval  EFI_SUCCESS           The TLS/SSL work mode was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL work mode.

**/
EFI_STATUS
EFIAPI
TlsSetConnectionEnd (
  IN     VOID     *Tls,
  IN     BOOLEAN  IsServer
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsServer) {
    //
    // Set TLS to work in Client mode.
    //
    SSL_set_connect_state (TlsConn->Ssl);
  } else {
    //
    // Set TLS to work in Server mode.
    // It is unsupported for UEFI version currently.
    //
    // SSL_set_accept_state (TlsConn->Ssl);
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Set the ciphers list to be used by the TLS object.

  This function sets the ciphers for use by a specified TLS object.

  @param[in]  Tls          Pointer to a TLS object.
  @param[in]  CipherId     Array of UINT16 cipher identifiers. Each UINT16
                           cipher identifier comes from the TLS Cipher Suite
                           Registry of the IANA, interpreting Byte1 and Byte2
                           in network (big endian) byte order.
  @param[in]  CipherNum    The number of cipher in the list.

  @retval  EFI_SUCCESS           The ciphers list was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       No supported TLS cipher was found in CipherId.
  @retval  EFI_OUT_OF_RESOURCES  Memory allocation failed.

**/
EFI_STATUS
EFIAPI
TlsSetCipherList (
  IN     VOID    *Tls,
  IN     UINT16  *CipherId,
  IN     UINTN   CipherNum
  )
{
  TLS_CONNECTION    *TlsConn;
  EFI_STATUS        Status;
  CONST SSL_CIPHER  **MappedCipher;
  UINTN             MappedCipherBytes;
  UINTN             MappedCipherCount;
  UINTN             CipherStringSize;
  UINTN             Index;
  INT32             StackIdx;
  CHAR8             *CipherString;
  CHAR8             *CipherStringPosition;

  STACK_OF (SSL_CIPHER)      *OpensslCipherStack;
  CONST SSL_CIPHER  *OpensslCipher;
  CONST CHAR8       *OpensslCipherName;
  UINTN             OpensslCipherNameLength;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate the MappedCipher array for recording the mappings that we find
  // for the input IANA identifiers in CipherId.
  //
  Status = SafeUintnMult (
             CipherNum,
             sizeof (*MappedCipher),
             &MappedCipherBytes
             );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  MappedCipher = AllocatePool (MappedCipherBytes);
  if (MappedCipher == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  OpensslCipherStack = SSL_get_ciphers (TlsConn->Ssl);

  //
  // Map the cipher IDs, and count the number of bytes for the full
  // CipherString.
  //
  MappedCipherCount = 0;
  CipherStringSize  = 0;
  for (Index = 0; OpensslCipherStack != NULL && Index < CipherNum; Index++) {
    //
    // Look up the IANA-to-OpenSSL mapping.
    //
    for (StackIdx = 0; StackIdx < sk_SSL_CIPHER_num (OpensslCipherStack); StackIdx++) {
      OpensslCipher = sk_SSL_CIPHER_value (OpensslCipherStack, StackIdx);
      if (CipherId[Index] != SSL_CIPHER_get_protocol_id (OpensslCipher)) {
        continue;
      }

      //
      // Accumulate cipher name string length into CipherStringSize. If this
      // is not the first successful mapping, account for a colon (":") prefix
      // too.
      //
      if (MappedCipherCount > 0) {
        Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
        if (EFI_ERROR (Status)) {
          Status = EFI_OUT_OF_RESOURCES;
          goto FreeMappedCipher;
        }
      }

      Status = SafeUintnAdd (
                 CipherStringSize,
                 AsciiStrLen (SSL_CIPHER_get_name (OpensslCipher)),
                 &CipherStringSize
                 );
      if (EFI_ERROR (Status)) {
        Status = EFI_OUT_OF_RESOURCES;
        goto FreeMappedCipher;
      }

      //
      // Record the mapping.
      //
      MappedCipher[MappedCipherCount++] = OpensslCipher;
      break;
    }

    if (StackIdx == sk_SSL_CIPHER_num (OpensslCipherStack)) {
      DEBUG ((
        DEBUG_VERBOSE,
        "%a:%a: skipping CipherId=0x%04x\n",
        gEfiCallerBaseName,
        __func__,
        CipherId[Index]
        ));
      //
      // Skipping the cipher is valid because CipherId is an ordered
      // preference list of ciphers, thus we can filter it as long as we
      // don't change the relative order of elements on it.
      //
    }
  }

  //
  // Verify that at least one IANA cipher ID could be mapped; account for the
  // terminating NUL character in CipherStringSize; allocate CipherString.
  //
  if (MappedCipherCount == 0) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a: no CipherId could be mapped\n",
      gEfiCallerBaseName,
      __func__
      ));
    Status = EFI_UNSUPPORTED;
    goto FreeMappedCipher;
  }

  Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeMappedCipher;
  }

  CipherString = AllocatePool (CipherStringSize);
  if (CipherString == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeMappedCipher;
  }

  //
  // Go over the collected mappings and populate CipherString.
  //
  CipherStringPosition = CipherString;
  for (Index = 0; Index < MappedCipherCount; Index++) {
    OpensslCipher           = MappedCipher[Index];
    OpensslCipherName       = SSL_CIPHER_get_name (OpensslCipher);
    OpensslCipherNameLength = AsciiStrLen (OpensslCipherName);
    //
    // Append the colon (":") prefix except for the first mapping, then append
    // OpensslCipherName.
    //
    if (Index > 0) {
      *(CipherStringPosition++) = ':';
    }

    CopyMem (
      CipherStringPosition,
      OpensslCipherName,
      OpensslCipherNameLength
      );
    CipherStringPosition += OpensslCipherNameLength;
  }

  //
  // NUL-terminate CipherString.
  //
  *(CipherStringPosition++) = '\0';
  ASSERT (CipherStringPosition == CipherString + CipherStringSize);

  //
  // Log CipherString for debugging. CipherString can be very long if the
  // caller provided a large CipherId array, so log CipherString in segments of
  // 79 non-newline characters. (MAX_DEBUG_MESSAGE_LENGTH is usually 0x100 in
  // DebugLib instances.)
  //
  DEBUG_CODE_BEGIN ();
  UINTN  FullLength;
  UINTN  SegmentLength;

  FullLength = CipherStringSize - 1;
  DEBUG ((
    DEBUG_VERBOSE,
    "%a:%a: CipherString={\n",
    gEfiCallerBaseName,
    __func__
    ));
  for (CipherStringPosition = CipherString;
       CipherStringPosition < CipherString + FullLength;
       CipherStringPosition += SegmentLength)
  {
    SegmentLength = FullLength - (CipherStringPosition - CipherString);
    if (SegmentLength > 79) {
      SegmentLength = 79;
    }

    DEBUG ((DEBUG_VERBOSE, "%.*a\n", SegmentLength, CipherStringPosition));
  }

  DEBUG ((DEBUG_VERBOSE, "}\n"));
  //
  // Restore the pre-debug value of CipherStringPosition by skipping over the
  // trailing NUL.
  //
  CipherStringPosition++;
  ASSERT (CipherStringPosition == CipherString + CipherStringSize);
  DEBUG_CODE_END ();

  //
  // Sets the ciphers for use by the Tls object.
  //
  if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
    Status = EFI_UNSUPPORTED;
    goto FreeCipherString;
  }

  Status = EFI_SUCCESS;

FreeCipherString:
  FreePool (CipherString);

FreeMappedCipher:
  FreePool ((VOID *)MappedCipher);

  return Status;
}

/**
  Set the compression method for TLS/SSL operations.

  This function handles TLS/SSL integrated compression methods.

  @param[in]  CompMethod    The compression method ID.

  @retval  EFI_SUCCESS        The compression method for the communication was
                              set successfully.
  @retval  EFI_UNSUPPORTED    Unsupported compression method.

**/
EFI_STATUS
EFIAPI
TlsSetCompressionMethod (
  IN     UINT8  CompMethod
  )
{
  COMP_METHOD  *Cm;
  INTN         Ret;

  Cm  = NULL;
  Ret = 0;

  if (CompMethod == 0) {
    //
    // TLS defines one standard compression method, CompressionMethod.null (0),
    // which specifies that data exchanged via the record protocol will not be compressed.
    // So, return EFI_SUCCESS directly (RFC 3749).
    //
    return EFI_SUCCESS;
  } else if (CompMethod == 1) {
    Cm = COMP_zlib ();
  } else {
    return EFI_UNSUPPORTED;
  }

  //
  // Adds the compression method to the list of available
  // compression methods.
  //
  Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
  if (Ret != 0) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Set peer certificate verification mode for the TLS connection.

  This function sets the verification mode flags for the TLS connection.

  @param[in]  Tls           Pointer to the TLS object.
  @param[in]  VerifyMode    A set of logically or'ed verification mode flags.

**/
VOID
EFIAPI
TlsSetVerify (
  IN     VOID    *Tls,
  IN     UINT32  VerifyMode
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return;
  }

  //
  // Set peer certificate verification parameters with NULL callback.
  //
  SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
}

/**
  Set the specified host name to be verified.

  @param[in]  Tls           Pointer to the TLS object.
  @param[in]  Flags         The setting flags during the validation.
  @param[in]  HostName      The specified host name to be verified.

  @retval  EFI_SUCCESS           The HostName setting was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_ABORTED           Invalid HostName setting.

**/
EFI_STATUS
EFIAPI
TlsSetVerifyHost (
  IN     VOID    *Tls,
  IN     UINT32  Flags,
  IN     CHAR8   *HostName
  )
{
  TLS_CONNECTION     *TlsConn;
  X509_VERIFY_PARAM  *VerifyParam;
  UINTN              BinaryAddressSize;
  UINT8              BinaryAddress[MAX (NS_INADDRSZ, NS_IN6ADDRSZ)];
  INTN               ParamStatus;

  TlsConn = (TLS_CONNECTION *)Tls;
  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (HostName == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((
    DEBUG_VERBOSE,
    "%a:%a: SNI hostname: %a\n",
    gEfiCallerBaseName,
    __func__,
    HostName
    ));

  if (!SSL_set_tlsext_host_name (TlsConn->Ssl, HostName)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a: Could not set hostname %a for SNI\n",
      gEfiCallerBaseName,
      __func__,
      HostName
      ));
  }

  SSL_set_hostflags (TlsConn->Ssl, Flags);

  VerifyParam = SSL_get0_param (TlsConn->Ssl);
  ASSERT (VerifyParam != NULL);

  BinaryAddressSize = 0;
  if (inet_pton (AF_INET6, HostName, BinaryAddress) == 1) {
    BinaryAddressSize = NS_IN6ADDRSZ;
  } else if (inet_pton (AF_INET, HostName, BinaryAddress) == 1) {
    BinaryAddressSize = NS_INADDRSZ;
  }

  if (BinaryAddressSize > 0) {
    DEBUG ((
      DEBUG_VERBOSE,
      "%a:%a: parsed \"%a\" as an IPv%c address "
      "literal\n",
      gEfiCallerBaseName,
      __func__,
      HostName,
      (UINTN)((BinaryAddressSize == NS_IN6ADDRSZ) ? '6' : '4')
      ));
    ParamStatus = X509_VERIFY_PARAM_set1_ip (
                    VerifyParam,
                    BinaryAddress,
                    BinaryAddressSize
                    );
  } else {
    ParamStatus = X509_VERIFY_PARAM_set1_host (VerifyParam, HostName, 0);
  }

  return (ParamStatus == 1) ? EFI_SUCCESS : EFI_ABORTED;
}

/**
  Callback function to get the server name.

  @param[in]  SSL
  @param[in]  INT32
  @param[in]  Arg

  @retval  INT32
**/
STATIC
INT32
SslServerNameCallback (
  SSL    *Ssl,
  INT32  *Ad,
  VOID   *Arg
  )
{
  const CHAR8  *HostName = NULL;
  TLS_EXT_CTX  *TlsCtx   = (TLS_EXT_CTX *)Arg;

  HostName = SSL_get_servername (Ssl, TLSEXT_NAMETYPE_host_name);

  if (SSL_get_servername_type (Ssl) != -1) {
    TlsCtx->Ack = !SSL_session_reused (Ssl) && HostName != NULL;
  }

  return SSL_TLSEXT_ERR_OK;
}

/**
  Set the specified server name in Server/Client.

  @param[in]  Tls           Pointer to the TLS object.
  @param[in]  SslCtx        Pointer to the SSL object.
  @param[in]  HostName      The specified server name to be set.

  @retval  EFI_SUCCESS      The Server Name was set successfully.
  @retval  EFI_UNSUPPORTED  Failed to set the Server Name.
**/
EFI_STATUS
EFIAPI
TlsSetServerName (
  VOID   *Tls,
  VOID   *SslCtx,
  CHAR8  *HostName
  )
{
  SSL_CTX         *Ctx;
  TLS_CONNECTION  *TlsConn;
  UINT32          RetVal;
  TLS_EXT_CTX     *TlsExtCtx = NULL;

  TlsConn = (TLS_CONNECTION *)Tls;
  Ctx     = (SSL_CTX *)SslCtx;

  if (TlsConn == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  TlsExtCtx = AllocateZeroPool (sizeof (TLS_EXT_CTX));
  if (TlsExtCtx == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  RetVal = SSL_CTX_set_tlsext_servername_callback (Ctx, SslServerNameCallback);
  if (!RetVal) {
    return EFI_UNSUPPORTED;
  }

  RetVal = SSL_CTX_set_tlsext_servername_arg (Ctx, TlsExtCtx);
  if (!RetVal) {
    return EFI_UNSUPPORTED;
  }

  RetVal = SSL_set_tlsext_host_name (TlsConn->Ssl, HostName);

  if (!RetVal) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Sets a TLS/SSL session ID to be used during TLS/SSL connect.

  This function sets a session ID to be used when the TLS/SSL connection is
  to be established.

  @param[in]  Tls             Pointer to the TLS object.
  @param[in]  SessionId       Session ID data used for session resumption.
  @param[in]  SessionIdLen    Length of Session ID in bytes.

  @retval  EFI_SUCCESS           Session ID was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       No available session for ID setting.

**/
EFI_STATUS
EFIAPI
TlsSetSessionId (
  IN     VOID    *Tls,
  IN     UINT8   *SessionId,
  IN     UINT16  SessionIdLen
  )
{
  TLS_CONNECTION  *TlsConn;
  SSL_SESSION     *Session;

  TlsConn = (TLS_CONNECTION *)Tls;
  Session = NULL;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Session = SSL_get_session (TlsConn->Ssl);
  if (Session == NULL) {
    return EFI_UNSUPPORTED;
  }

  SSL_SESSION_set1_id (Session, (const unsigned char *)SessionId, SessionIdLen);

  return EFI_SUCCESS;
}

/**
  Adds the CA to the cert store when requesting Server or Client authentication.

  This function adds the CA certificate to the list of CAs when requesting
  Server or Client authentication for the chosen TLS connection.

  @param[in]  Tls         Pointer to the TLS object.
  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
                          X.509 certificate or PEM-encoded X.509 certificate.
  @param[in]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
  @retval  EFI_ABORTED             Invalid X.509 certificate.

**/
EFI_STATUS
EFIAPI
TlsSetCaCertificate (
  IN     VOID   *Tls,
  IN     VOID   *Data,
  IN     UINTN  DataSize
  )
{
  BIO             *BioCert;
  X509            *Cert;
  X509_STORE      *X509Store;
  EFI_STATUS      Status;
  TLS_CONNECTION  *TlsConn;
  SSL_CTX         *SslCtx;
  INTN            Ret;

  BioCert   = NULL;
  Cert      = NULL;
  X509Store = NULL;
  Status    = EFI_SUCCESS;
  TlsConn   = (TLS_CONNECTION *)Tls;
  Ret       = 0;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
  //
  Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
  if (Cert == NULL) {
    //
    // Certificate is from PEM encoding.
    //
    BioCert = BIO_new (BIO_s_mem ());
    if (BioCert == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }

    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
    if (Cert == NULL) {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
  }

  SslCtx    = SSL_get_SSL_CTX (TlsConn->Ssl);
  X509Store = SSL_CTX_get_cert_store (SslCtx);
  if (X509Store == NULL) {
    Status = EFI_ABORTED;
    goto ON_EXIT;
  }

  //
  // Add certificate to X509 store
  //
  Ret = X509_STORE_add_cert (X509Store, Cert);
  if (Ret != 1) {
    unsigned long  ErrorCode;

    ErrorCode = ERR_peek_last_error ();
    //
    // Ignore "already in table" errors
    //
    if (!((ERR_GET_LIB (ErrorCode) == ERR_LIB_X509) &&
          (ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)))
    {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
  }

ON_EXIT:
  if (BioCert != NULL) {
    BIO_free (BioCert);
  }

  if (Cert != NULL) {
    X509_free (Cert);
  }

  return Status;
}

/**
  Loads the local public certificate into the specified TLS object.

  This function loads the X.509 certificate into the specified TLS object
  for TLS negotiation.

  @param[in]  Tls         Pointer to the TLS object.
  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
                          X.509 certificate or PEM-encoded X.509 certificate.
  @param[in]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
  @retval  EFI_ABORTED             Invalid X.509 certificate.

**/
EFI_STATUS
EFIAPI
TlsSetHostPublicCert (
  IN     VOID   *Tls,
  IN     VOID   *Data,
  IN     UINTN  DataSize
  )
{
  BIO             *BioCert;
  X509            *Cert;
  EFI_STATUS      Status;
  TLS_CONNECTION  *TlsConn;

  BioCert = NULL;
  Cert    = NULL;
  Status  = EFI_SUCCESS;
  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
  //
  Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
  if (Cert == NULL) {
    //
    // Certificate is from PEM encoding.
    //
    BioCert = BIO_new (BIO_s_mem ());
    if (BioCert == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }

    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
    if (Cert == NULL) {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    }
  }

  if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
    Status = EFI_ABORTED;
    goto ON_EXIT;
  }

ON_EXIT:
  if (BioCert != NULL) {
    BIO_free (BioCert);
  }

  if (Cert != NULL) {
    X509_free (Cert);
  }

  return Status;
}

/**
  Adds the local private key to the specified TLS object.

  This function adds the local private key (DER-encoded or PEM-encoded or PKCS#8 private
  key) into the specified TLS object for TLS negotiation.

  @param[in]  Tls         Pointer to the TLS object.
  @param[in]  Data        Pointer to the data buffer of a DER-encoded or PEM-encoded
                          or PKCS#8 private key.
  @param[in]  DataSize    The size of data buffer in bytes.
  @param[in]  Password    Pointer to NULL-terminated private key password, set it to NULL
                          if private key not encrypted.

  @retval  EFI_SUCCESS     The operation succeeded.
  @retval  EFI_UNSUPPORTED This function is not supported.
  @retval  EFI_ABORTED     Invalid private key data.

**/
EFI_STATUS
EFIAPI
TlsSetHostPrivateKeyEx (
  IN     VOID   *Tls,
  IN     VOID   *Data,
  IN     UINTN  DataSize,
  IN     VOID   *Password  OPTIONAL
  )
{
  TLS_CONNECTION  *TlsConn;
  BIO             *Bio;
  EVP_PKEY        *Pkey;
  BOOLEAN         Verify;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  // Try to parse the private key in DER format or un-encrypted PKC#8
  if (SSL_use_PrivateKey_ASN1 (
        EVP_PKEY_RSA,
        TlsConn->Ssl,
        Data,
        (long)DataSize
        ) == 1)
  {
    goto verify;
  }

  if (SSL_use_PrivateKey_ASN1 (
        EVP_PKEY_DSA,
        TlsConn->Ssl,
        Data,
        (long)DataSize
        ) == 1)
  {
    goto verify;
  }

  if (SSL_use_PrivateKey_ASN1 (
        EVP_PKEY_EC,
        TlsConn->Ssl,
        Data,
        (long)DataSize
        ) == 1)
  {
    goto verify;
  }

  // Try to parse the private key in PEM format or encrypted PKC#8
  Bio = BIO_new_mem_buf (Data, (int)DataSize);
  if (Bio != NULL) {
    Verify = FALSE;
    Pkey   = PEM_read_bio_PrivateKey (Bio, NULL, NULL, Password);
    if ((Pkey != NULL) && (SSL_use_PrivateKey (TlsConn->Ssl, Pkey) == 1)) {
      Verify = TRUE;
    }

    EVP_PKEY_free (Pkey);
    BIO_free (Bio);

    if (Verify) {
      goto verify;
    }
  }

  return EFI_ABORTED;

verify:
  if (SSL_check_private_key (TlsConn->Ssl) == 1) {
    return EFI_SUCCESS;
  }

  return EFI_ABORTED;
}

/**
  Adds the local private key to the specified TLS object.

  This function adds the local private key (DER-encoded or PEM-encoded or PKCS#8 private
  key) into the specified TLS object for TLS negotiation.

  @param[in]  Tls         Pointer to the TLS object.
  @param[in]  Data        Pointer to the data buffer of a DER-encoded or PEM-encoded
                          or PKCS#8 private key.
  @param[in]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS     The operation succeeded.
  @retval  EFI_UNSUPPORTED This function is not supported.
  @retval  EFI_ABORTED     Invalid private key data.

**/
EFI_STATUS
EFIAPI
TlsSetHostPrivateKey (
  IN     VOID   *Tls,
  IN     VOID   *Data,
  IN     UINTN  DataSize
  )
{
  return TlsSetHostPrivateKeyEx (Tls, Data, DataSize, NULL);
}

/**
  Adds the CA-supplied certificate revocation list for certificate validation.

  This function adds the CA-supplied certificate revocation list data for
  certificate validity checking.

  @param[in]  Data        Pointer to the data buffer of a DER-encoded CRL data.
  @param[in]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS     The operation succeeded.
  @retval  EFI_UNSUPPORTED This function is not supported.
  @retval  EFI_ABORTED     Invalid CRL data.

**/
EFI_STATUS
EFIAPI
TlsSetCertRevocationList (
  IN     VOID   *Data,
  IN     UINTN  DataSize
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Set the signature algorithm list to used by the TLS object.

  This function sets the signature algorithms for use by a specified TLS object.

  @param[in]  Tls                Pointer to a TLS object.
  @param[in]  Data               Array of UINT8 of signature algorithms. The array consists of
                                 pairs of the hash algorithm and the signature algorithm as defined
                                 in RFC 5246
  @param[in]  DataSize           The length the SignatureAlgoList. Must be divisible by 2.

  @retval  EFI_SUCCESS           The signature algorithm list was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameters are invalid.
  @retval  EFI_UNSUPPORTED       No supported TLS signature algorithm was found in SignatureAlgoList
  @retval  EFI_OUT_OF_RESOURCES  Memory allocation failed.

**/
EFI_STATUS
EFIAPI
TlsSetSignatureAlgoList (
  IN     VOID   *Tls,
  IN     UINT8  *Data,
  IN     UINTN  DataSize
  )
{
  TLS_CONNECTION  *TlsConn;
  UINTN           Index;
  UINTN           SignAlgoStrSize;
  CHAR8           *SignAlgoStr;
  CHAR8           *Pos;
  UINT8           *SignatureAlgoList;
  EFI_STATUS      Status;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize < 3) ||
      ((DataSize % 2) == 0) || (Data[0] != DataSize - 1))
  {
    return EFI_INVALID_PARAMETER;
  }

  SignatureAlgoList = Data + 1;
  SignAlgoStrSize   = 0;
  for (Index = 0; Index < Data[0]; Index += 2) {
    CONST CHAR8  *Tmp;

    if (SignatureAlgoList[Index] >= ARRAY_SIZE (TlsHashAlgoToName)) {
      return EFI_INVALID_PARAMETER;
    }

    Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
    if (!Tmp) {
      return EFI_INVALID_PARAMETER;
    }

    // Add 1 for the '+'
    SignAlgoStrSize += AsciiStrLen (Tmp) + 1;

    if (SignatureAlgoList[Index + 1] >= ARRAY_SIZE (TlsSignatureAlgoToName)) {
      return EFI_INVALID_PARAMETER;
    }

    Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
    if (!Tmp) {
      return EFI_INVALID_PARAMETER;
    }

    // Add 1 for the ':' or for the NULL terminator
    SignAlgoStrSize += AsciiStrLen (Tmp) + 1;
  }

  if (!SignAlgoStrSize) {
    return EFI_UNSUPPORTED;
  }

  SignAlgoStr = AllocatePool (SignAlgoStrSize);
  if (SignAlgoStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Pos = SignAlgoStr;
  for (Index = 0; Index < Data[0]; Index += 2) {
    CONST CHAR8  *Tmp;

    Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
    CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
    Pos   += AsciiStrLen (Tmp);
    *Pos++ = '+';

    Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
    CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
    Pos   += AsciiStrLen (Tmp);
    *Pos++ = ':';
  }

  *(Pos - 1) = '\0';

  if (SSL_set1_sigalgs_list (TlsConn->Ssl, SignAlgoStr) < 1) {
    Status = EFI_INVALID_PARAMETER;
  } else {
    Status = EFI_SUCCESS;
  }

  FreePool (SignAlgoStr);
  return Status;
}

/**
  Set the EC curve to be used for TLS flows

  This function sets the EC curve to be used for TLS flows.

  @param[in]  Tls                Pointer to a TLS object.
  @param[in]  Data               An EC named curve as defined in section 5.1.1 of RFC 4492.
  @param[in]  DataSize           Size of Data, it should be sizeof (UINT32)

  @retval  EFI_SUCCESS           The EC curve was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameters are invalid.
  @retval  EFI_UNSUPPORTED       The requested TLS EC curve is not supported

**/
EFI_STATUS
EFIAPI
TlsSetEcCurve (
  IN     VOID   *Tls,
  IN     UINT8  *Data,
  IN     UINTN  DataSize
  )
{
  TLS_CONNECTION  *TlsConn;
  EC_KEY          *EcKey;
  INT32           Nid;
  INT32           Ret;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize != sizeof (UINT32))) {
    return EFI_INVALID_PARAMETER;
  }

  switch (*((UINT32 *)Data)) {
    case TlsEcNamedCurveSecp256r1:
      return EFI_UNSUPPORTED;
    case TlsEcNamedCurveSecp384r1:
      Nid = NID_secp384r1;
      break;
    case TlsEcNamedCurveSecp521r1:
      Nid = NID_secp521r1;
      break;
    case TlsEcNamedCurveX25519:
      Nid = NID_X25519;
      break;
    case TlsEcNamedCurveX448:
      Nid = NID_X448;
      break;
    default:
      return EFI_UNSUPPORTED;
  }

  if (SSL_set1_curves (TlsConn->Ssl, &Nid, 1) != 1) {
    return EFI_UNSUPPORTED;
  }

  EcKey = EC_KEY_new_by_curve_name (Nid);
  if (EcKey == NULL) {
    return EFI_UNSUPPORTED;
  }

  Ret = SSL_set_tmp_ecdh (TlsConn->Ssl, EcKey);
  EC_KEY_free (EcKey);

  if (Ret != 1) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Set the Tls security level.

  This function Set the Tls security level.
  If Tls is NULL, nothing is done.

  @param[in]  Tls                Pointer to the TLS object.
  @param[in]  Level              Tls Security level need to set.

  @retval  EFI_SUCCESS           The Tls security level was set successfully.
  @retval  EFI_INVALID_PARAMETER The parameters are invalid.
  @retval  EFI_UNSUPPORTED       The requested TLS set security level is not supported.

**/
EFI_STATUS
EFIAPI
TlsSetSecurityLevel (
  IN VOID   *Tls,
  IN UINT8  Level
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  // Check if the security level is within the valid range (2 to 5).
  // Return EFI_INVALID_PARAMETER if the level is out of bounds.
  if ((Level < MIN_SECURITY_LEVEL) || (Level > MAX_SECURITY_LEVEL)) {
    return EFI_INVALID_PARAMETER;
  }

  SSL_set_security_level (TlsConn->Ssl, Level);

  return EFI_SUCCESS;
}

/**
  Gets the protocol version used by the specified TLS connection.

  This function returns the protocol version used by the specified TLS
  connection.

  If Tls is NULL, then ASSERT().

  @param[in]  Tls    Pointer to the TLS object.

  @return  The protocol version of the specified TLS connection.

**/
UINT16
EFIAPI
TlsGetVersion (
  IN     VOID  *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if (TlsConn == NULL) {
    return 0;
  }

  return (UINT16)(SSL_version (TlsConn->Ssl));
}

/**
  Gets the connection end of the specified TLS connection.

  This function returns the connection end (as client or as server) used by
  the specified TLS connection.

  If Tls is NULL, then ASSERT().

  @param[in]  Tls    Pointer to the TLS object.

  @return  The connection end used by the specified TLS connection.

**/
UINT8
EFIAPI
TlsGetConnectionEnd (
  IN     VOID  *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if (TlsConn == NULL) {
    return 0;
  }

  return (UINT8)SSL_is_server (TlsConn->Ssl);
}

/**
  Gets the cipher suite used by the specified TLS connection.

  This function returns current cipher suite used by the specified
  TLS connection.

  @param[in]      Tls         Pointer to the TLS object.
  @param[in,out]  CipherId    The cipher suite used by the TLS object.

  @retval  EFI_SUCCESS           The cipher suite was returned successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       Unsupported cipher suite.

**/
EFI_STATUS
EFIAPI
TlsGetCurrentCipher (
  IN     VOID    *Tls,
  IN OUT UINT16  *CipherId
  )
{
  TLS_CONNECTION    *TlsConn;
  CONST SSL_CIPHER  *Cipher;

  TlsConn = (TLS_CONNECTION *)Tls;
  Cipher  = NULL;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Cipher = SSL_get_current_cipher (TlsConn->Ssl);
  if (Cipher == NULL) {
    return EFI_UNSUPPORTED;
  }

  *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;

  return EFI_SUCCESS;
}

/**
  Gets the compression methods used by the specified TLS connection.

  This function returns current integrated compression methods used by
  the specified TLS connection.

  @param[in]      Tls              Pointer to the TLS object.
  @param[in,out]  CompressionId    The current compression method used by
                                   the TLS object.

  @retval  EFI_SUCCESS           The compression method was returned successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_ABORTED           Invalid Compression method.
  @retval  EFI_UNSUPPORTED       This function is not supported.

**/
EFI_STATUS
EFIAPI
TlsGetCurrentCompressionId (
  IN     VOID   *Tls,
  IN OUT UINT8  *CompressionId
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Gets the verification mode currently set in the TLS connection.

  This function returns the peer verification mode currently set in the
  specified TLS connection.

  If Tls is NULL, then ASSERT().

  @param[in]  Tls    Pointer to the TLS object.

  @return  The verification mode set in the specified TLS connection.

**/
UINT32
EFIAPI
TlsGetVerify (
  IN     VOID  *Tls
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if (TlsConn == NULL) {
    return 0;
  }

  return SSL_get_verify_mode (TlsConn->Ssl);
}

/**
  Gets the session ID used by the specified TLS connection.

  This function returns the TLS/SSL session ID currently used by the
  specified TLS connection.

  @param[in]      Tls             Pointer to the TLS object.
  @param[in,out]  SessionId       Buffer to contain the returned session ID.
  @param[in,out]  SessionIdLen    The length of Session ID in bytes.

  @retval  EFI_SUCCESS           The Session ID was returned successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.

**/
EFI_STATUS
EFIAPI
TlsGetSessionId (
  IN     VOID    *Tls,
  IN OUT UINT8   *SessionId,
  IN OUT UINT16  *SessionIdLen
  )
{
  TLS_CONNECTION  *TlsConn;
  SSL_SESSION     *Session;
  CONST UINT8     *SslSessionId;

  TlsConn = (TLS_CONNECTION *)Tls;
  Session = NULL;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL) || (SessionIdLen == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Session = SSL_get_session (TlsConn->Ssl);
  if (Session == NULL) {
    return EFI_UNSUPPORTED;
  }

  SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
  CopyMem (SessionId, SslSessionId, *SessionIdLen);

  return EFI_SUCCESS;
}

/**
  Gets the client random data used in the specified TLS connection.

  This function returns the TLS/SSL client random data currently used in
  the specified TLS connection.

  @param[in]      Tls             Pointer to the TLS object.
  @param[in,out]  ClientRandom    Buffer to contain the returned client
                                  random data (32 bytes).

**/
VOID
EFIAPI
TlsGetClientRandom (
  IN     VOID   *Tls,
  IN OUT UINT8  *ClientRandom
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ClientRandom == NULL)) {
    return;
  }

  SSL_get_client_random (TlsConn->Ssl, ClientRandom, SSL3_RANDOM_SIZE);
}

/**
  Gets the server random data used in the specified TLS connection.

  This function returns the TLS/SSL server random data currently used in
  the specified TLS connection.

  @param[in]      Tls             Pointer to the TLS object.
  @param[in,out]  ServerRandom    Buffer to contain the returned server
                                  random data (32 bytes).

**/
VOID
EFIAPI
TlsGetServerRandom (
  IN     VOID   *Tls,
  IN OUT UINT8  *ServerRandom
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ServerRandom == NULL)) {
    return;
  }

  SSL_get_server_random (TlsConn->Ssl, ServerRandom, SSL3_RANDOM_SIZE);
}

/**
  Gets the master key data used in the specified TLS connection.

  This function returns the TLS/SSL master key material currently used in
  the specified TLS connection.

  @param[in]      Tls            Pointer to the TLS object.
  @param[in,out]  KeyMaterial    Buffer to contain the returned key material.

  @retval  EFI_SUCCESS           Key material was returned successfully.
  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.

**/
EFI_STATUS
EFIAPI
TlsGetKeyMaterial (
  IN     VOID   *Tls,
  IN OUT UINT8  *KeyMaterial
  )
{
  TLS_CONNECTION  *TlsConn;
  SSL_SESSION     *Session;

  TlsConn = (TLS_CONNECTION *)Tls;
  Session = NULL;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (KeyMaterial == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Session = SSL_get_session (TlsConn->Ssl);

  if (Session == NULL) {
    return EFI_UNSUPPORTED;
  }

  SSL_SESSION_get_master_key (Session, KeyMaterial, SSL3_MASTER_SECRET_SIZE);

  return EFI_SUCCESS;
}

/**
  Gets the CA Certificate from the cert store.

  This function returns the CA certificate for the chosen
  TLS connection.

  @param[in]      Tls         Pointer to the TLS object.
  @param[out]     Data        Pointer to the data buffer to receive the CA
                              certificate data sent to the client.
  @param[in,out]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_UNSUPPORTED         This function is not supported.
  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.

**/
EFI_STATUS
EFIAPI
TlsGetCaCertificate (
  IN     VOID   *Tls,
  OUT    VOID   *Data,
  IN OUT UINTN  *DataSize
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Gets the local public Certificate set in the specified TLS object.

  This function returns the local public certificate which was currently set
  in the specified TLS object.

  @param[in]      Tls         Pointer to the TLS object.
  @param[out]     Data        Pointer to the data buffer to receive the local
                              public certificate.
  @param[in,out]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
  @retval  EFI_NOT_FOUND           The certificate is not found.
  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.

**/
EFI_STATUS
EFIAPI
TlsGetHostPublicCert (
  IN     VOID   *Tls,
  OUT    VOID   *Data,
  IN OUT UINTN  *DataSize
  )
{
  X509            *Cert;
  TLS_CONNECTION  *TlsConn;

  Cert    = NULL;
  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  Cert = SSL_get_certificate (TlsConn->Ssl);
  if (Cert == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Only DER encoding is supported currently.
  //
  if (*DataSize < (UINTN)i2d_X509 (Cert, NULL)) {
    *DataSize = (UINTN)i2d_X509 (Cert, NULL);
    return EFI_BUFFER_TOO_SMALL;
  }

  *DataSize = (UINTN)i2d_X509 (Cert, (unsigned char **)&Data);

  return EFI_SUCCESS;
}

/**
  Gets the local private key set in the specified TLS object.

  This function returns the local private key data which was currently set
  in the specified TLS object.

  @param[in]      Tls         Pointer to the TLS object.
  @param[out]     Data        Pointer to the data buffer to receive the local
                              private key data.
  @param[in,out]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_UNSUPPORTED         This function is not supported.
  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.

**/
EFI_STATUS
EFIAPI
TlsGetHostPrivateKey (
  IN     VOID   *Tls,
  OUT    VOID   *Data,
  IN OUT UINTN  *DataSize
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Gets the CA-supplied certificate revocation list data set in the specified
  TLS object.

  This function returns the CA-supplied certificate revocation list data which
  was currently set in the specified TLS object.

  @param[out]     Data        Pointer to the data buffer to receive the CRL data.
  @param[in,out]  DataSize    The size of data buffer in bytes.

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_UNSUPPORTED         This function is not supported.
  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.

**/
EFI_STATUS
EFIAPI
TlsGetCertRevocationList (
  OUT    VOID   *Data,
  IN OUT UINTN  *DataSize
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Derive keying material from a TLS connection.

  This function exports keying material using the mechanism described in RFC
  5705.

  @param[in]      Tls          Pointer to the TLS object
  @param[in]      Label        Description of the key for the PRF function
  @param[in]      Context      Optional context
  @param[in]      ContextLen   The length of the context value in bytes
  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
  @param[in]      KeyBufferLen The length of the KeyBuffer

  @retval  EFI_SUCCESS             The operation succeeded.
  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.

**/
EFI_STATUS
EFIAPI
TlsGetExportKey (
  IN     VOID        *Tls,
  IN     CONST VOID  *Label,
  IN     CONST VOID  *Context,
  IN     UINTN       ContextLen,
  OUT    VOID        *KeyBuffer,
  IN     UINTN       KeyBufferLen
  )
{
  TLS_CONNECTION  *TlsConn;

  TlsConn = (TLS_CONNECTION *)Tls;

  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  return SSL_export_keying_material (
           TlsConn->Ssl,
           KeyBuffer,
           KeyBufferLen,
           Label,
           AsciiStrLen (Label),
           Context,
           ContextLen,
           Context != NULL
           ) == 1 ?
         EFI_SUCCESS : EFI_PROTOCOL_ERROR;
}
