/** @file
  PKCS#7 SignedData Verification Wrapper Implementation over OpenSSL.

  Caution: This module requires additional review when modified.
  This library will have external input - signature (e.g. UEFI Authenticated
  Variable). It may by input in SMM mode.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated
  Variable and will do basic check for data structure.

Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalCryptLib.h"

#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs7.h>

UINT8  mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };

/**
  Check input P7Data is a wrapped ContentInfo structure or not. If not construct
  a new structure to wrap P7Data.

  Caution: This function may receive untrusted input.
  UEFI Authenticated Variable is external input, so this function will do basic
  check for PKCS#7 data structure.

  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
  @param[out] WrapFlag     If TRUE P7Data is a ContentInfo structure, otherwise
                           return FALSE.
  @param[out] WrapData     If return status of this function is TRUE:
                           1) when WrapFlag is TRUE, pointer to P7Data.
                           2) when WrapFlag is FALSE, pointer to a new ContentInfo
                           structure. It's caller's responsibility to free this
                           buffer.
  @param[out] WrapDataSize Length of ContentInfo structure in bytes.

  @retval     TRUE         The operation is finished successfully.
  @retval     FALSE        The operation is failed due to lack of resources.

**/
BOOLEAN
WrapPkcs7Data (
  IN  CONST UINT8  *P7Data,
  IN  UINTN        P7Length,
  OUT BOOLEAN      *WrapFlag,
  OUT UINT8        **WrapData,
  OUT UINTN        *WrapDataSize
  )
{
  BOOLEAN  Wrapped;
  UINT8    *SignedData;

  //
  // Check whether input P7Data is a wrapped ContentInfo structure or not.
  //
  Wrapped = FALSE;
  if ((P7Data[4] == 0x06) && (P7Data[5] == 0x09)) {
    if (CompareMem (P7Data + 6, mOidValue, sizeof (mOidValue)) == 0) {
      if ((P7Data[15] == 0xA0) && (P7Data[16] == 0x82)) {
        Wrapped = TRUE;
      }
    }
  }

  if (Wrapped) {
    *WrapData     = (UINT8 *)P7Data;
    *WrapDataSize = P7Length;
  } else {
    //
    // Wrap PKCS#7 signeddata to a ContentInfo structure - add a header in 19 bytes.
    //
    *WrapDataSize = P7Length + 19;
    *WrapData     = malloc (*WrapDataSize);
    if (*WrapData == NULL) {
      *WrapFlag = Wrapped;
      return FALSE;
    }

    SignedData = *WrapData;

    //
    // Part1: 0x30, 0x82.
    //
    SignedData[0] = 0x30;
    SignedData[1] = 0x82;

    //
    // Part2: Length1 = P7Length + 19 - 4, in big endian.
    //
    SignedData[2] = (UINT8)(((UINT16)(*WrapDataSize - 4)) >> 8);
    SignedData[3] = (UINT8)(((UINT16)(*WrapDataSize - 4)) & 0xff);

    //
    // Part3: 0x06, 0x09.
    //
    SignedData[4] = 0x06;
    SignedData[5] = 0x09;

    //
    // Part4: OID value -- 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x07 0x02.
    //
    CopyMem (SignedData + 6, mOidValue, sizeof (mOidValue));

    //
    // Part5: 0xA0, 0x82.
    //
    SignedData[15] = 0xA0;
    SignedData[16] = 0x82;

    //
    // Part6: Length2 = P7Length, in big endian.
    //
    SignedData[17] = (UINT8)(((UINT16)P7Length) >> 8);
    SignedData[18] = (UINT8)(((UINT16)P7Length) & 0xff);

    //
    // Part7: P7Data.
    //
    CopyMem (SignedData + 19, P7Data, P7Length);
  }

  *WrapFlag = Wrapped;
  return TRUE;
}

