Home | History | Annotate | Line # | Download | only in enginepkcs11
      1 #!/bin/sh
      2 #
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # SPDX-License-Identifier: MPL-2.0
      6 #
      7 # This Source Code Form is subject to the terms of the Mozilla Public
      8 # License, v. 2.0. If a copy of the MPL was not distributed with this
      9 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10 #
     11 # See the COPYRIGHT file distributed with this work for additional
     12 # information regarding copyright ownership.
     13 
     14 set -e
     15 
     16 # shellcheck source=conf.sh
     17 . ../conf.sh
     18 
     19 PWD=$(pwd)
     20 
     21 status=0
     22 ret=0
     23 n=0
     24 
     25 dig_with_opts() {
     26   $DIG +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@"
     27 }
     28 
     29 check_keys() {
     30   _zone=$1
     31   _expect=$2
     32   _ret=0
     33   _status=0
     34   _count=$(ls K*.key | grep "K${_zone}" | wc -l)
     35 
     36   test "$_count" -eq "$_expect" || _ret=1
     37   test "$_ret" -eq 0 || echo_i "failed (expected $_expect keys, got $_count)"
     38   _status=$((_status + _ret))
     39 
     40   _ret=0
     41   _count=$(cat K${_zone}*.private | grep Label | wc -l)
     42   test "$_count" -eq "$_expect" || _ret=1
     43   test "$_ret" -eq 0 || echo_i "failed (expected Label metadata in key files)"
     44   _status=$((_status + _ret))
     45 
     46   return $_status
     47 }
     48 
     49 # Perform tests inside ns1 dir
     50 cd ns1
     51 
     52 for algtypebits in rsasha256:rsa:2048 rsasha512:rsa:2048 \
     53   ecdsap256sha256:EC:prime256v1 ecdsap384sha384:EC:prime384v1; do # Edwards curves are not yet supported by OpenSC
     54   # ed25519:EC:edwards25519 ed448:EC:edwards448
     55   alg=$(echo "$algtypebits" | cut -f 1 -d :)
     56   type=$(echo "$algtypebits" | cut -f 2 -d :)
     57   bits=$(echo "$algtypebits" | cut -f 3 -d :)
     58   zone="${alg}.example"
     59   zonefile="zone.${zone}.db.signed"
     60 
     61   if [ ! -f $zonefile ]; then
     62     echo_i "skipping test for ${alg}:${type}:${bits}, no signed zone file ${zonefile}"
     63     continue
     64   fi
     65 
     66   # Basic checks if setup was successful.
     67   n=$((n + 1))
     68   ret=0
     69   echo_i "Test key generation was successful for $zone ($n)"
     70   check_keys $zone 4 || ret=1
     71   status=$((status + ret))
     72 
     73   n=$((n + 1))
     74   ret=0
     75   echo_i "Test zone signing was successful for $zone ($n)"
     76   $VERIFY -z -o $zone "${zonefile}" >verify.out.$zone.$n 2>&1 || ret=1
     77   test "$ret" -eq 0 || echo_i "failed (dnssec-verify failed)"
     78   status=$((status + ret))
     79 
     80   # Test inline signing with keys stored in engine.
     81   zskid1=$(cat "${zone}.zskid1")
     82   zskid2=$(cat "${zone}.zskid2")
     83 
     84   n=$((n + 1))
     85   ret=0
     86   echo_i "Test inline signing for $zone ($n)"
     87   dig_with_opts "$zone" @10.53.0.1 SOA >dig.out.soa.$zone.$n || ret=1
     88   awk '$4 == "RRSIG" { print $11 }' dig.out.soa.$zone.$n >dig.out.keyids.$zone.$n || ret=1
     89   numsigs=$(cat dig.out.keyids.$zone.$n | wc -l)
     90   test $numsigs -eq 1 || ret=1
     91   grep -w "$zskid1" dig.out.keyids.$zone.$n >/dev/null || ret=1
     92   test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed with key $zskid1)"
     93   status=$((status + ret))
     94 
     95   n=$((n + 1))
     96   ret=0
     97   echo_i "Dynamically update $zone, add new zsk ($n)"
     98   zsk2=$(grep -v ';' K${zone}.*.zsk2)
     99   cat >"update.cmd.zsk.$zone.$n" <<EOF
    100 server 10.53.0.1 $PORT
    101 ttl 300
    102 zone $zone
    103 update add $zsk2
    104 send
    105 EOF
    106 
    107   $NSUPDATE -v >"update.log.zsk.$zone.$n" <"update.cmd.zsk.$zone.$n" || ret=1
    108   test "$ret" -eq 0 || echo_i "failed (update failed)"
    109   status=$((status + ret))
    110 
    111   n=$((n + 1))
    112   ret=0
    113   echo_i "Test DNSKEY response for $zone after inline signing ($n)"
    114   _dig_dnskey() {
    115     dig_with_opts "$zone" @10.53.0.1 DNSKEY >dig.out.dnskey.$zone.$n || return 1
    116     count=$(awk 'BEGIN { count = 0 } $4 == "DNSKEY" { count++ } END {print count}' dig.out.dnskey.$zone.$n)
    117     test $count -eq 3
    118   }
    119   retry_quiet 10 _dig_dnskey || ret=1
    120   test "$ret" -eq 0 || echo_i "failed (expected 3 DNSKEY records)"
    121   status=$((status + ret))
    122 
    123   n=$((n + 1))
    124   ret=0
    125   echo_i "Test SOA response for $zone after inline signing ($n)"
    126   _dig_soa() {
    127     dig_with_opts "$zone" @10.53.0.1 SOA >dig.out.soa.$zone.$n || return 1
    128     awk '$4 == "RRSIG" { print $11 }' dig.out.soa.$zone.$n >dig.out.keyids.$zone.$n || return 1
    129     numsigs=$(cat dig.out.keyids.$zone.$n | wc -l)
    130     test $numsigs -eq 2 || return 1
    131     grep -w "$zskid1" dig.out.keyids.$zone.$n >/dev/null || return 1
    132     grep -w "$zskid2" dig.out.keyids.$zone.$n >/dev/null || return 1
    133     return 0
    134   }
    135   retry_quiet 10 _dig_soa || ret=1
    136   test "$ret" -eq 0 || echo_i "failed (expected 2 SOA RRSIG records)"
    137   status=$((status + ret))
    138 
    139   # Test inline signing with keys stored in engine (key signing).
    140   kskid1=$(cat "${zone}.kskid1")
    141   kskid2=$(cat "${zone}.kskid2")
    142 
    143   n=$((n + 1))
    144   ret=0
    145   echo_i "Dynamically update $zone, add new ksk ($n)"
    146   ksk2=$(grep -v ';' K${zone}.*.ksk2)
    147   cat >"update.cmd.ksk.$zone.$n" <<EOF
    148 server 10.53.0.1 $PORT
    149 ttl 300
    150 zone $zone
    151 update add $ksk2
    152 send
    153 EOF
    154 
    155   $NSUPDATE -v >"update.log.ksk.$zone.$n" <"update.cmd.ksk.$zone.$n" || ret=1
    156   test "$ret" -eq 0 || echo_i "failed (update failed)"
    157   status=$((status + ret))
    158 
    159   n=$((n + 1))
    160   ret=0
    161   echo_i "Test DNSKEY response for $zone after inline signing (key signing) ($n)"
    162   _dig_dnskey_ksk() {
    163     dig_with_opts "$zone" @10.53.0.1 DNSKEY >dig.out.dnskey.$zone.$n || return 1
    164     count=$(awk 'BEGIN { count = 0 } $4 == "DNSKEY" { count++ } END {print count}' dig.out.dnskey.$zone.$n)
    165     test $count -eq 4 || return 1
    166     awk '$4 == "RRSIG" { print $11 }' dig.out.dnskey.$zone.$n >dig.out.keyids.$zone.$n || return 1
    167     numsigs=$(cat dig.out.keyids.$zone.$n | wc -l)
    168     test $numsigs -eq 2 || return 1
    169     grep -w "$kskid1" dig.out.keyids.$zone.$n >/dev/null || return 1
    170     grep -w "$kskid2" dig.out.keyids.$zone.$n >/dev/null || return 1
    171     return 0
    172   }
    173   retry_quiet 10 _dig_dnskey_ksk || ret=1
    174   test "$ret" -eq 0 || echo_i "failed (expected 4 DNSKEY records, 2 KSK signatures)"
    175   status=$((status + ret))
    176 
    177   # Check dnssec-policy interaction.
    178 
    179   # Basic checks if setup was successful (dnssec-policy).
    180   zone="${alg}.kasp"
    181   n=$((n + 1))
    182   ret=0
    183   ret=0
    184   echo_i "Test key generation was successful for $zone ($n)"
    185   check_keys $zone 2 || ret=1
    186   status=$((status + ret))
    187 
    188   n=$((n + 1))
    189   ret=0
    190   echo_i "Test DNSKEY response for $zone ($n)"
    191   _dig_policy_dnskey() {
    192     dig_with_opts "$zone" @10.53.0.1 DNSKEY >dig.out.dnskey.$zone.$n || return 1
    193     count=$(awk 'BEGIN { count = 0 } $4 == "DNSKEY" { count++ } END {print count}' dig.out.dnskey.$zone.$n)
    194     test $count -eq 2
    195   }
    196   retry_quiet 2 _dig_policy_dnskey || ret=1
    197   test "$ret" -eq 0 || echo_i "failed (expected 2 DNSKEY records)"
    198   status=$((status + ret))
    199 
    200   n=$((n + 1))
    201   ret=0
    202   echo_i "Test SOA response for $zone ($n)"
    203   _dig_policy_soa() {
    204     dig_with_opts "$zone" @10.53.0.1 SOA >dig.out.soa.$zone.$n || return 1
    205     awk '$4 == "RRSIG" && $5 == "SOA" { print $11 }' dig.out.soa.$zone.$n >dig.out.keyids.$zone.$n || return 1
    206     numsigs=$(cat dig.out.keyids.$zone.$n | wc -l)
    207     test $numsigs -eq 1 || return 1
    208     return 0
    209   }
    210   retry_quiet 2 _dig_policy_soa || ret=1
    211   test "$ret" -eq 0 || echo_i "failed (expected a SOA RRSIG record)"
    212 
    213   zone="$alg.\"\:\;\?\&\[\]\@\!\$\*\+\,\|\=\.\(\)foo.weird"
    214   keyfile="${alg}.%22%3A%3B%3F%26%5B%5D%40%21%24%2A%2B%2C%7C%3D%2E%28%29foo.weird"
    215   n=$((n + 1))
    216   ret=0
    217   echo_i "Test key generation was successful for $zone ($n)"
    218   check_keys $keyfile 2 || ret=1
    219   status=$((status + ret))
    220 
    221   n=$((n + 1))
    222   ret=0
    223   echo_i "Test DNSKEY response for $zone ($n)"
    224   retry_quiet 2 _dig_policy_dnskey || ret=1
    225   test "$ret" -eq 0 || echo_i "failed (expected 2 DNSKEY records)"
    226   status=$((status + ret))
    227 
    228   n=$((n + 1))
    229   ret=0
    230   echo_i "Test SOA response for $zone ($n)"
    231   retry_quiet 2 _dig_policy_soa || ret=1
    232   test "$ret" -eq 0 || echo_i "failed (expected a SOA RRSIG record)"
    233   status=$((status + ret))
    234 
    235   # Check a dnssec-policy that uses multiple key-stores.
    236   zone="${alg}.split"
    237   echo_i "Test key generation was successful for $zone ($n)"
    238   # Check KSK.
    239   check_keys $zone 1 || ret=1
    240   # Check ZSK.
    241   count=$(ls keys/K*.key | grep "K${_zone}" | wc -l)
    242   test "$count" -eq 1 || ret=1
    243   test "$ret" -eq 0 || echo_i "failed (expected 1 key, got $count)"
    244   status=$((status + ret))
    245   ret=0
    246   count=$(cat keys/K${zone}*.private | grep Engine | wc -l)
    247   test "$count" -eq 0 || ret=1
    248   count=$(cat keys/K${zone}*.private | grep Label | wc -l)
    249   test "$count" -eq 0 || ret=1
    250   test "$ret" -eq 0 || echo_i "failed (unexpected Engine and Label in key files)"
    251   status=$((status + ret))
    252 
    253   # Check dnssec-keygen with dnssec-policy and key-store.
    254   zone="${alg}.keygen"
    255   n=$((n + 1))
    256   ret=0
    257   echo_i "Test dnssec-keygen for $zone ($n)"
    258   $KEYGEN $ENGINE_ARG -k $alg -l named.conf $zone >keygen.out.$zone.$n 2>/dev/null || ret=1
    259   check_keys $zone 2 || ret=1
    260   status=$((status + ret))
    261 
    262 done
    263 
    264 # Go back to main test dir.
    265 cd ..
    266 
    267 # Perform tests inside ns2 dir
    268 cd ns2
    269 
    270 algtypebits="ecdsap256sha256:EC:prime256v1"
    271 alg=$(echo "$algtypebits" | cut -f 1 -d :)
    272 type=$(echo "$algtypebits" | cut -f 2 -d :)
    273 bits=$(echo "$algtypebits" | cut -f 3 -d :)
    274 zone="${alg}.views"
    275 zonefile1="zone.$alg.views.view1.db.signed"
    276 zonefile2="zone.$alg.views.view2.db.signed"
    277 
    278 skip=0
    279 if [ ! -f $zonefile1 ]; then
    280   echo_i "skipping test for ${alg}:${type}:${bits}, no signed zone file ${zonefile1}"
    281   skip=1
    282 fi
    283 
    284 if [ ! -f $zonefile2 ]; then
    285   echo_i "skipping test for ${alg}:${type}:${bits}, no signed zone file ${zonefile2}"
    286   skip=1
    287 fi
    288 
    289 if [ $skip -eq 0 ]; then
    290   # Basic checks if setup was successful.
    291   n=$((n + 1))
    292   ret=0
    293   echo_i "Test key generation was successful for $zone ($n)"
    294   check_keys $zone 4 || ret=1
    295   status=$((status + ret))
    296 
    297   n=$((n + 1))
    298   ret=0
    299   echo_i "Test zone signing was successful for $zone in view1 ($n)"
    300   $VERIFY -z -o $zone "${zonefile1}" >verify.out.$zone.view1.$n 2>&1 || ret=1
    301   test "$ret" -eq 0 || echo_i "failed (dnssec-verify failed)"
    302   status=$((status + ret))
    303 
    304   n=$((n + 1))
    305   ret=0
    306   echo_i "Test zone signing was successful for $zone in view2 ($n)"
    307   $VERIFY -z -o $zone "${zonefile2}" >verify.out.$zone.view2.$n 2>&1 || ret=1
    308   test "$ret" -eq 0 || echo_i "failed (dnssec-verify failed)"
    309   status=$((status + ret))
    310 
    311   # Test dnssec-policy signing with keys stored in engine.
    312   zone="${alg}.same-policy.views"
    313 
    314   n=$((n + 1))
    315   ret=0
    316   echo_i "Test key generation was successful for $zone ($n)"
    317   check_keys $zone 1 || ret=1
    318   status=$((status + ret))
    319 
    320   _dig_inview() {
    321     _qtype="$1"
    322     _alg="$2"
    323     _tsig="$DEFAULT_HMAC:$3:$4"
    324     dig_with_opts "$zone" @10.53.0.2 $_qtype -y "$_tsig" >dig.out.$zone.$n || return 1
    325     awk -v cov="$_qtype" '$4 == "RRSIG" && $5 == cov { print $6 }' dig.out.$zone.$n >dig.out.alg.$zone.$n || return 1
    326     numsigs=$(cat dig.out.alg.$zone.$n | wc -l)
    327     test $numsigs -eq 1 || return 1
    328     grep -w "$_alg" dig.out.alg.$zone.$n >/dev/null || return 1
    329   }
    330 
    331   n=$((n + 1))
    332   ret=0
    333   echo_i "Test SOA is signed for $zone in view1 ($n)"
    334   VIEW1="YPfMoAk6h+3iN8MDRQC004iSNHY="
    335   retry_quiet 4 _dig_inview SOA 13 keyforview1 $VIEW1 || ret=1
    336   test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
    337   status=$((status + ret))
    338 
    339   n=$((n + 1))
    340   ret=0
    341   echo_i "Test DNSKEY is signed for $zone in view1 ($n)"
    342   retry_quiet 4 _dig_inview DNSKEY 13 keyforview1 $VIEW1 || ret=1
    343   test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
    344   status=$((status + ret))
    345 
    346   n=$((n + 1))
    347   ret=0
    348   echo_i "Test SOA is signed for $zone in view2 ($n)"
    349   VIEW2="4xILSZQnuO1UKubXHkYUsvBRPu8="
    350   retry_quiet 4 _dig_inview SOA 13 keyforview2 $VIEW2 || ret=1
    351   test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
    352   status=$((status + ret))
    353 
    354   n=$((n + 1))
    355   ret=0
    356   echo_i "Test DNSKEY is signed for $zone in view2 ($n)"
    357   retry_quiet 4 _dig_inview DNSKEY 13 keyforview2 $VIEW2 || ret=1
    358   test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
    359   status=$((status + ret))
    360 
    361   # Now test zone in different views using a different dnssec-policy.
    362   zone="zone-with.different-policy.views"
    363 
    364   n=$((n + 1))
    365   ret=0
    366   echo_i "Test key generation was successful for $zone in view1 ($n)"
    367   # view1
    368   check_keys $zone 1 || ret=1
    369   status=$((status + ret))
    370   # view2
    371   echo_i "Test key generation was successful for $zone in view2 ($n)"
    372   count=$(ls keys/K*.key | grep "K${zone}" | wc -l)
    373   test "$count" -eq 1 || ret=1
    374   test "$ret" -eq 0 || echo_i "failed (expected 1 key, got $count)"
    375   status=$((status + ret))
    376 
    377   n=$((n + 1))
    378   ret=0
    379   echo_i "Test SOA is signed for $zone in view1 ($n)"
    380   VIEW1="YPfMoAk6h+3iN8MDRQC004iSNHY="
    381   retry_quiet 4 _dig_inview SOA 13 keyforview1 $VIEW1 || ret=1
    382   test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
    383   status=$((status + ret))
    384 
    385   n=$((n + 1))
    386   ret=0
    387   echo_i "Test DNSKEY is signed for $zone in view1 ($n)"
    388   retry_quiet 4 _dig_inview DNSKEY 13 keyforview1 $VIEW1 || ret=1
    389   test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
    390   status=$((status + ret))
    391 
    392   n=$((n + 1))
    393   ret=0
    394   echo_i "Test SOA is signed for $zone in view2 ($n)"
    395   VIEW2="4xILSZQnuO1UKubXHkYUsvBRPu8="
    396   retry_quiet 4 _dig_inview SOA 8 keyforview2 $VIEW2 || ret=1
    397   test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
    398   status=$((status + ret))
    399 
    400   n=$((n + 1))
    401   ret=0
    402   echo_i "Test DNSKEY is signed for $zone in view2 ($n)"
    403   retry_quiet 4 _dig_inview DNSKEY 8 keyforview2 $VIEW2 || ret=1
    404   test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
    405   status=$((status + ret))
    406 fi
    407 
    408 # Go back to main test dir.
    409 cd ..
    410 
    411 n=$((n + 1))
    412 ret=0
    413 echo_i "Checking for assertion failure in pk11_numbits()"
    414 $PERL ../packet.pl -a "10.53.0.1" -p "$PORT" -t udp 2037-pk11_numbits-crash-test.pkt
    415 dig_with_opts @10.53.0.1 version.bind. CH TXT >dig.out.pk11_numbits || ret=1
    416 test "$ret" -eq 0 || echo_i "failed"
    417 status=$((status + ret))
    418 
    419 echo_i "exit status: $status"
    420 [ $status -eq 0 ] || exit 1
    421