/** @file
  PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over OpenSSL.

Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalCryptLib.h"
#include "KeyContext.h"
#include <openssl/pem.h>

/**
  Callback function for password phrase conversion used for retrieving the encrypted PEM.

  @param[out]  Buf      Pointer to the buffer to write the passphrase to.
  @param[in]   Size     Maximum length of the passphrase (i.e. the size of Buf).
  @param[in]   Flag     A flag which is set to 0 when reading and 1 when writing.
  @param[in]   Key      Key data to be passed to the callback routine.

  @retval  The number of characters in the passphrase or 0 if an error occurred.

**/
INTN
PasswordCallback (
  OUT  CHAR8  *Buf,
  IN   INTN   Size,
  IN   INTN   Flag,
  IN   VOID   *Key
  )
{
  INTN  KeyLength;

  ZeroMem ((VOID *)Buf, (UINTN)Size);
  if (Key != NULL) {
    //
    // Duplicate key phrase directly.
    //
    KeyLength = (INTN)AsciiStrLen ((CHAR8 *)Key);
    KeyLength = (KeyLength > Size) ? Size : KeyLength;
    CopyMem (Buf, Key, (UINTN)KeyLength);
    return KeyLength;
  } else {
    return 0;
  }
}

/**
  Retrieve a private key from PEM-encoded data using OpenSSL BIO.
  This helper function creates a memory BIO, writes the PEM data to it, and reads
  the private key using OpenSSL's PEM_read_bio_PrivateKey function. It supports
  password-protected PEM data.

  @param[in]  PemData   Pointer to the PEM-encoded key data.
  @param[in]  PemSize   Size of the PEM key data in bytes.
  @param[in]  Password  NULL-terminated passphrase used for encrypted PEM key data.
  @param[out] Pkey      Pointer to receive the EVP_PKEY structure containing the private key.

  @retval TRUE   Private key was retrieved successfully.
  @retval FALSE  Failed to create BIO, write data, or read private key.
**/
STATIC
BOOLEAN
GetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  EVP_PKEY     **Pkey
  )
{
  BIO      *PemBio;
  BOOLEAN  Result;

  // Create a memory BIO and write PEM data to it
  PemBio = BIO_new (BIO_s_mem ());
  if (PemBio == NULL) {
    return FALSE;
  }

  if (BIO_write (PemBio, PemData, (int)PemSize) <= 0) {
    BIO_free (PemBio);
    return FALSE;
  }

  Result = FALSE;

  // Read Private Key from encrypted PEM data
  *Pkey = PEM_read_bio_PrivateKey (PemBio, NULL, (pem_password_cb *)&PasswordCallback, (void *)Password);
  if (*Pkey != NULL) {
    Result = TRUE;
  }

  // Always free the BIO before returning
  BIO_free (PemBio);
  return Result;
}

/**
  Allocate and initialize a KEY_CONTEXT structure wrapping an EVP_PKEY.
  This helper function allocates a KEY_CONTEXT structure and wraps the provided
  EVP_PKEY pointer within it.

  @param[in]  Pkey     Pointer to an EVP_PKEY structure to be wrapped.
  @param[in]  Nid      The NID representing the type of key (e.g., EVP_PKEY_ED448).
  @param[out] Context  Pointer to receive the allocated KEY_CONTEXT structure.

  @retval TRUE   KEY_CONTEXT was allocated and initialized successfully.
  @retval FALSE  Memory allocation failed.
**/
STATIC
BOOLEAN
AllocateKeyContext (
  IN   EVP_PKEY  *Pkey,
  IN   INT32     Nid,
  OUT  VOID      **Context
  )
{
  KEY_CONTEXT  *Ctx;

  Ctx = (KEY_CONTEXT *)AllocateZeroPool (sizeof (KEY_CONTEXT));
  if (Ctx == NULL) {
    return FALSE;
  }

  Ctx->EvpPkey = Pkey;
  Ctx->Nid     = Nid;
  *Context     = (VOID *)Ctx;
  return TRUE;
}

