## @file
# This tool adds EFI_FIRMWARE_IMAGE_AUTHENTICATION for a binary.
#
# This tool only support CertType - EFI_CERT_TYPE_PKCS7_GUID
#   {0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7}}
#
# This tool has been tested with OpenSSL.
#
# Copyright (c) 2016 - 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.
#

'''
Pkcs7Sign
'''

import os
import sys
import argparse
import subprocess
import uuid
import struct
import collections
from Common.BuildVersion import gBUILD_VERSION

#
# Globals for help information
#
__prog__      = 'Pkcs7Sign'
__version__   = '%s Version %s' % (__prog__, '0.9 ' + gBUILD_VERSION)
__copyright__ = 'Copyright (c) 2016, Intel Corporation. All rights reserved.'
__usage__     = '%s -e|-d [options] <input_file>' % (__prog__)

#
# GUID for PKCS7 from UEFI Specification
#
WIN_CERT_REVISION      = 0x0200
WIN_CERT_TYPE_EFI_GUID = 0x0EF1
EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}')

#
# typedef struct _WIN_CERTIFICATE {
#   UINT32 dwLength;
#   UINT16 wRevision;
#   UINT16 wCertificateType;
# //UINT8 bCertificate[ANYSIZE_ARRAY];
# } WIN_CERTIFICATE;
#
# typedef struct _WIN_CERTIFICATE_UEFI_GUID {
#   WIN_CERTIFICATE Hdr;
#   EFI_GUID        CertType;
# //UINT8 CertData[ANYSIZE_ARRAY];
# } WIN_CERTIFICATE_UEFI_GUID;
#
# typedef struct {
#   UINT64                    MonotonicCount;
#   WIN_CERTIFICATE_UEFI_GUID AuthInfo;
# } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
#

#
# Filename of test signing private cert that is stored in same directory as this tool
#
TEST_SIGNER_PRIVATE_CERT_FILENAME = 'TestCert.pem'
TEST_OTHER_PUBLIC_CERT_FILENAME = 'TestSub.pub.pem'
TEST_TRUSTED_PUBLIC_CERT_FILENAME = 'TestRoot.pub.pem'

