#!/bin/sh -ex # vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: # # Copyright (c) 2016 Red Hat, Inc. # Author: Nathaniel McCallum # # 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 . # . helpers sanity_check trap 'on_exit' EXIT export TMP=`mktemp -d` mkdir -p $TMP/db 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 export PORT=$(random_port) start_server "${PORT}" export PID=$! sleep 0.5 # Make sure requests on the root fail fetch / && expected_fail # The request should fail (404) for non-signature key IDs fetch /adv/`jose jwk thp -i $TMP/db/exc.jwk` && expected_fail fetch /adv/`jose jwk thp -a S512 -i $TMP/db/exc.jwk` && expected_fail # The default advertisement fetch should succeed and pass verification fetch /adv fetch /adv | ver $TMP/db/sig.jwk fetch /adv/ | ver $TMP/db/sig.jwk # Fetching by any thumbprint should work fetch /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/sig.jwk fetch /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 /adv/`jose jwk thp -i $TMP/db/sig.jwk` | ver $TMP/db/.sig.jwk && expected_fail fetch /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 /adv/ | ver $TMP/db/.oth.jwk && expected_fail fetch /adv/ | ver $TMP/db/.sig.jwk && expected_fail # A private key advertisement is signed by all advertised keys and the requested private key fetch /adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/sig.jwk fetch /adv/`jose jwk thp -i $TMP/db/.sig.jwk` | ver $TMP/db/.sig.jwk fetch /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 /adv | jose fmt -j- -Og protected -SyOg cty -Sq "jwk-set+json" -E fetch /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)" = "$(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 /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 /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 /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 /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)" = "${thp}"