1# $OpenBSD: krl.sh,v 1.13 2025/05/06 06:05:48 djm Exp $ 2# Placed in the Public Domain. 3 4tid="key revocation lists" 5 6# Use ed25519 by default since it's fast and it's supported when building 7# w/out OpenSSL. Populate ktype[2-4] with the other types if supported. 8ktype1=ed25519; ktype2=ed25519; ktype3=ed25519; 9ktype4=ed25519; ktype5=ed25519; ktype6=ed25519; 10for t in $SSH_KEYTYPES; do 11 case "$t" in 12 ecdsa*) ktype2=ecdsa ;; 13 ssh-rsa) ktype3=rsa ;; 14 sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; 15 sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; 16 esac 17done 18 19# Do most testing with ssh-keygen; it uses the same verification code as sshd. 20 21# Old keys will interfere with ssh-keygen. 22rm -f $OBJ/revoked-* $OBJ/krl-* 23 24# Generate a CA key 25$SSHKEYGEN -t $ktype1 -f $OBJ/revoked-ca -C "" -N "" > /dev/null || 26 fatal "$SSHKEYGEN CA failed" 27$SSHKEYGEN -t $ktype2 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || 28 fatal "$SSHKEYGEN CA2 failed" 29 30# A specification that revokes some certificates by serial numbers 31# The serial pattern is chosen to ensure the KRL includes list, range and 32# bitmap sections. 33cat << EOF >> $OBJ/revoked-serials 34serial: 1-4 35serial: 10 36serial: 15 37serial: 30 38serial: 50 39serial: 90 40serial: 999 41# The following sum to 500-799 42serial: 500 43serial: 501 44serial: 502 45serial: 503-600 46serial: 700-797 47serial: 798 48serial: 799 49serial: 599-701 50# Some multiple consecutive serial number ranges 51serial: 10000-20000 52serial: 30000-40000 53EOF 54 55# A specification that revokes some certificated by key ID. 56touch $OBJ/revoked-keyid 57for n in 1 2 3 4 10 15 30 50 90 `jot 500 300` 999 1000 1001 1002; do 58 test "x$n" = "x499" && continue 59 # Fill in by-ID revocation spec. 60 echo "id: revoked $n" >> $OBJ/revoked-keyid 61done 62 63keygen() { 64 N=$1 65 f=$OBJ/revoked-`printf "%04d" $N` 66 # Vary the keytype. We use mostly ed25519 since this is fast and well 67 # supported. 68 keytype=$ktype1 69 case $N in 70 2 | 10 | 510 | 1001) keytype=$ktype2 ;; 71 4 | 30 | 520 | 1002) keytype=$ktype3 ;; 72 8 | 50 | 530 | 1003) keytype=$ktype4 ;; 73 16 | 70 | 540 | 1004) keytype=$ktype5 ;; 74 32 | 90 | 550 | 1005) keytype=$ktype6 ;; 75 esac 76 $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ 77 || fatal "$SSHKEYGEN failed" 78 # Sign cert 79 $SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \ 80 || fatal "$SSHKEYGEN sign failed" 81 echo $f 82} 83 84# Generate some keys. 85verbose "$tid: generating test keys" 86REVOKED_SERIALS="1 4 10 50 90 500 510 520 550 799 999" 87for n in $REVOKED_SERIALS ; do 88 f=`keygen $n` 89 RKEYS="$RKEYS ${f}.pub" 90 RCERTS="$RCERTS ${f}-cert.pub" 91done 92UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" 93UNREVOKED="" 94for n in $UNREVOKED_SERIALS ; do 95 f=`keygen $n` 96 UKEYS="$UKEYS ${f}.pub" 97 UCERTS="$UCERTS ${f}-cert.pub" 98done 99 100# Specifications that revoke keys by hash. 101touch $OBJ/revoked-sha1 $OBJ/revoked-sha256 $OBJ/revoked-hash 102for rkey in $RKEYS; do 103 (printf "sha1: "; cat $rkey) >> $OBJ/revoked-sha1 104 (printf "sha256: "; cat $rkey) >> $OBJ/revoked-sha256 105 (printf "hash: "; $SSHKEYGEN -lf $rkey | \ 106 awk '{ print $2 }') >> $OBJ/revoked-hash 107done 108 109genkrls() { 110 OPTS=$1 111$SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \ 112 >/dev/null || fatal "$SSHKEYGEN KRL failed" 113$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ 114 >/dev/null || fatal "$SSHKEYGEN KRL failed" 115$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ 116 >/dev/null || fatal "$SSHKEYGEN KRL failed" 117$SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ 118 >/dev/null || fatal "$SSHKEYGEN KRL failed" 119$SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ 120 >/dev/null || fatal "$SSHKEYGEN KRL failed" 121$SSHKEYGEN $OPTS -kf $OBJ/krl-sha1 $OBJ/revoked-sha1 \ 122 >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 123$SSHKEYGEN $OPTS -kf $OBJ/krl-sha256 $OBJ/revoked-sha256 \ 124 >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 125$SSHKEYGEN $OPTS -kf $OBJ/krl-hash $OBJ/revoked-hash \ 126 >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 127# This should fail as KRLs from serial/key-id spec need the CA specified. 128$SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ 129 >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" 130$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ 131 >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" 132# These should succeed; they specify an explicit CA key. 133$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ 134 $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" 135$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ 136 $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" 137# These should succeed; they specify an wildcard CA key. 138$SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ 139 >/dev/null || fatal "$SSHKEYGEN KRL failed" 140$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ 141 >/dev/null || fatal "$SSHKEYGEN KRL failed" 142# Revoke the same serials with the second CA key to ensure a multi-CA 143# KRL is generated. 144$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ 145 $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" 146} 147 148## XXX dump with trace and grep for set cert serials 149## XXX test ranges near (u64)-1, etc. 150 151verbose "$tid: generating KRLs" 152genkrls 153 154check_krl() { 155 KEY=$1 156 KRL=$2 157 EXPECT_REVOKED=$3 158 TAG=$4 159 $SSHKEYGEN -Qf $KRL $KEY >/dev/null 160 result=$? 161 if test "x$EXPECT_REVOKED" = "xy" -a $result -eq 0 ; then 162 fatal "key $KEY not revoked by KRL $KRL: $TAG" 163 elif test "x$EXPECT_REVOKED" = "xn" -a $result -ne 0 ; then 164 fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" 165 fi 166} 167test_rev() { 168 FILES=$1 169 TAG=$2 170 KEYS_RESULT=$3 171 ALL_RESULT=$4 172 HASH_RESULT=$5 173 SERIAL_RESULT=$6 174 KEYID_RESULT=$7 175 CERTS_RESULT=$8 176 CA_RESULT=$9 177 SERIAL_WRESULT=${10} 178 KEYID_WRESULT=${11} 179 verbose "$tid: checking revocations for $TAG" 180 for f in $FILES ; do 181 check_krl $f $OBJ/krl-empty no "$TAG" 182 check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" 183 check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" 184 check_krl $f $OBJ/krl-sha1 $HASH_RESULT "$TAG" 185 check_krl $f $OBJ/krl-sha256 $HASH_RESULT "$TAG" 186 check_krl $f $OBJ/krl-hash $HASH_RESULT "$TAG" 187 check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" 188 check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" 189 check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" 190 check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" 191 check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" 192 check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" 193 done 194} 195 196test_all() { 197 # wildcard 198 # keys all hash sr# ID cert CA srl ID 199 test_rev "$RKEYS" "revoked keys" y y y n n n n n n 200 test_rev "$UKEYS" "unrevoked keys" n n n n n n n n n 201 test_rev "$RCERTS" "revoked certs" y y y y y y y y y 202 test_rev "$UCERTS" "unrevoked certs" n n n n n n y n n 203} 204 205test_all 206 207# Check update. Results should be identical. 208verbose "$tid: testing KRL update" 209for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ 210 $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ 211 $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do 212 cp -f $OBJ/krl-empty $f 213 genkrls -u 214done 215 216test_all 217