From 77ca7783775597618cf5e9b459c7c8a281b1cec1 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 18 Nov 2021 14:22:04 +1100 Subject: [PATCH 1/6] Generate test zone with multiple NSEC and NSEC3 chains The method used to generate a test zone with multiple NSEC and NSEC3 chains was incorrect. Multiple calls to dnssec-signzone with multiple parameters is not additive. Extract the chain on each run then add them to the final signed zone instance. --- bin/tests/system/dnssec/clean.sh | 1 + bin/tests/system/dnssec/ns3/sign.sh | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index adcb52f7d2..b4ff9f3941 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -94,6 +94,7 @@ rm -f ./ns3/ttlpatch.example.db ./ns3/ttlpatch.example.db.signed rm -f ./ns3/ttlpatch.example.db.patched rm -f ./ns3/unsecure.example.db ./ns3/bogus.example.db ./ns3/keyless.example.db rm -f ./ns3/unsupported.managed.db.tmp ./ns3/unsupported.trusted.db.tmp +rm -f ./ns3/NSEC ./ns3/NSEC3 rm -f ./ns4/managed-keys.bind* rm -f ./ns4/named_dump.db* rm -f ./ns6/optout-tld.db diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index c32e462a11..59fd58d77c 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -340,17 +340,18 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null -mv "$zonefile".signed "$zonefile" -"$SIGNER" -P -u3 - -o "$zone" "$zonefile" > /dev/null -mv "$zonefile".signed "$zonefile" -"$SIGNER" -P -u3 AAAA -o "$zone" "$zonefile" > /dev/null -mv "$zonefile".signed "$zonefile" -"$SIGNER" -P -u3 BBBB -o "$zone" "$zonefile" > /dev/null -mv "$zonefile".signed "$zonefile" -"$SIGNER" -P -u3 CCCC -o "$zone" "$zonefile" > /dev/null -mv "$zonefile".signed "$zonefile" -"$SIGNER" -P -u3 DDDD -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -P -O full -o "$zone" "$zonefile" > /dev/null +awk '$4 == "NSEC" || ( $4 == "RRSIG" && $5 == "NSEC" ) { print }' "$zonefile".signed > NSEC +"$SIGNER" -P -O full -u3 - -o "$zone" "$zonefile" > /dev/null +awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed > NSEC3 +"$SIGNER" -P -O full -u3 AAAA -o "$zone" "$zonefile" > /dev/null +awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 +"$SIGNER" -P -O full -u3 BBBB -o "$zone" "$zonefile" > /dev/null +awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 +"$SIGNER" -P -O full -u3 CCCC -o "$zone" "$zonefile" > /dev/null +awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 +"$SIGNER" -P -O full -u3 DDDD -o "$zone" "$zonefile" > /dev/null +cat NSEC NSEC3 >> "$zonefile".signed # # A RSASHA256 zone. From dbeea1afa072da220c81f1f251c8a665cfceb0ce Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 18 Nov 2021 14:31:52 +1100 Subject: [PATCH 2/6] Don't use 'dnssec-signzone -P' unless necessary Most of the test zones in the dnssec system test can be verified. Use -z when only a single key is being used so that the verifier knows that only a single key is in use. --- bin/tests/system/dnssec/ns1/sign.sh | 2 +- bin/tests/system/dnssec/ns2/sign.sh | 32 +++++++++--------- bin/tests/system/dnssec/ns3/sign.sh | 50 ++++++++++++++--------------- bin/tests/system/dnssec/ns6/sign.sh | 2 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/bin/tests/system/dnssec/ns1/sign.sh b/bin/tests/system/dnssec/ns1/sign.sh index e59e534c51..75de1cf256 100644 --- a/bin/tests/system/dnssec/ns1/sign.sh +++ b/bin/tests/system/dnssec/ns1/sign.sh @@ -36,7 +36,7 @@ zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$ksk.key" "$zsk.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 # Configure the resolving server with a staitc key. keyfile_to_static_ds "$ksk" > trusted.conf diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index af2717825f..6e3893b782 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -36,7 +36,7 @@ keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zo cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 zone=trusted. infile=key.db.in @@ -47,7 +47,7 @@ keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zo cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 # The "example." zone. zone=example. @@ -72,7 +72,7 @@ keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zo cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 # # lower/uppercase the signature bits with the exception of the last characters @@ -134,7 +134,7 @@ keyname1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KS keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 # Sign the badparam secure file @@ -147,7 +147,7 @@ keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zon cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -3 - -H 1 -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -3 - -H 1 -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 sed -e 's/IN NSEC3 1 0 1 /IN NSEC3 1 0 10 /' "$zonefile.signed" > "$zonefile.bad" @@ -162,7 +162,7 @@ keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zon cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -3 - -A -H 1 -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 +"$SIGNER" -3 - -A -H 1 -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 # # algroll has just has the old DNSKEY records removed and is waiting @@ -180,7 +180,7 @@ keynew2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keynew1.key" "$keynew2.key" > "$zonefile" -"$SIGNER" -P -o "$zone" -k "$keyold1" -k "$keynew1" "$zonefile" "$keyold1" "$keyold2" "$keynew1" "$keynew2" > /dev/null 2>&1 +"$SIGNER" -o "$zone" -k "$keyold1" -k "$keynew1" "$zonefile" "$keyold1" "$keyold2" "$keynew1" "$keynew2" > /dev/null 2>&1 # # Make a zone big enough that it takes several seconds to generate a new @@ -204,7 +204,7 @@ done >> "$zonefile" key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone") key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$key1.key" "$key2.key" >> "$zonefile" -"$SIGNER" -P -3 - -A -H 1 -g -o "$zone" -k "$key1" "$zonefile" "$key2" > /dev/null 2>&1 +"$SIGNER" -3 - -A -H 1 -g -o "$zone" -k "$key1" "$zonefile" "$key2" > /dev/null 2>&1 zone=cds.secure infile=cds.secure.db.in @@ -213,7 +213,7 @@ key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") "$DSFROMKEY" -C "$key1.key" > "$key1.cds" cat "$infile" "$key1.key" "$key2.key" "$key1.cds" >$zonefile -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cds-x.secure infile=cds.secure.db.in @@ -223,7 +223,7 @@ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") "$DSFROMKEY" -C "$key2.key" > "$key2.cds" cat "$infile" "$key1.key" "$key2.key" "$key3.key" "$key2.cds" > "$zonefile" -"$SIGNER" -P -g -x -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -x -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cds-update.secure infile=cds-update.secure.db.in @@ -231,7 +231,7 @@ zonefile=cds-update.secure.db key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone") key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cds-kskonly.secure infile=cds-kskonly.secure.db.in @@ -239,7 +239,7 @@ zonefile=cds-kskonly.secure.db key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone") key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 keyfile_to_key_id "$key1" > cds-kskonly.secure.id zone=cds-auto.secure @@ -257,7 +257,7 @@ key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") sed 's/DNSKEY/CDNSKEY/' "$key1.key" > "$key1.cds" cat "$infile" "$key1.key" "$key2.key" "$key1.cds" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cdnskey-x.secure infile=cdnskey.secure.db.in @@ -267,7 +267,7 @@ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") sed 's/DNSKEY/CDNSKEY/' "$key1.key" > "$key1.cds" cat "$infile" "$key1.key" "$key2.key" "$key3.key" "$key1.cds" > "$zonefile" -"$SIGNER" -P -g -x -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -x -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cdnskey-update.secure infile=cdnskey-update.secure.db.in @@ -275,7 +275,7 @@ zonefile=cdnskey-update.secure.db key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone") key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 zone=cdnskey-kskonly.secure infile=cdnskey-kskonly.secure.db.in @@ -283,7 +283,7 @@ zonefile=cdnskey-kskonly.secure.db key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone") key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" -"$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -g -o "$zone" "$zonefile" > /dev/null 2>&1 keyfile_to_key_id "$key1" > cdnskey-kskonly.secure.id zone=cdnskey-auto.secure diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index 59fd58d77c..d89287f1bf 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -49,7 +49,7 @@ do keyname4=$("$KEYGEN" -f KSK -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$keyname4.key" > "$zonefile" - "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null + "$SIGNER" -z -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed # Make trusted-keys and managed keys conf sections for ns8. @@ -86,7 +86,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -o "$zone" "$zonefile" > /dev/null zone=bogus.example. infile=bogus.example.db.in @@ -96,7 +96,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -o "$zone" "$zonefile" > /dev/null zone=dynamic.example. infile=dynamic.example.db.in @@ -107,7 +107,7 @@ keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KS cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -o "$zone" "$zonefile" > /dev/null zone=keyless.example. infile=generic.example.db.in @@ -117,7 +117,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -o "$zone" "$zonefile" > /dev/null # Change the signer field of the a.b.keyless.example SIG A # to point to a provably nonexistent KEY record. @@ -138,7 +138,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -o "$zone" "$zonefile" > /dev/null # # NSEC3/NSEC3 test zone @@ -151,7 +151,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -o "$zone" "$zonefile" > /dev/null # # OPTOUT/NSEC3 test zone @@ -164,7 +164,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -A -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -A -o "$zone" "$zonefile" > /dev/null # # A nsec3 zone (non-optout). @@ -177,7 +177,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -g -3 - -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -g -3 - -o "$zone" "$zonefile" > /dev/null # # OPTOUT/NSEC test zone @@ -190,7 +190,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -o "$zone" "$zonefile" > /dev/null # # OPTOUT/NSEC3 test zone @@ -203,7 +203,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -o "$zone" "$zonefile" > /dev/null # # OPTOUT/OPTOUT test zone @@ -216,7 +216,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -A -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -A -o "$zone" "$zonefile" > /dev/null # # A optout nsec3 zone. @@ -229,7 +229,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -g -3 - -A -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -g -3 - -A -o "$zone" "$zonefile" > /dev/null # # A nsec3 zone (non-optout) with unknown nsec3 hash algorithm (-U). @@ -242,7 +242,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -U -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -PU -o "$zone" "$zonefile" > /dev/null # # A optout nsec3 zone with a unknown nsec3 hash algorithm (-U). @@ -255,7 +255,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -U -A -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -3 - -PU -A -o "$zone" "$zonefile" > /dev/null # # A zone that is signed with an unknown DNSKEY algorithm. @@ -269,7 +269,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null +"$SIGNER" -z -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null awk '$4 == "DNSKEY" { $7 = 100 } $4 == "RRSIG" { $6 = 100 } { print }' ${zonefile}.tmp > ${zonefile}.signed @@ -288,7 +288,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null +"$SIGNER" -z -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed @@ -308,7 +308,7 @@ zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$ksk.key" "$zsk.key" unsupported-algorithm.key > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null +"$SIGNER" -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null # # A zone with a unknown DNSKEY algorithm + unknown NSEC3 hash algorithm (-U). @@ -322,7 +322,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -o "$zone" -U -O full -f ${zonefile}.tmp "$zonefile" > /dev/null +"$SIGNER" -z -3 - -o "$zone" -PU -O full -f ${zonefile}.tmp "$zonefile" > /dev/null awk '$4 == "DNSKEY" { $7 = 100; print } $4 == "RRSIG" { $6 = 100; print } { print }' ${zonefile}.tmp > ${zonefile}.signed @@ -340,17 +340,17 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -O full -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -o "$zone" "$zonefile" > /dev/null awk '$4 == "NSEC" || ( $4 == "RRSIG" && $5 == "NSEC" ) { print }' "$zonefile".signed > NSEC -"$SIGNER" -P -O full -u3 - -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -u3 - -o "$zone" "$zonefile" > /dev/null awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed > NSEC3 -"$SIGNER" -P -O full -u3 AAAA -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -u3 AAAA -o "$zone" "$zonefile" > /dev/null awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 -"$SIGNER" -P -O full -u3 BBBB -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -u3 BBBB -o "$zone" "$zonefile" > /dev/null awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 -"$SIGNER" -P -O full -u3 CCCC -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -u3 CCCC -o "$zone" "$zonefile" > /dev/null awk '$4 == "NSEC3" || ( $4 == "RRSIG" && $5 == "NSEC3" ) { print }' "$zonefile".signed >> NSEC3 -"$SIGNER" -P -O full -u3 DDDD -o "$zone" "$zonefile" > /dev/null +"$SIGNER" -z -O full -u3 DDDD -o "$zone" "$zonefile" > /dev/null cat NSEC NSEC3 >> "$zonefile".signed # diff --git a/bin/tests/system/dnssec/ns6/sign.sh b/bin/tests/system/dnssec/ns6/sign.sh index 4eb2fa5b71..d308f4844b 100644 --- a/bin/tests/system/dnssec/ns6/sign.sh +++ b/bin/tests/system/dnssec/ns6/sign.sh @@ -24,4 +24,4 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone cat "$infile" "$keyname.key" > "$zonefile" -"$SIGNER" -P -3 - -A -o "$zone" "$zonefile" > /dev/null 2>&1 +"$SIGNER" -z -3 - -A -o "$zone" "$zonefile" > /dev/null 2>&1 From a482a6b2049c62ef77b8b8f11d0a6c32f7ac05c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Fri, 19 Nov 2021 10:32:21 +0100 Subject: [PATCH 3/6] Fix parsing ECDSA keys raw_key_to_ossl() assumes fixed ECDSA private key sizes (32 bytes for ECDSAP256SHA256, 48 bytes for ECDSAP384SHA384). Meanwhile, in rare cases, ECDSAP256SHA256 private keys are representable in 31 bytes or less (similarly for ECDSAP384SHA384) and that is how they are then stored in the "PrivateKey" field of the key file. Nevertheless, raw_key_to_ossl() always calls BN_bin2bn() with a fixed length argument, which in the cases mentioned above leads to erroneously interpreting uninitialized memory as a part of the private key. This results in the latter being malformed and broken signatures being generated. Address by using the key length provided by the caller rather than a fixed one. Apply the same change to public key parsing code for consistency, adding an INSIST() to prevent buffer overruns. --- lib/dns/opensslecdsa_link.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 4dee158b31..08f061208c 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -66,24 +66,16 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, OSSL_PARAM *params = NULL; EVP_PKEY_CTX *ctx = NULL; BIGNUM *priv = NULL; - size_t len = 0; unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; if (key_alg == DST_ALG_ECDSA256) { groupname = "P-256"; - len = private ? DNS_KEY_ECDSA256SIZE / 2 : DNS_KEY_ECDSA256SIZE; } else if (key_alg == DST_ALG_ECDSA384) { groupname = "P-384"; - len = private ? DNS_KEY_ECDSA384SIZE / 2 : DNS_KEY_ECDSA384SIZE; } else { DST_RET(ISC_R_NOTIMPLEMENTED); } - ret = (private ? DST_R_INVALIDPRIVATEKEY : DST_R_INVALIDPUBLICKEY); - if (*key_len < len) { - DST_RET(ret); - } - bld = OSSL_PARAM_BLD_new(); if (bld == NULL) { DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_new", @@ -98,7 +90,7 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, } if (private) { - priv = BN_bin2bn(key, len, NULL); + priv = BN_bin2bn(key, *key_len, NULL); if (priv == NULL) { DST_RET(dst__openssl_toresult2("BN_bin2bn", DST_R_OPENSSLFAILURE)); @@ -111,11 +103,12 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, DST_R_OPENSSLFAILURE)); } } else { + INSIST(*key_len < sizeof(buf)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; - memmove(buf + 1, key, len); + memmove(buf + 1, key, *key_len); status = OSSL_PARAM_BLD_push_octet_string( - bld, OSSL_PKEY_PARAM_PUB_KEY, buf, 1 + len); + bld, OSSL_PKEY_PARAM_PUB_KEY, buf, 1 + *key_len); if (status != 1) { DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" "octet_string", @@ -146,7 +139,6 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, DST_R_OPENSSLFAILURE)); } - *key_len = len; ret = ISC_R_SUCCESS; err: @@ -1184,8 +1176,6 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { #if OPENSSL_VERSION_NUMBER < 0x30000000L EC_KEY *eckey = NULL; EC_KEY *pubeckey = NULL; -#else - size_t len; #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ const char *engine = NULL; const char *label = NULL; @@ -1257,14 +1247,9 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->keydata.pkey = NULL; } - if (key->key_alg == DST_ALG_ECDSA256) { - len = DNS_KEY_ECDSA256SIZE / 2; - } else { - len = DNS_KEY_ECDSA384SIZE / 2; - } - ret = raw_key_to_ossl(key->key_alg, 1, - priv.elements[privkey_index].data, &len, + priv.elements[privkey_index].data, + &priv.elements[privkey_index].length, &key->keydata.pkey); #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ From a9ab2bf60ba19e76d163a8e661657cebfbf1d49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Fri, 19 Nov 2021 10:32:21 +0100 Subject: [PATCH 4/6] Pass key length to raw_key_to_ossl() by value As raw_key_to_ossl() no longer stores anything at the pointer passed to it in the 'key_len' parameter, change the type of the latter to size_t. --- lib/dns/opensslecdsa_link.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 08f061208c..284f05e4e0 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -58,7 +58,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x30000000L static isc_result_t raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, - size_t *key_len, EVP_PKEY **pkey) { + size_t key_len, EVP_PKEY **pkey) { isc_result_t ret; int status; const char *groupname; @@ -90,7 +90,7 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, } if (private) { - priv = BN_bin2bn(key, *key_len, NULL); + priv = BN_bin2bn(key, key_len, NULL); if (priv == NULL) { DST_RET(dst__openssl_toresult2("BN_bin2bn", DST_R_OPENSSLFAILURE)); @@ -103,12 +103,12 @@ raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, DST_R_OPENSSLFAILURE)); } } else { - INSIST(*key_len < sizeof(buf)); + INSIST(key_len < sizeof(buf)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; - memmove(buf + 1, key, *key_len); + memmove(buf + 1, key, key_len); status = OSSL_PARAM_BLD_push_octet_string( - bld, OSSL_PKEY_PARAM_PUB_KEY, buf, 1 + *key_len); + bld, OSSL_PKEY_PARAM_PUB_KEY, buf, 1 + key_len); if (status != 1) { DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" "octet_string", @@ -789,7 +789,7 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } #else len = r.length; - ret = raw_key_to_ossl(key->key_alg, 0, r.base, &len, &pkey); + ret = raw_key_to_ossl(key->key_alg, 0, r.base, len, &pkey); if (ret != ISC_R_SUCCESS) { DST_RET(ret); } @@ -1249,7 +1249,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { ret = raw_key_to_ossl(key->key_alg, 1, priv.elements[privkey_index].data, - &priv.elements[privkey_index].length, + priv.elements[privkey_index].length, &key->keydata.pkey); #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ From 34f324062270af2c8b8b32962ad3751e2111c664 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 19 Nov 2021 10:54:05 +0100 Subject: [PATCH 5/6] Reject too long ECDSA public keys opensslecdsa_fromdns() already rejects too short ECDSA public keys. Make it also reject too long ones. Remove an assignment made redundant by this change. --- lib/dns/opensslecdsa_link.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 284f05e4e0..75411c5b68 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -752,7 +752,7 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { if (r.length == 0) { DST_RET(ISC_R_SUCCESS); } - if (r.length < len) { + if (r.length != len) { DST_RET(DST_R_INVALIDPUBLICKEY); } @@ -788,7 +788,6 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { DST_RET(dst__openssl_toresult(ISC_R_FAILURE)); } #else - len = r.length; ret = raw_key_to_ossl(key->key_alg, 0, r.base, len, &pkey); if (ret != ISC_R_SUCCESS) { DST_RET(ret); From f584df4614f0b91beb8c097c8faf23b6295efe89 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 18 Nov 2021 17:34:33 +1100 Subject: [PATCH 6/6] Add CHANGES for [GL #3014] --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 244c982267..bab431b256 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5761. [bug] OpenSSL 3.0.0 support could fail to correctly read + ECDSA private keys leading to incorrect signatures + being generated. [GL #3014] + 5760. [bug] Prevent a possible use-after-free error in resolver. [GL #3018]