#!/bin/bash

set -e

usage() {
        echo "" 1>&2;
        echo "This script is used to create a request for a new TA Authority."
        echo "Usage: $0 <options> <platform-name> <name> <profile-id> <device-id/file maximum of 10 Device id>" 1>&2;
        echo "" 1>&2;
        echo " <platform-name> - name for the platform for which the request is created" 1>&2;
        echo " <name> - up to 16 character TA Authority name (lowercase and _ only)." 1>&2;
        echo " <profile-id> to 16 character Profile ID (lowercase and _ only)." 1>&2;
        echo " <device-id's> - multiple strings of 36 char seperated by space similar to UUID can be obtain using ./tee_test_uuid." 1>&2;
        echo " <options>" 1>&2;
        echo "  -k <location>   Location of private key to use" 1>&2;
        echo "  -e <name>       Use OpenSSL engine" 1>&2;
        echo "  -n <name>       Chipset name (needed for use HSM)" 1>&2;
        echo "  -m <name>       model name (default name: UNOFFICIAL_BUILD_MODEL)" 1>&2;
        echo "  -p              Encrypt key with password" 1>&2;
        echo "  -f <filename>   file from where the device-id's will be taken from" 1>&2
        echo "  -t <type>       key type: rsa (default) or ec" 1>&2
        echo "  -h              Display this usage information" 1>&2;
        exit 1;
}

id_var=0
DEVICEIDFILE="false"

KEY=""
DONTSTOREKEY="false"
PROMPTFORPASSWORD="false"
ENGINE=""
CHIPSET_NAME=""
HSM_ENABLED="false"
AUTHORITY_NAME=""
TYPE="rsa"
MODEL_NAME="UNOFFICIAL_BUILD_MODEL"
CURRENT_PATH=$(dirname $0)
PASSWORD=""

while getopts ":k:e:f:n:m:pht:" o; do
    case "${o}" in
        k)
            KEY="-key ${OPTARG}"
            DONTSTOREKEY="true"
            ;;
        p)
            PROMPTFORPASSWORD="true"
            ;;
        e)
            ENGINE="-engine ${OPTARG} -keyform ENGINE"
            ;;
        n)
            CHIPSET_NAME="${OPTARG}"
            ;;
        f)
            DEVICEIDFILE="true"
            ;;
        t)
            TYPE=${OPTARG}
            ;;
        m)
            MODEL_NAME="${OPTARG}"
            ;;
        h)
            usage
            ;;
    esac
done

shift $((OPTIND-1))

if [ "$1" == "" ]; then
    usage
fi

if [[ "$2" == "" ]]; then
    usage
fi

if [[ "$3" == "" ]]; then
    usage
fi

if [[ "$4" == "" ]]; then
    usage
fi

if [[ "$5" == "" ]]; then
    usage
fi

if [[ "$PROMPTFORPASSWORD" == "true" && "$6" == "" ]]; then
    usage
else
    PASSWORD=$6
fi

AUTHORITY_NAME=$2

if [[ "$DEVICEIDFILE" == true ]]; then
    if [[ ! -f "$4" ]]; then
        usage
    fi
fi

if [ -n "$ENGINE" ]; then #HSM enanbled
    if [ "$CHIPSET_NAME" == "" ]; then
        echo "For use HSM, Chipset name (option -n) is required"
        usage
    fi

    HSM_ENABLED="true"
    echo "HSM module enabled"
fi

QB_ID=$5
echo $PASSWORD

key_location=$CURRENT_PATH/$QB_ID/$2/private
req_location=$CURRENT_PATH/$QB_ID/$2

if [ "$TYPE" == "rsa" ]; then
    KEY_ARG="rsa:2048"
elif [ "$TYPE" == "ec" ]; then
    ECPARAM=$(mktemp)
    openssl ecparam -name prime256v1 > $ECPARAM
    KEY_ARG="ec:$ECPARAM"
else
    echo "Unknown key type $TYPE"
    exit 1
fi

KEY="-newkey $KEY_ARG -keyout $key_location/key.pem"
#echo $KEY
count=0

if [[ "$DEVICEIDFILE" == true ]]; then
    while read LINE
    do
         count=$(( count+1 ))
    done < $4

    echo "The Device ID count is $count"
    if [[ $count -gt 10 ]]; then
        echo "The number of Device ID count should be restricted to 10"
        usage
    fi
