BaseTools/Capsule: Prevent to Read the STDOUT Content as Signature

- Within the capsule generate script, it is using the STDOUT result
  as signature while signing the hash digest via OpenSSL tool.

- There would have incorrect result when the user terminal have
  the output when executing the startup script.

- Incorrect the content of signature would make the verification failed.

- Use the "-output" flag to export the signature then read it back
  as the resolution.

Signed-off-by: Jason1 Lin <jason1.lin@intel.com>
This commit is contained in:
Jason1 Lin 2026-04-30 15:14:48 +08:00 committed by mergify[bot]
parent ebb314b12d
commit ddd94f778b

View file

@ -10,7 +10,7 @@
# keep the tool as simple as possible, it has the following limitations:
# * Do not support vendor code bytes in a capsule.
#
# Copyright (c) 2018 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2018 - 2026, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -38,8 +38,8 @@ from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass
# Globals for help information
#
__prog__ = 'GenerateCapsule'
__version__ = '0.11'
__copyright__ = 'Copyright (c) 2024, Intel Corporation. All rights reserved.'
__version__ = '0.12'
__copyright__ = 'Copyright (c) 2026, Intel Corporation. All rights reserved.'
__description__ = 'Generate a capsule.\n'
#
@ -175,6 +175,16 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer
#
CheckHashAlgorithmSupported (TOOL_OPENSSL, HashAlgorithm)
#
# Create a temporary directory
#
TempDirectoryPath = tempfile.mkdtemp()
#
# Get the temp signature file name
#
TempSignatureFilePath = os.path.join (TempDirectoryPath, 'Signature.bin')
#
# Build openssl command
#
@ -183,24 +193,38 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer
Command = ''
Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl'))
Command = Command + 'smime -sign -binary -outform DER -md {HashAlgorithm} '.format (HashAlgorithm = HashAlgorithm)
Command = Command + '-signer "{Private}" -certfile "{Public}"'.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile)
Command = Command + '-signer "{Private}" -certfile "{Public}" '.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile)
Command = Command + '-out "{Output}"'.format (Output = TempSignatureFilePath)
if Verbose:
print (Command)
#
# Sign the input file using the specified private key and capture signature from STDOUT
# Sign the input file using the specified private key
#
try:
Process = subprocess.Popen (Command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True)
Result = Process.communicate(input = Payload)
Signature = Result[0]
except:
shutil.rmtree (TempDirectoryPath)
raise ValueError ('GenerateCapsule: error: can not run openssl.')
if Process.returncode != 0:
shutil.rmtree (TempDirectoryPath)
print (Result[1].decode())
raise ValueError ('GenerateCapsule: error: openssl failed.')
#
# Read the signature from the generated output file
#
try:
with open (TempSignatureFilePath, 'rb') as File:
Signature = File.read ()
except:
shutil.rmtree (TempDirectoryPath)
raise ValueError ('GenerateCapsule: error: can not read signature file.')
shutil.rmtree (TempDirectoryPath)
return Signature
def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False):