#!/bin/bash 
#SCRIPT_PURPOSE - allow some visibility into key file contents

# File to examine
THE_FILE=""

# optional certificate to try and validate against
THE_CERTIFICATE="$2"

# do not check the signing of binaries on the system
DO_AUDIT="FALSE"

# Unless auditing, don't keep data
AUDIT_FILE="/tmp/signing-audit.txt"
FILES_SIGNED_WITH_FILE="${AUDIT_FILE}.cn"

BIOS_KEY_DIR="$(pwd)/exported-uefi-bios-keys"

SIGN_CHECK_LOG="/tmp/sign-check.log"

# standard prefix to round up files
CORRELATE_PREFIX="/tmp/cor_"

function fxnHelp()
{

    echo""
    echo "Usage  : $(basename "$0"):  [options] [file]"
    echo ""
    echo " Dump information about encrypted files "
    echo ""
    echo " -c | --cert               Is optional. If a signed file is passed,"
    echo "                            its signing can be checked against "
    echo "                            the certificate for a match."
    echo " -a | --audit              Check signing of system binaries."
    echo "      --checksums            check EFI binaries."
    echo "      --get-bios-keys      Dump keys from the BIOS."
    echo "      --cert-check <cert>     Run signing checks."
    echo ""
    echo " Examples:"
    echo "  Get key information: "
    echo "   $0 foo.pem"
    echo "  See if a certificate matches a signed file"
    echo "   $0 signed-file --cert mycert.pem"
    echo "     Ex: $0 grubx64.efi.signed --cert dev-x509-cert.pem "
    echo "  See what system binaries were signed with"
    echo "   $0 --audit "
    echo "  See if a certificate is _really_ in the BIOS."
    echo "   $0 --cert-check dev-x509-cert-pem "
    echo ""

    echo "Supply a key or key related file to validate."

}

function fxnHeader()
{
    echo "----------------------------------------------------"
    echo "- $1"
    echo "----------------------------------------------------"
}
# Pull public keys out of the bios for examination
function fxnGetBIOSKeys()
{


    if [ -e "$BIOS_KEY_DIR" ];then
        rm -rf "$BIOS_KEY_DIR"
    fi
    mkdir "$BIOS_KEY_DIR"

    fxnHeader "Exporting UEFI database keys to [ $BIOS_KEY_DIR ]"

    cd "$BIOS_KEY_DIR"

    # To get the platform key, this must be run as root.
    for database in db kek pk dbx
    do
        mkdir "${database}-keys"
        cd "${database}-keys"
        echo "${database} keys"
        mokutil --export --${database}
        ls -l
        cd ..
    done

    cd ..
    echo "Done exporting keys and creating certificates in $BIOS_KEY_DIR"
    echo ""
    echo "Use certificates to validate .efi signing as follows:"
    echo "$0 /boot/efi/EFI/cumulus-linux/grubx64.efi --cert ./exported-uefi-bios-keys/db-keys/DB-0001.crt"
    echo ""
}


function fxnDerToCert()
{
    local theDer="$1"
    local base="${theDer%.*}"
    local certName="${base}.crt"
    openssl x509 -inform der -in "$theDer" -out "$certName"

}


# Certificates can be generated with the same strings,
# and look identical. Correlate UEFI vs signing
#
function fxnCertCheck()
{
    local presentCert="$1"
    local ders
    local certs
    local logMatches=""

    fxnHeader "Creating certificates from UEFI vars."
    #
    #    fxnDerToCert "./exported-uefi-bios-keys/db-keys/DB-0001.der"
    fxnGetBIOSKeys

    ders=$( find "$BIOS_KEY_DIR"/ -name *.der )
    for file in ${ders[@]}
    do
        fxnDerToCert "$file"
    done

    if [ -e "$1" ];then
        fxnHeader "Comparing certificates from BIOS against $1"
        certs=$( find "$BIOS_KEY_DIR"/ -name *.crt )
        for file in ${certs[@]}
        do
            echo "Diffing [ $1 ] vs $file"
            echo -n "    "
            diff -q "$1" "$file"
            if [ $? = "0" ];then
                echo ""
                echo "Match: $1 $file"
                logMatches+="  $file "
                echo ""
            fi
        done

        fxnHeader "Certificates that matched [ $1 ]"
        if [ "$logMatches" = "" ];then
            echo "None."
        else
            echo -n $logMatches
        fi
        echo ""
    fi

}

