118316Swollman# $OpenBSD: cert-userkey.sh,v 1.16 2016/05/03 12:15:49 dtucker Exp $ 218316Swollman# Placed in the Public Domain. 318316Swollman 418316Swollmantid="certified user keys" 518316Swollman 618316Swollmanrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 718316Swollmancp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 818316Swollmancp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak 918316Swollman 1018316SwollmanPLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` 1118316Swollman 1218316Swollmanif echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then 1318316Swollman PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" 1418316Swollmanfi 1518316Swollman 1618316Swollmankname() { 1718316Swollman case $ktype in 1818316Swollman rsa-sha2-*) ;; 1918316Swollman # subshell because some seds will add a newline 2018316Swollman *) n=$(echo $1 | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; 2118316Swollman esac 2218316Swollman echo "$n*,ssh-rsa*,ssh-ed25519*" 2318316Swollman} 2418316Swollman 2518316Swollman# Create a CA key 2618316Swollman${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ 2718316Swollman fail "ssh-keygen of user_ca_key failed" 2846303Smarkm 2950476Speter# Generate and sign user keys 3018316Swollmanfor ktype in $PLAIN_TYPES $EXTRA_TYPES ; do 3118316Swollman verbose "$tid: sign user ${ktype} cert" 3218316Swollman ${SSHKEYGEN} -q -N '' -t ${ktype} \ 3318316Swollman -f $OBJ/cert_user_key_${ktype} || \ 3418316Swollman fatal "ssh-keygen of cert_user_key_${ktype} failed" 3518316Swollman # Generate RSA/SHA2 certs for rsa-sha2* keys. 3646303Smarkm case $ktype in 3718316Swollman rsa-sha2-*) tflag="-t $ktype" ;; 3818316Swollman *) tflag="" ;; 39126250Sbms esac 4046303Smarkm ${SSHKEYGEN} -q -s $OBJ/user_ca_key -z $$ \ 41126250Sbms -I "regress user key for $USER" \ 42126250Sbms -n ${USER},mekmitasdigoat $tflag $OBJ/cert_user_key_${ktype} || \ 43126250Sbms fatal "couldn't sign cert_user_key_${ktype}" 44126250Sbmsdone 45126250Sbms 4646303Smarkm# Test explicitly-specified principals 4746303Smarkmfor ktype in $EXTRA_TYPES $PLAIN_TYPES ; do 4846303Smarkm t=$(kname $ktype) 4918316Swollman for privsep in yes no ; do 50102231Strhodes _prefix="${ktype} privsep $privsep" 5118316Swollman 5218316Swollman # Setup for AuthorizedPrincipalsFile 5318316Swollman rm -f $OBJ/authorized_keys_$USER 5418316Swollman ( 5518316Swollman cat $OBJ/sshd_proxy_bak 5620339Swollman echo "UsePrivilegeSeparation $privsep" 5781604Speter echo "AuthorizedPrincipalsFile " \ 5846303Smarkm "$OBJ/authorized_principals_%u" 59118582Simp echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" 60118582Simp echo "PubkeyAcceptedKeyTypes ${t}" 6120339Swollman ) > $OBJ/sshd_proxy 6218316Swollman ( 6318316Swollman cat $OBJ/ssh_proxy_bak 6446303Smarkm echo "PubkeyAcceptedKeyTypes ${t}" 6518316Swollman ) > $OBJ/ssh_proxy 6618316Swollman 6719880Swollman # Missing authorized_principals 6819880Swollman verbose "$tid: ${_prefix} missing authorized_principals" 6919880Swollman rm -f $OBJ/authorized_principals_$USER 7019880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 7119880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 7219880Swollman if [ $? -eq 0 ]; then 7319880Swollman fail "ssh cert connect succeeded unexpectedly" 7419880Swollman fi 7519880Swollman 7619880Swollman # Empty authorized_principals 7719880Swollman verbose "$tid: ${_prefix} empty authorized_principals" 7819880Swollman echo > $OBJ/authorized_principals_$USER 7919880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 8019880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 8119880Swollman if [ $? -eq 0 ]; then 8219880Swollman fail "ssh cert connect succeeded unexpectedly" 8319880Swollman fi 8419880Swollman 8519880Swollman # Wrong authorized_principals 8619880Swollman verbose "$tid: ${_prefix} wrong authorized_principals" 8719880Swollman echo gregorsamsa > $OBJ/authorized_principals_$USER 8819880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 8919880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 9019880Swollman if [ $? -eq 0 ]; then 9119880Swollman fail "ssh cert connect succeeded unexpectedly" 9219880Swollman fi 9319880Swollman 9419880Swollman # Correct authorized_principals 9519880Swollman verbose "$tid: ${_prefix} correct authorized_principals" 9619880Swollman echo mekmitasdigoat > $OBJ/authorized_principals_$USER 9719880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 9819880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 9919880Swollman if [ $? -ne 0 ]; then 10019880Swollman fail "ssh cert connect failed" 10119880Swollman fi 10219880Swollman 10319880Swollman # authorized_principals with bad key option 10419880Swollman verbose "$tid: ${_prefix} authorized_principals bad key opt" 10519880Swollman echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER 10619880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 10719880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 10819880Swollman if [ $? -eq 0 ]; then 10919880Swollman fail "ssh cert connect succeeded unexpectedly" 11019880Swollman fi 11119880Swollman 11219880Swollman # authorized_principals with command=false 11319880Swollman verbose "$tid: ${_prefix} authorized_principals command=false" 11419880Swollman echo 'command="false" mekmitasdigoat' > \ 11519880Swollman $OBJ/authorized_principals_$USER 11619880Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 11719880Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 11819880Swollman if [ $? -eq 0 ]; then 11919880Swollman fail "ssh cert connect succeeded unexpectedly" 12018316Swollman fi 12118316Swollman 12218316Swollman 12318316Swollman # authorized_principals with command=true 12418316Swollman verbose "$tid: ${_prefix} authorized_principals command=true" 12518316Swollman echo 'command="true" mekmitasdigoat' > \ 12618316Swollman $OBJ/authorized_principals_$USER 12718316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 12818316Swollman -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 12918316Swollman if [ $? -ne 0 ]; then 13018316Swollman fail "ssh cert connect failed" 13118316Swollman fi 13218316Swollman 13318316Swollman # Setup for principals= key option 13418316Swollman rm -f $OBJ/authorized_principals_$USER 13518316Swollman ( 13618316Swollman cat $OBJ/sshd_proxy_bak 13718316Swollman echo "UsePrivilegeSeparation $privsep" 13818316Swollman echo "PubkeyAcceptedKeyTypes ${t}" 13918316Swollman ) > $OBJ/sshd_proxy 14018316Swollman ( 14146303Smarkm cat $OBJ/ssh_proxy_bak 14218316Swollman echo "PubkeyAcceptedKeyTypes ${t}" 14318316Swollman ) > $OBJ/ssh_proxy 14418316Swollman 14518316Swollman # Wrong principals list 14618316Swollman verbose "$tid: ${_prefix} wrong principals key option" 14718316Swollman ( 14818316Swollman printf 'cert-authority,principals="gregorsamsa" ' 14918316Swollman cat $OBJ/user_ca_key.pub 15018316Swollman ) > $OBJ/authorized_keys_$USER 15118316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 15218316Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 15318316Swollman if [ $? -eq 0 ]; then 15418316Swollman fail "ssh cert connect succeeded unexpectedly" 15518316Swollman fi 15646303Smarkm 15718316Swollman # Correct principals list 15818316Swollman verbose "$tid: ${_prefix} correct principals key option" 15918316Swollman ( 16018316Swollman printf 'cert-authority,principals="mekmitasdigoat" ' 16118316Swollman cat $OBJ/user_ca_key.pub 16218316Swollman ) > $OBJ/authorized_keys_$USER 16318316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 16418316Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 16518316Swollman if [ $? -ne 0 ]; then 16618316Swollman fail "ssh cert connect failed" 16720339Swollman fi 16820339Swollman done 16918316Swollmandone 17018316Swollman 17118316Swollmanbasic_tests() { 17220339Swollman auth=$1 17320339Swollman if test "x$auth" = "xauthorized_keys" ; then 17418316Swollman # Add CA to authorized_keys 17520339Swollman ( 17618316Swollman printf 'cert-authority ' 17718316Swollman cat $OBJ/user_ca_key.pub 17818316Swollman ) > $OBJ/authorized_keys_$USER 17918316Swollman else 18018316Swollman echo > $OBJ/authorized_keys_$USER 18146303Smarkm extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" 18218316Swollman fi 18318316Swollman 18418316Swollman for ktype in $PLAIN_TYPES ; do 18518316Swollman t=$(kname $ktype) 18618316Swollman for privsep in yes no ; do 18718316Swollman _prefix="${ktype} privsep $privsep $auth" 18818316Swollman # Simple connect 189126250Sbms verbose "$tid: ${_prefix} connect" 19046303Smarkm ( 19118316Swollman cat $OBJ/sshd_proxy_bak 19218316Swollman echo "UsePrivilegeSeparation $privsep" 19318316Swollman echo "PubkeyAcceptedKeyTypes ${t}" 19418316Swollman echo "$extra_sshd" 19518316Swollman ) > $OBJ/sshd_proxy 19646303Smarkm ( 19746303Smarkm cat $OBJ/ssh_proxy_bak 19818316Swollman echo "PubkeyAcceptedKeyTypes ${t}" 19918316Swollman ) > $OBJ/ssh_proxy 20018316Swollman 20118316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 20218316Swollman -F $OBJ/ssh_proxy somehost true 20318316Swollman if [ $? -ne 0 ]; then 20418316Swollman fail "ssh cert connect failed" 20546303Smarkm fi 20620339Swollman 20720339Swollman # Revoked keys 20820339Swollman verbose "$tid: ${_prefix} revoked key" 20918316Swollman ( 21046303Smarkm cat $OBJ/sshd_proxy_bak 21146303Smarkm echo "UsePrivilegeSeparation $privsep" 21246303Smarkm echo "RevokedKeys $OBJ/cert_user_key_revoked" 21346303Smarkm echo "PubkeyAcceptedKeyTypes ${t}" 21446303Smarkm echo "$extra_sshd" 21546303Smarkm ) > $OBJ/sshd_proxy 21618316Swollman cp $OBJ/cert_user_key_${ktype}.pub \ 21718316Swollman $OBJ/cert_user_key_revoked 21820339Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 21918316Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 22018316Swollman if [ $? -eq 0 ]; then 22118316Swollman fail "ssh cert connect succeeded unexpecedly" 22218316Swollman fi 22318316Swollman verbose "$tid: ${_prefix} revoked via KRL" 22418316Swollman rm $OBJ/cert_user_key_revoked 22518316Swollman ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ 22618316Swollman $OBJ/cert_user_key_${ktype}.pub 22718316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 22846303Smarkm -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 22918316Swollman if [ $? -eq 0 ]; then 23018316Swollman fail "ssh cert connect succeeded unexpecedly" 23118316Swollman fi 23218316Swollman verbose "$tid: ${_prefix} empty KRL" 23318316Swollman ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked 23446303Smarkm ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 23518316Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 23618316Swollman if [ $? -ne 0 ]; then 23718316Swollman fail "ssh cert connect failed" 23818316Swollman fi 23918316Swollman done 24018316Swollman 24118316Swollman # Revoked CA 24218316Swollman verbose "$tid: ${ktype} $auth revoked CA key" 243126250Sbms ( 24446303Smarkm cat $OBJ/sshd_proxy_bak 24518316Swollman echo "RevokedKeys $OBJ/user_ca_key.pub" 24646303Smarkm echo "PubkeyAcceptedKeyTypes ${t}" 24718316Swollman echo "$extra_sshd" 24818316Swollman ) > $OBJ/sshd_proxy 24918316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 25018316Swollman somehost true >/dev/null 2>&1 25118316Swollman if [ $? -eq 0 ]; then 25220339Swollman fail "ssh cert connect succeeded unexpecedly" 25320339Swollman fi 25418316Swollman done 25546303Smarkm 25620339Swollman verbose "$tid: $auth CA does not authenticate" 25718316Swollman ( 25846303Smarkm cat $OBJ/sshd_proxy_bak 25920339Swollman echo "PubkeyAcceptedKeyTypes ${t}" 26020339Swollman echo "$extra_sshd" 26120339Swollman ) > $OBJ/sshd_proxy 26220339Swollman verbose "$tid: ensure CA key does not authenticate user" 26320339Swollman ${SSH} -2i $OBJ/user_ca_key \ 26446303Smarkm -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 26520339Swollman if [ $? -eq 0 ]; then 26620339Swollman fail "ssh cert connect with CA key succeeded unexpectedly" 26720339Swollman fi 26820339Swollman} 26920339Swollman 27020339Swollmanbasic_tests authorized_keys 27120339Swollmanbasic_tests TrustedUserCAKeys 27220339Swollman 27320339Swollmantest_one() { 27420339Swollman ident=$1 27520339Swollman result=$2 27620339Swollman sign_opts=$3 27720339Swollman auth_choice=$4 27820339Swollman auth_opt=$5 27920339Swollman 28020339Swollman if test "x$auth_choice" = "x" ; then 28120339Swollman auth_choice="authorized_keys TrustedUserCAKeys" 28220339Swollman fi 28320339Swollman 28420339Swollman for auth in $auth_choice ; do 28520339Swollman for ktype in rsa ed25519 ; do 28620339Swollman cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 28720339Swollman if test "x$auth" = "xauthorized_keys" ; then 28820339Swollman # Add CA to authorized_keys 28920339Swollman ( 29020339Swollman printf "cert-authority${auth_opt} " 29120339Swollman cat $OBJ/user_ca_key.pub 29220339Swollman ) > $OBJ/authorized_keys_$USER 29320339Swollman else 29420339Swollman echo > $OBJ/authorized_keys_$USER 29520339Swollman echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ 29620339Swollman >> $OBJ/sshd_proxy 29720339Swollman echo "PubkeyAcceptedKeyTypes ${t}*" \ 29820339Swollman >> $OBJ/sshd_proxy 29946303Smarkm if test "x$auth_opt" != "x" ; then 30046303Smarkm echo $auth_opt >> $OBJ/sshd_proxy 30120339Swollman fi 30220339Swollman fi 30318316Swollman 30418316Swollman verbose "$tid: $ident auth $auth expect $result $ktype" 30546303Smarkm ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ 30618316Swollman -I "regress user key for $USER" \ 30718316Swollman $sign_opts $OBJ/cert_user_key_${ktype} || 30820339Swollman fail "couldn't sign cert_user_key_${ktype}" 30920339Swollman 31020339Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 31118316Swollman -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 31220339Swollman rc=$? 31320339Swollman if [ "x$result" = "xsuccess" ] ; then 31420339Swollman if [ $rc -ne 0 ]; then 31520339Swollman fail "$ident failed unexpectedly" 31620339Swollman fi 31720339Swollman else 31820339Swollman if [ $rc -eq 0 ]; then 31920339Swollman fail "$ident succeeded unexpectedly" 32020339Swollman fi 32120339Swollman fi 32218316Swollman done 32318316Swollman done 32418316Swollman} 32518316Swollman 32618316Swollmantest_one "correct principal" success "-n ${USER}" 32718316Swollmantest_one "host-certificate" failure "-n ${USER} -h" 32818316Swollmantest_one "wrong principals" failure "-n foo" 32920339Swollmantest_one "cert not yet valid" failure "-n ${USER} -V20200101:20300101" 33020339Swollmantest_one "cert expired" failure "-n ${USER} -V19800101:19900101" 33120339Swollmantest_one "cert valid interval" success "-n ${USER} -V-1w:+2w" 33220339Swollmantest_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" 33320339Swollmantest_one "force-command" failure "-n ${USER} -Oforce-command=false" 33420339Swollman 33520339Swollman# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals 33620339Swollmantest_one "empty principals" success "" authorized_keys 33720339Swollmantest_one "empty principals" failure "" TrustedUserCAKeys 33820339Swollman 33920339Swollman# Check explicitly-specified principals: an empty principals list in the cert 34020339Swollman# should always be refused. 34120339Swollman 34220339Swollman# AuthorizedPrincipalsFile 34320339Swollmanrm -f $OBJ/authorized_keys_$USER 34420339Swollmanecho mekmitasdigoat > $OBJ/authorized_principals_$USER 34520339Swollmantest_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ 34620339Swollman TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 34746303Smarkmtest_one "AuthorizedPrincipalsFile no principals" failure "" \ 34818316Swollman TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 34918316Swollman 35018316Swollman# principals= key option 35118316Swollmanrm -f $OBJ/authorized_principals_$USER 35218316Swollmantest_one "principals key option principals" success "-n mekmitasdigoat" \ 35320339Swollman authorized_keys ',principals="mekmitasdigoat"' 35420339Swollmantest_one "principals key option no principals" failure "" \ 35520339Swollman authorized_keys ',principals="mekmitasdigoat"' 35620339Swollman 35720339Swollman# Wrong certificate 35820339Swollmancat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy 35920339Swollmanfor ktype in $PLAIN_TYPES ; do 36020339Swollman t=$(kname $ktype) 36120339Swollman # Self-sign 36220339Swollman ${SSHKEYGEN} -q -s $OBJ/cert_user_key_${ktype} -I \ 36318316Swollman "regress user key for $USER" \ 36418316Swollman -n $USER $OBJ/cert_user_key_${ktype} || 36518316Swollman fatal "couldn't sign cert_user_key_${ktype}" 36646303Smarkm verbose "$tid: user ${ktype} connect wrong cert" 36718316Swollman ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 36846303Smarkm somehost true >/dev/null 2>&1 36918316Swollman if [ $? -eq 0 ]; then 37020339Swollman fail "ssh cert connect $ident succeeded unexpectedly" 37120339Swollman fi 37220339Swollmandone 37318316Swollman 37420339Swollmanrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* 37520339Swollmanrm -f $OBJ/authorized_principals_$USER 37620339Swollman 37720339Swollman