# Extra packages required in this snippet:
#  * keylime-agent-rust
#  * grubby
#  * openssl
#  * ima-evm-utils

LOG_FILE=/root/postinstall-keylime-agent.log
[ -n "@NO_SAVE@" ] && LOG_FILE=/dev/null

exec < /dev/tty3 > /dev/tty3
chvt 3
echo "#######################"
echo "# %post keylime-agent #"
echo "#######################"
(
  REQ_PKGS='keylime-agent-rust grubby openssl ima-evm-utils'

  # Sanity check.
  skip=
  for _pkg in ${REQ_PKGS}; do
    rpm -q "${_pkg}" >/dev/null || skip=true
  done

  if [ -z "${skip}" ]; then
    IMA_STATE="on"
    IMA_POLICY="tcb"
    IMA_APPRAISE="fix"
    IMA_TEMPLATE="ima-ng"

    # IMA policy magic.
    IMA_BASEDIR=/etc/10mt-ima-setup

    # openssl + evmctl (ima-emv-utils)
    mkdir -p "${IMA_BASEDIR}"/ima

    # IMA private key.
    I_CA_PRIVKEY="${IMA_BASEDIR}"/ima/ca.key
    I_CA_CSR="${IMA_BASEDIR}"/ima/ca.csr
    I_CA_CRT="${IMA_BASEDIR}"/ima/ca.crt
    I_CA_CSR_CNF="${IMA_BASEDIR}"/ima/ima.cnf

    # IMA private key.
    openssl genrsa -out "${I_CA_PRIVKEY}" 4096

    # IMA ca CSR config.
    cat << EOF > "${I_CA_CSR_CNF}"
[req]
default_bits        = 4096
default_md          = sha256
distinguished_name  = req_distinguished_name
req_extensions      = v3_req
prompt              = no
string_mask         = utf8only

[req_distinguished_name]
countryName         = US
organizationName    = ExampleCorp
commonName          = RootCA

[v3_req]
basicConstraints       = critical, CA:TRUE
keyUsage               = critical, keyCertSign
subjectKeyIdentifier   = hash
EOF

    openssl req -new -key "${I_CA_PRIVKEY}" -out "${I_CA_CSR}" -config "${I_CA_CSR_CNF}"
    # IMA CA cert
    openssl x509 -req -days 1825 -sha256 \
    -extfile "${I_CA_CSR_CNF}" -extensions v3_req \
    -in "${I_CA_CSR}" -signkey "${I_CA_PRIVKEY}" -out "${I_CA_CRT}"

    # IMA signing key.
    I_S_PRIVKEY="${IMA_BASEDIR}"/ima/signing-private.key
    I_S_CSR_CNF="${IMA_BASEDIR}"/ima/signing.cnf
    I_S_CSR="${IMA_BASEDIR}"/ima/signing.csr
    I_S_CRT="${IMA_BASEDIR}"/ima/signing.crt


    openssl genrsa -out "${I_S_PRIVKEY}" 3072

    # IMA signing key CSR config
    cat << EOF > "${I_S_CSR_CNF}"
[req]
default_bits        = 4096
default_md          = sha256
distinguished_name  = req_distinguished_name
req_extensions      = v3_req
prompt              = no
string_mask         = utf8only

[req_distinguished_name]
countryName         = US
organizationName    = ExampleCorp
commonName          = IMA signing

[v3_req]
basicConstraints       = critical, CA:FALSE
keyUsage               = critical, digitalSignature, nonRepudiation
extendedKeyUsage       = codeSigning
subjectKeyIdentifier   = hash
EOF

    # IMA signing key CSR.
    openssl req -new -key "${I_S_PRIVKEY}" -out "${I_S_CSR}" -config "${I_S_CSR_CNF}"

    openssl x509 -req -days 365 -sha256 \
    -CA "${I_CA_CRT}" -CAkey "${I_CA_PRIVKEY}" -CAcreateserial \
    -in "${I_S_CSR}" -out ${I_S_CRT} \
    -extfile "${I_S_CSR_CNF}" -extensions v3_req

    IMA_POLICY_F="${IMA_BASEDIR}"/ima-policy
    IMA_SIGNED_POLICY=/etc/ima/ima-policy

    cat << EOF > "${IMA_POLICY_F}"
# PROC_SUPER_MAGIC
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC
dont_measure fsmagic=0x01021994
# RAMFS_MAGIC
dont_measure fsmagic=0x858458f6
# SECURITYFS_MAGIC
dont_measure fsmagic=0x73636673
# MEASUREMENTS
measure func=BPRM_CHECK
measure func=FILE_MMAP mask=MAY_EXEC
measure func=MODULE_CHECK uid=0
appraise func=BPRM_CHECK fowner=0 appraise_type=imasig
EOF

    # Now let's sign the policy and install it.
    install -D -m 0644 "${IMA_POLICY_F}" "${IMA_SIGNED_POLICY}"
    evmctl ima_sign --hashalgo sha256 --key "${I_S_PRIVKEY}" "${IMA_SIGNED_POLICY}"
    # IMA complete!

    grubby --update-kernel DEFAULT --args="ima=${IMA_STATE} ima_appraise=${IMA_APPRAISE} ima_canonical_fmt ima_policy=${IMA_POLICY}"
  else
    echo "##################################################################"
    echo "#    Kickstart snippet skipped. Please make sure the required    #"
    echo "# variables are defined and the required packages are installed. #"
    echo "##################################################################"
    echo
    echo "* Required packages: ${REQ_PKGS}"
    echo
    echo "* Installed packages:"
    rpm -qa | sort
  fi
) 2>&1 | tee "${LOG_FILE}"
chvt 1

# vim:set ts=2 sw=2 et:

