2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

dnssec-keygen can create keys given dnssec-policy

This commit adds code for generating keys with dnssec-keygen given
a specific dnssec-policy.

The dnssec-policy can be set with a new option '-k'. The '-l'
option can be used to set a configuration file that contains a
specific dnssec-policy.

Because the dnssec-policy dictates how the keys should look like,
many of the existing dnssec-keygen options cannot be used together
with '-k'.

If the dnssec-policy lists multiple keys, dnssec-keygen has now the
possibility to generate multiple keys at one run.

Add two tests for creating keys with '-k': One with the default
policy, one with multiple keys from the configuration.
This commit is contained in:
Matthijs Mekking
2019-09-11 16:38:49 +02:00
parent 97a5698e06
commit 09ac224c5c
9 changed files with 480 additions and 18 deletions

View File

@@ -0,0 +1,17 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
set -e
rm -f ./keygen.*
rm -f ./K*.private ./K*.key ./K*.state ./K*.cmp
rm -f ./keys/K*
rmdir ./keys/

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* This is just a random selection of configuration options.
*/
dnssec-policy "kasp" {
dnskey-ttl 200;
keys {
csk key-directory P1Y 13;
ksk key-directory P1Y 8;
zsk key-directory P30D 8 1024;
zsk key-directory P6M 8 2000;
};
};

View File

@@ -0,0 +1,19 @@
#!/bin/sh -e
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. "$SYSTEMTESTTOP/conf.sh"
set -e
$SHELL clean.sh
mkdir keys

View File

