/** @file
  This module verifies that Enhanced Key Usages (EKU's) are present within
  a PKCS7 signature blob using OpenSSL.

  Copyright (C) Microsoft Corporation. All Rights Reserved.
  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Base.h>
#include "InternalCryptLib.h"
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/bio.h>
#include <crypto/x509.h>
#include <openssl/pkcs7.h>
#include <openssl/bn.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <crypto/asn1.h>

/**
  This function will return the leaf signer certificate in a chain.  This is
  required because certificate chains are not guaranteed to have the
  certificates in the order that they were issued.

  A typical certificate chain looks like this:


                 ----------------------------
                |            Root            |
                 ----------------------------
                               ^
                               |
                 ----------------------------
                |          Policy CA         | <-- Typical Trust Anchor.
                 ----------------------------
                               ^
                               |
                 ----------------------------
                |         Issuing CA         |
                 ----------------------------
                               ^
                               |
                 -----------------------------
                /  End-Entity (leaf) signer  / <-- Bottom certificate.
                -----------------------------  EKU: "1.3.6.1.4.1.311.76.9.21.1"
                                                    (Firmware Signing)


  @param[in]   CertChain            Certificate chain.

  @param[out]  SignerCert           Last certificate in the chain.  For PKCS7 signatures,
                                    this will be the end-entity (leaf) signer cert.

  @retval EFI_SUCCESS               The required EKUs were found in the signature.
  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
  @retval EFI_NOT_FOUND             The number of signers found was not 1.

**/
STATIC
EFI_STATUS
GetSignerCertificate (
  IN CONST PKCS7  *CertChain,
  OUT X509        **SignerCert
  )
{
  EFI_STATUS  Status;

  STACK_OF (X509)  *Signers;
  INT32  NumberSigners;

  Status        = EFI_SUCCESS;
  Signers       = NULL;
  NumberSigners = 0;

  if ((CertChain == NULL) || (SignerCert == NULL)) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Get the signers from the chain.
  //
  Signers = PKCS7_get0_signers ((PKCS7 *)CertChain, NULL, PKCS7_BINARY);
  if (Signers == NULL) {
    //
    // Fail to get signers form PKCS7
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // There should only be one signer in the PKCS7 stack.
  //
  NumberSigners = sk_X509_num (Signers);
  if (NumberSigners != 1) {
    //
    // The number of singers should have been 1
    //
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  *SignerCert = sk_X509_value (Signers, 0);

Exit:
  //
  // Release Resources
  //
  if (Signers != NULL) {
    sk_X509_free (Signers);
  }

  return Status;
}

/**
  Determines if the specified EKU represented in ASN1 form is present
  in a given certificate.

  @param[in]  Cert                  The certificate to check.

  @param[in]  Asn1ToFind            The EKU to look for.

  @retval EFI_SUCCESS               We successfully identified the signing type.
  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.

**/
STATIC
EFI_STATUS
IsEkuInCertificate (
  IN CONST X509   *Cert,
  IN ASN1_OBJECT  *Asn1ToFind
  )
{
  EFI_STATUS          Status;
  X509                *ClonedCert;
  X509_EXTENSION      *Extension;
  EXTENDED_KEY_USAGE  *Eku;
  INT32               ExtensionIndex;
  INTN                NumExtensions;
  ASN1_OBJECT         *Asn1InCert;
  INTN                Index;

  Status         = EFI_NOT_FOUND;
  ClonedCert     = NULL;
  Extension      = NULL;
  Eku            = NULL;
  ExtensionIndex = -1;
  NumExtensions  = 0;
  Asn1InCert     = NULL;

  if ((Cert == NULL) || (Asn1ToFind == NULL)) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Clone the certificate.  This is required because the Extension API's
  // only work once per instance of an X509 object.
  //
  ClonedCert = X509_dup ((X509 *)Cert);
  if (ClonedCert == NULL) {
    //
    // Fail to duplicate cert.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Look for the extended key usage.
  //
  ExtensionIndex = X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -1);

  if (ExtensionIndex < 0) {
    //
    // Fail to find 'NID_ext_key_usage' in Cert.
    //
    goto Exit;
  }

  Extension = X509_get_ext (ClonedCert, ExtensionIndex);
  if (Extension == NULL) {
    //
    // Fail to get Extension form cert.
    //
    goto Exit;
  }

  Eku = (EXTENDED_KEY_USAGE *)X509V3_EXT_d2i (Extension);
  if (Eku == NULL) {
    //
    // Fail to get Eku from extension.
    //
    goto Exit;
  }

  NumExtensions = sk_ASN1_OBJECT_num (Eku);

  //
  // Now loop through the extensions, looking for the specified Eku.
  //
  for (Index = 0; Index < NumExtensions; Index++) {
    Asn1InCert = sk_ASN1_OBJECT_value (Eku, (INT32)Index);
    if (Asn1InCert == NULL) {
      //
      // Fail to get ASN object from Eku.
      //
      goto Exit;
    }

    if ((Asn1InCert->length == Asn1ToFind->length) &&
        (CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length) == 0))
    {
      //
      // Found Eku in certificate.
      //
      Status = EFI_SUCCESS;
      goto Exit;
    }
  }

Exit:

  //
  // Release Resources
  //
  if (ClonedCert != NULL) {
    X509_free (ClonedCert);
  }

  if (Eku != NULL) {
    sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);
  }

  return Status;
}

