limit-keytype.sh revision 1.7
1# $OpenBSD: limit-keytype.sh,v 1.7 2019/11/01 01:55:41 djm Exp $ 2# Placed in the Public Domain. 3 4tid="restrict pubkey type" 5 6rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* 7rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* 8 9mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig 10mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig 11 12ktype1=ed25519; ktype2=$ktype1; ktype3=$ktype1; ktype4=$ktype1 13for t in `${SSH} -Q key-plain | grep -v ^sk-`; do 14 case "$t" in 15 ssh-rsa) ktype2=rsa ;; 16 ecdsa*) ktype3=ecdsa ;; # unused 17 ssh-dss) ktype4=dsa ;; 18 esac 19done 20 21# Create a CA key 22${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_ca_key ||\ 23 fatal "ssh-keygen failed" 24 25# Make some keys and a certificate. 26${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_key1 || \ 27 fatal "ssh-keygen failed" 28${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key2 || \ 29 fatal "ssh-keygen failed" 30${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key3 || \ 31 fatal "ssh-keygen failed" 32${SSHKEYGEN} -q -N '' -t $ktype4 -f $OBJ/user_key4 || \ 33 fatal "ssh-keygen failed" 34${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ 35 -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || 36 fatal "couldn't sign user_key1" 37# Copy the private key alongside the cert to allow better control of when 38# it is offered. 39mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub 40 41grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy 42 43opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" 44certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub" 45 46echo mekmitasdigoat > $OBJ/authorized_principals_$USER 47cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER 48cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER 49 50prepare_config() { 51 ( 52 grep -v "Protocol" $OBJ/sshd_proxy.orig 53 echo "Protocol 2" 54 echo "AuthenticationMethods publickey" 55 echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" 56 echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 57 for x in "$@" ; do 58 echo "$x" 59 done 60 ) > $OBJ/sshd_proxy 61} 62 63# Return the required parameter for PubkeyAcceptedKeyTypes corresponding to 64# the supplied key type. 65keytype() { 66 case "$1" in 67 ecdsa) printf "ecdsa-sha2-*" ;; 68 ed25519) printf "ssh-ed25519" ;; 69 dsa) printf "ssh-dss" ;; 70 rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;; 71 esac 72} 73 74prepare_config 75 76# Check we can log in with all key types. 77${SSH} $certopts proxy true || fatal "cert failed" 78${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 79${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 80 81# Allow plain Ed25519 and RSA. The certificate should fail. 82verbose "allow $ktype2,$ktype1" 83prepare_config \ 84 "PubkeyAcceptedKeyTypes `keytype $ktype2`,`keytype $ktype1`" 85${SSH} $certopts proxy true && fatal "cert succeeded" 86${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 87${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 88 89# Allow Ed25519 only. 90verbose "allow $ktype1" 91prepare_config "PubkeyAcceptedKeyTypes `keytype $ktype1`" 92${SSH} $certopts proxy true && fatal "cert succeeded" 93${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 94if [ "$ktype1" != "$ktype2" ]; then 95 ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" 96fi 97 98# Allow all certs. Plain keys should fail. 99verbose "allow cert only" 100prepare_config "PubkeyAcceptedKeyTypes *-cert-v01@openssh.com" 101${SSH} $certopts proxy true || fatal "cert failed" 102${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" 103${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" 104 105# Allow RSA in main config, Ed25519 for non-existent user. 106verbose "match w/ no match" 107prepare_config "PubkeyAcceptedKeyTypes `keytype $ktype2`" \ 108 "Match user x$USER" "PubkeyAcceptedKeyTypes +`keytype $ktype1`" 109${SSH} $certopts proxy true && fatal "cert succeeded" 110if [ "$ktype1" != "$ktype2" ]; then 111 ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" 112fi 113${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 114 115# Allow only DSA in main config, Ed25519 for user. 116verbose "match w/ matching" 117prepare_config "PubkeyAcceptedKeyTypes `keytype $ktype4`" \ 118 "Match user $USER" "PubkeyAcceptedKeyTypes +`keytype $ktype1`" 119${SSH} $certopts proxy true || fatal "cert failed" 120${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 121${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded" 122 123