fi

# Add private extension request based on either file or input parameters

TMPCONFFILE=file_conf.$$

cat <<@eof >$TMPCONFFILE
    # openssl x509 parameters extfile
    extensions = v3_req
    req_extensions = v3_req
    [req]
     prompt = no
     distinguished_name = dn-field
    [dn-field] # DN field
    domainComponent = $MODEL_NAME
    commonName = $2:$3
    [v3_req] # openssl extensions
    # basicConstraints = critical,CA:false
     1.3.6.1.4.1.236.5.10.101 = ASN1:SEQUENCE:DeviceID
    [DeviceID]
@eof


 if [[ "$DEVICEIDFILE" == true ]]; then
    cat $4 | while read LINE
    do
cat <<@eof >>$TMPCONFFILE
    DeviceID.$id_var=UTF8:$LINE
@eof
    id_var=$(( id_var+1 ))
    done
 else
    shift
    shift
    shift
    echo "The number of device-id passed as parameters are $(($#)) " 1>&2
    if [[ $(($#)) -gt 10 ]]; then
        echo "The number of Device ID count should be restricted to 10"
        rm $TMPCONFFILE
        usage
    fi

    if [[ $1 == ALL ]]; then
        echo $1
cat <<@eof >>$TMPCONFFILE
            DeviceID.$id_var=UTF8:$1
@eof
    else
        while test $(($#)) -gt 0
        do
                echo $1
                if [[ ${#1} -ne 36 ]]; then
                    rm -rf $TMPCONFFILE
                    echo "Device ID length missmatch, it should be 36"
                    usage
                fi
cat <<@eof >>$TMPCONFFILE
            DeviceID.$id_var=UTF8:$1
@eof
            id_var=$(( id_var+1 ))
            shift
       done
    fi
 fi

#create the request certificate
if [ ! -d "$key_location" ]; then
        mkdir -p $key_location
        chmod 700 $key_location

        if [[ "$DONTSTOREKEY" == "false" && "$PROMPTFORPASSWORD" == "false" ]]; then
                KEY="$KEY -nodes"
        else
                KEY="$KEY -passout pass:$PASSWORD"
        fi

        if [ "$HSM_ENABLED" == "true" ]; then
            source hsm_setup.sh
            CHIPSET_NAME=`echo ${CHIPSET_NAME,,} | sed 's/[^a-z,A-Z,0-9]//g'` #HSM only support lowcase key index name
            AUTHORITY_NAME=`echo ${AUTHORITY_NAME,,} | sed -e "s/_//g"`

            HSM_KEY_INDEX="${HSM_KEY_INDEX_PREFIX}${CHIPSET_NAME}${AUTHORITY_NAME}${HSM_KEY_INDEX_SUFFIX}"
            echo "HSM KEY NAME is ${HSM_KEY_INDEX}"
            #Generate new Key in HSM
            #${HSM_NCIPHER_BIN_PATH}${HSM_GENERATE_KEY_CMD} --generate --module ${HSM_MODULE_NUM} --batch hwcrhk ident=${HSM_KEY_INDEX} size=${HSM_KEY_SIZE}
            ${HSM_NCIPHER_BIN_PATH}${HSM_GENERATE_KEY_CMD} --g hwcrhk protect=module type=rsa ident=${HSM_KEY_INDEX} size=${HSM_KEY_SIZE} module=1 pubexp=10001 nvram=no

            #Make certificate signing request(req) and signing
            ${HSM_NCIPHER_BIN_PATH}${HSM_OPENSSL_CMD} req -config $TMPCONFFILE -sha256 $ENGINE -key ${HSM_KEY_INDEX} -new -outform PEM -out $req_location/request.csr
        else
            echo openssl req -config $TMPCONFFILE -sha256 $KEY $ENGINE -new -outform PEM -out $req_location/request.csr
            openssl req -config $TMPCONFFILE -sha256 $KEY $ENGINE -new -outform PEM -out $req_location/request.csr
            if [[ "$DONTSTOREKEY" == "false" ]]; then
                    chmod 400 $key_location/key.pem
            fi
        fi

        echo "Request created please send $req_location/request.csr to the Root Authority."
else
        echo "You have already created a request and private key."
fi

rm $TMPCONFFILE
rm -f $ECPARAM

