1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#!/bin/sh -ex
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2016 Red Hat, Inc.
# Author: Nathaniel McCallum <npmccallum@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
. helpers
trap 'on_exit' EXIT
export TMP=`mktemp -d`
mkdir -p $TMP/db
adv_startup () {
tangd-keygen $TMP/db sig exc
# Make sure keys generated by tangd-keygen have proper permissions.
valid_key_perm "${TMP}/db/sig.jwk"
valid_key_perm "${TMP}/db/exc.jwk"
jose jwk gen -i '{"alg": "ES512"}' -o $TMP/db/.sig.jwk
jose jwk gen -i '{"alg": "ES512"}' -o $TMP/db/.oth.jwk
}
adv_second_phase () {
# Make sure requests on the root fail
fetch "${ENDPOINT}"/ && expected_fail
# The request should fail (404) for non-signature key IDs
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/exc.jwk` && expected_fail
fetch "${ENDPOINT}"/adv/`jose jwk thp -a S512 -i $TMP/db/exc.jwk` && expected_fail
# The default advertisement fetch should succeed and pass verification
fetch "${ENDPOINT}"/adv
fetch "${ENDPOINT}"/adv | ver $TMP/db/sig.jwk
fetch "${ENDPOINT}"/adv/ | ver $TMP/db/sig.jwk
# Fetching by any thumbprint should work
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/sig.jwk
fetch "${ENDPOINT}"/adv/`jose jwk thp -a S512 -i $TMP/db/sig.jwk` | ver $TMP/db/sig.jwk
# Requesting an adv by an advertised key ID should't be signed by hidden keys
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.sig.jwk && expected_fail
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.oth.jwk && expected_fail
# Verify that the default advertisement is not signed with hidden signature keys
fetch "${ENDPOINT}"/adv/ | ver $TMP/db/.oth.jwk && expected_fail
fetch "${ENDPOINT}"/adv/ | ver $TMP/db/.sig.jwk && expected_fail
# A private key advertisement is signed by all advertised keys and the requested private key
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/sig.jwk
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/.sig.jwk
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/.oth.jwk && expected_fail
# Verify that the advertisements contain the cty parameter
fetch "${ENDPOINT}"/adv | jose fmt -j- -Og protected -SyOg cty -Sq "jwk-set+json" -E
fetch "${ENDPOINT}"/adv/`jose jwk thp -i $TMP/db/.sig.jwk` \
| jose fmt -j- -Og signatures -A \
-g 0 -Og protected -SyOg cty -Sq "jwk-set+json" -EUUUUU \
-g 1 -Og protected -SyOg cty -Sq "jwk-set+json" -EUUUUU
THP_DEFAULT_HASH=S256 # SHA-256.
test "$(tang-show-keys $PORT $ENDPOINT)" = "$(jose jwk thp -a "${THP_DEFAULT_HASH}" -i $TMP/db/sig.jwk)"
# Check that new keys will be created if none exist.
rm -rf "${TMP}/db" && mkdir -p "${TMP}/db"
fetch "${ENDPOINT}"/adv
# Now let's make sure the new keys were named using our default thumbprint
# hash and then rotate them and check if we still create new keys.
cd "${TMP}/db"
for k in *.jwk; do
# Check for the key name (SHA-256).
test "${k}" = "$(jose jwk thp -a "${THP_DEFAULT_HASH}" -i "${k}")".jwk
# Rotate the key.
mv -f -- "${k}" ".${k}"
done
cd -
fetch "${ENDPOINT}"/adv
# Lets's now test with multiple pairs of keys.
for i in 1 2 3 4 5 6 7 8 9; do
tangd-keygen "${TMP}"/db other-sig-${i} other-exc-${i}
# Make sure the requested keys exist and are valid.
validate_sig "${TMP}/db/other-sig-${i}.jwk"
validate_exc "${TMP}/db/other-exc-${i}.jwk"
# Make sure keys generated by tangd-keygen have proper permissions.
valid_key_perm "${TMP}/db/other-sig-${i}.jwk"
valid_key_perm "${TMP}/db/other-exc-${i}.jwk"
done
# Verify the advertisement is correct.
validate "$(fetch "${ENDPOINT}"/adv)"
# And make sure we can fetch an adv by its thumbprint.
for jwk in "${TMP}"/db/other-sig-*.jwk; do
for alg in $(jose alg -k hash); do
fetch "${ENDPOINT}"/adv/"$(jose jwk thp -a "${alg}" -i "${jwk}")" | ver "${jwk}"
done
done
# Now let's test keys rotation.
tangd-rotate-keys -d "${TMP}/db"
for i in 1 2 3 4 5 6 7 8 9; do
# Make sure keys were excluded from advertisement.
validate_sig "${TMP}/db/.other-sig-${i}.jwk"
validate_exc "${TMP}/db/.other-exc-${i}.jwk"
done
# And test also that we have valid keys after rotation.
thp=
for jwk in "${TMP}"/db/*.jwk; do
validate_sig "${jwk}" && thp="$(jose jwk thp -a "${THP_DEFAULT_HASH}" \
-i "${jwk}")"
# Make sure keys generated by tangd-rotate-keys have proper permissions.
valid_key_perm "${jwk}"
done
[ -z "${thp}" ] && die "There should be valid keys after rotation"
test "$(tang-show-keys $PORT $ENDPOINT)" = "${thp}"
}
|