1*c0aad570Sdjm# $OpenBSD: krl.sh,v 1.12 2023/01/16 04:11:29 djm Exp $ 241c5d6efSdjm# Placed in the Public Domain. 341c5d6efSdjm 441c5d6efSdjmtid="key revocation lists" 541c5d6efSdjm 683c77e6eSdtucker# Use ed25519 by default since it's fast and it's supported when building 783c77e6eSdtucker# w/out OpenSSL. Populate ktype[2-4] with the other types if supported. 82a103fdeSdjmktype1=ed25519; ktype2=ed25519; ktype3=ed25519; 92a103fdeSdjmktype4=ed25519; ktype5=ed25519; ktype6=ed25519; 10364308ccSdjmfor t in $SSH_KEYTYPES; do 1183c77e6eSdtucker case "$t" in 1283c77e6eSdtucker ecdsa*) ktype2=ecdsa ;; 1383c77e6eSdtucker ssh-rsa) ktype3=rsa ;; 1483c77e6eSdtucker ssh-dss) ktype4=dsa ;; 152a103fdeSdjm sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; 162a103fdeSdjm sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; 1783c77e6eSdtucker esac 1883c77e6eSdtuckerdone 1983c77e6eSdtucker 2041c5d6efSdjm# Do most testing with ssh-keygen; it uses the same verification code as sshd. 2141c5d6efSdjm 2241c5d6efSdjm# Old keys will interfere with ssh-keygen. 2341c5d6efSdjmrm -f $OBJ/revoked-* $OBJ/krl-* 2441c5d6efSdjm 2541c5d6efSdjm# Generate a CA key 2683c77e6eSdtucker$SSHKEYGEN -t $ktype1 -f $OBJ/revoked-ca -C "" -N "" > /dev/null || 2741c5d6efSdjm fatal "$SSHKEYGEN CA failed" 2883c77e6eSdtucker$SSHKEYGEN -t $ktype2 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || 29db70674bSdjm fatal "$SSHKEYGEN CA2 failed" 3041c5d6efSdjm 3141c5d6efSdjm# A specification that revokes some certificates by serial numbers 3241c5d6efSdjm# The serial pattern is chosen to ensure the KRL includes list, range and 3341c5d6efSdjm# bitmap sections. 3441c5d6efSdjmcat << EOF >> $OBJ/revoked-serials 3541c5d6efSdjmserial: 1-4 3641c5d6efSdjmserial: 10 3741c5d6efSdjmserial: 15 3841c5d6efSdjmserial: 30 3941c5d6efSdjmserial: 50 402a103fdeSdjmserial: 90 4141c5d6efSdjmserial: 999 4241c5d6efSdjm# The following sum to 500-799 4341c5d6efSdjmserial: 500 4441c5d6efSdjmserial: 501 4541c5d6efSdjmserial: 502 4641c5d6efSdjmserial: 503-600 4741c5d6efSdjmserial: 700-797 4841c5d6efSdjmserial: 798 4941c5d6efSdjmserial: 799 5041c5d6efSdjmserial: 599-701 513e482054Sdjm# Some multiple consecutive serial number ranges 523e482054Sdjmserial: 10000-20000 533e482054Sdjmserial: 30000-40000 5441c5d6efSdjmEOF 5541c5d6efSdjm 5641c5d6efSdjm# A specification that revokes some certificated by key ID. 5741c5d6efSdjmtouch $OBJ/revoked-keyid 582a103fdeSdjmfor n in 1 2 3 4 10 15 30 50 90 `jot 500 300` 999 1000 1001 1002; do 59408a1ce8Sdjm test "x$n" = "x499" && continue 6041c5d6efSdjm # Fill in by-ID revocation spec. 6141c5d6efSdjm echo "id: revoked $n" >> $OBJ/revoked-keyid 6241c5d6efSdjmdone 6341c5d6efSdjm 6441c5d6efSdjmkeygen() { 6541c5d6efSdjm N=$1 6641c5d6efSdjm f=$OBJ/revoked-`printf "%04d" $N` 6783c77e6eSdtucker # Vary the keytype. We use mostly ed25519 since this is fast and well 6883c77e6eSdtucker # supported. 6983c77e6eSdtucker keytype=$ktype1 7041c5d6efSdjm case $N in 7183c77e6eSdtucker 2 | 10 | 510 | 1001) keytype=$ktype2 ;; 7283c77e6eSdtucker 4 | 30 | 520 | 1002) keytype=$ktype3 ;; 7383c77e6eSdtucker 8 | 50 | 530 | 1003) keytype=$ktype4 ;; 742a103fdeSdjm 16 | 70 | 540 | 1004) keytype=$ktype5 ;; 752a103fdeSdjm 32 | 90 | 550 | 1005) keytype=$ktype6 ;; 7641c5d6efSdjm esac 7741c5d6efSdjm $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ 7841c5d6efSdjm || fatal "$SSHKEYGEN failed" 7941c5d6efSdjm # Sign cert 8041c5d6efSdjm $SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \ 8141c5d6efSdjm || fatal "$SSHKEYGEN sign failed" 8241c5d6efSdjm echo $f 8341c5d6efSdjm} 8441c5d6efSdjm 8541c5d6efSdjm# Generate some keys. 8641c5d6efSdjmverbose "$tid: generating test keys" 872a103fdeSdjmREVOKED_SERIALS="1 4 10 50 90 500 510 520 550 799 999" 8841c5d6efSdjmfor n in $REVOKED_SERIALS ; do 8941c5d6efSdjm f=`keygen $n` 9019dce0afSdjm RKEYS="$RKEYS ${f}.pub" 9119dce0afSdjm RCERTS="$RCERTS ${f}-cert.pub" 9241c5d6efSdjmdone 93408a1ce8SdjmUNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" 94408a1ce8SdjmUNREVOKED="" 95408a1ce8Sdjmfor n in $UNREVOKED_SERIALS ; do 96408a1ce8Sdjm f=`keygen $n` 9719dce0afSdjm UKEYS="$UKEYS ${f}.pub" 9819dce0afSdjm UCERTS="$UCERTS ${f}-cert.pub" 9941c5d6efSdjmdone 10041c5d6efSdjm 101ec37a17eSdjm# Specifications that revoke keys by hash. 102ec37a17eSdjmtouch $OBJ/revoked-sha1 $OBJ/revoked-sha256 $OBJ/revoked-hash 103ec37a17eSdjmfor rkey in $RKEYS; do 104ec37a17eSdjm (printf "sha1: "; cat $rkey) >> $OBJ/revoked-sha1 105ec37a17eSdjm (printf "sha256: "; cat $rkey) >> $OBJ/revoked-sha256 106ec37a17eSdjm (printf "hash: "; $SSHKEYGEN -lf $rkey | \ 107ec37a17eSdjm awk '{ print $2 }') >> $OBJ/revoked-hash 108ec37a17eSdjmdone 109ec37a17eSdjm 11041c5d6efSdjmgenkrls() { 11141c5d6efSdjm OPTS=$1 11241c5d6efSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \ 11341c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 11419dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ 11541c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 11619dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ 11741c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 11819dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ 11941c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 12041c5d6efSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ 12141c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 122ec37a17eSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-sha1 $OBJ/revoked-sha1 \ 123ec37a17eSdjm >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 124ec37a17eSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-sha256 $OBJ/revoked-sha256 \ 125ec37a17eSdjm >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 126ec37a17eSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-hash $OBJ/revoked-hash \ 127ec37a17eSdjm >/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed" 128db70674bSdjm# This should fail as KRLs from serial/key-id spec need the CA specified. 12941c5d6efSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ 13041c5d6efSdjm >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" 13141c5d6efSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ 13241c5d6efSdjm >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" 13319dce0afSdjm# These should succeed; they specify an explicit CA key. 13419dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ 13519dce0afSdjm $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" 13619dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ 13719dce0afSdjm $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" 13819dce0afSdjm# These should succeed; they specify an wildcard CA key. 13919dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ 14019dce0afSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 14119dce0afSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ 14241c5d6efSdjm >/dev/null || fatal "$SSHKEYGEN KRL failed" 143db70674bSdjm# Revoke the same serials with the second CA key to ensure a multi-CA 144db70674bSdjm# KRL is generated. 145db70674bSdjm$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ 146db70674bSdjm $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" 14741c5d6efSdjm} 14841c5d6efSdjm 149e36b9660Sdjm## XXX dump with trace and grep for set cert serials 150e36b9660Sdjm## XXX test ranges near (u64)-1, etc. 151e36b9660Sdjm 15241c5d6efSdjmverbose "$tid: generating KRLs" 15341c5d6efSdjmgenkrls 15441c5d6efSdjm 15541c5d6efSdjmcheck_krl() { 15641c5d6efSdjm KEY=$1 15741c5d6efSdjm KRL=$2 15841c5d6efSdjm EXPECT_REVOKED=$3 15941c5d6efSdjm TAG=$4 16041c5d6efSdjm $SSHKEYGEN -Qf $KRL $KEY >/dev/null 16141c5d6efSdjm result=$? 162ec37a17eSdjm if test "x$EXPECT_REVOKED" = "xy" -a $result -eq 0 ; then 16341c5d6efSdjm fatal "key $KEY not revoked by KRL $KRL: $TAG" 164ec37a17eSdjm elif test "x$EXPECT_REVOKED" = "xn" -a $result -ne 0 ; then 16541c5d6efSdjm fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" 16641c5d6efSdjm fi 16741c5d6efSdjm} 16819dce0afSdjmtest_rev() { 16941c5d6efSdjm FILES=$1 17041c5d6efSdjm TAG=$2 17141c5d6efSdjm KEYS_RESULT=$3 17241c5d6efSdjm ALL_RESULT=$4 173ec37a17eSdjm HASH_RESULT=$5 174ec37a17eSdjm SERIAL_RESULT=$6 175ec37a17eSdjm KEYID_RESULT=$7 176ec37a17eSdjm CERTS_RESULT=$8 177ec37a17eSdjm CA_RESULT=$9 178*c0aad570Sdjm SERIAL_WRESULT=${10} 179*c0aad570Sdjm KEYID_WRESULT=${11} 18041c5d6efSdjm verbose "$tid: checking revocations for $TAG" 18141c5d6efSdjm for f in $FILES ; do 18241c5d6efSdjm check_krl $f $OBJ/krl-empty no "$TAG" 18341c5d6efSdjm check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" 18441c5d6efSdjm check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" 185ec37a17eSdjm check_krl $f $OBJ/krl-sha1 $HASH_RESULT "$TAG" 186ec37a17eSdjm check_krl $f $OBJ/krl-sha256 $HASH_RESULT "$TAG" 187ec37a17eSdjm check_krl $f $OBJ/krl-hash $HASH_RESULT "$TAG" 18841c5d6efSdjm check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" 18941c5d6efSdjm check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" 19041c5d6efSdjm check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" 19141c5d6efSdjm check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" 19219dce0afSdjm check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" 19319dce0afSdjm check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" 19441c5d6efSdjm done 19541c5d6efSdjm} 19619dce0afSdjm 19719dce0afSdjmtest_all() { 19819dce0afSdjm # wildcard 199ec37a17eSdjm # keys all hash sr# ID cert CA srl ID 200ec37a17eSdjm test_rev "$RKEYS" "revoked keys" y y y n n n n n n 201ec37a17eSdjm test_rev "$UKEYS" "unrevoked keys" n n n n n n n n n 202ec37a17eSdjm test_rev "$RCERTS" "revoked certs" y y y y y y y y y 203ec37a17eSdjm test_rev "$UCERTS" "unrevoked certs" n n n n n n y n n 20419dce0afSdjm} 20519dce0afSdjm 20619dce0afSdjmtest_all 20741c5d6efSdjm 20841c5d6efSdjm# Check update. Results should be identical. 20941c5d6efSdjmverbose "$tid: testing KRL update" 21041c5d6efSdjmfor f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ 21119dce0afSdjm $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ 21219dce0afSdjm $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do 21341c5d6efSdjm cp -f $OBJ/krl-empty $f 21441c5d6efSdjm genkrls -u 21541c5d6efSdjmdone 21619dce0afSdjm 21719dce0afSdjmtest_all 218