/**
  Convert an ML-DSA type name string to an OpenSSL NID.

  This helper function translates ML-DSA type name strings (e.g., "ML-DSA-87")
  to their corresponding OpenSSL EVP_PKEY NIDs (e.g., EVP_PKEY_ML_DSA_87).

  If the type name is not recognized, EVP_PKEY_NONE is returned.

  @param[in]  TypeName   ML-DSA type name string (e.g., "ML-DSA-87").

  @retval OpenSSL NID (e.g., EVP_PKEY_ML_DSA_87) if recognized.
  @retval EVP_PKEY_NONE if the type name is not recognized.

**/
STATIC
INT32
MlDsaTypeNameToNid (
  IN CONST CHAR8  *TypeName
  )
{
  INT32  Nid;

  if (AsciiStrCmp (TypeName, "ML-DSA-87") == 0) {
    Nid = EVP_PKEY_ML_DSA_87;
  } else {
    Nid = EVP_PKEY_NONE;
  }

  return Nid;
}

/**
  Check if the given NID is supported for ML-DSA.

  This helper function checks if the provided NID corresponds to a supported
  ML-DSA type. Currently, only EVP_PKEY_ML_DSA_87 is supported.

  @param[in]  Nid   The NID to check.

  @retval TRUE   The NID is supported for ML-DSA.
  @retval FALSE  The NID is not supported for ML-DSA.

**/
STATIC
BOOLEAN
IsMlDsaNidSupported (
  IN INT32  Nid
  )
{
  switch (Nid) {
    case EVP_PKEY_ML_DSA_87:
      return TRUE;
    default:
      return FALSE;
  }
}

/**
  Convert an SLH-DSA type name string to an OpenSSL NID.

  This helper function translates SLH-DSA type name strings (e.g., "SLH-DSA-SHAKE-256s")
  to their corresponding OpenSSL EVP_PKEY NIDs (e.g., EVP_PKEY_SLH_DSA_SHAKE_256S).

  If the type name is not recognized, EVP_PKEY_NONE is returned.

  @param[in]  TypeName   SLH-DSA type name string (e.g., "SLH-DSA-SHAKE-256s").

  @retval OpenSSL NID (e.g., EVP_PKEY_SLH_DSA_SHAKE_256S) if recognized.
  @retval EVP_PKEY_NONE if the type name is not recognized.

**/
STATIC
INT32
SlhDsaTypeNameToNid (
  IN CONST CHAR8  *TypeName
  )
{
  INT32  Nid;

  if (AsciiStrCmp (TypeName, "SLH-DSA-SHAKE-256s") == 0) {
    Nid = EVP_PKEY_SLH_DSA_SHAKE_256S;
  } else {
    Nid = EVP_PKEY_NONE;
  }

  return Nid;
}

/**
  Check if the given NID is supported for SLH-DSA.

  This helper function checks if the provided NID corresponds to a supported
  SLH-DSA type. Currently, only EVP_PKEY_SLH_DSA_SHAKE_256S is supported.

  @param[in]  Nid   The NID to check.

  @retval TRUE   The NID is supported for SLH-DSA.
  @retval FALSE  The NID is not supported for SLH-DSA.

**/
STATIC
BOOLEAN
IsSlhDsaNidSupported (
  IN INT32  Nid
  )
{
  switch (Nid) {
    case EVP_PKEY_SLH_DSA_SHAKE_256S:
      return TRUE;
    default:
      return FALSE;
  }
}

