limit-keytype.sh revision 1.6
1#	$OpenBSD: limit-keytype.sh,v 1.6 2019/07/26 04:22:21 dtucker 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`; 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