#!/bin/bash
#----------------------------------------------------------------
#
#      File:   n1k_image_verification_script
#      Name:   Gleb Sapozhnikov
#
#      Description: Signature verification script for Nexus 1000V
#                   released images
#
#      Copyright (c) 2014, 2015 by Cisco Systems, Inc.
#      All rights reserved.
#
#----------------------------------------------------------------
#
# Script to verify Nexus 1000V image against its official signature

function usage {
    local ec=$1

    cat << EOT
$0 -s signature-file image-file
   The mandatory -s option is a path to a text file containing a hex signature
   (obtained from Cisco) for the given image file.
   The argument is a path to the image file.
   PREREQUISITES: must have openssl and base64 utilities in the path.
EOT

    exit $ec
}

if [[ -z $1 || $1 = -h ]]; then
    usage 0
fi

if [[ ! $1 = -s || -z $3 ]]; then
    usage
fi

shift

SIGNATURE=$1
IMAGE=$2

if [[ ! -f $SIGNATURE ]]; then
    echo "Signature file must exist!"
    usage 1
fi
if [[ ! -f $IMAGE ]]; then
    echo "Image file must exist!"
    usage 1
fi

SHA512_REL_PUBKEY=$(cat << "EOT"
-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQDv5kkHzwKznDtAghJiEtkc
gfjxJ2A/7VXFzriaidX6/7a2mWN2dPzKNiUw/VdM6zvlTve/yoe7fkS12l603RKL
fcJAulkATelKoyqE0BdMSwZXVrLUkc4BxI+hGPdt3ez0X9W51DBItzemxa5ROyvk
7XamKP2dD+4Rv5oicceJWB1iLhj87WiL8bs3CpkfDcGicSbX0qTb1xWXTo3tOoTA
ZKPJrrLECldjoB+gP7eHe/mgj5dYBMm4Rq/rEir21eG+JTho+je6iNIWwjEfSqpr
b1ge1GynTr0sovaXik0nd3EjWczSIX5CapZ5VwqBh8eTfg8wFarzJafSGqPq1anP
AgMBAAE=
-----END PUBLIC KEY-----
EOT
)

TMPFILE_PUBKEY=/tmp/$(basename $0)_$$.pub
TMPFILE_SIG=/tmp/$(basename $0)_$$.sig

# Test write: checks that /tmp has enough space
echo "$SHA512_REL_PUBKEY" > $TMPFILE_PUBKEY
if [[ ! $? = 0 ]]; then
    echo "Failed to write out public key. Insufficient space in /tmp"
    echo "    or directory not writable!"
    usage 1
fi

tst=$(which openssl 2>/dev/null)
if [[ -z $tst ]]; then
    echo "Must have openssl in PATH!"
    usage 1
fi
tst=$(which base64 2>/dev/null)
if [[ -z $tst ]]; then
    echo "Must have base64 in PATH!"
    usage 1
fi

# Convert signature to binary
cat $SIGNATURE | base64 -d -i > $TMPFILE_SIG
if [[ ! $? = 0 ]]; then
    echo "Failed to write the binary signature."
    echo "    Insufficient space in /tmp?"
    usage 1
fi

# Verify!
output=`openssl dgst -sha512 -verify $TMPFILE_PUBKEY -signature $TMPFILE_SIG $IMAGE 2>&1`
ec=$?
if [[ $ec -eq 0 ]]; then
    echo "Authenticity of Cisco-signed image $IMAGE has been successfully verified!"
else
    echo "Image $IMAGE failed authenticity check based on signature $SIGNATURE!"
    echo "Output from openssl:"
    echo "$output"
fi

# Clean up
rm -f $TMPFILE_PUBKEY $TMPFILE_SIG

exit $ec
