-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP WIP WIP -- not tested Let's try a different approach to expressing complex policies: - Policies as restricted bash scripts that can do very little besides evaluate TPM policies, and which are invoked via... - ...a driver script, `sbin/tpm2-policy`, that sets up the environment for running the policy, and takes optional additional artifacts to make available to the policy. - Constant artifacts would be things like: - signer keys for `policysigned` and `policyauthorize` - signer key names for `policyticket` and such - anything else you can imagine Non-constant artifacts would be things like: - saved object context files for signer keys for `policysigned` and `policyauthorize` - tickets from `verifysignature`, `policysecret`, and `policysigned` - timeout files - anything else you can imagine all of which can be written only in `.` / `$PWD`. - The policy scripts would run in the following environment: - a temp dir as the current directory, with `$TMPDIR` set to `$PWD` and in which all the necessary artifacts, including the policy script itself, shall have been placed - various TPM2_POLICY... env vars, mainly TPM2_POLICY_SESSION - `$PATH` set to have just two paths: an `rbin` (see below), and the `$PWD`/`$TMPDIR` itself into which the policy script will have been copied (this will allow the policy script to implement different sub-policies selected by its arguments by executing itself, possibly through the `rbin/policyor` wrapper). - The "rbin" directory in the PATH for the execution of policy scripts, with: - wrappers for all the tpm2_policy... commands - the wrapper for tpm2_policyor is a bit special, naturally - wrappers for tpm2_loadexternal and tpm2_verifysignature, and possibly others - links to or wrappers of a handful of useful system commands like `sha256sum`, `xxd`, `dc`, `bc`, `jq`, etc. - a wrapper around `xxd` and `cat` for creating files from stdin so that artifacts can be embedded as here documents in the script This way policies get all the expressive power of bash, and access to all the functionality of tpm2-tools' policy commands. TBD: - Test, debug, test, ... - Add rbin wrappers for importing duplicated keys (so they can provide authValues discretely!). - Maybe allow execution of `sbin/tpm2-recv` by linking it from the rbin? - Add sample policies that are interesting, like using a combination of `policysigned` and `policyauthorize` and `curl` (outside the policy script) to execute an external script that varies at runtime, or policies that use different passwords for N different users, or which use `policysigned` to let some other entity authenticate N different users (using `policyRef` to name them, say), policies requiring golden PCRs OR external policy, etc. Showcase `policyor`! It'd be very nice to be able to have a policy like this: (golden PCRs && user authValue) || (admin authValue OTP && NV revocation of OTP index) || (superadmin authValue) || ($policy_containing_policy_signed && policyauthorize_of_it) Perhaps with multiple superadmin authValues via `policyor`. Such a policy would allow a laptop to boot normally with a user password, and after emergency updates boot with an admin OTP, or after any mishaps via a superadmin password, or with a separate policy that blesses the current PCRs as golden. Such a policy could be used for sealing an NV index, or it could be set on local storage keys encrypted to the TPM's EKpub via `sbin/tpm2-send`, allowing for unattended server booting post-attestation, or attended server booting post-mishap (if the encrypted assets get stored "in the clear").
- Loading branch information
1 parent
62509a5
commit 0b70fc2
Showing
32 changed files
with
2,569 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/bin/bash | ||
|
||
PROG=${0##*/} | ||
# Restore the environment so that we have a sane PATH and can find, e.g., | ||
# tpm2-tools. | ||
# shellcheck disable=SC1090 disable=SC1091 | ||
. ./env | ||
|
||
set -euo pipefail | ||
shopt -s extglob | ||
|
||
TMPDIR=$PWD | ||
[[ -n ${TPM2_POLICY_SESSION:-} ]] \ | ||
|| die "TPM2_POLICY_SESSION is not set" | ||
[[ ${TPM2_POLICY_SESSION} != */* || | ||
${TPM2_POLICY_SESSION} = ${PWD}/* ]] \ | ||
|| die "TPM2_POLICY_SESSION does not exist" | ||
[[ -s ${TPM2_POLICY_SESSION} ]] \ | ||
|| die "TPM2_POLICY_SESSION does not exist" | ||
|
||
# shellcheck disable=SC2209 | ||
function usage { | ||
((${1:-1} > 0)) && exec 1>&2 | ||
pager=cat | ||
if [[ -t 0 && -t 1 && -t 2 ]]; then | ||
if [[ -z ${PAGER:-} ]] && type less >/dev/null 2>&1; then | ||
pager=less | ||
elif [[ -z ${PAGER:-} ]] && type more >/dev/null 2>&1; then | ||
pager=more | ||
elif [[ -n ${PAGER:-} ]]; then | ||
pager=$PAGER | ||
fi | ||
fi | ||
$pager <<EOF | ||
Usage: $PROG [options] | ||
{$PROG} is a wrapper around {tpm2 flushcontext}. | ||
See {${BASEDIR}/sbin/tpm2-policy}. | ||
Options: | ||
-h | --help This help message. | ||
-x | --trace Trace this script. | ||
-t | --transient-object | ||
-l | --loaded-session | ||
-s | --saved-session | ||
EOF | ||
exit "${1:-1}" | ||
} | ||
|
||
# shellcheck disable=SC1090 disable=SC1091 | ||
. "$BASEDIR/functions.sh" | ||
|
||
# shellcheck disable=SC2034 | ||
declare -A lopts=( | ||
[help]='' | ||
[trace]='' | ||
[transient-object]=: | ||
[loaded-session]=: | ||
[saved-session]=: | ||
) | ||
|
||
declare -a args=(--policy "$TPM2_POLICY" --session "$TPM2_POLICY_SESSION") | ||
|
||
while getopts_long lopts +:hxlst opt "$@"; do | ||
# opt is set in getopts_long | ||
# shellcheck disable=SC2154 | ||
case "$opt" in | ||
h|help) usage 0;; | ||
x|trace) set -vx;; | ||
t|transient-object|l|loaded-session|s|saved-session) | ||
args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
*) usage;; | ||
esac | ||
done | ||
shift $((OPTIND - 1)) | ||
|
||
# Finally: | ||
tpm2_flushcontext "${args[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/bin/bash | ||
|
||
PROG=${0##*/} | ||
# shellcheck disable=SC1090 disable=SC1091 | ||
. ./env | ||
|
||
set -euo pipefail | ||
shopt -s extglob | ||
|
||
TMPDIR=$PWD | ||
|
||
# shellcheck disable=SC2209 | ||
function usage { | ||
((${1:-1} > 0)) && exec 1>&2 | ||
pager=cat | ||
if [[ -t 0 && -t 1 && -t 2 ]]; then | ||
if [[ -z ${PAGER:-} ]] && type less >/dev/null 2>&1; then | ||
pager=less | ||
elif [[ -z ${PAGER:-} ]] && type more >/dev/null 2>&1; then | ||
pager=more | ||
elif [[ -n ${PAGER:-} ]]; then | ||
pager=$PAGER | ||
fi | ||
fi | ||
$pager <<EOF | ||
Usage: $PROG [options] AUTH | ||
{$PROG} is a wrapper around {tpm2 import}. | ||
See {${BASEDIR}/sbin/tpm2-policy}. | ||
Options: | ||
-h | --help This help message. | ||
-x | --trace Trace this script. | ||
-C | --parent-context OBJECT New parent for imported object. | ||
-U | --parent-public FILE Parent's public part. | ||
-s | --seed FILE Output of {tpm2 duplicate}. | ||
-u | --public FILE Output of {tpm2 duplicate}. | ||
-i | --input FILE Output of {tpm2 duplicate}. | ||
-r | --private FILE Output for {tpm2 load}. | ||
-g | --hash-algorithm ALGORITHM Hash algorithm. | ||
-G | --key-algorithm ALGORITHM Key algorithm. | ||
-a | --attributes ATTRIBUTES Attributes for raw external key. | ||
-L | --policy FILE Policy for raw external key. | ||
-k | --encryption-key | ||
-P | --parent-auth AUTH | ||
-p | --key-auth AUTH | ||
--cphash FILE Write cpHash of TPM2_Import() command. | ||
Input and output files are limited to files in the current directory. | ||
EOF | ||
exit "${1:-1}" | ||
} | ||
|
||
# shellcheck disable=SC1090 disable=SC1091 | ||
. "$BASEDIR/functions.sh" | ||
|
||
# shellcheck disable=SC2034 | ||
declare -A lopts=( | ||
[help]='' | ||
[trace]='' | ||
[parent-context]=: | ||
[parent-public]=: | ||
[seed]=: | ||
[private]=: | ||
[public]=: | ||
[input]=: | ||
[hash-algorithm]=: | ||
[key-algorithm]=: | ||
[attributes]=: | ||
[encryption-key]=: | ||
[parent-auth]=: | ||
[key-auth]=: | ||
[cphash]=: | ||
) | ||
|
||
declare -a args=(--policy "$TPM2_POLICY" --session "$TPM2_POLICY_SESSION") | ||
|
||
while getopts_long lopts +:hxC:U:s:r:u:i:g:G:a:L:k:P:p: opt "$@"; do | ||
# opt is set in getopts_long | ||
# shellcheck disable=SC2154 | ||
case "$opt" in | ||
h|help) usage 0;; | ||
x|trace) set -vx;; | ||
C|parent-context|U|parent-public|s|seed|r|private|u|public|k|encryption-key|cphash) | ||
[[ $OPTARG = */* ]] \ | ||
&& die "Cannot reference files outside the current directory" | ||
args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
P|parent-auth|p|key-auth) | ||
case "$OPTARG" in | ||
str:*) args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
hex:*) args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
file:*) [[ $OPTARG = */* ]] \ | ||
&& die "Cannot reference input files outside the current directory" | ||
args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
*) die "Auth values must start with str: hex: or file:";; | ||
esac;; | ||
*) usage;; | ||
esac | ||
done | ||
shift $((OPTIND - 1)) | ||
|
||
# Finally: | ||
tpm2_import "${args[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#!/bin/bash | ||
|
||
PROG=${0##*/} | ||
# shellcheck disable=SC1090 disable=SC1091 | ||
. ./env | ||
|
||
set -euo pipefail | ||
shopt -s extglob | ||
|
||
TMPDIR=$PWD | ||
|
||
# shellcheck disable=SC2209 | ||
function usage { | ||
((${1:-1} > 0)) && exec 1>&2 | ||
pager=cat | ||
if [[ -t 0 && -t 1 && -t 2 ]]; then | ||
if [[ -z ${PAGER:-} ]] && type less >/dev/null 2>&1; then | ||
pager=less | ||
elif [[ -z ${PAGER:-} ]] && type more >/dev/null 2>&1; then | ||
pager=more | ||
elif [[ -n ${PAGER:-} ]]; then | ||
pager=$PAGER | ||
fi | ||
fi | ||
$pager <<EOF | ||
Usage: $PROG [options] AUTH | ||
{$PROG} is a wrapper around {tpm2 load}. | ||
See {${BASEDIR}/sbin/tpm2-policy}. | ||
Options: | ||
-h | --help This help message. | ||
-x | --trace Trace this script. | ||
-C | --parent-context OBJECT Parent object. | ||
-c | --key-context OBJECT Saved object context file. | ||
-P | --parent-auth AUTH | ||
-r | --private FILE Output of {tpm2 import}. | ||
-u | --public FILE Output of {tpm2 duplicate, readpublic}. | ||
-n | --name FILE File in which to save the name of the | ||
loaded object. | ||
--cphash FILE Write cpHash of TPM2_Import() command. | ||
Input and output files are limited to files in the current directory. | ||
EOF | ||
exit "${1:-1}" | ||
} | ||
|
||
# shellcheck disable=SC1090 disable=SC1091 | ||
. "$BASEDIR/functions.sh" | ||
|
||
# shellcheck disable=SC2034 | ||
declare -A lopts=( | ||
[help]='' | ||
[trace]='' | ||
[parent-context]=: | ||
[key-context]=: | ||
[parent-auth]=: | ||
[private]=: | ||
[public]=: | ||
[name]=: | ||
[cphash]=: | ||
) | ||
|
||
declare -a args=(--policy "$TPM2_POLICY" --session "$TPM2_POLICY_SESSION") | ||
|
||
while getopts_long lopts +:hxC:c:P:r:u:n: opt "$@"; do | ||
# opt is set in getopts_long | ||
# shellcheck disable=SC2154 | ||
case "$opt" in | ||
h|help) usage 0;; | ||
x|trace) set -vx;; | ||
C|parent-context|c|key-context|r|private|u|public|n|name|cphash) | ||
[[ $OPTARG = */* ]] \ | ||
&& die "Cannot reference files outside the current directory" | ||
args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
P|parent-auth) | ||
case "$OPTARG" in | ||
str:*) args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
hex:*) args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
file:*) [[ $OPTARG = */* ]] \ | ||
&& die "Cannot reference input files outside the current directory" | ||
args+=(-"${OPTOPT}$opt" "$OPTARG");; | ||
*) die "Auth values must start with str: hex: or file:";; | ||
esac;; | ||
*) usage;; | ||
esac | ||
done | ||
shift $((OPTIND - 1)) | ||
|
||
# Finally: | ||
tpm2_load "${args[@]}" "$@" |
Oops, something went wrong.