#
# checksum files in efi directory.
#
function fxnPrintEFIChecksums()
{
    local efiDir="/boot/efi/EFI/$1"
    local auditFile="$2"
    echo ""
    echo "####################################################"
    echo "# checksums in [ $efiDir ]"
    echo "####################################################"
    echo ""
    echo "" >> "$auditFile"
    sha256sum "${efiDir}/grubx64.efi"

    sha256sum "${efiDir}/shimx64.efi"

    sha256sum  "${efiDir}/mmx64.efi"

}

#
# Checksum all efi directories
function fxnPrintAllEFIChecksums()
{

    fxnPrintEFIChecksums "cumulus-linux"  "$AUDIT_FILE"
    fxnPrintEFIChecksums "debian"         "$AUDIT_FILE"
    fxnPrintEFIChecksums "onie"           "$AUDIT_FILE"

}

# takes: cumulus-linux , onie, debian
function fxnAuditEFI()
{
    local efiDir="/boot/efi/EFI/$1"
    local auditFile="$2"
    echo ""
    echo "####################################################"
    echo "# Signed files in [ $efiDir ]"
    echo "####################################################"
    echo ""
    echo "" >> "$auditFile"
    $0  "${efiDir}/grubx64.efi" --audit-file "$auditFile"

    $0  "${efiDir}/shimx64.efi" --audit-file "$auditFile"

    $0  "${efiDir}/mmx64.efi"   --audit-file "$auditFile"

}

#
# Look for CN strings in UEFI variables
# Takes:
#  Name of UEFI variable to inspect (db, KEK, MOK, PK, etc..)
#  Text label for user as a string.
function fxnParseUEFIDatabase()
{
    local UEFIName="$1"
    local UEFILabel="$2"
    local CNStrings
    local varSet
    echo ""
    echo "----------------------------------------------------"
    echo "- $UEFILabel CN string matches:"
    echo "----------------------------------------------------"
    varSet=$(efivar --list | grep "$UEFIName" )
    if [ "$varSet" = "" ];then
        echo "    Variable $UEFIName is not set."
        return 0
    fi
    CNStrings=$( efivar --print --name=$(efivar --list | grep "$UEFIName" ) | awk -F '|' '{printf "%s", $2}'  )

    for cnType in "${FILES_SIGNED_WITH_CN[@]}"
    do
        echo "$CNStrings" | grep -q "$cnType"
        if [ $? = "0" ];then
            echo " [ $cnType ]"
        fi
    done

}

# Use mokutil to parse, as it does key decode.
function fxnParseMokutil()
{

    local UEFIName="$1"
    local UEFILabel="$2"
    local Counter=0
    local matchResult="  None"
    local CNStrings
    local CNFingerPrints

    echo ""
    echo "----------------------------------------------------"
    echo "- $UEFILabel CN string matches:"
    echo "----------------------------------------------------"
    echo ""
    echo " Strings found:"

    CNStrings=$( mokutil --${UEFIName} \
                     | grep "Subject:" \
                     | sed -e 's/ .*Subject/   Subject/g' \
                     | sed -e 's/*.CN=//g' )
    # read sorted mokutil output into the array
    readarray -t CN_CORRELATE_ARRAY < <( mokutil --${UEFIName} \
                                             | grep "Subject:" \
                                             | sed -e 's/ .*Subject/   Subject/g' \
                                             | sed -e 's/*.CN=//g' )


    # Put fingerprint data with CN data in a file for this database,
    # to be sorted later
    readarray -t PrintArray < <( mokutil --${UEFIName} | grep 'SHA1 Fingerprint:'  )
    counter=0

    if [ -e ${CORRELATE_PREFIX}${UEFIName}.txt ];then
        rm -f ${CORRELATE_PREFIX}${UEFIName}.txt
    fi
    for fp in "${PrintArray[@]}"
    do
        echo "${CN_CORRELATE_ARRAY[$counter]},${PrintArray[$counter]}" >> ${CORRELATE_PREFIX}${UEFIName}.txt
        counter=$(( counter +1 ))
    done

    #
    # correlate strings and fingerprints
    #

    if [ "$CNStrings" = "" ];then
        echo "  None"
        # nothing else to do here.
        return 0
    else
        # Got certificate strings
        cat ${CORRELATE_PREFIX}${UEFIName}.txt  | sort | uniq

    fi
    echo ""

    echo " Matches:"

    for cnType in "${FILES_SIGNED_WITH_CN[@]}"
    do
        grep -q "CN=${cnType}" ${CORRELATE_PREFIX}${UEFIName}.txt
        #        echo "$CNStrings" | grep -q "$cnType"

        if [ $? = "0" ];then
            # Got a match, so do not print 'None'
            matchResult=""
            echo "   Match: [ $cnType ]"
            grep "$cnType" ${CORRELATE_PREFIX}${UEFIName}.txt
        fi

    done

    echo "$matchResult"

}