if __name__ == '__main__':
  #
  # Create command line argument parser object
  #
  parser = argparse.ArgumentParser(prog=__prog__, version=__version__, usage=__usage__, description=__copyright__, conflict_handler='resolve')
  group = parser.add_mutually_exclusive_group(required=True)
  group.add_argument("-e", action="store_true", dest='Encode', help='encode file')
  group.add_argument("-d", action="store_true", dest='Decode', help='decode file')
  parser.add_argument("-o", "--output", dest='OutputFile', type=str, metavar='filename', help="specify the output filename", required=True)
  parser.add_argument("--signer-private-cert", dest='SignerPrivateCertFile', type=argparse.FileType('rb'), help="specify the signer private cert filename.  If not specified, a test signer private cert is used.")
  parser.add_argument("--other-public-cert", dest='OtherPublicCertFile', type=argparse.FileType('rb'), help="specify the other public cert filename.  If not specified, a test other public cert is used.")
  parser.add_argument("--trusted-public-cert", dest='TrustedPublicCertFile', type=argparse.FileType('rb'), help="specify the trusted public cert filename.  If not specified, a test trusted public cert is used.")
  parser.add_argument("--monotonic-count", dest='MonotonicCountStr', type=str, help="specify the MonotonicCount in FMP capsule.  If not specified, 0 is used.")
  parser.add_argument("--signature-size", dest='SignatureSizeStr', type=str, help="specify the signature size for decode process.")
  parser.add_argument("-v", "--verbose", dest='Verbose', action="store_true", help="increase output messages")
  parser.add_argument("-q", "--quiet", dest='Quiet', action="store_true", help="reduce output messages")
  parser.add_argument("--debug", dest='Debug', type=int, metavar='[0-9]', choices=range(0,10), default=0, help="set debug level")
  parser.add_argument(metavar="input_file", dest='InputFile', type=argparse.FileType('rb'), help="specify the input filename")

  #
  # Parse command line arguments
  #
  args = parser.parse_args()

  #
  # Generate file path to Open SSL command
  #
  OpenSslCommand = 'openssl'
  try:
    OpenSslPath = os.environ['OPENSSL_PATH']
    OpenSslCommand = os.path.join(OpenSslPath, OpenSslCommand)
    if ' ' in OpenSslCommand:
      OpenSslCommand = '"' + OpenSslCommand + '"'
  except:
    pass

  #
  # Verify that Open SSL command is available
  #
  try:
    Process = subprocess.Popen('%s version' % (OpenSslCommand), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  except:
    print 'ERROR: Open SSL command not available.  Please verify PATH or set OPENSSL_PATH'
    sys.exit(1)

  Version = Process.communicate()
  if Process.returncode <> 0:
    print 'ERROR: Open SSL command not available.  Please verify PATH or set OPENSSL_PATH'
    sys.exit(Process.returncode)
  print Version[0]

  #
  # Read input file into a buffer and save input filename
  #
  args.InputFileName   = args.InputFile.name
  args.InputFileBuffer = args.InputFile.read()
  args.InputFile.close()

  #
  # Save output filename and check if path exists
  #
  OutputDir = os.path.dirname(args.OutputFile)
  if not os.path.exists(OutputDir):
    print 'ERROR: The output path does not exist: %s' % OutputDir
    sys.exit(1)
  args.OutputFileName = args.OutputFile

  try:
    if args.MonotonicCountStr.upper().startswith('0X'):
      args.MonotonicCountValue = (long)(args.MonotonicCountStr, 16)
    else:
      args.MonotonicCountValue = (long)(args.MonotonicCountStr)
  except:
    args.MonotonicCountValue = (long)(0)

  if args.Encode:
    #
    # Save signer private cert filename and close private cert file
    #
    try:
      args.SignerPrivateCertFileName = args.SignerPrivateCertFile.name
      args.SignerPrivateCertFile.close()
    except:
      try:
        #
        # Get path to currently executing script or executable
        #
        if hasattr(sys, 'frozen'):
            Pkcs7ToolPath = sys.executable
        else:
            Pkcs7ToolPath = sys.argv[0]
        if Pkcs7ToolPath.startswith('"'):
            Pkcs7ToolPath = Pkcs7ToolPath[1:]
        if Pkcs7ToolPath.endswith('"'):
            Pkcs7ToolPath = RsaToolPath[:-1]
        args.SignerPrivateCertFileName = os.path.join(os.path.dirname(os.path.realpath(Pkcs7ToolPath)), TEST_SIGNER_PRIVATE_CERT_FILENAME)
        args.SignerPrivateCertFile = open(args.SignerPrivateCertFileName, 'rb')
        args.SignerPrivateCertFile.close()
      except:
        print 'ERROR: test signer private cert file %s missing' % (args.SignerPrivateCertFileName)
        sys.exit(1)

    #
    # Save other public cert filename and close public cert file
    #
    try:
      args.OtherPublicCertFileName = args.OtherPublicCertFile.name
      args.OtherPublicCertFile.close()
    except:
      try:
        #
        # Get path to currently executing script or executable
        #
        if hasattr(sys, 'frozen'):
            Pkcs7ToolPath = sys.executable
        else:
            Pkcs7ToolPath = sys.argv[0]
        if Pkcs7ToolPath.startswith('"'):
            Pkcs7ToolPath = Pkcs7ToolPath[1:]
        if Pkcs7ToolPath.endswith('"'):
            Pkcs7ToolPath = RsaToolPath[:-1]
        args.OtherPublicCertFileName = os.path.join(os.path.dirname(os.path.realpath(Pkcs7ToolPath)), TEST_OTHER_PUBLIC_CERT_FILENAME)
        args.OtherPublicCertFile = open(args.OtherPublicCertFileName, 'rb')
        args.OtherPublicCertFile.close()
      except:
        print 'ERROR: test other public cert file %s missing' % (args.OtherPublicCertFileName)
        sys.exit(1)

    format = "%dsQ" % len(args.InputFileBuffer)
    FullInputFileBuffer = struct.pack(format, args.InputFileBuffer, args.MonotonicCountValue)

    #
    # Sign the input file using the specified private key and capture signature from STDOUT
    #
    Process = subprocess.Popen('%s smime -sign -binary -signer "%s" -outform DER -md sha256 -certfile "%s"' % (OpenSslCommand, args.SignerPrivateCertFileName, args.OtherPublicCertFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    Signature = Process.communicate(input=FullInputFileBuffer)[0]
    if Process.returncode <> 0:
      sys.exit(Process.returncode)

    #
    # Write output file that contains Signature, and Input data
    #
    args.OutputFile = open(args.OutputFileName, 'wb')
    args.OutputFile.write(Signature)
    args.OutputFile.write(args.InputFileBuffer)
    args.OutputFile.close()

  if args.Decode:
    #
    # Save trusted public cert filename and close public cert file
    #
    try:
      args.TrustedPublicCertFileName = args.TrustedPublicCertFile.name
      args.TrustedPublicCertFile.close()
    except:
      try:
        #
        # Get path to currently executing script or executable
        #
        if hasattr(sys, 'frozen'):
            Pkcs7ToolPath = sys.executable
        else:
            Pkcs7ToolPath = sys.argv[0]
        if Pkcs7ToolPath.startswith('"'):
            Pkcs7ToolPath = Pkcs7ToolPath[1:]
        if Pkcs7ToolPath.endswith('"'):
            Pkcs7ToolPath = RsaToolPath[:-1]
        args.TrustedPublicCertFileName = os.path.join(os.path.dirname(os.path.realpath(Pkcs7ToolPath)), TEST_TRUSTED_PUBLIC_CERT_FILENAME)
        args.TrustedPublicCertFile = open(args.TrustedPublicCertFileName, 'rb')
        args.TrustedPublicCertFile.close()
      except:
        print 'ERROR: test trusted public cert file %s missing' % (args.TrustedPublicCertFileName)
        sys.exit(1)

    if not args.SignatureSizeStr:
      print "ERROR: please use the option --signature-size to specify the size of the signature data!"
      sys.exit(1)
    else:
      if args.SignatureSizeStr.upper().startswith('0X'):
        SignatureSize = (long)(args.SignatureSizeStr, 16)
      else:
        SignatureSize = (long)(args.SignatureSizeStr)
    if SignatureSize < 0:
        print "ERROR: The value of option --signature-size can't be set to negative value!"
        sys.exit(1)
    elif SignatureSize > len(args.InputFileBuffer):
        print "ERROR: The value of option --signature-size is exceed the size of the input file !"
        sys.exit(1)

    args.SignatureBuffer = args.InputFileBuffer[0:SignatureSize]
    args.InputFileBuffer = args.InputFileBuffer[SignatureSize:]

    format = "%dsQ" % len(args.InputFileBuffer)
    FullInputFileBuffer = struct.pack(format, args.InputFileBuffer, args.MonotonicCountValue)

    #
    # Save output file contents from input file
    #
    open(args.OutputFileName, 'wb').write(FullInputFileBuffer)

    #
    # Verify signature
    #
    Process = subprocess.Popen('%s smime -verify -inform DER -content %s -CAfile %s' % (OpenSslCommand, args.OutputFileName, args.TrustedPublicCertFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    Process.communicate(input=args.SignatureBuffer)[0]
    if Process.returncode <> 0:
      print 'ERROR: Verification failed'
      os.remove (args.OutputFileName)
      sys.exit(Process.returncode)

    open(args.OutputFileName, 'wb').write(args.InputFileBuffer)