/**
  Pop single certificate from STACK_OF(X509).

  If X509Stack, Cert, or CertSize is NULL, then return FALSE.

  @param[in]  X509Stack       Pointer to a X509 stack object.
  @param[out] Cert            Pointer to a X509 certificate.
  @param[out] CertSize        Length of output X509 certificate in bytes.

  @retval     TRUE            The X509 stack pop succeeded.
  @retval     FALSE           The pop operation failed.

**/
BOOLEAN
X509PopCertificate (
  IN  VOID   *X509Stack,
  OUT UINT8  **Cert,
  OUT UINTN  *CertSize
  )
{
  BIO   *CertBio;
  X509  *X509Cert;

  STACK_OF (X509)  *CertStack;
  BOOLEAN  Status;
  INT32    Result;
  BUF_MEM  *Ptr;
  INT32    Length;
  VOID     *Buffer;

  Status = FALSE;

  if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) {
    return Status;
  }

  CertStack = (STACK_OF (X509) *) X509Stack;

  X509Cert = sk_X509_pop (CertStack);

  if (X509Cert == NULL) {
    return Status;
  }

  Buffer = NULL;

  CertBio = BIO_new (BIO_s_mem ());
  if (CertBio == NULL) {
    return Status;
  }

  Result = i2d_X509_bio (CertBio, X509Cert);
  if (Result == 0) {
    goto _Exit;
  }

  BIO_get_mem_ptr (CertBio, &Ptr);
  Length = (INT32)(Ptr->length);
  if (Length <= 0) {
    goto _Exit;
  }

  Buffer = malloc (Length);
  if (Buffer == NULL) {
    goto _Exit;
  }

  Result = BIO_read (CertBio, Buffer, Length);
  if (Result != Length) {
    goto _Exit;
  }

  *Cert     = Buffer;
  *CertSize = Length;

  Status = TRUE;

_Exit:

  BIO_free (CertBio);

  if (!Status && (Buffer != NULL)) {
    free (Buffer);
  }

  return Status;
}

/**
  Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:
  Cryptographic Message Syntax Standard". The input signed data could be wrapped
  in a ContentInfo structure.

  If P7Data, CertStack, StackLength, TrustedCert or CertLength is NULL, then
  return FALSE. If P7Length overflow, then return FALSE.

  Caution: This function may receive untrusted input.
  UEFI Authenticated Variable is external input, so this function will do basic
  check for PKCS#7 data structure.

  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
  @param[out] CertStack    Pointer to Signer's certificates retrieved from P7Data.
                           It's caller's responsibility to free the buffer with
                           Pkcs7FreeSigners().
                           This data structure is EFI_CERT_STACK type.
  @param[out] StackLength  Length of signer's certificates in bytes.
  @param[out] TrustedCert  Pointer to a trusted certificate from Signer's certificates.
                           It's caller's responsibility to free the buffer with
                           Pkcs7FreeSigners().
  @param[out] CertLength   Length of the trusted certificate in bytes.

  @retval  TRUE            The operation is finished successfully.
  @retval  FALSE           Error occurs during the operation.

**/
BOOLEAN
EFIAPI
Pkcs7GetSigners (
  IN  CONST UINT8  *P7Data,
  IN  UINTN        P7Length,
  OUT UINT8        **CertStack,
  OUT UINTN        *StackLength,
  OUT UINT8        **TrustedCert,
  OUT UINTN        *CertLength
  )
{
  PKCS7        *Pkcs7;
  BOOLEAN      Status;
  UINT8        *SignedData;
  CONST UINT8  *Temp;
  UINTN        SignedDataSize;
  BOOLEAN      Wrapped;

  STACK_OF (X509)   *Stack;
  UINT8  Index;
  UINT8  *CertBuf;
  UINT8  *OldBuf;
  UINTN  BufferSize;
  UINTN  OldSize;
  UINT8  *SingleCert;
  UINTN  SingleCertSize;

  if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
      (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX))
  {
    return FALSE;
  }

  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
  if (!Status) {
    return Status;
  }

  Status     = FALSE;
  Pkcs7      = NULL;
  Stack      = NULL;
  CertBuf    = NULL;
  OldBuf     = NULL;
  SingleCert = NULL;

  //
  // Retrieve PKCS#7 Data (DER encoding)
  //
  if (SignedDataSize > INT_MAX) {
    goto _Exit;
  }

  Temp  = SignedData;
  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
  if (Pkcs7 == NULL) {
    goto _Exit;
  }

  //
  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
  //
  if (!PKCS7_type_is_signed (Pkcs7)) {
    goto _Exit;
  }

  Stack = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);
  if (Stack == NULL) {
    goto _Exit;
  }

  //
  // Convert CertStack to buffer in following format:
  // UINT8  CertNumber;
  // UINT32 Cert1Length;
  // UINT8  Cert1[];
  // UINT32 Cert2Length;
  // UINT8  Cert2[];
  // ...
  // UINT32 CertnLength;
  // UINT8  Certn[];
  //
  BufferSize = sizeof (UINT8);
  OldSize    = BufferSize;

  for (Index = 0; ; Index++) {
    Status = X509PopCertificate (Stack, &SingleCert, &SingleCertSize);
    if (!Status) {
      break;
    }

    OldSize    = BufferSize;
    OldBuf     = CertBuf;
    BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
    CertBuf    = malloc (BufferSize);

    if (CertBuf == NULL) {
      goto _Exit;
    }

    if (OldBuf != NULL) {
      CopyMem (CertBuf, OldBuf, OldSize);
      free (OldBuf);
      OldBuf = NULL;
    }

    WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
    CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);

    free (SingleCert);
    SingleCert = NULL;
  }

  if (CertBuf != NULL) {
    //
    // Update CertNumber.
    //
    CertBuf[0] = Index;

    *CertLength  = BufferSize - OldSize - sizeof (UINT32);
    *TrustedCert = malloc (*CertLength);
    if (*TrustedCert == NULL) {
      goto _Exit;
    }

    CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
    *CertStack   = CertBuf;
    *StackLength = BufferSize;
    Status       = TRUE;
  }