# sort out unique keys and fingerprints
function fxnCorrelateFPNames()
{

    echo ""
    echo "----------------------------------------------------"
    echo "- These keys were found in various UEFI databases "
    echo "----------------------------------------------------"
    ls ${CORRELATE_PREFIX}*.txt > /dev/null 2>&1
    if [ $? = "0" ];then
        readarray -t CN_FPNAME_ARRAY < <(cat ${CORRELATE_PREFIX}*.txt | sort | uniq )
        for fp in "${CN_FPNAME_ARRAY[@]}"
        do
            echo "$fp" | sed -e 's/,/\n    /g'
        done
    else
        echo " No UEFI database keys found."
    fi

}
# Hold CN strings
declare FILES_SIGNED_WITH_CN
declare CN_FINGERPRINT_ARRAY

function fxnAuditSystem()
{
    #
    # top level audit invocation - create and delete audit log.
    #
    if [ -e "$AUDIT_FILE" ];then
        rm "$AUDIT_FILE"
    fi
    touch "$AUDIT_FILE"

    # Get all uefi keys and export them locally
    # Do this first so that kernel signing has keys to check against.
    
    fxnCertCheck
    
    # Track signatures
    echo "" > "$FILES_SIGNED_WITH_FILE"
    echo "####################################################"
    echo "# Kernel signed with:"
    echo "####################################################"
    $0  /boot/vmlinuz* --audit-file "$AUDIT_FILE"

    echo ""
    echo "####################################################"
    echo "# Spot check the encrypted-keys.ko kernel module."
    echo "####################################################"
    # There are a ton of modules down there. Pick one that should be
    # present for secure boot and dump it as a sanity check and as a
    # reminder of how to validate this.
    modinfo /usr/lib/modules/*/kernel/security/keys/encrypted-keys/encrypted-keys.ko
    if [ $? != "0" ];then
        echo "ERROR - kernel modules are not signed."
    fi


    echo ""

    fxnAuditEFI "cumulus-linux"  "$AUDIT_FILE"
    fxnAuditEFI "debian"         "$AUDIT_FILE"
    fxnAuditEFI "onie"           "$AUDIT_FILE"


    echo ""
    echo ""
    echo "####################################################"
    echo "# System signing audit summary:"
    echo "####################################################"

    # Remove any whitespaces when de-duplicating kek entries
    SeenCNS="$( cat "$FILES_SIGNED_WITH_FILE" | sort -u )"
    echo "$SeenCNS" | sed  '/^[[:space:]]*$/d'  > "$FILES_SIGNED_WITH_FILE"
    readarray -t FILES_SIGNED_WITH_CN < "$FILES_SIGNED_WITH_FILE"


    echo "####################################################"
    echo "# Correlating file signatures with UEFI variables:"
    echo "####################################################"


    #
    # Check databases for CN strings to correlate keys used in
    # signing with what is on board. Have this informaton ready
    # to present with strings.
    #
    fxnParseMokutil "db"  "db  - UEFI key database"

    fxnParseMokutil "kek" "KEK - Key Exchange Key database"

    fxnParseMokutil "mok" "MOK - Machine Owner Key database"

    fxnParseMokutil "pk"  "PK  - Platform key"

    #
    # What, if any, keys are in the shims?
    # Search for strings matching CN= values, as
    # that seems to be as high tech as this gets...
    #
    echo ""
    echo "----------------------------------------------------"
    echo "- CN= strings compiled in to the shim binaries:"
    echo "----------------------------------------------------"

    shimArray="$( find /boot/efi/EFI/ -name shimx64.efi )"
    # For every shim found
    for shimFile in ${shimArray[@]}
    do
        shimKeyFound="FALSE"
        echo " $shimFile "
        # Check it for all possible keys
        for cnType in "${FILES_SIGNED_WITH_CN[@]}"
        do
            # Look for the string in the shim.
            grep -q "$cnType" "$shimFile"
            if [ $? = "0" ];then
                echo "   Key: [ $cnType ]"
                shimKeyFound="TRUE"
            fi
        done
        if [ "$shimKeyFound" = "FALSE" ];then
            echo "   No keys that match signed binaries."
        fi
    done
    echo ""

    echo ""
    echo "----------------------------------------------------"
    echo "- Files have been signed with these CN= strings:"
    echo "----------------------------------------------------"

    # Print neatly with numbers
    theCount=1
    for cnType in "${FILES_SIGNED_WITH_CN[@]}"
    do
        echo " $theCount  $cnType"
        theCount=$(( theCount +1 ))
    done

    echo ""

    fxnCorrelateFPNames

    echo ""
    echo "####################################################"
    echo "# EFI binary signing status:"
    echo "# [X] indicates the key to validate the binary is"
    echo "#     present in the UEFI BIOS."
    echo "####################################################"
    echo ""
    cat "$AUDIT_FILE"
    echo ""

    #
    # let's sanity check secure boot.
    #

    # Is secure boot active?
    echo ""
    echo "----------------------------------------------------"
    echo "- Is Secure Boot active?"
    echo "----------------------------------------------------"
    echo ""
    mokutil --sb-state
    echo ""

    # Clean up temp files
    rm "$AUDIT_FILE"
    rm -f ${CORRELATE_PREFIX}*.txt    
    #   echo "SEE $AUDIT_FILE"
    rm "$FILES_SIGNED_WITH_FILE"

    echo "DONE."
    echo ""

    exit
}

# Figure out if the file was signed with the
# passed in certificate
function fxnWasSignedWithCertificate()
{
    local theCertificate="$1"
    if [ -e "$theCertificate" ];then
        echo ""
        echo "----------------------------------------------------"
        echo "-- Was [ $THE_FILE ] signed with [ $theCertificate ]"
        echo "----------------------------------------------------"
        #openssl x509 -text -noout -in ./exported-uefi-bios-keys/db-keys/DB-0001.crt
        sbverify --cert "$theCertificate"  "$THE_FILE"

        if [ $? = "0" ];then
            echo ""
            echo " Yes."
            echo "- [ $THE_FILE ] was signed with [ $theCertificate ]"
            echo "----------------------------------------------------"
            sbverify --list "$THE_FILE"

            echo "   $THE_FILE uses UEFI key $( openssl x509 -text -noout  -in $theCertificate | grep "Issuer" )"
            # logging to file?
            if [ -e "$AUDIT_FILE" ];then
                #printf "  %-45s %s \n"  "[X] $( echo $THE_FILE | sed -e 's#/boot/efi/EFI##g' ) uses UEFI key:" "$( openssl x509 -text -noout  -in $theCertificate | grep "Subject:" )" >> "$AUDIT_FILE"
                printf "  %-50s %s \n"  "[X] $( echo $THE_FILE | sed -e 's#/boot/efi/EFI##g' )" "Key is present in UEFI BIOS."  >> "$AUDIT_FILE"
            fi
            return 0
        else
            echo " No. "
            return 1
        fi
    else
        echo "Invalid certificate path supplied [ $theCertificate ]. Exiting."
        exit 1
    fi


}
#
# Look for signing at the end of the file and try to identify it.
#
function fxnCheckFileSigning()
{
    #   openssl base64 -d -in <signature> -out /tmp/sign.sha256
    #openssl dgst -sha256 -verify <pub-key> -signature /tmp/sign.sha256 <file>

    # This would be to check a file that has been signed.
    # ~/validateAKey.sh grubx64.efi.signed ~/sign-packages/debian-signing/onie/keys/ONIE-shim-key-cert.pem

    local certs=""

    echo ""
    echo "----------------------------------------------------"
    echo "- Checking signing of [ $THE_FILE ] "
    echo "----------------------------------------------------"
    echo ""

    theSubject=$( sbverify --list "$THE_FILE" 2>&1 \
                      |  grep  " - subject: " )
    if [ $? = "0" ];then

        echo "$theSubject" | sed -e 's#.*CN=##g' >> "$FILES_SIGNED_WITH_FILE"
        # File is signed - print the info
        if [ -e "$AUDIT_FILE" ];then
            printf " %-45s %s \n" "$THE_FILE" "$theSubject" >> "$AUDIT_FILE"
		else
			echo " File is signed with: "
			echo "$theSubject"
        fi

        if [ -e "$BIOS_KEY_DIR" ];then
	    foundKey="FALSE"
            # Exported BIOS certificates. Try them all.
            find "$BIOS_KEY_DIR" -iname *.crt
            certs=$( find "$BIOS_KEY_DIR"/ -name *.crt )
            for publicCert in ${certs[@]}
            do
                fxnWasSignedWithCertificate "$publicCert"
                if [ $? = "0" ];then
		    foundKey="TRUE"
                    # It was signed with a key from the BIOS. Done.
                    break
                fi
            done
	    if [ "$foundKey" = "FALSE" ];then
                printf "  %-50s %s \n"  "[ ] $( echo $THE_FILE | sed -e 's#/boot/efi/EFI##g' )" "NO key found in UEFI BIOS."  >> "$AUDIT_FILE"		
#		echo "  [ ] $( echo $THE_FILE | sed -e 's#/boot/efi/EFI##g' ) no key in BIOS"  >> "$AUDIT_FILE"
	    fi
        else
            # Check of an individual file with a certificate
            if [ "$THE_CERTIFICATE" != "" ];then

                fxnWasSignedWithCertificate "$THE_CERTIFICATE"
            fi
        fi
    else
        if [ -e "$AUDIT_FILE" ];then
            printf " %-45s Not Signed\n" "$THE_FILE" >> "$AUDIT_FILE"
        fi
    fi

}

# put a header on parsing output
function fxnParseHeader()
{
    local fileType="$1"
    echo ""
    echo "----------------------------------------------------"
    echo "- Parsing as: $1"
    echo "----------------------------------------------------"
    echo ""
}
#
# handle comparing signed and unsigned binaries.
function fxnDetachedSignature()
{
    # Remove a signature: sbattach --signum 1 --remove <file name>
    echo "To implement"
}
if [ "$#" = "0" ];then
    # Require an argument for action.
    # Always trigger help messages on no action.
    fxnHelp
    exit 0
fi


while [[ $# -gt 0 ]]
do
    term="$1"

    case $term in

        --cert )
            THE_CERTIFICATE="$2"
            shift
            ;;

        --audit )
            DO_AUDIT="TRUE"
            ;;

        --audit-file )
            # Used to store results on recursive invocations, so this is NOT
            # listed in the help.
            AUDIT_FILE="$2"
            if [ "$AUDIT_FILE" = "" ];then
                echo "Must provide a filename to store the audit summary in."
                exit 1
            fi
            shift
            ;;

        --checksums )
            DO_EFI_CHECKSUMS="TRUE"
            ;;

        --get-bios-keys )
            # Dump all keys in the bios
            fxnGetBIOSKeys
            exit
            ;;
        --cert-check )
            # Are thigs _really_ signed the way you think they are?
            fxnCertCheck $2
            exit
            ;;

        '--verbose' )
            DO_QUIET="/dev/tty"
            ;;

        -h|--help)
            fxnHelp
            exit 0
            ;;


        --file )
            # Left for backwards compatibility
            THE_FILE="$2"
            shift
            ;;

        --*)
            # catch mistyped/bad options
            fxnHelp
            echo "Unrecognized option [ $term ]. Exiting"
            exit 1
            ;;

        * )
            # Assume anything left is the file to check.
            THE_FILE="$1"
            ;;


    esac
    shift # skip over argument

done


#
# Sanity check that openssl and sbsigntool are installed.
#  Audit is not going to get far without them.
if [ ! -e /usr/bin/sbverify ];then
    echo "Missing cryptographic tools."
    echo " Please install the following:"
    echo " sudo apt-get install sbsigntool openssl. "
    exit 1
fi

if [ "$DO_EFI_CHECKSUMS" = "TRUE" ];then
    fxnPrintAllEFIChecksums
    exit
fi

if [ "$DO_AUDIT" = "TRUE" ];then
    fxnAuditSystem
    exit
fi
if [ ! -e "$THE_FILE" ];then
    fxnHelp
    echo ""
    echo "Error. Failed to find file [ $THE_FILE ]"
    echo ""
    exit 1
fi


#
# diagnose the signing on a running system
#
if [ "$THE_FILE" = "systemAudit" ];then
    fxnAuditSystem
    exit
fi

#
# Some files have fixed names, like the PKCS#11 database files
#
fileBasename=$(basename $THE_FILE)
fileDir=$(dirname $THE_FILE )
case $fileBasename in
    cert9.db | key4.db )
        # Run this from the file's directory
        cd $fileDir
        certutil -d sql:"${PWD}" -L
        echo "Dump individual certificates with:    certutil -d sql:\$(pwd) -L -n <Certificate Nickname>"
        certificates=$( certutil -d sql:"${PWD}" -L cert9.db | tail -n +5 | awk '{print$1}' )
        echo " Detailing found certificates:"
        echo "---------------------------------"
        for cert in $certificates ; do
            echo ""
            echo " Certificate [ $cert ]"
            echo "---------------------------------"

            certutil -d sql:"${PWD}" -L -n $cert
            echo ""
        done
        echo " Done listing certificates in $THE_FILE"
        echo "  [ $certificates ]"
        echo "---------------------------------"

        exit
        ;;

esac

# There can be a lot going on with a PEM file
function fxnDecodePEM()
{
    local checkCertificate="TRUE"

    echo "-File [ $THE_FILE ]. PEM can contain (or not) a number of things."
    echo "-Anything that fails to load is not there."

    echo "- Look for a public key"
    openssl rsa -inform PEM -pubin -in  $THE_FILE   2> >( grep -v ":error:"  >&2)
    if [ $? = 0 ];then
        # not much else to do with a public pem
        echo ""
        echo "Done - no private keys or certificates are with a public key in .pem."
        checkCertificate="FALSE"
    else
        echo "- Look for a private key."
        #       set -x
        #       openssl rsa -check -in debian-signing/keys/dev/dev-private.pem
        openssl rsa -inform PEM -check  -in  $THE_FILE 2> >( grep -v ":error:"  >&2)
        if [ $? = "0" ];then
            echo ""
            openssl x509   -text -noout -in $THE_FILE 2> >( grep -v ":error:"  >&2)
            # This will dump hex and validate a private key.
            #openssl rsa -inform PEM -in "$THE_FILE" -check 2> >( grep -v ":error:"  >&2)
            echo ""
            echo -n "-  Modulus: "
            openssl rsa -noout -modulus -in "$THE_FILE" | openssl md5
            #echo "  Not sure where it came from, but the key is coherent."
            # get size of key used
            echo ""
            openssl rsa -in "$THE_FILE" -text -noout | grep Private-Key

            echo ""
            echo "- Fingerprint"
            echo -n "-  MD5 form:  "
            ssh-keygen -E md5 -lf "$THE_FILE"
            echo ""
            openssl rsa -in "$THE_FILE" -pubout -outform DER | openssl md5 -c
            echo ""
            echo -n "-  SHA256 form: "
            echo ""
            ssh-keygen -lf "$THE_FILE"
            echo ""
            echo "- Public key generated from private key looks like: "
            openssl rsa -inform PEM -in "$THE_FILE" -pubout
            echo ""
        fi
    fi

    if [ "$checkCertificate" = "TRUE" ];then
        echo "- Look for a certificate."
        openssl x509   -text -noout -in $THE_FILE 2> >( grep -v ":error:"  >&2)
        if [ $? = "0" ];then
            openssl x509 -in "$THE_FILE"  -noout -issuer -issuer_hash 2> >( grep -v ":error:"  >&2)
            if [ $? = "0" ];then
                echo "- Check certificate hash:"
                openssl x509 -in "$THE_FILE"  -noout -hash 2> >( grep -v ":error:"  >&2)

                # get modulus of a certficate
                echo ""
                echo -n "- Modulus: "
                openssl x509 -noout -modulus -in "$THE_FILE" 2> >( grep -v ":error:"  >&2) | openssl md5
                echo ""

                # Get the SHA256 fingerprint, used by trusted_certs in cumulus.yaml.in
                #
                echo -n "- "
                openssl x509 -in "$THE_FILE" -noout -sha256 -fingerprint
                echo ""

            fi
        else
            echo "No certificate found."
        fi
    fi

}

#
# Some files may have a prefix, like the kernel.
# This assures it is part of any audit.
#
if [[ "$fileBasename" == vmlinuz* ]];then
    fxnCheckFileSigning
    exit
fi

# Take a hint from the end of the file name
suffix=$( echo $THE_FILE | sed -e 's/.*\.//g' )

# Openssl spews a bunch of additional error messages that
#  most users won't find helpful, right after printing one that is.
# Declutter it with the following:

# >( )  <- treat process in here as a file
# 2>    Redirect stderr to file/process
# grep*  Filter out :error: messages
# >&2   Redirect filtered stderr back out
#openssl x509   -text -noout -inform der -in $THE_FILE  2> >( grep -v ":error:"  >&2)

case $suffix in
    der )
        fxnParseHeader "der"
        openssl asn1parse -in $THE_FILE --inform DER 2> >( grep -v ":error:"  >&2)
        echo "- Certificate (may not be present) decode: "
        openssl x509 -in $THE_FILE -inform DER -text 2> >( grep -v ":error:"  >&2)

        ;;
    pem )
        fxnParseHeader "pem"
        fxnDecodePEM
        ;;

    p12 )
        fxnParseHeader "p12 - Expect to be asked for a password."

        # ..although if you had it, you could command line pass it like this:
        #       pk12util -l "${tempKeyName}" -W $password
        pk12util -l $THE_FILE
        ;;

    csr )
        fxnParseHeader "csr"
        echo -n "Modulus: "
        openssl req -noout -modulus -in "$THE_FILE" | openssl md5
        echo ""
        openssl req -in $THE_FILE -text -noout
        ;;

    crt )
        # get modulus of a certficate. Can be compared to other file's modulus
        # to see if one was derived from the other
        fxnParseHeader ".crt"
        openssl x509  -text -noout  -in "$THE_FILE"
        echo ""
        echo -n "Modulus: "
        openssl x509 -noout -modulus -in "$THE_FILE" | openssl md5
        echo ""
        echo "Key size:"
        openssl x509  -text -noout  -in "$THE_FILE"  | grep "Public-Key"
        ;;


    efi | signed )
        fxnParseHeader "Signed file ending in [ $suffix ]"
        fxnCheckFileSigning
        ;;

    ko )
        fxnParseHeader "Signed kernel module ending in [ ko ]"
        # kernel modules. Seems to be no good way to check these
        if [ ! $(grep -q "Module signature appended" "$THE_FILE" ) ];then
            tail -c 396  "$THE_FILE" | hexdump -C
            echo ""
            echo "Module [ $THE_FILE ] is signed."

        else
            echo "No 'Module signature appended' found in [ $THE_FILE ]"
        fi
        echo ""
        ;;

    req )
        fxnParseHeader "req"
        cat $THE_FILE
        echo -n "Modulus: "
        openssl req -noout -modulus -in "$THE_FILE" | openssl md5

        ;;
    key )
        # key format is a PEM with no certificate information.
        # It works, but good luck figuring out where it came from
        fxnParseHeader "key"
        cat $THE_FILE
        echo ""
        echo -n "Modulus: "
        openssl rsa -noout -modulus -in "$THE_FILE" | openssl md5

        ;;
    txt )
        fxnParseHeader "txt"
        cat $THE_FILE
        ;;

    cfg )
        fxnParseHeader "Configuration file"
        cat $THE_FILE
        ;;

    auth )
        fxnParseHeader "auth signed efi varaible"
        # Used as ONIE sets DB and KEK UEFI variables.
        # Seems like sig-list-to-certs should parse this, but
        # Settle for a hex dump that should show the certificates.
        hexdump -C "$THE_FILE"
        ;;

    * )

        # at this point it's ether garbage, or maybe a signed
        # file like a vmlinuz, so see if there is a signature.
        echo "#################################"
        echo "#                               #"
        echo "# Unsupported suffix for: [ $suffix ]"
        echo "#                               #"
        echo "#################################"
        echo ""
        echo "Guessing it is a signed file? "
        echo " Running [ sbveriify --list $THE_FILE ]"
        echo ""
        echo "---------------------------------"
        echo ""
        sbverify --list $THE_FILE
        if [ "$?" = "0" ];then
            if [ "$2" != "" ];then

                if [ -e "$2" ];then
                    echo "Seeing if file [ $THE_FILE ] was signed with [ $THE_CERTIFICATE ]"
                    echo ""
                    sbverify --cert $THE_CERTIFICATE  $THE_FILE
                    if [ "$?" = "0"  ];then
                        echo ""
                        echo " It was signed with [ $THE_CERTIFICATE ]."
                        echo ""
                        exit 0
                    else
                        echo ""
                        echo " It was NOT signed with [ $THE_CERTIFICATE ]."
                        echo ""
                        exit 1
                    fi
                fi

            fi
        else
            echo "No signature detected."
        fi
        echo ""
        echo "---------------------------------"

        exit 1

esac


