1*5bdc47d2Sdjm# $OpenBSD: limit-keytype.sh,v 1.10 2021/02/25 03:27:34 djm Exp $ 269cd3fa0Sdjm# Placed in the Public Domain. 369cd3fa0Sdjm 469cd3fa0Sdjmtid="restrict pubkey type" 569cd3fa0Sdjm 62a103fdeSdjm# XXX sk-* keys aren't actually tested ATM. 72a103fdeSdjm 869cd3fa0Sdjmrm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* 969cd3fa0Sdjmrm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* 1069cd3fa0Sdjm 1169cd3fa0Sdjmmv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig 1269cd3fa0Sdjmmv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig 1369cd3fa0Sdjm 142a103fdeSdjmktype1=ed25519; ktype2=ed25519; ktype3=ed25519; 152a103fdeSdjmktype4=ed25519; ktype5=ed25519; ktype6=ed25519; 16364308ccSdjmfor t in $SSH_KEYTYPES ; do 173bfb7743Sdtucker case "$t" in 183bfb7743Sdtucker ssh-rsa) ktype2=rsa ;; 193bfb7743Sdtucker ecdsa*) ktype3=ecdsa ;; # unused 203bfb7743Sdtucker ssh-dss) ktype4=dsa ;; 212a103fdeSdjm sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; 222a103fdeSdjm sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; 233bfb7743Sdtucker esac 243bfb7743Sdtuckerdone 253bfb7743Sdtucker 2669cd3fa0Sdjm# Create a CA key 273bfb7743Sdtucker${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_ca_key ||\ 2869cd3fa0Sdjm fatal "ssh-keygen failed" 2969cd3fa0Sdjm 3069cd3fa0Sdjm# Make some keys and a certificate. 313bfb7743Sdtucker${SSHKEYGEN} -q -N '' -t $ktype1 -f $OBJ/user_key1 || \ 3269cd3fa0Sdjm fatal "ssh-keygen failed" 333bfb7743Sdtucker${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key2 || \ 3469cd3fa0Sdjm fatal "ssh-keygen failed" 353bfb7743Sdtucker${SSHKEYGEN} -q -N '' -t $ktype2 -f $OBJ/user_key3 || \ 3669cd3fa0Sdjm fatal "ssh-keygen failed" 373bfb7743Sdtucker${SSHKEYGEN} -q -N '' -t $ktype4 -f $OBJ/user_key4 || \ 3887700296Sdjm fatal "ssh-keygen failed" 392a103fdeSdjm${SSHKEYGEN} -q -N '' -t $ktype5 -f $OBJ/user_key5 || \ 402a103fdeSdjm fatal "ssh-keygen failed" 412a103fdeSdjm${SSHKEYGEN} -q -N '' -t $ktype6 -f $OBJ/user_key6 || \ 422a103fdeSdjm fatal "ssh-keygen failed" 4369cd3fa0Sdjm${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ 4469cd3fa0Sdjm -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || 4569cd3fa0Sdjm fatal "couldn't sign user_key1" 4669cd3fa0Sdjm# Copy the private key alongside the cert to allow better control of when 4769cd3fa0Sdjm# it is offered. 4869cd3fa0Sdjmmv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub 4969cd3fa0Sdjm 5069cd3fa0Sdjmgrep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy 5169cd3fa0Sdjm 5269cd3fa0Sdjmopts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" 53640e545aSdjmcertopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub" 5469cd3fa0Sdjm 5569cd3fa0Sdjmecho mekmitasdigoat > $OBJ/authorized_principals_$USER 5669cd3fa0Sdjmcat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER 5769cd3fa0Sdjmcat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER 5869cd3fa0Sdjm 5969cd3fa0Sdjmprepare_config() { 6069cd3fa0Sdjm ( 6169cd3fa0Sdjm grep -v "Protocol" $OBJ/sshd_proxy.orig 6269cd3fa0Sdjm echo "Protocol 2" 6369cd3fa0Sdjm echo "AuthenticationMethods publickey" 6469cd3fa0Sdjm echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" 6569cd3fa0Sdjm echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" 6669cd3fa0Sdjm for x in "$@" ; do 6769cd3fa0Sdjm echo "$x" 6869cd3fa0Sdjm done 6969cd3fa0Sdjm ) > $OBJ/sshd_proxy 7069cd3fa0Sdjm} 7169cd3fa0Sdjm 72*5bdc47d2Sdjm# Return the required parameter for PubkeyAcceptedAlgorithms corresponding to 733bfb7743Sdtucker# the supplied key type. 743bfb7743Sdtuckerkeytype() { 753bfb7743Sdtucker case "$1" in 763bfb7743Sdtucker ecdsa) printf "ecdsa-sha2-*" ;; 773bfb7743Sdtucker ed25519) printf "ssh-ed25519" ;; 783bfb7743Sdtucker dsa) printf "ssh-dss" ;; 793bfb7743Sdtucker rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;; 802a103fdeSdjm sk-ecdsa) printf "sk-ecdsa-*" ;; 812a103fdeSdjm sk-ssh-ed25519) printf "sk-ssh-ed25519-*" ;; 823bfb7743Sdtucker esac 833bfb7743Sdtucker} 843bfb7743Sdtucker 8569cd3fa0Sdjmprepare_config 8669cd3fa0Sdjm 8769cd3fa0Sdjm# Check we can log in with all key types. 88640e545aSdjm${SSH} $certopts proxy true || fatal "cert failed" 8969cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 9069cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 9169cd3fa0Sdjm 9269cd3fa0Sdjm# Allow plain Ed25519 and RSA. The certificate should fail. 933bfb7743Sdtuckerverbose "allow $ktype2,$ktype1" 949df3914dSdjmprepare_config \ 95*5bdc47d2Sdjm "PubkeyAcceptedAlgorithms `keytype $ktype2`,`keytype $ktype1`" 96ab1578beSdtucker${SSH} $certopts proxy true && fatal "cert succeeded" 9769cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 9869cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 9969cd3fa0Sdjm 10069cd3fa0Sdjm# Allow Ed25519 only. 1013bfb7743Sdtuckerverbose "allow $ktype1" 102*5bdc47d2Sdjmprepare_config "PubkeyAcceptedAlgorithms `keytype $ktype1`" 103640e545aSdjm${SSH} $certopts proxy true && fatal "cert succeeded" 10469cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 1053bfb7743Sdtuckerif [ "$ktype1" != "$ktype2" ]; then 10669cd3fa0Sdjm ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" 1073bfb7743Sdtuckerfi 10869cd3fa0Sdjm 10969cd3fa0Sdjm# Allow all certs. Plain keys should fail. 110640e545aSdjmverbose "allow cert only" 111*5bdc47d2Sdjmprepare_config "PubkeyAcceptedAlgorithms *-cert-v01@openssh.com" 112640e545aSdjm${SSH} $certopts proxy true || fatal "cert failed" 11369cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" 11469cd3fa0Sdjm${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" 11569cd3fa0Sdjm 11687700296Sdjm# Allow RSA in main config, Ed25519 for non-existent user. 11787700296Sdjmverbose "match w/ no match" 118*5bdc47d2Sdjmprepare_config "PubkeyAcceptedAlgorithms `keytype $ktype2`" \ 119*5bdc47d2Sdjm "Match user x$USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`" 12087700296Sdjm${SSH} $certopts proxy true && fatal "cert succeeded" 1213bfb7743Sdtuckerif [ "$ktype1" != "$ktype2" ]; then 12287700296Sdjm ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" 1233bfb7743Sdtuckerfi 12487700296Sdjm${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" 12587700296Sdjm 12687700296Sdjm# Allow only DSA in main config, Ed25519 for user. 12787700296Sdjmverbose "match w/ matching" 128*5bdc47d2Sdjmprepare_config "PubkeyAcceptedAlgorithms `keytype $ktype4`" \ 129*5bdc47d2Sdjm "Match user $USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`" 13087700296Sdjm${SSH} $certopts proxy true || fatal "cert failed" 13187700296Sdjm${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" 13287700296Sdjm${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded" 13387700296Sdjm 134