_Exit:
  //
  // Release Resources
  //
  if (!Wrapped) {
    free (SignedData);
  }

  if (Pkcs7 != NULL) {
    PKCS7_free (Pkcs7);
  }

  if (Stack != NULL) {
    sk_X509_pop_free (Stack, X509_free);
  }

  if (SingleCert !=  NULL) {
    free (SingleCert);
  }

  if (!Status && (CertBuf != NULL)) {
    free (CertBuf);
    *CertStack = NULL;
  }

  if (OldBuf != NULL) {
    free (OldBuf);
  }

  return Status;
}

/**
  Wrap function to use free() to free allocated memory for certificates.

  @param[in]  Certs        Pointer to the certificates to be freed.

**/
VOID
EFIAPI
Pkcs7FreeSigners (
  IN  UINT8  *Certs
  )
{
  if (Certs == NULL) {
    return;
  }

  free (Certs);
}

/**
  Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:
  Cryptographic Message Syntax Standard", and outputs two certificate lists chained and
  unchained to the signer's certificates.
  The input signed data could be wrapped in a ContentInfo structure.

  @param[in]  P7Data            Pointer to the PKCS#7 message.
  @param[in]  P7Length          Length of the PKCS#7 message in bytes.
  @param[out] SignerChainCerts  Pointer to the certificates list chained to signer's
                                certificate. It's caller's responsibility to free the buffer
                                with Pkcs7FreeSigners().
                                This data structure is EFI_CERT_STACK type.
  @param[out] ChainLength       Length of the chained certificates list buffer in bytes.
  @param[out] UnchainCerts      Pointer to the unchained certificates lists. It's caller's
                                responsibility to free the buffer with Pkcs7FreeSigners().
                                This data structure is EFI_CERT_STACK type.
  @param[out] UnchainLength     Length of the unchained certificates list buffer in bytes.

  @retval  TRUE         The operation is finished successfully.
  @retval  FALSE        Error occurs during the operation.

**/
BOOLEAN
EFIAPI
Pkcs7GetCertificatesList (
  IN  CONST UINT8  *P7Data,
  IN  UINTN        P7Length,
  OUT UINT8        **SignerChainCerts,
  OUT UINTN        *ChainLength,
  OUT UINT8        **UnchainCerts,
  OUT UINTN        *UnchainLength
  )
{
  BOOLEAN         Status;
  UINT8           *NewP7Data;
  UINTN           NewP7Length;
  BOOLEAN         Wrapped;
  UINT8           Index;
  PKCS7           *Pkcs7;
  X509_STORE_CTX  *CertCtx;

  STACK_OF (X509)   *CtxChain;
  STACK_OF (X509)   *CtxUntrusted;
  X509  *CtxCert;

  STACK_OF (X509)   *Signers;
  X509       *Signer;
  X509       *Cert;
  X509       *Issuer;
  X509_NAME  *IssuerName;
  UINT8      *CertBuf;
  UINT8      *OldBuf;
  UINTN      BufferSize;
  UINTN      OldSize;
  UINT8      *SingleCert;
  UINTN      CertSize;

  //
  // Initializations
  //
  Status       = FALSE;
  NewP7Data    = NULL;
  Pkcs7        = NULL;
  CertCtx      = NULL;
  CtxChain     = NULL;
  CtxCert      = NULL;
  CtxUntrusted = NULL;
  Cert         = NULL;
  SingleCert   = NULL;
  CertBuf      = NULL;
  OldBuf       = NULL;
  Signers      = NULL;

  ZeroMem (&CertCtx, sizeof (CertCtx));

  //
  // Parameter Checking
  //
  if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||
      (UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX))
  {
    return Status;
  }

  *SignerChainCerts = NULL;
  *ChainLength      = 0;
  *UnchainCerts     = NULL;
  *UnchainLength    = 0;

  //
  // Construct a new PKCS#7 data wrapping with ContentInfo structure if needed.
  //
  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &NewP7Data, &NewP7Length);
  if (!Status || (NewP7Length > INT_MAX)) {
    goto _Error;
  }

  //
  // Decodes PKCS#7 SignedData
  //
  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&NewP7Data, (int)NewP7Length);
  if ((Pkcs7 == NULL) || (!PKCS7_type_is_signed (Pkcs7))) {
    goto _Error;
  }

  //
  // Obtains Signer's Certificate from PKCS#7 data
  // NOTE: Only one signer case will be handled in this function, which means SignerInfos
  //       should include only one signer's certificate.
  //
  Signers = PKCS7_get0_signers (Pkcs7, NULL, PKCS7_BINARY);
  if ((Signers == NULL) || (sk_X509_num (Signers) != 1)) {
    goto _Error;
  }

  Signer = sk_X509_value (Signers, 0);

  CertCtx = X509_STORE_CTX_new ();
  if (CertCtx == NULL) {
    goto _Error;
  }

  if (!X509_STORE_CTX_init (CertCtx, NULL, Signer, Pkcs7->d.sign->cert)) {
    goto _Error;
  }

  //
  // Initialize Chained & Untrusted stack
  //
  CtxChain = X509_STORE_CTX_get0_chain (CertCtx);
  CtxCert  = X509_STORE_CTX_get0_cert (CertCtx);
  if (CtxChain == NULL) {
    if (((CtxChain = sk_X509_new_null ()) == NULL) ||
        (!sk_X509_push (CtxChain, CtxCert)))
    {
      goto _Error;
    }
  }

  CtxUntrusted = X509_STORE_CTX_get0_untrusted (CertCtx);
  if (CtxUntrusted != NULL) {
    (VOID)sk_X509_delete_ptr (CtxUntrusted, Signer);
  }

  //
  // Build certificates stack chained from Signer's certificate.
  //
  Cert = Signer;
  for ( ; ;) {
    //
    // Self-Issue checking
    //
    Issuer = NULL;
    if (X509_STORE_CTX_get1_issuer (&Issuer, CertCtx, Cert) == 1) {
      if (X509_cmp (Issuer, Cert) == 0) {
        break;
      }
    }

    //
    // Found the issuer of the current certificate
    //
    if (CtxUntrusted != NULL) {
      Issuer     = NULL;
      IssuerName = X509_get_issuer_name (Cert);
      Issuer     = X509_find_by_subject (CtxUntrusted, IssuerName);
      if (Issuer != NULL) {
        if (!sk_X509_push (CtxChain, Issuer)) {
          goto _Error;
        }

        (VOID)sk_X509_delete_ptr (CtxUntrusted, Issuer);

        Cert = Issuer;
        continue;
      }
    }

    break;
  }

  //
  // Converts Chained and Untrusted Certificate to Certificate Buffer in following format:
  //      UINT8  CertNumber;
  //      UINT32 Cert1Length;
  //      UINT8  Cert1[];
  //      UINT32 Cert2Length;
  //      UINT8  Cert2[];
  //      ...
  //      UINT32 CertnLength;
  //      UINT8  Certn[];
  //

  if (CtxChain != NULL) {
    BufferSize = sizeof (UINT8);
    CertBuf    = NULL;

    for (Index = 0; ; Index++) {
      Status = X509PopCertificate (CtxChain, &SingleCert, &CertSize);
      if (!Status) {
        break;
      }

      OldSize    = BufferSize;
      OldBuf     = CertBuf;
      BufferSize = OldSize + CertSize + sizeof (UINT32);
      CertBuf    = malloc (BufferSize);

      if (CertBuf == NULL) {
        Status = FALSE;
        goto _Error;
      }

      if (OldBuf != NULL) {
        CopyMem (CertBuf, OldBuf, OldSize);
        free (OldBuf);
        OldBuf = NULL;
      }

      WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)CertSize);
      CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);

      free (SingleCert);
      SingleCert = NULL;
    }

    if (CertBuf != NULL) {
      //
      // Update CertNumber.
      //
      CertBuf[0] = Index;

      *SignerChainCerts = CertBuf;
      *ChainLength      = BufferSize;
    }
  }

  if (CtxUntrusted != NULL) {
    BufferSize = sizeof (UINT8);
    CertBuf    = NULL;

    for (Index = 0; ; Index++) {
      Status = X509PopCertificate (CtxUntrusted, &SingleCert, &CertSize);
      if (!Status) {
        break;
      }

      OldSize    = BufferSize;
      OldBuf     = CertBuf;
      BufferSize = OldSize + CertSize + sizeof (UINT32);
      CertBuf    = malloc (BufferSize);

      if (CertBuf == NULL) {
        Status = FALSE;
        goto _Error;
      }

      if (OldBuf != NULL) {
        CopyMem (CertBuf, OldBuf, OldSize);
        free (OldBuf);
        OldBuf = NULL;
      }

      WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)CertSize);
      CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, CertSize);

      free (SingleCert);
      SingleCert = NULL;
    }

    if (CertBuf != NULL) {
      //
      // Update CertNumber.
      //
      CertBuf[0] = Index;

      *UnchainCerts  = CertBuf;
      *UnchainLength = BufferSize;
    }
  }

  Status = TRUE;