/**
  Retrieve the RSA Private Key from the password-protected PEM key data.

  @param[in]  PemData      Pointer to the PEM-encoded key data to be retrieved.
  @param[in]  PemSize      Size of the PEM key data in bytes.
  @param[in]  Password     NULL-terminated passphrase used for encrypted PEM key data.
  @param[out] RsaContext   Pointer to new-generated RSA context which contain the retrieved
                           RSA private key component. Use RsaFree() function to free the
                           resource.

  If PemData is NULL, then return FALSE.
  If RsaContext is NULL, then return FALSE.

  @retval  TRUE   RSA Private Key was retrieved successfully.
  @retval  FALSE  Invalid PEM key data or incorrect password.

**/
BOOLEAN
EFIAPI
RsaGetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  VOID         **RsaContext
  )
{
  BOOLEAN  Status;
  BIO      *PemBio;

  //
  // Check input parameters.
  //
  if ((PemData == NULL) || (RsaContext == NULL) || (PemSize > INT_MAX)) {
    return FALSE;
  }

  //
  // Add possible block-cipher descriptor for PEM data decryption.
  // NOTE: Only support most popular ciphers AES for the encrypted PEM.
  //
  if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {
    return FALSE;
  }

  if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {
    return FALSE;
  }

  if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {
    return FALSE;
  }

  Status = FALSE;

  //
  // Read encrypted PEM Data.
  //
  PemBio = BIO_new (BIO_s_mem ());
  if (PemBio == NULL) {
    goto _Exit;
  }

  if (BIO_write (PemBio, PemData, (int)PemSize) <= 0) {
    goto _Exit;
  }

  //
  // Retrieve RSA Private Key from encrypted PEM data.
  //
  *RsaContext = PEM_read_bio_RSAPrivateKey (PemBio, NULL, (pem_password_cb *)&PasswordCallback, (void *)Password);
  if (*RsaContext != NULL) {
    Status = TRUE;
  }

_Exit:
  //
  // Release Resources.
  //
  BIO_free (PemBio);

  return Status;
}

/**
  Retrieve the EC Private Key from the password-protected PEM key data.

  @param[in]  PemData      Pointer to the PEM-encoded key data to be retrieved.
  @param[in]  PemSize      Size of the PEM key data in bytes.
  @param[in]  Password     NULL-terminated passphrase used for encrypted PEM key data.
  @param[out] EcContext    Pointer to new-generated EC DSA context which contain the retrieved
                           EC private key component. Use EcFree() function to free the
                           resource.

  If PemData is NULL, then return FALSE.
  If EcContext is NULL, then return FALSE.

  @retval  TRUE   EC Private Key was retrieved successfully.
  @retval  FALSE  Invalid PEM key data or incorrect password.

**/
BOOLEAN
EFIAPI
EcGetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  VOID         **EcContext
  )
{
  BOOLEAN  Status;
  BIO      *PemBio;

  //
  // Check input parameters.
  //
  if ((PemData == NULL) || (EcContext == NULL) || (PemSize > INT_MAX)) {
    return FALSE;
  }

  //
  // Add possible block-cipher descriptor for PEM data decryption.
  // NOTE: Only support most popular ciphers AES for the encrypted PEM.
  //
  if (EVP_add_cipher (EVP_aes_128_cbc ()) == 0) {
    return FALSE;
  }

  if (EVP_add_cipher (EVP_aes_192_cbc ()) == 0) {
    return FALSE;
  }

  if (EVP_add_cipher (EVP_aes_256_cbc ()) == 0) {
    return FALSE;
  }

  Status = FALSE;

  //
  // Read encrypted PEM Data.
  //
  PemBio = BIO_new (BIO_s_mem ());
  if (PemBio == NULL) {
    goto _Exit;
  }

  if (BIO_write (PemBio, PemData, (int)PemSize) <= 0) {
    goto _Exit;
  }

  //
  // Retrieve EC Private Key from encrypted PEM data.
  //
  *EcContext = PEM_read_bio_ECPrivateKey (PemBio, NULL, (pem_password_cb *)&PasswordCallback, (void *)Password);
  if (*EcContext != NULL) {
    Status = TRUE;
  }

_Exit:
  //
  // Release Resources.
  //
  BIO_free (PemBio);

  return Status;
}

