+
+} # CheckSecureBoot()
+
+# Check for the presence of locally-generated keys from a previous installation in
+# $EtcKeysDir (/etc/refind.d/keys). If they're not present, generate them using
+# openssl.
+GenerateKeys() {
+ PrivateKey=$EtcKeysDir/$LocalKeysBase.key
+ CertKey=$EtcKeysDir/$LocalKeysBase.crt
+ DerKey=$EtcKeysDir/$LocalKeysBase.cer
+ OpenSSL=`which openssl 2> /dev/null`
+
+ # Do the work only if one or more of the necessary keys is missing
+ # TODO: Technically, we don't need the DerKey; but if it's missing and openssl
+ # is also missing, this will fail. This could be improved.
+ if [[ ! -f $PrivateKey || ! -f $CertKey || ! -f $DerKey ]] ; then
+ echo "Generating a fresh set of local keys...."
+ mkdir -p $EtcKeysDir
+ chmod 0700 $EtcKeysDir
+ if [[ ! -x $OpenSSL ]] ; then
+ echo "Can't find openssl, which is required to create your private signing keys!"
+ echo "Aborting!"
+ exit 1
+ fi
+ if [[ -f $PrivateKey ]] ; then
+ echo "Backing up existing $PrivateKey"
+ cp -f $PrivateKey $PrivateKey.backup 2> /dev/null
+ fi
+ if [[ -f $CertKey ]] ; then
+ echo "Backing up existing $CertKey"
+ cp -f $CertKey $CertKey.backup 2> /dev/null
+ fi
+ if [[ -f $DerKey ]] ; then
+ echo "Backing up existing $DerKey"
+ cp -f $DerKey $DerKey.backup 2> /dev/null
+ fi
+ $OpenSSL req -new -x509 -newkey rsa:2048 -keyout $PrivateKey -out $CertKey \
+ -nodes -days 3650 -subj "/CN=Locally-generated rEFInd key/"
+ $OpenSSL x509 -in $CertKey -out $DerKey -outform DER
+ chmod 0600 $PrivateKey
+ else
+ echo "Using existing local keys...."
+ fi
+}
+
+# Sign a single binary. Requires parameters:
+# $1 = source file
+# $2 = destination file
+# Also assumes that the SBSign, PESign, UseSBSign, UsePESign, and various key variables are set
+# appropriately.
+# Aborts script on error
+SignOneBinary() {
+ $SBSign --key $PrivateKey --cert $CertKey --output $2 $1
+ if [[ $? != 0 ]] ; then
+ echo "Problem signing the binary $1! Aborting!"
+ exit 1
+ fi
+}
+
+# Re-sign the x86-64 binaries with a locally-generated key, First look for appropriate
+# key files in $EtcKeysDir. If they're present, use them to re-sign the binaries. If
+# not, try to generate new keys and store them in $EtcKeysDir.
+ReSignBinaries() {
+ SBSign=`which sbsign 2> /dev/null`
+ echo "Found sbsign at $SBSign"
+ TempDir="/tmp/refind_local"
+ if [[ ! -x $SBSign ]] ; then
+ echo "Can't find sbsign, which is required to sign rEFInd with your own keys!"
+ echo "Aborting!"
+ exit 1
+ fi
+ GenerateKeys
+ mkdir -p $TempDir/drivers_x64
+ cp $RefindDir/refind.conf-sample $TempDir 2> /dev/null
+ cp $ThisDir/refind.conf-sample $TempDir 2> /dev/null
+ cp $RefindDir/refind_ia32.efi $TempDir
+ cp -a $RefindDir/drivers_ia32 $TempDir 2> /dev/null
+ cp -a $ThisDir/drivers_ia32 $TempDir 2> /dev/null
+ SignOneBinary $RefindDir/refind_x64.efi $ThisDir/refind_x64.efi
+ for Driver in `ls $RefindDir/drivers_x64/*.efi $ThisDir/drivers_x64/*.efi 2> /dev/null` ; do
+ TempName=`basename $Driver`
+ SignOneBinary $Driver $TempDir/drivers_x64/$TempName
+ done
+ RefindDir=$TempDir
+ DeleteRefindDir=1