audk/BaseTools/Source/Python/Rsa2048Sha256Sign/Rsa2048Sha256GenerateKeys.py
Liming Gao 1ccc4d895d Revert BaseTools: PYTHON3 migration
This reverts commit 6693f359b3c213513c5096a06c6f67244a44dc52..
678f85131238622e576705117e299d81cff755c9.

Python3 migration is the fundamental change. It requires every developer
to install Python3. Before this migration, the well communication and wide
verification must be done. But now, most people is not aware of this change,
and not try it. So, Python3 migration is reverted and be moved to edk2-staging
Python3 branch for the edk2 user evaluation.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
2018-10-15 08:29:14 +08:00

176 lines
6.6 KiB
Python

## @file
# This tool can be used to generate new RSA 2048 bit private/public key pairs
# in a PEM file format using OpenSSL command line utilities that are installed
# on the path specified by the system environment variable OPENSSL_PATH.
# This tool can also optionally write one or more SHA 256 hashes of 2048 bit
# public keys to a binary file, write one or more SHA 256 hashes of 2048 bit
# public keys to a file in a C structure format, and in verbose mode display
# one or more SHA 256 hashes of 2048 bit public keys in a C structure format
# on STDOUT.
# This tool has been tested with OpenSSL 1.0.1e 11 Feb 2013
#
# Copyright (c) 2013 - 2018, 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.
#
'''
Rsa2048Sha256GenerateKeys
'''
from __future__ import print_function
import os
import sys
import argparse
import subprocess
from Common.BuildVersion import gBUILD_VERSION
#
# Globals for help information
#
__prog__ = 'Rsa2048Sha256GenerateKeys'
__version__ = '%s Version %s' % (__prog__, '0.9 ' + gBUILD_VERSION)
__copyright__ = 'Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.'
__usage__ = '%s [options]' % (__prog__)
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("-o", "--output", dest='OutputFile', type=argparse.FileType('wb'), metavar='filename', nargs='*', help="specify the output private key filename in PEM format")
group.add_argument("-i", "--input", dest='InputFile', type=argparse.FileType('rb'), metavar='filename', nargs='*', help="specify the input private key filename in PEM format")
parser.add_argument("--public-key-hash", dest='PublicKeyHashFile', type=argparse.FileType('wb'), help="specify the public key hash filename that is SHA 256 hash of 2048 bit RSA public key in binary format")
parser.add_argument("--public-key-hash-c", dest='PublicKeyHashCFile', type=argparse.FileType('wb'), help="specify the public key hash filename that is SHA 256 hash of 2048 bit RSA public key in C structure format")
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")
#
# 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])
args.PemFileName = []
#
# Check for output file argument
#
if args.OutputFile is not None:
for Item in args.OutputFile:
#
# Save PEM filename and close output file
#
args.PemFileName.append(Item.name)
Item.close()
#
# Generate private key and save it to output file in a PEM file format
#
Process = subprocess.Popen('%s genrsa -out %s 2048' % (OpenSslCommand, Item.name), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Process.communicate()
if Process.returncode != 0:
print('ERROR: RSA 2048 key generation failed')
sys.exit(Process.returncode)
#
# Check for input file argument
#
if args.InputFile is not None:
for Item in args.InputFile:
#
# Save PEM filename and close input file
#
args.PemFileName.append(Item.name)
Item.close()
PublicKeyHash = ''
for Item in args.PemFileName:
#
# Extract public key from private key into STDOUT
#
Process = subprocess.Popen('%s rsa -in %s -modulus -noout' % (OpenSslCommand, Item), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
PublicKeyHexString = Process.communicate()[0].split('=')[1].strip()
if Process.returncode != 0:
print('ERROR: Unable to extract public key from private key')
sys.exit(Process.returncode)
PublicKey = ''
for Index in range (0, len(PublicKeyHexString), 2):
PublicKey = PublicKey + chr(int(PublicKeyHexString[Index:Index + 2], 16))
#
# Generate SHA 256 hash of RSA 2048 bit public key into STDOUT
#
Process = subprocess.Popen('%s dgst -sha256 -binary' % (OpenSslCommand), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
Process.stdin.write (PublicKey)
PublicKeyHash = PublicKeyHash + Process.communicate()[0]
if Process.returncode != 0:
print('ERROR: Unable to extract SHA 256 hash of public key')
sys.exit(Process.returncode)
#
# Write SHA 256 hash of 2048 bit binary public key to public key hash file
#
try:
args.PublicKeyHashFile.write (PublicKeyHash)
args.PublicKeyHashFile.close ()
except:
pass
#
# Convert public key hash to a C structure string
#
PublicKeyHashC = '{'
for Item in PublicKeyHash:
PublicKeyHashC = PublicKeyHashC + '0x%02x, ' % (ord(Item))
PublicKeyHashC = PublicKeyHashC[:-2] + '}'
#
# Write SHA 256 of 2048 bit binary public key to public key hash C structure file
#
try:
args.PublicKeyHashCFile.write (PublicKeyHashC)
args.PublicKeyHashCFile.close ()
except:
pass
#
# If verbose is enabled display the public key in C structure format
#
if args.Verbose:
print('PublicKeySha256 = ' + PublicKeyHashC)