/**
  Determines if the specified EKUs are present in a signing certificate.

  @param[in]  SignerCert            The certificate to check.
  @param[in]  RequiredEKUs          The EKUs to look for.
  @param[in]  RequiredEKUsSize      The number of EKUs
  @param[in]  RequireAllPresent     If TRUE, then all the specified EKUs
                                    must be present in the certificate.

  @retval EFI_SUCCESS               We successfully identified the signing type.
  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.
**/
STATIC
EFI_STATUS
CheckEKUs (
  IN CONST X509    *SignerCert,
  IN CONST CHAR8   *RequiredEKUs[],
  IN CONST UINT32  RequiredEKUsSize,
  IN BOOLEAN       RequireAllPresent
  )
{
  EFI_STATUS   Status;
  ASN1_OBJECT  *Asn1ToFind;
  UINT32       NumEkusFound;
  UINT32       Index;

  Status       = EFI_SUCCESS;
  Asn1ToFind   = NULL;
  NumEkusFound = 0;

  if ((SignerCert == NULL) || (RequiredEKUs == NULL) || (RequiredEKUsSize == 0)) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  for (Index = 0; Index < RequiredEKUsSize; Index++) {
    //
    // Finding required EKU in cert.
    //
    if (Asn1ToFind != NULL) {
      ASN1_OBJECT_free (Asn1ToFind);
      Asn1ToFind = NULL;
    }

    Asn1ToFind = OBJ_txt2obj (RequiredEKUs[Index], 0);
    if (Asn1ToFind == NULL) {
      //
      // Fail to convert required EKU to ASN1.
      //
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    Status = IsEkuInCertificate (SignerCert, Asn1ToFind);
    if (Status == EFI_SUCCESS) {
      NumEkusFound++;
      if (!RequireAllPresent) {
        //
        // Found at least one, so we are done.
        //
        goto Exit;
      }
    } else {
      //
      // Fail to find Eku in cert
      break;
    }
  }

Exit:

  if (Asn1ToFind != NULL) {
    ASN1_OBJECT_free (Asn1ToFind);
  }

  if (RequireAllPresent &&
      (NumEkusFound == RequiredEKUsSize))
  {
    //
    // Found all required EKUs in certificate.
    //
    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  This function receives a PKCS#7 formatted signature blob,
  looks for the EKU SEQUENCE blob, and if found then looks
  for all the required EKUs. This function was created so that
  the Surface team can cut down on the number of Certificate
  Authorities (CA's) by checking EKU's on leaf signers for
  a specific product. This prevents one product's certificate
  from signing another product's firmware or unlock blobs.

  Note that this function does not validate the certificate chain.
  That needs to be done before using this function.

  @param[in]  Pkcs7Signature       The PKCS#7 signed information content block. An array
                                   containing the content block with both the signature,
                                   the signer's certificate, and any necessary intermediate
                                   certificates.
  @param[in]  Pkcs7SignatureSize   Number of bytes in Pkcs7Signature.
  @param[in]  RequiredEKUs         Array of null-terminated strings listing OIDs of
                                   required EKUs that must be present in the signature.
  @param[in]  RequiredEKUsSize     Number of elements in the RequiredEKUs string array.
  @param[in]  RequireAllPresent    If this is TRUE, then all of the specified EKU's
                                   must be present in the leaf signer.  If it is
                                   FALSE, then we will succeed if we find any
                                   of the specified EKU's.

  @retval EFI_SUCCESS              The required EKUs were found in the signature.
  @retval EFI_INVALID_PARAMETER    A parameter was invalid.
  @retval EFI_NOT_FOUND            One or more EKU's were not found in the signature.

**/
EFI_STATUS
EFIAPI
VerifyEKUsInPkcs7Signature (
  IN CONST UINT8   *Pkcs7Signature,
  IN CONST UINT32  SignatureSize,
  IN CONST CHAR8   *RequiredEKUs[],
  IN CONST UINT32  RequiredEKUsSize,
  IN BOOLEAN       RequireAllPresent
  )
{
  EFI_STATUS  Status;
  PKCS7       *Pkcs7;

  STACK_OF (X509)    *CertChain;
  INT32    SignatureType;
  INT32    NumberCertsInSignature;
  X509     *SignerCert;
  UINT8    *SignedData;
  UINT8    *Temp;
  UINTN    SignedDataSize;
  BOOLEAN  IsWrapped;
  BOOLEAN  Ok;

  Status                 = EFI_SUCCESS;
  Pkcs7                  = NULL;
  CertChain              = NULL;
  SignatureType          = 0;
  NumberCertsInSignature = 0;
  SignerCert             = NULL;
  SignedData             = NULL;
  SignedDataSize         = 0;
  IsWrapped              = FALSE;
  Ok                     = FALSE;

  //
  // Validate the input parameters.
  //
  if ((Pkcs7Signature   == NULL) ||
      (SignatureSize    == 0) ||
      (RequiredEKUs     == NULL) ||
      (RequiredEKUsSize == 0))
  {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  if (RequiredEKUsSize == 1) {
    RequireAllPresent = TRUE;
  }

  //
  // Wrap the PKCS7 data if needed.
  //
  Ok = WrapPkcs7Data (
         Pkcs7Signature,
         SignatureSize,
         &IsWrapped,
         &SignedData,
         &SignedDataSize
         );
  if (!Ok) {
    //
    // Fail to Wrap the PKCS7 data.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  Temp = SignedData;

  //
  // Create the PKCS7 object.
  //
  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (INT32)SignedDataSize);
  if (Pkcs7 == NULL) {
    //
    // Fail to read PKCS7 data.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Get the certificate chain.
  //
  SignatureType = OBJ_obj2nid (Pkcs7->type);
  switch (SignatureType) {
    case NID_pkcs7_signed:
      if (Pkcs7->d.sign != NULL) {
        CertChain = Pkcs7->d.sign->cert;
      }

      break;
    case NID_pkcs7_signedAndEnveloped:
      if (Pkcs7->d.signed_and_enveloped != NULL) {
        CertChain = Pkcs7->d.signed_and_enveloped->cert;
      }

      break;
    default:
      break;
  }

  //
  // Ensure we have a certificate stack
  //
  if (CertChain == NULL) {
    //
    // Fail to get the certificate stack from signature.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Find out how many certificates were in the PKCS7 signature.
  //
  NumberCertsInSignature = sk_X509_num (CertChain);

  if (NumberCertsInSignature == 0) {
    //
    // Fail to find any certificates in signature.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Get the leaf signer.
  //
  Status = GetSignerCertificate (Pkcs7, &SignerCert);
  if ((Status != EFI_SUCCESS) || (SignerCert == NULL)) {
    //
    // Fail to get the end-entity leaf signer certificate.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  Status = CheckEKUs (SignerCert, RequiredEKUs, RequiredEKUsSize, RequireAllPresent);
  if (Status != EFI_SUCCESS) {
    goto Exit;
  }

Exit:

  //
  // Release Resources
  //
  // If the signature was not wrapped, then the call to WrapData() will allocate
  // the data and add a header to it
  //
  if (!IsWrapped && SignedData) {
    free (SignedData);
  }

  if (Pkcs7 != NULL) {
    PKCS7_free (Pkcs7);
  }

  return Status;
}
