#!/bin/bash
function store_cert_on_vehicle {
    if [ "$IS_LOCAL" = "true" ]; then
        # make sure the birth storage dir exists and create it if it does not.
        if ! "$VEHICLE_MKDIR" -p "$BIRTH_STORE_DIR"; then
            echo "Could not create the birth storage directory locally: $BIRTH_STORE_DIR . Check permissions."
            exit 1
        fi
        # check that the birth gen directory contains the recently generated birth cert
        if ! test -f "$BIRTH_GEN_DIR/$VEHICLE_NAME.crt"; then
            echo "Generated birth certificate, $VEHICLE_NAME.crt, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
            exit 1
        fi
        # check that the private key exists (extension depends on whether a tpm is used on the vehicle or not)
        if [ "$VEHICLE_TPM" = "false" ]; then
            # check that the birth gen directory contains the 'unsealed' private key (indicated by .key extension)
            if ! test -f "$BIRTH_GEN_DIR/$VEHICLE_NAME.key"; then
                echo "Generated birth unsealed key, $VEHICLE_NAME.key, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
                exit 1
            fi
            # clear the current birth storage dir
            if ! "$VEHICLE_RM" -f "$BIRTH_STORE_DIR/$BIRTH_STORE_EXTENSIONS"; then
                echo "Could not clear existing contents of the birth storage directory: $BIRTH_STORE_DIR . Check permissions."
                exit 1
            fi
            # copy the unsealed private key and birth cert into the birth storage dir
            if ! "$VEHICLE_CP" "$BIRTH_GEN_DIR/$VEHICLE_NAME.key" "$BIRTH_STORE_DIR"; then
                echo "Could not copy the unsealed private key $BIRTH_GEN_DIR/$VEHICLE_NAME.key to $BIRTH_STORE_DIR. Check file accessiblity."
                exit 1
            fi
            if ! "$VEHICLE_CP" "$BIRTH_GEN_DIR/$VEHICLE_NAME.crt" "$BIRTH_STORE_DIR"; then
                echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.crt to $BIRTH_STORE_DIR. Check file accessiblity."
                exit 1
            fi
        else
            if [ "$VEHICLE_TPM" = "true" ]; then
                # check that the birth cert gen directory contains the recently generated 'sealed' private key and birth cert
                if ! test -f "$BIRTH_GEN_DIR/$VEHICLE_NAME.bin"; then
                    echo "Generated birth sealed key, $VEHICLE_NAME.bin, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
                    exit 1
                fi
                # clear the corresponding indices for storing birth cert and private key from the tpm
                if ! "$TPM2_NV_UNDEFINE" "$VEHICLE_TPM2_BIRTH_CERT_INDEX 2>/dev/null"; then
                    echo "Could not clear TPM NVRAM index $VEHICLE_TPM2_BIRTH_CERT_INDEX allocated for storing birth certificate. Check accessibility of TPM tools, TPM module, and correctness of PCR policies."
                    echo "Ignore If the TPM device has not been provisioned with a birth cert before."
                    #exit 1
                fi
                if ! "$TPM2_NV_UNDEFINE" "$VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX 2>/dev/null"; then
                    echo "Could not clear TPM NVRAM index $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX allocated for storing sealed birth key. Check accessibility of TPM tools, TPM module, and correctness of PCR policies."
                    echo "Ignore If the TPM device has not been provisioned with a birth cert before. Otherwise, you must reprovision again as no birth cert exists on the TPM now (previous birth cert, if any, has been removed)."
                    #exit 1
                fi

                # clear the current birth storage dir
                if ! "$VEHICLE_RM" -f "$BIRTH_STORE_DIR/$BIRTH_STORE_EXTENSIONS"; then
                    echo "Could not clear existing contents of the birth storage directory: $BIRTH_STORE_DIR . Check permissions."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi

                ##### store birth cert  on corresponding indeces in the tpm #####
                # convert the generated birth cert, which is in PEM format to the more efficient DER format for storage on tpm
                if ! "$VEHICLE_OPENSSL" x509 -inform PEM -outform DER -in "$BIRTH_GEN_DIR/$VEHICLE_NAME.crt" -out "$BIRTH_GEN_DIR/$VEHICLE_NAME.der"; then
                    echo "Could not convert the generated PEM birth certificate into a DER certificate. Ensure the generated cert is formatted correctly."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                # find size of the birth cert
                if ! VEHICLE_BIRTH_CERT_SIZE="$("$VEHICLE_CAT" "$BIRTH_GEN_DIR/$VEHICLE_NAME.der" | "$VEHICLE_WC" -c )"; then
                    echo "Could not calculate size of the birth cert. Ensure the birth cert has been generated successfully and $VEHICLE_CAT and $VEHICLE_WC are runnable."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                # define tpm nvram index where the birth cert would be written
                if ! "$TPM2_NV_DEFINE" "$VEHICLE_TPM2_BIRTH_CERT_INDEX" -C o -s "$VEHICLE_BIRTH_CERT_SIZE"; then
                    echo "Could not allocate TPM NVRAM index $VEHICLE_TPM2_BIRTH_CERT_INDEX for the birth certificate of size $VEHICLE_BIRTH_CERT_SIZE. Ensure the size is within acceptable range, tpm tools are accessible, and PCR policies are correctly set."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                # write birth cert onto the corresponding tpm nvram index
                if ! "$TPM2_NV_WRITE" "$VEHICLE_TPM2_BIRTH_CERT_INDEX" -i "$BIRTH_GEN_DIR/$VEHICLE_NAME.der" -C o ; then
                    echo "Could not write the generated birth certificate (in DER) onto the TPM NVRAM. Check the cert is available, TPM tools are accessible, and PCR policies are set correctly."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                ##### storing sealed birth key on corresponding index in the tpm
                # find size of the birth key
                if ! VEHICLE_BIRTH_KEY_SIZE="$("$VEHICLE_CAT" "$BIRTH_GEN_DIR/$VEHICLE_NAME.bin" | "$VEHICLE_WC" -c )"; then
                    echo "Could not calculate size of the birth key. Ensure the birth key has been generated successfully and $VEHICLE_CAT and $VEHICLE_WC are runnable."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                # define tpm nvram index where the birth key would be written
                if ! "$TPM2_NV_DEFINE" "$VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX" -C o -s "$VEHICLE_BIRTH_KEY_SIZE"; then
                    echo "Could not allocate TPM NVRAM index $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX for the birth key of size $VEHICLE_BIRTH_KEY_SIZE. Ensure the size is within acceptable range, tpm tools are accessible, and PCR policies are correctly set."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi
                # write birth key onto the corresponding tpm nvram index
                if ! "$TPM2_NV_WRITE" "$VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX" -i "$BIRTH_GEN_DIR/$VEHICLE_NAME.bin" -C o; then
                    echo "Could not write the generated birth key onto the TPM NVRAM. Check the key file is available, TPM tools are accessible, and PCR policies are set correctly."
                    echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                    exit 1
                fi

                # copy the sealed private key, PEM & DER birth certs into the storage birth cert dir. This is done for testing purposes here. Vehicles should overwrite this directory by extracting and copying cert and sealed key from the tpm upon startup (separate script needed).
                if ! "$VEHICLE_CP" "$BIRTH_GEN_DIR/$VEHICLE_NAME.bin" "$BIRTH_STORE_DIR"; then
                    echo "Could not copy the sealed private key $BIRTH_GEN_DIR/$VEHICLE_NAME.bin to $BIRTH_STORE_DIR. Check file accessiblity."
                    exit 1
                fi
                if ! "$VEHICLE_CP" "$BIRTH_GEN_DIR/$VEHICLE_NAME.der" "$BIRTH_STORE_DIR"; then
                    echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.der to $BIRTH_STORE_DIR. Check file accessiblity."
                    exit 1
                fi
                if ! "$VEHICLE_CP" "$BIRTH_GEN_DIR/$VEHICLE_NAME.crt" "$BIRTH_STORE_DIR"; then
                    echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.crt to $BIRTH_STORE_DIR. Check file accessiblity."
                    exit 1
                fi

            else
                echo "Invalid value for option '-p' or '--with-vehicle-tpm'. Legitimate values are: 'true' or 'false'; case-sensitive and without single-quotes."
                exit 1
            fi
        fi
    else
        if [ "$IS_LOCAL" = "false" ]; then
            if [ -z "$VEHICLE_USER" ]; then
                echo "Vehicle user not provided."
                exit 1
            fi
            if [ -z "$VEHICLE_ADDR" ]; then
                echo "Vehicle address not provided."
                exit 1
            fi

            # make sure the birth storage dir exists and create it if it does not.
            if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_MKDIR -p $BIRTH_STORE_DIR"; then
                echo "Could not create the birth storage directory locally: $BIRTH_STORE_DIR . Check permissions."
                exit 1
            fi
            # check that the birth gen directory contains the recently generated birth cert
            if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "test -f $BIRTH_GEN_DIR/$VEHICLE_NAME.crt"; then
                echo "Generated birth certificate, $VEHICLE_NAME.crt, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
                exit 1
            fi
            # check that the private key exists (extension depends on whether a tpm is used on the vehicle or not)
            if [ "$VEHICLE_TPM" = "false" ]; then
                # check that the birth gen directory contains the 'unsealed' private key (indicated by .key extension)
                if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "test -f $BIRTH_GEN_DIR/$VEHICLE_NAME.key"; then
                    echo "Generated birth unsealed key, $VEHICLE_NAME.key, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
                    exit 1
                fi
                # clear the current birth storage dir
                if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_RM -f $BIRTH_STORE_DIR/$BIRTH_STORE_EXTENSIONS"; then
                    echo "Could not clear existing contents of the birth storage directory: $BIRTH_STORE_DIR . Check permissions."
                    exit 1
                fi
                # copy the unsealed private key and birth cert into the birth storage dir
                if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CP $BIRTH_GEN_DIR/$VEHICLE_NAME.key $BIRTH_STORE_DIR"; then
                    echo "Could not copy the unsealed private key $BIRTH_GEN_DIR/$VEHICLE_NAME.key to $BIRTH_STORE_DIR. Check file accessiblity."
                    exit 1
                fi
                if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CP $BIRTH_GEN_DIR/$VEHICLE_NAME.crt $BIRTH_STORE_DIR"; then
                    echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.crt to $BIRTH_STORE_DIR. Check file accessiblity."
                    exit 1
                fi
            else
                if [ "$VEHICLE_TPM" = "true" ]; then
                    # check that the birth cert gen directory contains the recently generated 'sealed' private key and birth cert
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "test -f $BIRTH_GEN_DIR/$VEHICLE_NAME.bin"; then
                        echo "Generated birth sealed key, $VEHICLE_NAME.bin, cannot be found at $BIRTH_GEN_DIR . Make sure it is generated successfully and is accessible."
                        exit 1
                    fi
                    # clear the corresponding indices for storing birth cert and private key from the tpm
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_UNDEFINE $VEHICLE_TPM2_BIRTH_CERT_INDEX 2>/dev/null"; then
                        echo "Could not clear TPM NVRAM index $VEHICLE_TPM2_BIRTH_CERT_INDEX allocated for storing birth certificate. Check accessibility of TPM tools, TPM module, and correctness of PCR policies."
                        echo "Ignore If the TPM device has not been provisioned with a birth cert before."
                        #exit 1
                    fi
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_UNDEFINE $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX 2>/dev/null"; then
                        echo "Could not clear TPM NVRAM index $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX allocated for storing sealed birth key. Check accessibility of TPM tools, TPM module, and correctness of PCR policies."
                        echo "Ignore If the TPM device has not been provisioned with a birth cert before. Otherwise, you must reprovision again as no birth cert exists on the TPM now (previous birth cert, if any, has been removed)."
                        #exit 1
                    fi

                    # clear the current birth storage dir
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_RM -f $BIRTH_STORE_DIR/$BIRTH_STORE_EXTENSIONS"; then
                        echo "Could not clear existing contents of the birth storage directory: $BIRTH_STORE_DIR . Check permissions."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi

                    ##### store birth cert  on corresponding indeces in the tpm #####
                    # convert the generated birth cert, which is in PEM format to the more efficient DER format for storage on tpm
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_OPENSSL x509 -inform PEM -outform DER -in $BIRTH_GEN_DIR/$VEHICLE_NAME.crt -out $BIRTH_GEN_DIR/$VEHICLE_NAME.der"; then
                        echo "Could not convert the generated PEM birth certificate into a DER certificate. Ensure the generated cert is formatted correctly."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi

                    # find size of the birth cert
                    if ! VEHICLE_BIRTH_CERT_SIZE="$("$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CAT $BIRTH_GEN_DIR/$VEHICLE_NAME.der | $VEHICLE_WC -c" )"; then
                        echo "Could not calculate size of the birth cert. Ensure the birth cert has been generated successfully and $VEHICLE_CAT and $VEHICLE_WC are runnable."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi
                    # define tpm nvram index where the birth cert would be written
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_DEFINE $VEHICLE_TPM2_BIRTH_CERT_INDEX -C o -s $VEHICLE_BIRTH_CERT_SIZE"; then
                        echo "Could not allocate TPM NVRAM index $VEHICLE_TPM2_BIRTH_CERT_INDEX for the birth certificate of size $VEHICLE_BIRTH_CERT_SIZE. Ensure the size is within acceptable range, tpm tools are accessible, and PCR policies are correctly set."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi
                    # write birth cert onto the corresponding tpm nvram index
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_WRITE $VEHICLE_TPM2_BIRTH_CERT_INDEX -i $BIRTH_GEN_DIR/$VEHICLE_NAME.der -C o"; then
                        echo "Could not write the generated birth certificate onto the TPM NVRAM. Check the cert is available, TPM tools are accessible, and PCR policies are set correctly."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi
                    ##### storing sealed birth key on corresponding indeces in the tpm
                    # find size of the birth key
                    if ! VEHICLE_BIRTH_KEY_SIZE="$("$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CAT $BIRTH_GEN_DIR/$VEHICLE_NAME.bin | $VEHICLE_WC -c" )"; then
                        echo "Could not calculate size of the birth key. Ensure the birth key has been generated successfully and $VEHICLE_CAT and $VEHICLE_WC are runnable."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi
                    # define tpm nvram index where the birth key would be written
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_DEFINE $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX -C o -s $VEHICLE_BIRTH_KEY_SIZE"; then
                        echo "Could not allocate TPM NVRAM index $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX for the birth key of size $VEHICLE_BIRTH_KEY_SIZE. Ensure the size is within acceptable range, tpm tools are accessible, and PCR policies are correctly set."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi
                    # write birth key onto the corresponding tpm nvram index
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$TPM2_NV_WRITE $VEHICLE_TPM2_BIRTH_SEALEDKEY_INDEX -i $BIRTH_GEN_DIR/$VEHICLE_NAME.bin -C o"; then
                        echo "Could not write the generated birth key onto the TPM NVRAM. Check the key file is available, TPM tools are accessible, and PCR policies are set correctly."
                        echo "You must reprovision again as no birth cert and key exists on the TPM now (previous birth cert and key, if any, have been removed)."
                        exit 1
                    fi

                    # copy the sealed private key, PEM & DER birth certs into the storage birth cert dir. This is done for testing purposes here. Vehicles should overwrite this directory by extracting and copying cert and sealed key from the tpm upon startup (separate script needed).
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CP $BIRTH_GEN_DIR/$VEHICLE_NAME.bin $BIRTH_STORE_DIR"; then
                        echo "Could not copy the sealed private key $BIRTH_GEN_DIR/$VEHICLE_NAME.bin to $BIRTH_STORE_DIR. Check file accessiblity."
                        exit 1
                    fi
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CP $BIRTH_GEN_DIR/$VEHICLE_NAME.der $BIRTH_STORE_DIR"; then
                        echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.der to $BIRTH_STORE_DIR. Check file accessiblity."
                        exit 1
                    fi
                    if ! "$OP_SSH" -q "$VEHICLE_USER@$VEHICLE_ADDR" "$VEHICLE_CP $BIRTH_GEN_DIR/$VEHICLE_NAME.crt $BIRTH_STORE_DIR"; then
                        echo "Could not copy the generated birth certificate $BIRTH_GEN_DIR/$VEHICLE_NAME.crt to $BIRTH_STORE_DIR. Check file accessiblity."
                        exit 1
                    fi


                else
                    echo "Invalid value for option '-p' or '--with-vehicle-tpm'. Legitimate values are: 'true' or 'false'; case-sensitive and without single-quotes."
                    exit 1
                fi
            fi

        else
            echo "Invalid value for '-l' or '--local' option. Legitimate values are: 'true' or 'false'; case-sensitive and without single-quotes."
            exit 1
        fi
    fi
}
