#!/bin/sh -eux

if ! groups | grep -q softhsm; then
    echo "User $(whoami) is not in 'softhsm' group. Fixing permissions..."
    sudo adduser $(whoami) softhsm
    exec newgrp -c "$0" softhsm
fi

dir=$(mktemp -d)

mkdir -p "$dir/keys"

cd "$dir/keys"

/usr/share/libexec/imx-code-signing-tool/pki_scripts/hab4_pki_tree.sh -existing-ca n -kt ecc -kl p256 -num-srk 1 -duration 100 -srk-ca y

cd "$dir/crts"

srktool --h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c SRK1_sha256_secp256r1_v3_ca_crt.pem

cd "$dir"

pkcs11_module="/usr/lib/softhsm/libsofthsm2.so"
token="softhsmcst"
pin="1234"
so_pin="5678"
key_pass=$(head -n 1 "${dir}/keys/key_pass.txt")

softhsm2-util --init-token --slot 0 --label "$token" --pin "$pin" --so-pin "$so_pin"
openssl ec -in "${dir}/keys/CSF1_1_sha256_secp256r1_v3_usr_key.pem" -out "${dir}/keys/CSF1_1_sha256_secp256r1_v3_usr_key.decrypted.pem" -passin pass:"$key_pass"
openssl ec -in "${dir}/keys/IMG1_1_sha256_secp256r1_v3_usr_key.pem" -out "${dir}/keys/IMG1_1_sha256_secp256r1_v3_usr_key.decrypted.pem" -passin pass:"$key_pass"

pkcs11-tool --module $pkcs11_module -l --write-object "${dir}/keys/CSF1_1_sha256_secp256r1_v3_usr_key.decrypted.pem" --type privkey --usage-sign --id 01 --label CSF_1_1 --pin "$pin"
pkcs11-tool --module $pkcs11_module -l --write-object "${dir}/keys/IMG1_1_sha256_secp256r1_v3_usr_key.decrypted.pem" --type privkey --usage-sign --id 02 --label IMG_1_1 --pin "$pin"
pkcs11-tool --module $pkcs11_module -l --write-object "${dir}/crts/CSF1_1_sha256_secp256r1_v3_usr_crt.pem" --type cert --id 01 --label CSF_1_1 --pin "$pin"
pkcs11-tool --module $pkcs11_module -l --write-object "${dir}/crts/IMG1_1_sha256_secp256r1_v3_usr_crt.pem" --type cert --id 02 --label IMG_1_1 --pin "$pin"

write_csf() {
    cat > "$1" <<EOF
[Header]
  Version = 4.0
  Hash Algorithm = sha256
  Engine = ANY
  Engine Configuration = 0
  Certificate Format = X509
  Signature Format = CMS

[Install SRK]
  File = "crts/SRK_1_2_3_4_table.bin"
  Source Index = 0

[Install CSFK]
  File = "pkcs11:token=${token};object=CSF_1_1;type=cert$2"

[Authenticate CSF]

[Install Key]
  Verification Index = 0
  Target Index = 2
  File = "pkcs11:token=${token};object=IMG_1_1;type=cert$2"
EOF
}

printf '%s\n' "$pin" > pin.txt

cat > openssl-pin.cnf <<EOF
openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
pkcs11 = pkcs11_sect

[default_sect]
activate = 1

[pkcs11_sect]
pkcs11-module-token-pin = file:${dir}/pin.txt
EOF

write_csf pin-in-uri.csf "?pin-value=${pin}"
write_csf no-pin.csf ""

cat > expected-csf.log <<EOF
SRK Table file created

CSF Certificate Detected

IMG Certificate Detected

Certificate file created

Certificate file created

Signature file created

EOF

assert_bin_signed() {
    hab_csf_parser -c "$1" > "$1.log"
    diff -u expected-csf.log "$1.log"
}

# Test 1: PIN from CSF embedded pin-value argument
setsid -w cst -i pin-in-uri.csf -o pin-in-uri.bin -b pkcs11 < /dev/null
assert_bin_signed pin-in-uri.bin

# Test 2: PIN from OpenSSL configuration file
OPENSSL_CONF="${dir}/openssl-pin.cnf" setsid -w cst -i no-pin.csf -o pin-in-config.bin -b pkcs11 < /dev/null
assert_bin_signed pin-in-config.bin

softhsm2-util --delete-token --token "$token"