/**
   Retrieve the EdDSA Private Key from the password-protected PEM key data.

   @param[in]  PemData        Pointer to the PEM-encoded key data to be retrieved.
   @param[in]  PemSize        Size of the PEM key data in bytes.
   @param[in]  Password       NULL-terminated passphrase used for encrypted PEM key data.
   @param[out] EdDsaContext   Pointer to new-generated EdDSA context which contains the retrieved
   EdDSA private key component. Use EdDsaFree() function to free the
   resource.

   If PemData is NULL, then return FALSE.
   If EdDsaContext is NULL, then return FALSE.

   @retval  TRUE   EdDSA Private Key was retrieved successfully.
   @retval  FALSE  Invalid PEM key data or incorrect password.

**/
BOOLEAN
EFIAPI
EdDsaGetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  VOID         **EdDsaContext
  )
{
  EVP_PKEY  *Pkey;
  INT32     Nid;

  // Check input parameters
  if ((PemData == NULL) || (EdDsaContext == NULL) || (PemSize > INT_MAX)) {
    return FALSE;
  }

  // Read PEM data
  if (!GetPrivateKeyFromPem (PemData, PemSize, Password, &Pkey)) {
    return FALSE;
  }

  Nid = EVP_PKEY_id (Pkey);
  if (Nid != EVP_PKEY_ED448) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  // Allocate wrapper structure (now consistent with other key types)
  if (!AllocateKeyContext (Pkey, Nid, EdDsaContext)) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  return TRUE;
}

/**
  Retrieve the ML-DSA Private Key from the password-protected PEM key data.

  If PemData is NULL, then return FALSE.
  If MlDsaContext is NULL, then return FALSE.

  @param[in]  PemData       Pointer to the PEM-encoded key data to be retrieved.
  @param[in]  PemSize       Size of the PEM key data in bytes.
  @param[in]  Password      NULL-terminated passphrase used for encrypted PEM key data.
  @param[out] MlDsaContext  Pointer to new-generated ML-DSA context which contains
                            the retrieved ML-DSA private key. Use MlDsaFree() to free.

  @retval  TRUE   ML-DSA Private Key was retrieved successfully.
  @retval  FALSE  Invalid PEM key data or incorrect password.

**/
BOOLEAN
EFIAPI
MlDsaGetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  VOID         **MlDsaContext
  )
{
  EVP_PKEY  *Pkey;
  INT32     Nid;

  //
  // Check input parameters.
  //
  if ((PemData == NULL) || (MlDsaContext == NULL) || (PemSize > INT_MAX)) {
    return FALSE;
  }

  // Read PEM data
  if (!GetPrivateKeyFromPem (PemData, PemSize, Password, &Pkey)) {
    return FALSE;
  }

  Nid = MlDsaTypeNameToNid (EVP_PKEY_get0_type_name (Pkey));
  if (!IsMlDsaNidSupported (Nid)) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  // Allocate wrapper structure (now consistent with other key types)
  if (!AllocateKeyContext (Pkey, Nid, MlDsaContext)) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  return TRUE;
}

/**
  Retrieve the SLH-DSA Private Key from the password-protected PEM key data.

  If PemData is NULL, then return FALSE.
  If SlhDsaContext is NULL, then return FALSE.

  @param[in]  PemData        Pointer to the PEM-encoded key data to be retrieved.
  @param[in]  PemSize        Size of the PEM key data in bytes.
  @param[in]  Password       NULL-terminated passphrase used for encrypted PEM key data.
  @param[out] SlhDsaContext  Pointer to new-generated SLH-DSA context which contains
                             the retrieved SLH-DSA private key. Use SlhDsaFree() to free.

  @retval  TRUE   SLH-DSA Private Key was retrieved successfully.
  @retval  FALSE  Invalid PEM key data or incorrect password.

**/
BOOLEAN
EFIAPI
SlhDsaGetPrivateKeyFromPem (
  IN   CONST UINT8  *PemData,
  IN   UINTN        PemSize,
  IN   CONST CHAR8  *Password,
  OUT  VOID         **SlhDsaContext
  )
{
  EVP_PKEY  *Pkey;
  INT32     Nid;

  //
  // Check input parameters.
  //
  if ((PemData == NULL) || (SlhDsaContext == NULL) || (PemSize > INT_MAX)) {
    return FALSE;
  }

  // Read PEM data
  if (!GetPrivateKeyFromPem (PemData, PemSize, Password, &Pkey)) {
    return FALSE;
  }

  Nid = SlhDsaTypeNameToNid (EVP_PKEY_get0_type_name (Pkey));
  if (!IsSlhDsaNidSupported (Nid)) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  // Allocate wrapper structure (now consistent with other key types)
  if (!AllocateKeyContext (Pkey, Nid, SlhDsaContext)) {
    EVP_PKEY_free (Pkey);
    return FALSE;
  }

  return TRUE;
}
