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