cert-userkey.sh revision 1.13
1# $OpenBSD: cert-userkey.sh,v 1.13 2015/07/03 04:39:23 djm Exp $ 2# Placed in the Public Domain. 3 4tid="certified user keys" 5 6rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 7cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 8 9PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` 10 11# Create a CA key 12${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ 13 fail "ssh-keygen of user_ca_key failed" 14 15# Generate and sign user keys 16for ktype in $PLAIN_TYPES ; do 17 verbose "$tid: sign user ${ktype} cert" 18 ${SSHKEYGEN} -q -N '' -t ${ktype} \ 19 -f $OBJ/cert_user_key_${ktype} || \ 20 fail "ssh-keygen of cert_user_key_${ktype} failed" 21 ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ 22 -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || 23 fail "couldn't sign cert_user_key_${ktype}" 24done 25 26# Test explicitly-specified principals 27for ktype in $PLAIN_TYPES ; do 28 for privsep in yes no ; do 29 _prefix="${ktype} privsep $privsep" 30 31 # Setup for AuthorizedPrincipalsFile 32 rm -f $OBJ/authorized_keys_$USER 33 ( 34 cat $OBJ/sshd_proxy_bak 35 echo "UsePrivilegeSeparation $privsep" 36 echo "AuthorizedPrincipalsFile " \ 37 "$OBJ/authorized_principals_%u" 38 echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" 39 ) > $OBJ/sshd_proxy 40 41 # Missing authorized_principals 42 verbose "$tid: ${_prefix} missing authorized_principals" 43 rm -f $OBJ/authorized_principals_$USER 44 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 45 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 46 if [ $? -eq 0 ]; then 47 fail "ssh cert connect succeeded unexpectedly" 48 fi 49 50 # Empty authorized_principals 51 verbose "$tid: ${_prefix} empty authorized_principals" 52 echo > $OBJ/authorized_principals_$USER 53 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 54 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 55 if [ $? -eq 0 ]; then 56 fail "ssh cert connect succeeded unexpectedly" 57 fi 58 59 # Wrong authorized_principals 60 verbose "$tid: ${_prefix} wrong authorized_principals" 61 echo gregorsamsa > $OBJ/authorized_principals_$USER 62 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 63 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 64 if [ $? -eq 0 ]; then 65 fail "ssh cert connect succeeded unexpectedly" 66 fi 67 68 # Correct authorized_principals 69 verbose "$tid: ${_prefix} correct authorized_principals" 70 echo mekmitasdigoat > $OBJ/authorized_principals_$USER 71 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 72 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 73 if [ $? -ne 0 ]; then 74 fail "ssh cert connect failed" 75 fi 76 77 # authorized_principals with bad key option 78 verbose "$tid: ${_prefix} authorized_principals bad key opt" 79 echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER 80 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 81 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 82 if [ $? -eq 0 ]; then 83 fail "ssh cert connect succeeded unexpectedly" 84 fi 85 86 # authorized_principals with command=false 87 verbose "$tid: ${_prefix} authorized_principals command=false" 88 echo 'command="false" mekmitasdigoat' > \ 89 $OBJ/authorized_principals_$USER 90 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 91 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 92 if [ $? -eq 0 ]; then 93 fail "ssh cert connect succeeded unexpectedly" 94 fi 95 96 97 # authorized_principals with command=true 98 verbose "$tid: ${_prefix} authorized_principals command=true" 99 echo 'command="true" mekmitasdigoat' > \ 100 $OBJ/authorized_principals_$USER 101 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 102 -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 103 if [ $? -ne 0 ]; then 104 fail "ssh cert connect failed" 105 fi 106 107 # Setup for principals= key option 108 rm -f $OBJ/authorized_principals_$USER 109 ( 110 cat $OBJ/sshd_proxy_bak 111 echo "UsePrivilegeSeparation $privsep" 112 ) > $OBJ/sshd_proxy 113 114 # Wrong principals list 115 verbose "$tid: ${_prefix} wrong principals key option" 116 ( 117 printf 'cert-authority,principals="gregorsamsa" ' 118 cat $OBJ/user_ca_key.pub 119 ) > $OBJ/authorized_keys_$USER 120 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 121 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 122 if [ $? -eq 0 ]; then 123 fail "ssh cert connect succeeded unexpectedly" 124 fi 125 126 # Correct principals list 127 verbose "$tid: ${_prefix} correct principals key option" 128 ( 129 printf 'cert-authority,principals="mekmitasdigoat" ' 130 cat $OBJ/user_ca_key.pub 131 ) > $OBJ/authorized_keys_$USER 132 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 133 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 134 if [ $? -ne 0 ]; then 135 fail "ssh cert connect failed" 136 fi 137 done 138done 139 140basic_tests() { 141 auth=$1 142 if test "x$auth" = "xauthorized_keys" ; then 143 # Add CA to authorized_keys 144 ( 145 printf 'cert-authority ' 146 cat $OBJ/user_ca_key.pub 147 ) > $OBJ/authorized_keys_$USER 148 else 149 echo > $OBJ/authorized_keys_$USER 150 extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" 151 fi 152 153 for ktype in $PLAIN_TYPES ; do 154 for privsep in yes no ; do 155 _prefix="${ktype} privsep $privsep $auth" 156 # Simple connect 157 verbose "$tid: ${_prefix} connect" 158 ( 159 cat $OBJ/sshd_proxy_bak 160 echo "UsePrivilegeSeparation $privsep" 161 echo "$extra_sshd" 162 ) > $OBJ/sshd_proxy 163 164 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 165 -F $OBJ/ssh_proxy somehost true 166 if [ $? -ne 0 ]; then 167 fail "ssh cert connect failed" 168 fi 169 170 # Revoked keys 171 verbose "$tid: ${_prefix} revoked key" 172 ( 173 cat $OBJ/sshd_proxy_bak 174 echo "UsePrivilegeSeparation $privsep" 175 echo "RevokedKeys $OBJ/cert_user_key_revoked" 176 echo "$extra_sshd" 177 ) > $OBJ/sshd_proxy 178 cp $OBJ/cert_user_key_${ktype}.pub \ 179 $OBJ/cert_user_key_revoked 180 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 181 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 182 if [ $? -eq 0 ]; then 183 fail "ssh cert connect succeeded unexpecedly" 184 fi 185 verbose "$tid: ${_prefix} revoked via KRL" 186 rm $OBJ/cert_user_key_revoked 187 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ 188 $OBJ/cert_user_key_${ktype}.pub 189 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 190 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 191 if [ $? -eq 0 ]; then 192 fail "ssh cert connect succeeded unexpecedly" 193 fi 194 verbose "$tid: ${_prefix} empty KRL" 195 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked 196 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 197 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 198 if [ $? -ne 0 ]; then 199 fail "ssh cert connect failed" 200 fi 201 done 202 203 # Revoked CA 204 verbose "$tid: ${ktype} $auth revoked CA key" 205 ( 206 cat $OBJ/sshd_proxy_bak 207 echo "RevokedKeys $OBJ/user_ca_key.pub" 208 echo "$extra_sshd" 209 ) > $OBJ/sshd_proxy 210 ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 211 somehost true >/dev/null 2>&1 212 if [ $? -eq 0 ]; then 213 fail "ssh cert connect succeeded unexpecedly" 214 fi 215 done 216 217 verbose "$tid: $auth CA does not authenticate" 218 ( 219 cat $OBJ/sshd_proxy_bak 220 echo "$extra_sshd" 221 ) > $OBJ/sshd_proxy 222 verbose "$tid: ensure CA key does not authenticate user" 223 ${SSH} -2i $OBJ/user_ca_key \ 224 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 225 if [ $? -eq 0 ]; then 226 fail "ssh cert connect with CA key succeeded unexpectedly" 227 fi 228} 229 230basic_tests authorized_keys 231basic_tests TrustedUserCAKeys 232 233test_one() { 234 ident=$1 235 result=$2 236 sign_opts=$3 237 auth_choice=$4 238 auth_opt=$5 239 240 if test "x$auth_choice" = "x" ; then 241 auth_choice="authorized_keys TrustedUserCAKeys" 242 fi 243 244 for auth in $auth_choice ; do 245 for ktype in rsa ed25519 ; do 246 cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 247 if test "x$auth" = "xauthorized_keys" ; then 248 # Add CA to authorized_keys 249 ( 250 printf "cert-authority${auth_opt} " 251 cat $OBJ/user_ca_key.pub 252 ) > $OBJ/authorized_keys_$USER 253 else 254 echo > $OBJ/authorized_keys_$USER 255 echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ 256 >> $OBJ/sshd_proxy 257 if test "x$auth_opt" != "x" ; then 258 echo $auth_opt >> $OBJ/sshd_proxy 259 fi 260 fi 261 262 verbose "$tid: $ident auth $auth expect $result $ktype" 263 ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ 264 -I "regress user key for $USER" \ 265 $sign_opts $OBJ/cert_user_key_${ktype} || 266 fail "couldn't sign cert_user_key_${ktype}" 267 268 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 269 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 270 rc=$? 271 if [ "x$result" = "xsuccess" ] ; then 272 if [ $rc -ne 0 ]; then 273 fail "$ident failed unexpectedly" 274 fi 275 else 276 if [ $rc -eq 0 ]; then 277 fail "$ident succeeded unexpectedly" 278 fi 279 fi 280 done 281 done 282} 283 284test_one "correct principal" success "-n ${USER}" 285test_one "host-certificate" failure "-n ${USER} -h" 286test_one "wrong principals" failure "-n foo" 287test_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" 288test_one "cert expired" failure "-n ${USER} -V19800101:19900101" 289test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" 290test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" 291test_one "force-command" failure "-n ${USER} -Oforce-command=false" 292 293# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals 294test_one "empty principals" success "" authorized_keys 295test_one "empty principals" failure "" TrustedUserCAKeys 296 297# Check explicitly-specified principals: an empty principals list in the cert 298# should always be refused. 299 300# AuthorizedPrincipalsFile 301rm -f $OBJ/authorized_keys_$USER 302echo mekmitasdigoat > $OBJ/authorized_principals_$USER 303test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ 304 TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 305test_one "AuthorizedPrincipalsFile no principals" failure "" \ 306 TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 307 308# principals= key option 309rm -f $OBJ/authorized_principals_$USER 310test_one "principals key option principals" success "-n mekmitasdigoat" \ 311 authorized_keys ',principals="mekmitasdigoat"' 312test_one "principals key option no principals" failure "" \ 313 authorized_keys ',principals="mekmitasdigoat"' 314 315# Wrong certificate 316cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 317for ktype in $PLAIN_TYPES ; do 318 # Self-sign 319 ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \ 320 "regress user key for $USER" \ 321 -n $USER $OBJ/cert_user_key_${ktype} || 322 fail "couldn't sign cert_user_key_${ktype}" 323 verbose "$tid: user ${ktype} connect wrong cert" 324 ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 325 somehost true >/dev/null 2>&1 326 if [ $? -eq 0 ]; then 327 fail "ssh cert connect $ident succeeded unexpectedly" 328 fi 329done 330 331rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 332rm -f $OBJ/authorized_principals_$USER 333 334