#
# Demo script to generate KSK signed DNSKEY RRsets /w s/w ZSKs
#
if [ -z "$DOMAIN" ]; then echo "You must \"export DOMAIN=yourdomain\" first"; exit 1; fi
dn0="$DOMAIN."
if [ "$TEST" ]; then # Accelerated test setup
  step=160
  recovery=$(( $step / 2 ))
  validity=$(( $step + $recovery ))
  ttl=$(( $validity / 4 ))
else
  ttl="3600"  # dnskey TTL
  recovery=432000 # 5d worst case time to recover from system failure
  step=864000 # 10d validity > step + recovery
  validity=$(( $step + $recovery ))  # > ttl
fi
slot="0"
tmpfile="$$.tmp"
mkdir tmp/ 2>/dev/null
#
# For encrypting/decrypting keybundles
read -s -p "Passphrase to encrypt keybundles: " dtkey
echo ""
if [ -z "$dtkey" ]; then echo "Cannot be null"; exit -1; fi
export dtkey
# See if we are rolling from an old (latest) keybundle
lastkb=`ls | grep -P [0-9]{14}."$dn0""keybundle.tar.gz.aes256" | tail -1`
if [ -z "$lastkb" ]; then  # No, so just start now
  tstartstr=`date -u +%Y%m%d%H%M%S` # may be different on BSD
  lastzsk=""
else  # Yes, so start with this keybundle
  tstartstr=`echo $lastkb | cut -f1 -d'.'`
  openssl enc -d -aes256 -pass env:dtkey -in $lastkb | tar -zxf -
  if [ $? -ne 0 ]; then exit -1; fi
  lastzsk="$dn0""zsk"  # format is $dn.zsk.[key][private]
  if [ ! -f "$lastzsk.private" ]; then
    echo "Could not find $lastzsk.key/$lastzsk.private"
    exit -1
  fi
  echo "Rolling from $lastkb"
fi
echo "Start time: $tstartstr"
zlst=`ls K$dn0+*.key`
if [ -z "$zlst" ]; then
  echo "Could not find any ZSKs for $dn0"
  exit -1
fi
read -p "KSK CKA_LABEL: " ckalabel
export PKCS11_LIBRARY_PATH="/opt/dccom/lib/opensc-pkcs11.so"
read -s -p "KSK HSM PIN: " PKCS11_LIBRARY_PIN
echo ""
export PKCS11_LIBRARY_PIN

# Create BIND stlye K files for KSK
ksk=`pkcs11-backup -S $slot -f$ckalabel:8:257:$dn0 | tail -1`
rs=`echo $ksk | grep ^K$DOMAIN`
if [ -z "$rs" ]; then
  echo "Could not run \"pkcs11-backup -S $slot -f$ckalabel:8:257:$dn0\""
  echo "Could not create BIND style K files for CKA_LABEL $ckalabel"
  exit -1
fi

# phase 1 lasts long enough for dnskey rrset to clear caches
rolloverph1=$(( $ttl * 2 ))
rolloverph1v=$(( $rolloverph1 + $recovery ))
# phase 2 last long enough for slaves to update
rolloverph2=$ttl
rolloverph2v=$(( $rolloverph2 + $recovery ))
rollph2=""
ulastzsk="$lastzsk"
tinc=0
for i in $zlst; do
  rs=`grep "IN DNSKEY 257 " $i`
  if [ "$rs" ]; then continue; fi  # This is a KSK so skip
  zsk=`echo $i | sed s/.key$//`
  if [ "$zsk" = "$lastzsk" ]; then continue; fi # dont repeat old zsk if in zlst
  cnt=1
  while [ $cnt -lt 9 ]; do
    uzsk=$zsk
    # Create a temp zonefile for dnssec-signzone
    echo "$dn0 IN SOA ns.dc.org. postmaster."$dn0"nic. 1 1 1 1 $ttl" > $tmpfile
    cat $uzsk.key >> $tmpfile
    cat $ksk.key >> $tmpfile
    inc=`addsecs2date $tstartstr $tinc`
    if [ "$ulastzsk" ]; then # rolling from last key
      cat $ulastzsk.key >> $tmpfile
      if [ "$rollph2" ]; then # Phase 2 of roll
        expinc=$rolloverph2v
        tinc=$(( $tinc + $rolloverph2 ))
        cnt=$(( $cnt + 1 ))
        keys="$zsk $ulastzsk"
        rm -rf $ulastzsk.*   # remove old ZSK
        rollph2=""
        ulastzsk=""
      else # Phase 1 - Good for at least 2x DNSKEY TTL + 5 day normal recovery time
        expinc=$rolloverph1v
        tinc=$(( $tinc + $rolloverph1 ))
        uzsk=$ulastzsk # Use old zsk for RRSIGs in phase 1
        keys="$ulastzsk $zsk"
        rollph2="do"
      fi
    else
      expinc=$validity
      tinc=$(( $tinc + $step ))
      cnt=$(( $cnt + 1 ))
      keys="$zsk"
    fi
    # Run pkcs11 dnssec-signzone to generate KSK signed DNSKEY RRset
    #echo "dnssec-signzone -v 3 -x -s $inc -e +$expinc -P -o $dn0 $tmpfile $ksk"
    dnssec-signzone -v 3 -x -s $inc -e +$expinc -P -o $dn0 $tmpfile $ksk >> logfile.txt 2>&1
    if [ $? -ne 0 ]; then exit -1; fi
    # Extract only the KSK signed DNSKEY RRset
    cat $tmpfile.signed | grep -A 100 "SOA RRSIG NSEC DNSKEY" | grep -v "SOA RRSIG NSEC DNSKEY" | sed s/"\t\t\t$ttl"/"$dn0\t\t$ttl"/ > tmp/"$dn0""dnskeyrrset"
    # create key bundle
    cp -p $uzsk.key tmp/"$dn0"zsk.key
    cp -p $uzsk.private tmp/"$dn0"zsk.private
    cd tmp
    tar -zcf - * | openssl enc -e -aes256 -pass env:dtkey -out ../$inc."$dn0"keybundle.tar.gz.aes256
    cd ..
    echo "Created $inc.""$dn0""keybundle.tar.gz.aes256 $keys $expinc"
    rm -f tmp/*  # clean up after ourselves
  done
  ulastzsk="$zsk"
done
if [ "$ulastzsk" ]; then rm -rf $ulastzsk.*; fi  # remove old ZSK if any
rm -f $tmpfile* "$dn0""dnskeyrrset" dsset-"$dn0"
#
# end
#
