1262566Sdes# $OpenBSD: cert-userkey.sh,v 1.12 2013/12/06 13:52:46 markus Exp $ 2204861Sdes# Placed in the Public Domain. 3204861Sdes 4204861Sdestid="certified user keys" 5204861Sdes 6204861Sdesrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 7204861Sdescp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 8204861Sdes 9262566SdesPLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` 10262566Sdes 11262566Sdestype_has_legacy() { 12262566Sdes case $1 in 13262566Sdes ed25519*|ecdsa*) return 1 ;; 14262566Sdes esac 15262566Sdes return 0 16262566Sdes} 17262566Sdes 18204861Sdes# Create a CA key 19204861Sdes${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ 20204861Sdes fail "ssh-keygen of user_ca_key failed" 21204861Sdes 22204861Sdes# Generate and sign user keys 23262566Sdesfor ktype in $PLAIN_TYPES ; do 24204861Sdes verbose "$tid: sign user ${ktype} cert" 25204861Sdes ${SSHKEYGEN} -q -N '' -t ${ktype} \ 26204861Sdes -f $OBJ/cert_user_key_${ktype} || \ 27204861Sdes fail "ssh-keygen of cert_user_key_${ktype} failed" 28248613Sdes ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ 29248613Sdes -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || 30204861Sdes fail "couldn't sign cert_user_key_${ktype}" 31262566Sdes type_has_legacy $ktype || continue 32214979Sdes cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00 33214979Sdes cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub 34262566Sdes verbose "$tid: sign host ${ktype}_v00 cert" 35214979Sdes ${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \ 36214979Sdes "regress user key for $USER" \ 37214979Sdes -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype}_v00 || 38262566Sdes fatal "couldn't sign cert_user_key_${ktype}_v00" 39204861Sdesdone 40204861Sdes 41214979Sdes# Test explicitly-specified principals 42262566Sdesfor ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 43214979Sdes for privsep in yes no ; do 44214979Sdes _prefix="${ktype} privsep $privsep" 45214979Sdes 46214979Sdes # Setup for AuthorizedPrincipalsFile 47214979Sdes rm -f $OBJ/authorized_keys_$USER 48214979Sdes ( 49214979Sdes cat $OBJ/sshd_proxy_bak 50214979Sdes echo "UsePrivilegeSeparation $privsep" 51214979Sdes echo "AuthorizedPrincipalsFile " \ 52214979Sdes "$OBJ/authorized_principals_%u" 53214979Sdes echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" 54214979Sdes ) > $OBJ/sshd_proxy 55214979Sdes 56214979Sdes # Missing authorized_principals 57214979Sdes verbose "$tid: ${_prefix} missing authorized_principals" 58214979Sdes rm -f $OBJ/authorized_principals_$USER 59214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 60214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 61214979Sdes if [ $? -eq 0 ]; then 62214979Sdes fail "ssh cert connect succeeded unexpectedly" 63214979Sdes fi 64214979Sdes 65214979Sdes # Empty authorized_principals 66214979Sdes verbose "$tid: ${_prefix} empty authorized_principals" 67214979Sdes echo > $OBJ/authorized_principals_$USER 68214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 69214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 70214979Sdes if [ $? -eq 0 ]; then 71214979Sdes fail "ssh cert connect succeeded unexpectedly" 72214979Sdes fi 73214979Sdes 74214979Sdes # Wrong authorized_principals 75214979Sdes verbose "$tid: ${_prefix} wrong authorized_principals" 76214979Sdes echo gregorsamsa > $OBJ/authorized_principals_$USER 77214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 78214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 79214979Sdes if [ $? -eq 0 ]; then 80214979Sdes fail "ssh cert connect succeeded unexpectedly" 81214979Sdes fi 82214979Sdes 83214979Sdes # Correct authorized_principals 84214979Sdes verbose "$tid: ${_prefix} correct authorized_principals" 85214979Sdes echo mekmitasdigoat > $OBJ/authorized_principals_$USER 86214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 87214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 88214979Sdes if [ $? -ne 0 ]; then 89214979Sdes fail "ssh cert connect failed" 90214979Sdes fi 91214979Sdes 92214979Sdes # authorized_principals with bad key option 93214979Sdes verbose "$tid: ${_prefix} authorized_principals bad key opt" 94214979Sdes echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER 95214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 96214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 97214979Sdes if [ $? -eq 0 ]; then 98214979Sdes fail "ssh cert connect succeeded unexpectedly" 99214979Sdes fi 100214979Sdes 101214979Sdes # authorized_principals with command=false 102214979Sdes verbose "$tid: ${_prefix} authorized_principals command=false" 103214979Sdes echo 'command="false" mekmitasdigoat' > \ 104214979Sdes $OBJ/authorized_principals_$USER 105214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 106214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 107214979Sdes if [ $? -eq 0 ]; then 108214979Sdes fail "ssh cert connect succeeded unexpectedly" 109214979Sdes fi 110214979Sdes 111214979Sdes 112214979Sdes # authorized_principals with command=true 113214979Sdes verbose "$tid: ${_prefix} authorized_principals command=true" 114214979Sdes echo 'command="true" mekmitasdigoat' > \ 115214979Sdes $OBJ/authorized_principals_$USER 116214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 117214979Sdes -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 118214979Sdes if [ $? -ne 0 ]; then 119214979Sdes fail "ssh cert connect failed" 120214979Sdes fi 121214979Sdes 122214979Sdes # Setup for principals= key option 123214979Sdes rm -f $OBJ/authorized_principals_$USER 124214979Sdes ( 125214979Sdes cat $OBJ/sshd_proxy_bak 126214979Sdes echo "UsePrivilegeSeparation $privsep" 127214979Sdes ) > $OBJ/sshd_proxy 128214979Sdes 129214979Sdes # Wrong principals list 130214979Sdes verbose "$tid: ${_prefix} wrong principals key option" 131214979Sdes ( 132255670Sdes printf 'cert-authority,principals="gregorsamsa" ' 133214979Sdes cat $OBJ/user_ca_key.pub 134214979Sdes ) > $OBJ/authorized_keys_$USER 135214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 136214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 137214979Sdes if [ $? -eq 0 ]; then 138214979Sdes fail "ssh cert connect succeeded unexpectedly" 139214979Sdes fi 140214979Sdes 141214979Sdes # Correct principals list 142214979Sdes verbose "$tid: ${_prefix} correct principals key option" 143214979Sdes ( 144255670Sdes printf 'cert-authority,principals="mekmitasdigoat" ' 145214979Sdes cat $OBJ/user_ca_key.pub 146214979Sdes ) > $OBJ/authorized_keys_$USER 147214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 148214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 149214979Sdes if [ $? -ne 0 ]; then 150214979Sdes fail "ssh cert connect failed" 151214979Sdes fi 152214979Sdes done 153214979Sdesdone 154214979Sdes 155204861Sdesbasic_tests() { 156204861Sdes auth=$1 157204861Sdes if test "x$auth" = "xauthorized_keys" ; then 158204861Sdes # Add CA to authorized_keys 159204861Sdes ( 160255670Sdes printf 'cert-authority ' 161204861Sdes cat $OBJ/user_ca_key.pub 162204861Sdes ) > $OBJ/authorized_keys_$USER 163204861Sdes else 164204861Sdes echo > $OBJ/authorized_keys_$USER 165204861Sdes extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" 166204861Sdes fi 167204861Sdes 168262566Sdes for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 169204861Sdes for privsep in yes no ; do 170204861Sdes _prefix="${ktype} privsep $privsep $auth" 171204861Sdes # Simple connect 172204861Sdes verbose "$tid: ${_prefix} connect" 173204861Sdes ( 174204861Sdes cat $OBJ/sshd_proxy_bak 175204861Sdes echo "UsePrivilegeSeparation $privsep" 176204861Sdes echo "$extra_sshd" 177204861Sdes ) > $OBJ/sshd_proxy 178204861Sdes 179204861Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 180204861Sdes -F $OBJ/ssh_proxy somehost true 181204861Sdes if [ $? -ne 0 ]; then 182204861Sdes fail "ssh cert connect failed" 183204861Sdes fi 184204861Sdes 185204861Sdes # Revoked keys 186204861Sdes verbose "$tid: ${_prefix} revoked key" 187204861Sdes ( 188204861Sdes cat $OBJ/sshd_proxy_bak 189204861Sdes echo "UsePrivilegeSeparation $privsep" 190248613Sdes echo "RevokedKeys $OBJ/cert_user_key_revoked" 191204861Sdes echo "$extra_sshd" 192204861Sdes ) > $OBJ/sshd_proxy 193248613Sdes cp $OBJ/cert_user_key_${ktype}.pub \ 194248613Sdes $OBJ/cert_user_key_revoked 195204861Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 196204861Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 197204861Sdes if [ $? -eq 0 ]; then 198204861Sdes fail "ssh cert connect succeeded unexpecedly" 199204861Sdes fi 200248613Sdes verbose "$tid: ${_prefix} revoked via KRL" 201248613Sdes rm $OBJ/cert_user_key_revoked 202248613Sdes ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ 203248613Sdes $OBJ/cert_user_key_${ktype}.pub 204248613Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 205248613Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 206248613Sdes if [ $? -eq 0 ]; then 207248613Sdes fail "ssh cert connect succeeded unexpecedly" 208248613Sdes fi 209248613Sdes verbose "$tid: ${_prefix} empty KRL" 210248613Sdes ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked 211248613Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 212248613Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 213248613Sdes if [ $? -ne 0 ]; then 214248613Sdes fail "ssh cert connect failed" 215248613Sdes fi 216204861Sdes done 217204861Sdes 218204861Sdes # Revoked CA 219204861Sdes verbose "$tid: ${ktype} $auth revoked CA key" 220204861Sdes ( 221204861Sdes cat $OBJ/sshd_proxy_bak 222204861Sdes echo "RevokedKeys $OBJ/user_ca_key.pub" 223204861Sdes echo "$extra_sshd" 224204861Sdes ) > $OBJ/sshd_proxy 225204861Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 226204861Sdes somehost true >/dev/null 2>&1 227204861Sdes if [ $? -eq 0 ]; then 228204861Sdes fail "ssh cert connect succeeded unexpecedly" 229204861Sdes fi 230204861Sdes done 231204861Sdes 232204861Sdes verbose "$tid: $auth CA does not authenticate" 233204861Sdes ( 234204861Sdes cat $OBJ/sshd_proxy_bak 235204861Sdes echo "$extra_sshd" 236204861Sdes ) > $OBJ/sshd_proxy 237204861Sdes verbose "$tid: ensure CA key does not authenticate user" 238204861Sdes ${SSH} -2i $OBJ/user_ca_key \ 239204861Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 240204861Sdes if [ $? -eq 0 ]; then 241204861Sdes fail "ssh cert connect with CA key succeeded unexpectedly" 242204861Sdes fi 243204861Sdes} 244204861Sdes 245204861Sdesbasic_tests authorized_keys 246204861Sdesbasic_tests TrustedUserCAKeys 247204861Sdes 248204861Sdestest_one() { 249204861Sdes ident=$1 250204861Sdes result=$2 251204861Sdes sign_opts=$3 252204861Sdes auth_choice=$4 253214979Sdes auth_opt=$5 254204861Sdes 255204861Sdes if test "x$auth_choice" = "x" ; then 256204861Sdes auth_choice="authorized_keys TrustedUserCAKeys" 257204861Sdes fi 258204861Sdes 259204861Sdes for auth in $auth_choice ; do 260214979Sdes for ktype in rsa rsa_v00 ; do 261218767Sdes case $ktype in 262218767Sdes *_v00) keyv="-t v00" ;; 263218767Sdes *) keyv="" ;; 264218767Sdes esac 265218767Sdes 266214979Sdes cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 267214979Sdes if test "x$auth" = "xauthorized_keys" ; then 268214979Sdes # Add CA to authorized_keys 269214979Sdes ( 270255670Sdes printf "cert-authority${auth_opt} " 271214979Sdes cat $OBJ/user_ca_key.pub 272214979Sdes ) > $OBJ/authorized_keys_$USER 273214979Sdes else 274214979Sdes echo > $OBJ/authorized_keys_$USER 275214979Sdes echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ 276214979Sdes >> $OBJ/sshd_proxy 277214979Sdes if test "x$auth_opt" != "x" ; then 278214979Sdes echo $auth_opt >> $OBJ/sshd_proxy 279214979Sdes fi 280214979Sdes fi 281214979Sdes 282214979Sdes verbose "$tid: $ident auth $auth expect $result $ktype" 283214979Sdes ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ 284214979Sdes -I "regress user key for $USER" \ 285218767Sdes $sign_opts $keyv \ 286214979Sdes $OBJ/cert_user_key_${ktype} || 287214979Sdes fail "couldn't sign cert_user_key_${ktype}" 288204861Sdes 289214979Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 290214979Sdes -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 291214979Sdes rc=$? 292214979Sdes if [ "x$result" = "xsuccess" ] ; then 293214979Sdes if [ $rc -ne 0 ]; then 294214979Sdes fail "$ident failed unexpectedly" 295214979Sdes fi 296214979Sdes else 297214979Sdes if [ $rc -eq 0 ]; then 298214979Sdes fail "$ident succeeded unexpectedly" 299214979Sdes fi 300204861Sdes fi 301214979Sdes done 302204861Sdes done 303204861Sdes} 304204861Sdes 305204861Sdestest_one "correct principal" success "-n ${USER}" 306204861Sdestest_one "host-certificate" failure "-n ${USER} -h" 307204861Sdestest_one "wrong principals" failure "-n foo" 308204861Sdestest_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" 309204861Sdestest_one "cert expired" failure "-n ${USER} -V19800101:19900101" 310204861Sdestest_one "cert valid interval" success "-n ${USER} -V-1w:+2w" 311204861Sdestest_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" 312204861Sdestest_one "force-command" failure "-n ${USER} -Oforce-command=false" 313204861Sdes 314204861Sdes# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals 315204861Sdestest_one "empty principals" success "" authorized_keys 316204861Sdestest_one "empty principals" failure "" TrustedUserCAKeys 317204861Sdes 318214979Sdes# Check explicitly-specified principals: an empty principals list in the cert 319214979Sdes# should always be refused. 320214979Sdes 321214979Sdes# AuthorizedPrincipalsFile 322214979Sdesrm -f $OBJ/authorized_keys_$USER 323214979Sdesecho mekmitasdigoat > $OBJ/authorized_principals_$USER 324214979Sdestest_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ 325214979Sdes TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 326214979Sdestest_one "AuthorizedPrincipalsFile no principals" failure "" \ 327214979Sdes TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 328214979Sdes 329214979Sdes# principals= key option 330214979Sdesrm -f $OBJ/authorized_principals_$USER 331214979Sdestest_one "principals key option principals" success "-n mekmitasdigoat" \ 332214979Sdes authorized_keys ',principals="mekmitasdigoat"' 333214979Sdestest_one "principals key option no principals" failure "" \ 334214979Sdes authorized_keys ',principals="mekmitasdigoat"' 335214979Sdes 336204861Sdes# Wrong certificate 337214979Sdescat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 338262566Sdesfor ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do 339214979Sdes case $ktype in 340214979Sdes *_v00) args="-t v00" ;; 341214979Sdes *) args="" ;; 342214979Sdes esac 343204861Sdes # Self-sign 344214979Sdes ${SSHKEYGEN} $args -q -s $OBJ/cert_user_key_${ktype} -I \ 345204861Sdes "regress user key for $USER" \ 346204861Sdes -n $USER $OBJ/cert_user_key_${ktype} || 347204861Sdes fail "couldn't sign cert_user_key_${ktype}" 348204861Sdes verbose "$tid: user ${ktype} connect wrong cert" 349204861Sdes ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 350204861Sdes somehost true >/dev/null 2>&1 351204861Sdes if [ $? -eq 0 ]; then 352204861Sdes fail "ssh cert connect $ident succeeded unexpectedly" 353204861Sdes fi 354204861Sdesdone 355204861Sdes 356204861Sdesrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 357214979Sdesrm -f $OBJ/authorized_principals_$USER 358204861Sdes 359