#!/bin/bash

# option to use a lock to ensure that we run a single instance of the script. This has two consequences:
#   1. avoid accidentally running multiple instances of this script concurrently to provision the same machine.
#   2. avoid provisioning more than one provisioner at a time using this script on the same provisioning machine.
ENABLE_LOCKING="false"
SCRIPT_NAME="${0##*/}"
if [ "$ENABLE_LOCKING" = "true" ]; then
    FLOCK_TOOL="/usr/bin/flock"
    if ! test -f "$FLOCK_TOOL"; then
        echo "'flock' not found on the provisioner machine at $FLOCK_TOOL"
        exit 1
    fi
    SCRIPT_LOCK="/tmp/$SCRIPT_NAME.lock"
    exec 200> "$SCRIPT_LOCK"
    "$FLOCK_TOOL" -n -x 200 || { echo "$SCRIPT_NAME is already running." && exit 1; }
fi

# provisioning certificate generation directory for keeping intermediate artifacts; modify if corresponding directorly layout on the provisioner is changed.
# note: do not use a generic and world-accessible gen dir (such as /tmp) for security reasons.
CERT_GEN_DIR="/home/zoox/.provisioner_identity/files/gen"
#CERT_GEN_DIR="/Users/hsoroush/work/provisioner3/files/gen"

# provisioning cert storage and sealed (or unsealed) key storage directory.
CERT_STORE_DIR="/home/zoox/.provisioner_identity/files/current"
#CERT_STORE_DIR="/Users/hsoroush/work/provisioner3/files/current"

# indicates if intermediate artifacts should be removed once the script exits or is terminated, set to 'false' for debugging
ENABLE_CLEANUP="true"

# operator parameters
OP_NAME=
OP_PASSWORD=
OP_TPM="true"
OP_PROVISIONING_CERT=

# operator CSR configuration details; may be over-written or modified by Vault upon cert issuance
OP_CSR_COUNTRY="US"
OP_CSR_STATE="CA"
OP_CSR_LOCALITY="Foster\ City" 
OP_CSR_ORG="Zoox"
OP_CSR_ORG_UNIT="ProdSec"

# provisioning certificate cryptographic parameters
OP_PROVISIONING_KEY_ALG="rsa"
OP_PROVISIONING_KEY_SIZE="2048" # same as vehicles
OP_PROVISIONING_KEY_NOTPM_OPTIONS="rsa_keygen_bits:2048" # same as vehicles

# provisioning certificate generation artifact extensions; used to specify unsealed private key (.key), sealed keys (.bin), CSR (.csr), JSON CSR (.json) file, and the provisioning certificate (.crt, .der).
CERT_GEN_EXTENSIONS="{*.key,*.bin,*.csr,*.json,*.crt,*.der,*.p12}"
# provisioning storage artifact extensions. used to specify unsealed private key (.key), sealed keys (.bin), and certificate (.crt, .der)
CERT_STORE_EXTENSIONS="{*.key,*.bin,*.crt,*.der}"

# operator tpm-specific parameters: modify if corresponding directorly layout is changed, or new tpm device or tpm software stack is used
TPM2TSS_ENGINE="/usr/local/zoox/tpm/tpm2-tss-engine-1.0.1/lib/engines"
TPM2DEVICE="/dev/tpmrm0"
OP_TPM2TSSENGINE_TCTI="device:$TPM2DEVICE"
TPM2TSS_GENKEY="/usr/local/zoox/tpm/tpm2-tss-engine-1.0.1/bin/tpm2tss-genkey"
TPM2_NV_DEFINE="/usr/local/zoox/tpm/tpm2-tools-4.1.3/bin/tpm2_nvdefine"
TPM2_NV_UNDEFINE="/usr/local/zoox/tpm/tpm2-tools-4.1.3/bin/tpm2_nvundefine"
TPM2_NV_WRITE="/usr/local/zoox/tpm/tpm2-tools-4.1.3/bin/tpm2_nvwrite"
TPM2_NV_READ="/usr/local/zoox/tpm/tpm2-tools-4.1.3/bin/tpm2_nvread"
OP_TPM2_PROVISIONING_CERT_INDEX="0x01800010"
OP_TPM2_PROVISIONING_SEALEDKEY_INDEX="0x01800011"
OP_TPM="false"

# invocations
OP_MKDIR="/bin/mkdir"
OP_RM="/bin/rm"
OP_CAT="/bin/cat"
OP_CP="/bin/cp"
OP_WC="/usr/bin/wc"
OP_JQ="/usr/bin/jq"
#OP_JQ="/usr/local/bin/jq"
OP_CURL="/usr/local/zoox/tpm/curl-7.71.0/bin/curl"
#OP_CURL="/usr/bin/curl"
OP_OPENSSL="/usr/local/zoox/tpm/openssl-1.1.1g/bin/openssl"
#OP_OPENSSL="/usr/bin/openssl"

# vault parameters
VAULT_TOKEN=
VAULT_ADDR="https://vault-rsi.zooxlabs.com" # critical security point here: always use https, never use http
VAULT_TOKEN_TTL_FOR_PROVISIONING_CERT_LOGINS="3600"

# testing parameters (the following are used to test the provisioning cert login when a tpm is used. If the tpm is not used, we directly use the stored cert and key)
TEST_PROVISIONING_CERT_DER="$CERT_GEN_DIR/test-provisioning-cert.der"
TEST_PROVISIONING_CERT_CRT="$CERT_GEN_DIR/test-provisioning-cert.crt"
TEST_PROVISIONING_SEALED_KEY="$CERT_GEN_DIR/test-provisioning-cert.bin"