_Error:
  //
  // Release Resources.
  //
  if (!Wrapped && (NewP7Data != NULL)) {
    free (NewP7Data);
  }

  if (Pkcs7 != NULL) {
    PKCS7_free (Pkcs7);
  }

  sk_X509_free (Signers);

  if (CertCtx != NULL) {
    X509_STORE_CTX_cleanup (CertCtx);
    X509_STORE_CTX_free (CertCtx);
  }

  if (SingleCert != NULL) {
    free (SingleCert);
  }

  if (OldBuf != NULL) {
    free (OldBuf);
  }

  if (!Status && (CertBuf != NULL)) {
    free (CertBuf);
    *SignerChainCerts = NULL;
    *UnchainCerts     = NULL;
  }

  return Status;
}

/**
  Verifies the validity of a PKCS#7 signed data as described in "PKCS #7:
  Cryptographic Message Syntax Standard". The input signed data could be wrapped
  in a ContentInfo structure.

  If P7Data, TrustedCert or InData is NULL, then return FALSE.
  If P7Length, CertLength or DataLength overflow, then return FALSE.

  Caution: This function may receive untrusted input.
  UEFI Authenticated Variable is external input, so this function will do basic
  check for PKCS#7 data structure.

  @param[in]  P7Data       Pointer to the PKCS#7 message to verify.
  @param[in]  P7Length     Length of the PKCS#7 message in bytes.
  @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which
                           is used for certificate chain verification.
  @param[in]  CertLength   Length of the trusted certificate in bytes.
  @param[in]  InData       Pointer to the content to be verified.
  @param[in]  DataLength   Length of InData in bytes.

  @retval  TRUE  The specified PKCS#7 signed data is valid.
  @retval  FALSE Invalid PKCS#7 signed data.

**/
BOOLEAN
EFIAPI
Pkcs7Verify (
  IN  CONST UINT8  *P7Data,
  IN  UINTN        P7Length,
  IN  CONST UINT8  *TrustedCert,
  IN  UINTN        CertLength,
  IN  CONST UINT8  *InData,
  IN  UINTN        DataLength
  )
{
  PKCS7        *Pkcs7;
  BIO          *DataBio;
  BOOLEAN      Status;
  X509         *Cert;
  X509_STORE   *CertStore;
  UINT8        *SignedData;
  CONST UINT8  *Temp;
  UINTN        SignedDataSize;
  BOOLEAN      Wrapped;

  //
  // Check input parameters.
  //
  if ((P7Data == NULL) || (TrustedCert == NULL) || (InData == NULL) ||
      (P7Length > INT_MAX) || (CertLength > INT_MAX) || (DataLength > INT_MAX))
  {
    return FALSE;
  }

  Pkcs7     = NULL;
  DataBio   = NULL;
  Cert      = NULL;
  CertStore = NULL;

  //
  // Register & Initialize necessary digest algorithms for PKCS#7 Handling
  //
  if (EVP_add_digest (EVP_md5 ()) == 0) {
    return FALSE;
  }

  if (EVP_add_digest (EVP_sha1 ()) == 0) {
    return FALSE;
  }

  if (EVP_add_digest (EVP_sha256 ()) == 0) {
    return FALSE;
  }

  if (EVP_add_digest (EVP_sha384 ()) == 0) {
    return FALSE;
  }

  if (EVP_add_digest (EVP_sha512 ()) == 0) {
    return FALSE;
  }

  if (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA) == 0) {
    return FALSE;
  }

  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
  if (!Status) {
    return Status;
  }

  Status = FALSE;

  //
  // Retrieve PKCS#7 Data (DER encoding)
  //
  if (SignedDataSize > INT_MAX) {
    goto _Exit;
  }

  Temp  = SignedData;
  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
  if (Pkcs7 == NULL) {
    goto _Exit;
  }

  //
  // Check if it's PKCS#7 Signed Data (for Authenticode Scenario)
  //
  if (!PKCS7_type_is_signed (Pkcs7)) {
    goto _Exit;
  }

  //
  // Read DER-encoded root certificate and Construct X509 Certificate
  //
  Temp = TrustedCert;
  Cert = d2i_X509 (NULL, &Temp, (long)CertLength);
  if (Cert == NULL) {
    goto _Exit;
  }

  //
  // Setup X509 Store for trusted certificate
  //
  CertStore = X509_STORE_new ();
  if (CertStore == NULL) {
    goto _Exit;
  }

  if (!(X509_STORE_add_cert (CertStore, Cert))) {
    goto _Exit;
  }

  //
  // For generic PKCS#7 handling, InData may be NULL if the content is present
  // in PKCS#7 structure. So ignore NULL checking here.
  //
  DataBio = BIO_new_mem_buf (InData, (int)DataLength);
  if (DataBio == NULL) {
    goto _Exit;
  }

  //
  // Allow partial certificate chains, terminated by a non-self-signed but
  // still trusted intermediate certificate. Also disable time checks.
  //
  X509_STORE_set_flags (
    CertStore,
    X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
    );

  //
  // OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and
  // doesn't support the extended key usage for Authenticode Code Signing.
  // Bypass the certificate purpose checking by enabling any purposes setting.
  //
  X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);

  //
  // Verifies the PKCS#7 signedData structure
  //
  Status = (BOOLEAN)PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, PKCS7_BINARY);

_Exit:
  //
  // Release Resources
  //
  BIO_free (DataBio);
  X509_free (Cert);
  X509_STORE_free (CertStore);
  PKCS7_free (Pkcs7);

  if (!Wrapped) {
    OPENSSL_free (SignedData);
  }

  return Status;
}