@@ -0,0 +1,182 @@
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
SYSTEMTESTTOP=..
. "$SYSTEMTESTTOP/conf.sh"
set -e
status=0
n=0
log=1
################################################################################
# Utilities #
################################################################################
# Get the key ids from key files for zone $2 in directory $1
# that matches algorithm $3.
get_keyids() {
dir=$1
zone=$2
algorithm=$(printf "%03d" $3)
start="${dir}/K${zone}.+${algorithm}+"
end=".key"
ls ${start}*${end} | sed "s/$dir\/K${zone}.+${algorithm}+\([0-9]\{5\}\)${end}/\1/"
}
log_error() {
test $log -eq 1 && echo_i "error: $1"
ret=$((ret+1))
}
# Check the created key in directory $1 for zone $2.
# $3: key role. Must be one of "csk", "ksk", or "zsk".
# $4: key identifier (zero padded)
# $5: algorithm number
# $6: algorithm (string format)
# $7: algorithm length
# $8: dnskey ttl
# $9: key lifetime
check_created_key() {
dir=$1
zone=$2
role=$3
key_idpad=$4
key_id=$(echo $key_idpad | sed 's/^0*//')
alg_num=$5
alg_numpad=$(printf "%03d" $alg_num)
alg_string=$6
length=$7
dnskey_ttl=$8
lifetime=$9
ksk="no"
zsk="no"
if [ "$role" == "ksk" ]; then
role2="key-signing"
ksk="yes"
flags="257"
elif [ "$role" == "zsk" ]; then
role2="zone-signing"
zsk="yes"
flags="256"
elif [ "$role" == "csk" ]; then
role2="key-signing"
zsk="yes"
ksk="yes"
flags="257"
fi
KEY_FILE="${dir}/K${zone}.+${alg_numpad}+${key_idpad}.key"
PRIVATE_FILE="${dir}/K${zone}.+${alg_numpad}+${key_idpad}.private"
STATE_FILE="${dir}/K${zone}.+${alg_numpad}+${key_idpad}.state"
# Check the public key file. We expect three lines: a comment,
# a "Created" line, and the DNSKEY record.
lines=$(cat $KEY_FILE | wc -l)
test "$lines" -eq 3 || log_error "bad public keyfile $KEY_FILE"
grep "This is a ${role2} key, keyid ${key_id}, for ${zone}." $KEY_FILE > /dev/null || log_error "mismatch top comment in $KEY_FILE"
grep "; Created:" $KEY_FILE > /dev/null || log_error "mismatch created comment in $KEY_FILE"
grep "${zone}\. ${dnskey_ttl} IN DNSKEY ${flags} 3 ${alg_num}" $KEY_FILE > /dev/null || log_error "mismatch DNSKEY record in $KEY_FILE"
# Now check the private key file.
grep "Private-key-format: v1.3" $PRIVATE_FILE > /dev/null || log_error "mismatch private key format in $PRIVATE_FILE"
grep "Algorithm: ${alg_num} (${alg_string})" $PRIVATE_FILE > /dev/null || log_error "mismatch algorithm in $PRIVATE_FILE"
grep "Created:" $PRIVATE_FILE > /dev/null || log_error "mismatch created in $PRIVATE_FILE"
# Now check the key state file. There should be seven lines:
# a top comment, "Generated", "Lifetime", "Algorithm", "Length",
# "KSK", and "ZSK".
lines=$(cat $STATE_FILE | wc -l)
test "$lines" -eq 7 || log_error "bad state keyfile $STATE_FILE"
grep "This is the state of key ${key_id}, for ${zone}." $STATE_FILE > /dev/null || log_error "mismatch top comment in $STATE_FILE"
# XXX: Could check if generated is ~now.
grep "Generated: " $STATE_FILE > /dev/null || log_error "mismatch generated in $STATE_FILE"
grep "Lifetime: ${lifetime}" $STATE_FILE > /dev/null || log_error "mismatch lifetime in $STATE_FILE"
grep "Algorithm: ${alg_num}" $STATE_FILE > /dev/null || log_error "mismatch algorithm in $STATE_FILE"
grep "Length: ${length}" $STATE_FILE > /dev/null || log_error "mismatch length in $STATE_FILE"
grep "KSK: ${ksk}" $STATE_FILE > /dev/null || log_error "mismatch ksk in $STATE_FILE"
grep "ZSK: ${zsk}" $STATE_FILE > /dev/null || log_error "mismatch zsk in $STATE_FILE"
}
################################################################################
# Tests #
################################################################################
#
# dnssec-keygen
#
n=$((n+1))
echo_i "check that 'dnssec-keygen -k' (default policy) creates valid files ($n)"
ret=0
$KEYGEN -k _default kasp > keygen.out._default.test$n 2>/dev/null || ret=1
lines=$(cat keygen.out._default.test$n | wc -l)
test "$lines" -eq 1 || log_error "wrong number of keys created for policy _default"
KEY_ID=$(get_keyids "." "kasp" "13")
echo_i "check key $KEY_ID..."
check_created_key "." "kasp" "csk" $KEY_ID "13" "ECDSAP256SHA256" "256" "3600" "0"
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
n=$((n+1))
echo_i "check that 'dnssec-keygen -k' (configured policy) creates valid files ($n)"
ret=0
$KEYGEN -K keys -k kasp -l kasp.conf kasp > keygen.out.kasp.test$n 2>/dev/null || ret=1
lines=$(cat keygen.out.kasp.test$n | wc -l)
test "$lines" -eq 4 || log_error "wrong number of keys created for policy kasp"
# Check one algorithm.
KEY_ID=$(get_keyids "keys" "kasp" "13")
echo_i "check key $KEY_ID..."
check_created_key "keys" "kasp" "csk" $KEY_ID "13" "ECDSAP256SHA256" "256" "200" "31536000"
# Temporarily don't log errors because we are searching multiple files.
log=0
# Check the other algorithm.
KEY_IDS=$(get_keyids "keys" "kasp" "8")
for KEY_ID in $KEY_IDS; do
echo_i "check key $KEY_ID..."
# There are three key files with the same algorithm.
# Check them until a match is found.
ret=0 && check_created_key "keys" "kasp" "ksk" $KEY_ID "8" "RSASHA256" "2048" "200" "31536000"
test "$ret" -gt 0 && ret=0 && check_created_key "keys" "kasp" "zsk" $KEY_ID "8" "RSASHA256" "1024" "200" "2592000"
test "$ret" -gt 0 && ret=0 && check_created_key "keys" "kasp" "zsk" $KEY_ID "8" "RSASHA256" "2000" "200" "16070400"
# If ret is non-zero, non of the files matched.
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
done
# Turn error logs on again.
log=1
n=$((n+1))
echo_i "check that 'dnssec-keygen -k' (default policy) creates valid files ($n)"
ret=0
$KEYGEN -k default kasp > keygen.out.default.test$n 2>/dev/null || ret=1
lines=$(cat keygen.out.default.test$n | wc -l)
test "$lines" -eq 1 || log_error "wrong number of keys created for policy default"
KEY_ID=$(get_keyids "." "kasp" "13")
echo_i "check key $KEY_ID..."
check_created_key "." "kasp" "csk" $KEY_ID "13" "ECDSAP256SHA256" "256" "3600" "0"
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
#
# dnssec-settime
#
#
# named
#
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1