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