/** @file
  PKCS#7 SignedData Sign Wrapper Implementation over OpenSSL.

Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<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 "InternalCryptLib.h"

#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/pkcs7.h>

/**
  Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
  Syntax Standard, version 1.5". This interface is only intended to be used for
  application to perform PKCS#7 functionality validation.

  @param[in]  PrivateKey       Pointer to the PEM-formatted private key data for
                               data signing.
  @param[in]  PrivateKeySize   Size of the PEM private key data in bytes.
  @param[in]  KeyPassword      NULL-terminated passphrase used for encrypted PEM
                               key data.
  @param[in]  InData           Pointer to the content to be signed.
  @param[in]  InDataSize       Size of InData in bytes.
  @param[in]  SignCert         Pointer to signer's DER-encoded certificate to sign with.
  @param[in]  OtherCerts       Pointer to an optional additional set of certificates to
                               include in the PKCS#7 signedData (e.g. any intermediate
                               CAs in the chain).
  @param[out] SignedData       Pointer to output PKCS#7 signedData. It's caller's
                               responsibility to free the buffer with FreePool().
  @param[out] SignedDataSize   Size of SignedData in bytes.

  @retval     TRUE             PKCS#7 data signing succeeded.
  @retval     FALSE            PKCS#7 data signing failed.

**/
BOOLEAN
EFIAPI
Pkcs7Sign (
  IN   CONST UINT8  *PrivateKey,
  IN   UINTN        PrivateKeySize,
  IN   CONST UINT8  *KeyPassword,
  IN   UINT8        *InData,
  IN   UINTN        InDataSize,
  IN   UINT8        *SignCert,
  IN   UINT8        *OtherCerts      OPTIONAL,
  OUT  UINT8        **SignedData,
  OUT  UINTN        *SignedDataSize
  )
{
  BOOLEAN   Status;
  EVP_PKEY  *Key;
  BIO       *DataBio;
  PKCS7     *Pkcs7;
  UINT8     *RsaContext;
  UINT8     *P7Data;
  UINTN     P7DataSize;
  UINT8     *Tmp;

  //
  // Check input parameters.
  //
  if (PrivateKey == NULL || KeyPassword == NULL || InData == NULL ||
    SignCert == NULL || SignedData == NULL || SignedDataSize == NULL || InDataSize > INT_MAX) {
    return FALSE;
  }

  RsaContext = NULL;
  Key        = NULL;
  Pkcs7      = NULL;
  DataBio    = NULL;
  Status     = FALSE;

  //
  // Retrieve RSA private key from PEM data.
  //
  Status = RsaGetPrivateKeyFromPem (
             PrivateKey,
             PrivateKeySize,
             (CONST CHAR8 *) KeyPassword,
             (VOID **) &RsaContext
             );
  if (!Status) {
    return Status;
  }

  Status = FALSE;

  //
  // Register & Initialize necessary digest algorithms and PRNG for PKCS#7 Handling
  //
  if (EVP_add_digest (EVP_md5 ()) == 0) {
    goto _Exit;
  }
  if (EVP_add_digest (EVP_sha1 ()) == 0) {
    goto _Exit;
  }
  if (EVP_add_digest (EVP_sha256 ()) == 0) {
    goto _Exit;
  }

  RandomSeed (NULL, 0);

  //
  // Construct OpenSSL EVP_PKEY for private key.
  //
  Key = EVP_PKEY_new ();
  if (Key == NULL) {
    goto _Exit;
  }
  if (EVP_PKEY_assign_RSA (Key, (RSA *) RsaContext) == 0) {
    goto _Exit;
  }

  //
  // Convert the data to be signed to BIO format. 
  //
  DataBio = BIO_new (BIO_s_mem ());
  if (DataBio == NULL) {
    goto _Exit;
  }

  if (BIO_write (DataBio, InData, (int) InDataSize) <= 0) {
    goto _Exit;
  }

  //
  // Create the PKCS#7 signedData structure.
  //
  Pkcs7 = PKCS7_sign (
            (X509 *) SignCert,
            Key,
            (STACK_OF(X509) *) OtherCerts,
            DataBio,
            PKCS7_BINARY | PKCS7_NOATTR | PKCS7_DETACHED
            );
  if (Pkcs7 == NULL) {
    goto _Exit;
  }

  //
  // Convert PKCS#7 signedData structure into DER-encoded buffer.
  //
  P7DataSize = i2d_PKCS7 (Pkcs7, NULL);
  if (P7DataSize <= 19) {
    goto _Exit;
  }

  P7Data     = malloc (P7DataSize);
  if (P7Data == NULL) {
    goto _Exit;
  }

  Tmp        = P7Data;
  P7DataSize = i2d_PKCS7 (Pkcs7, (unsigned char **) &Tmp);
  ASSERT (P7DataSize > 19);

  //
  // Strip ContentInfo to content only for signeddata. The data be trimmed off
  // is totally 19 bytes.
  //
  *SignedDataSize = P7DataSize - 19;
  *SignedData     = AllocatePool (*SignedDataSize);
  if (*SignedData == NULL) {
    OPENSSL_free (P7Data);
    goto _Exit;
  }

  CopyMem (*SignedData, P7Data + 19, *SignedDataSize);

  OPENSSL_free (P7Data);

  Status = TRUE;

_Exit:
  //
  // Release Resources
  //
  if (Key != NULL) {
    EVP_PKEY_free (Key);
  }

  if (DataBio != NULL) {
    BIO_free (DataBio);
  }

  if (Pkcs7 != NULL) {
    PKCS7_free (Pkcs7);
  }

  return Status;
}
