ssh signing: verify ssh-keygen in test prereq

Do a full ssh signing, find-principals and verify operation in the test prereq's to make sure ssh-keygen works as expected. Only generating the keys and verifying its presence is not sufficient in some situations. One example was ssh-keygen creating unusable ssh keys in cygwin because of unsafe default permissions for the key files. The other a broken openssh 8.7 that segfaulted on any find-principals operation. This extended prereq check avoids future test breakages in case ssh-keygen or any environment behaviour changes. Signed-off-by: Fabian Stelzer <fs@gigacodes.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Fabian Stelzer committed Dec 9, 2021 at 09:52 UTC 50992f96c546ebdc0c149660f6baa948739888d9
1 file changed +40 -13
t/lib-gpg.sh
+40 -13
@@ -109,34 +109,61 @@ test_lazy_prereq GPGSSH '
109 echo $ssh_version | grep -q "find-principals:missing signature file"
110 test $? = 0 || exit 1;
111
112 - # some broken versions of ssh-keygen segfault on find-principals;
113 - # avoid testing with them.
114 - ssh-keygen -Y find-principals -f /dev/null -s /dev/null
115 - test $? = 139 && exit 1
116 -
112 + # Setup some keys and an allowed signers file
113 mkdir -p "${GNUPGHOME}" &&
114 chmod 0700 "${GNUPGHOME}" &&
115 (setfacl -k "${GNUPGHOME}" 2>/dev/null || true) &&
116 ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GPGSSH_KEY_PRIMARY}" >/dev/null &&
121 - echo "\"principal with number 1\" $(cat "${GPGSSH_KEY_PRIMARY}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
117 ssh-keygen -t rsa -b 2048 -N "" -C "git rsa2048 key" -f "${GPGSSH_KEY_SECONDARY}" >/dev/null &&
123 - echo "\"principal with number 2\" $(cat "${GPGSSH_KEY_SECONDARY}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
118 ssh-keygen -t ed25519 -N "${GPGSSH_KEY_PASSPHRASE}" -C "git ed25519 encrypted key" -f "${GPGSSH_KEY_WITH_PASSPHRASE}" >/dev/null &&
125 - echo "\"principal with number 3\" $(cat "${GPGSSH_KEY_WITH_PASSPHRASE}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
126 - ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GPGSSH_KEY_UNTRUSTED}" >/dev/null
119 + ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GPGSSH_KEY_UNTRUSTED}" >/dev/null &&
120 +
121 + cat >"${GPGSSH_ALLOWED_SIGNERS}" <<-EOF &&
122 + "principal with number 1" $(cat "${GPGSSH_KEY_PRIMARY}.pub")"
123 + "principal with number 2" $(cat "${GPGSSH_KEY_SECONDARY}.pub")"
124 + "principal with number 3" $(cat "${GPGSSH_KEY_WITH_PASSPHRASE}.pub")"
125 + EOF
126 +
127 + # Verify if at least one key and ssh-keygen works as expected
128 + echo "testpayload" |
129 + ssh-keygen -Y sign -n "git" -f "${GPGSSH_KEY_PRIMARY}" >gpgssh_prereq.sig &&
130 + ssh-keygen -Y find-principals -f "${GPGSSH_ALLOWED_SIGNERS}" -s gpgssh_prereq.sig &&
131 + echo "testpayload" |
132 + ssh-keygen -Y verify -n "git" -f "${GPGSSH_ALLOWED_SIGNERS}" -I "principal with number 1" -s gpgssh_prereq.sig
133 '
134
135 test_lazy_prereq GPGSSH_VERIFYTIME '
136 # Check if ssh-keygen has a verify-time option by passing an invalid date to it
137 ssh-keygen -Overify-time=INVALID -Y check-novalidate -s doesnotmatter 2>&1 | grep -q -F "Invalid \"verify-time\"" &&
138 +
139 + # Set up keys with key lifetimes
140 ssh-keygen -t ed25519 -N "" -C "timeboxed valid key" -f "${GPGSSH_KEY_TIMEBOXEDVALID}" >/dev/null &&
133 - echo "\"timeboxed valid key\" valid-after=\"20050407000000\",valid-before=\"200504100000\" $(cat "${GPGSSH_KEY_TIMEBOXEDVALID}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
141 + key_valid=$(cat "${GPGSSH_KEY_TIMEBOXEDVALID}.pub") &&
142 ssh-keygen -t ed25519 -N "" -C "timeboxed invalid key" -f "${GPGSSH_KEY_TIMEBOXEDINVALID}" >/dev/null &&
135 - echo "\"timeboxed invalid key\" valid-after=\"20050401000000\",valid-before=\"20050402000000\" $(cat "${GPGSSH_KEY_TIMEBOXEDINVALID}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
143 + key_invalid=$(cat "${GPGSSH_KEY_TIMEBOXEDINVALID}.pub") &&
144 ssh-keygen -t ed25519 -N "" -C "expired key" -f "${GPGSSH_KEY_EXPIRED}" >/dev/null &&
137 - echo "\"principal with expired key\" valid-before=\"20000101000000\" $(cat "${GPGSSH_KEY_EXPIRED}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}" &&
145 + key_expired=$(cat "${GPGSSH_KEY_EXPIRED}.pub") &&
146 ssh-keygen -t ed25519 -N "" -C "not yet valid key" -f "${GPGSSH_KEY_NOTYETVALID}" >/dev/null &&
139 - echo "\"principal with not yet valid key\" valid-after=\"29990101000000\" $(cat "${GPGSSH_KEY_NOTYETVALID}.pub")" >> "${GPGSSH_ALLOWED_SIGNERS}"
147 + key_notyetvalid=$(cat "${GPGSSH_KEY_NOTYETVALID}.pub") &&
148 +
149 + # Timestamps outside of test_tick span
150 + ts2005a=20050401000000 ts2005b=200504020000 &&
151 + # Timestamps within test_tick span
152 + ts2005c=20050407000000 ts2005d=200504100000 &&
153 + # Definitely not yet valid / expired timestamps
154 + ts2000=20000101000000 ts2999=29990101000000 &&
155 +
156 + cat >>"${GPGSSH_ALLOWED_SIGNERS}" <<-EOF &&
157 + "timeboxed valid key" valid-after="$ts2005c",valid-before="$ts2005d" $key_valid"
158 + "timeboxed invalid key" valid-after="$ts2005a",valid-before="$ts2005b" $key_invalid"
159 + "principal with expired key" valid-before="$ts2000" $key_expired"
160 + "principal with not yet valid key" valid-after="$ts2999" $key_notyetvalid"
161 + EOF
162 +
163 + # and verify ssh-keygen verifies the key lifetime
164 + echo "testpayload" |
165 + ssh-keygen -Y sign -n "git" -f "${GPGSSH_KEY_EXPIRED}" >gpgssh_verifytime_prereq.sig &&
166 + ! (ssh-keygen -Y verify -n "git" -f "${GPGSSH_ALLOWED_SIGNERS}" -I "principal with expired key" -s gpgssh_verifytime_prereq.sig)
167 '
168
169 sanitize_pgp() {