1#!/bin/sh
2#
3# Copyright (C) 2010-2012  Internet Systems Consortium, Inc. ("ISC")
4#
5# Permission to use, copy, modify, and/or distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15# PERFORMANCE OF THIS SOFTWARE.
16
17# $Id$
18
19SYSTEMTESTTOP=..
20. $SYSTEMTESTTOP/conf.sh
21
22status=0
23
24RANDFILE=./random.data
25
26pzone=parent.nil
27pfile=parent.db
28
29czone=child.parent.nil
30cfile=child.db
31
32echo "I:generating child's keys"
33# active zsk
34czsk1=`$KEYGEN -q -r $RANDFILE $czone`
35
36# not yet published or active
37czsk2=`$KEYGEN -q -r $RANDFILE -P none -A none $czone`
38
39# published but not active
40czsk3=`$KEYGEN -q -r $RANDFILE -A none $czone`
41
42# inactive
43czsk4=`$KEYGEN -q -r $RANDFILE -P now-24h -A now-24h -I now $czone`
44
45# active in 12 hours, inactive 12 hours after that...
46czsk5=`$KEYGEN -q -r $RANDFILE -P now+12h -A now+12h -I now+24h $czone`
47
48# explicit successor to czk5
49# (suppressing warning about lack of removal date)
50czsk6=`$KEYGEN -q -r $RANDFILE -S $czsk5 -i 6h 2>&-` 
51
52# active ksk
53cksk1=`$KEYGEN -q -r $RANDFILE -fk $czone`
54
55# published but not YET active; will be active in 20 seconds
56cksk2=`$KEYGEN -q -r $RANDFILE -fk $czone`
57# $SETTIME moved after other $KEYGENs
58
59echo I:revoking key
60# revoking key changes its ID
61cksk3=`$KEYGEN -q -r $RANDFILE -fk $czone`
62cksk4=`$REVOKE $cksk3`
63
64echo I:generating parent keys
65pzsk=`$KEYGEN -q -r $RANDFILE $pzone`
66pksk=`$KEYGEN -q -r $RANDFILE -fk $pzone`
67
68echo "I:setting child's activation time"
69$SETTIME -A now+30s $cksk2 > /dev/null
70
71echo I:signing child zone
72czoneout=`$SIGNER -Sg -r $RANDFILE -o $czone $cfile 2>&1`
73
74echo I:signing parent zone
75pzoneout=`$SIGNER -Sg -r $RANDFILE -o $pzone $pfile 2>&1`
76
77czactive=`echo $czsk1 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
78czgenerated=`echo $czsk2 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
79czpublished=`echo $czsk3 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
80czinactive=`echo $czsk4 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
81czpredecessor=`echo $czsk5 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
82czsuccessor=`echo $czsk6 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
83ckactive=`echo $cksk1 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
84ckpublished=`echo $cksk2 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
85ckprerevoke=`echo $cksk3 | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
86ckrevoked=`echo $cksk4 | sed 's/.*+005+0*\([0-9]*\)$/\1/'`
87
88pzid=`echo $pzsk | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
89pkid=`echo $pksk | sed 's/^K.*+005+0*\([0-9]\)/\1/'`
90
91echo "I:checking dnssec-signzone output matches expectations"
92ret=0
93echo "$pzoneout" | grep 'KSKs: 1 active, 0 stand-by, 0 revoked' > /dev/null || ret=1
94echo "$pzoneout" | grep 'ZSKs: 1 active, 0 stand-by, 0 revoked' > /dev/null || ret=1
95echo "$czoneout" | grep 'KSKs: 1 active, 1 stand-by, 1 revoked' > /dev/null || ret=1
96echo "$czoneout" | grep 'ZSKs: 1 active, 2 stand-by, 0 revoked' > /dev/null || ret=1
97if [ $ret != 0 ]; then
98	echo "I: parent $pzoneout"
99	echo "I: child $czoneout"
100	echo "I:failed";
101fi
102status=`expr $status + $ret`
103
104echo "I:rechecking dnssec-signzone output with -x"
105ret=0
106# use an alternate output file so -x doesn't interfere with later checks
107pzoneout=`$SIGNER -Sxg -r $RANDFILE -o $pzone -f ${pzone}2.signed $pfile 2>&1`
108czoneout=`$SIGNER -Sxg -r $RANDFILE -o $czone -f ${czone}2.signed $cfile 2>&1`
109echo "$pzoneout" | grep 'KSKs: 1 active, 0 stand-by, 0 revoked' > /dev/null || ret=1
110echo "$pzoneout"| grep 'ZSKs: 1 active, 0 present, 0 revoked' > /dev/null || ret=1
111echo "$czoneout"| grep 'KSKs: 1 active, 1 stand-by, 1 revoked' > /dev/null || ret=1
112echo "$czoneout"| grep 'ZSKs: 1 active, 2 present, 0 revoked' > /dev/null || ret=1
113if [ $ret != 0 ]; then
114	echo "I: parent $pzoneout"
115	echo "I: child $czoneout"
116	echo "I:failed";
117fi
118status=`expr $status + $ret`
119
120echo "I:checking parent zone DNSKEY set"
121ret=0
122grep "key id = $pzid" $pfile.signed > /dev/null || {
123	ret=1
124	echo "I: missing expected parent ZSK id = $pzid"
125}
126grep "key id = $pkid" $pfile.signed > /dev/null || {
127	ret=1
128	echo "I: missing expected parent KSK id = $pkid"
129}
130if [ $ret != 0 ]; then echo "I:failed"; fi
131status=`expr $status + $ret`
132
133echo "I:checking parent zone DS records"
134ret=0
135awk '$2 == "DS" {print $3}' $pfile.signed > dsset.out
136grep -w "$ckactive" dsset.out > /dev/null || ret=1
137grep -w "$ckpublished" dsset.out > /dev/null || ret=1
138# revoked key should not be there, hence the &&
139grep -w "$ckprerevoke" dsset.out > /dev/null && ret=1
140grep -w "$ckrevoked" dsset.out > /dev/null && ret=1
141if [ $ret != 0 ]; then echo "I:failed"; fi
142status=`expr $status + $ret`
143
144echo "I:checking child zone DNSKEY set"
145ret=0
146grep "key id = $ckactive" $cfile.signed > /dev/null || {
147	ret=1
148	echo "I: missing expected child KSK id = $ckactive"
149}
150grep "key id = $ckpublished" $cfile.signed > /dev/null || {
151	ret=1
152	echo "I: missing expected child prepublished KSK id = $ckpublished"
153}
154grep "key id = $ckrevoked" $cfile.signed > /dev/null || {
155	ret=1
156	echo "I: missing expected child revoked KSK id = $ckrevoked"
157}
158grep "key id = $czactive" $cfile.signed > /dev/null || {
159	ret=1
160	echo "I: missing expected child ZSK id = $czactive"
161}
162grep "key id = $czpublished" $cfile.signed > /dev/null || {
163	ret=1
164	echo "I: missing expected child prepublished ZSK id = $czpublished"
165}
166grep "key id = $czinactive" $cfile.signed > /dev/null || {
167	ret=1
168	echo "I: missing expected child inactive ZSK id = $czinactive"
169}
170# should not be there, hence the &&
171grep "key id = $ckprerevoke" $cfile.signed > /dev/null && {
172	ret=1
173	echo "I: found unexpect child pre-revoke ZSK id = $ckprerevoke"
174}
175grep "key id = $czgenerated" $cfile.signed > /dev/null && {
176	ret=1
177	echo "I: found unexpected child generated ZSK id = $czgenerated"
178}
179grep "key id = $czpredecessor" $cfile.signed > /dev/null && {
180	echo "I: found unexpected ZSK predecessor id = $czpredecessor (ignored)"
181}
182grep "key id = $czsuccessor" $cfile.signed > /dev/null && {
183	echo "I: found unexpected ZSK successor id = $czsuccessor (ignored)"
184}
185#grep "key id = $czpredecessor" $cfile.signed > /dev/null && ret=1
186#grep "key id = $czsuccessor" $cfile.signed > /dev/null && ret=1
187if [ $ret != 0 ]; then echo "I:failed"; fi
188status=`expr $status + $ret`
189
190echo "I:checking child zone signatures"
191ret=0
192# check DNSKEY signatures first
193awk '$2 == "RRSIG" && $3 == "DNSKEY" { getline; print $2 }' $cfile.signed > dnskey.sigs
194grep -w "$ckactive" dnskey.sigs > /dev/null || ret=1
195grep -w "$ckrevoked" dnskey.sigs > /dev/null || ret=1
196grep -w "$czactive" dnskey.sigs > /dev/null || ret=1
197# should not be there:
198grep -w "$ckprerevoke" dnskey.sigs > /dev/null && ret=1
199grep -w "$ckpublished" dnskey.sigs > /dev/null && ret=1
200grep -w "$czpublished" dnskey.sigs > /dev/null && ret=1
201grep -w "$czinactive" dnskey.sigs > /dev/null && ret=1
202grep -w "$czgenerated" dnskey.sigs > /dev/null && ret=1
203# now check other signatures
204awk '$2 == "RRSIG" && $3 != "DNSKEY" { getline; print $2 }' $cfile.signed | sort -un > other.sigs
205# should not be there:
206grep -w "$ckactive" other.sigs > /dev/null && ret=1
207grep -w "$ckpublished" other.sigs > /dev/null && ret=1
208grep -w "$ckprerevoke" other.sigs > /dev/null && ret=1
209grep -w "$ckrevoked" other.sigs > /dev/null && ret=1
210grep -w "$czpublished" other.sigs > /dev/null && ret=1
211grep -w "$czinactive" other.sigs > /dev/null && ret=1
212grep -w "$czgenerated" other.sigs > /dev/null && ret=1
213grep -w "$czpredecessor" other.sigs > /dev/null && ret=1
214grep -w "$czsuccessor" other.sigs > /dev/null && ret=1
215if [ $ret != 0 ]; then echo "I:failed"; fi
216status=`expr $status + $ret`
217
218echo "I:waiting 30 seconds for key activation"
219sleep 30
220echo "I:re-signing child zone"
221czoneout2=`$SIGNER -Sg -r $RANDFILE -o $czone -f $cfile.new $cfile.signed 2>&1`
222mv $cfile.new $cfile.signed
223
224echo "I:checking dnssec-signzone output matches expectations"
225ret=0
226echo "$czoneout2" | grep 'KSKs: 2 active, 0 stand-by, 1 revoked' > /dev/null || ret=1
227if [ $ret != 0 ]; then echo "I:failed"; fi
228status=`expr $status + $ret`
229
230echo "I:checking child zone signatures again"
231ret=0
232awk '$2 == "RRSIG" && $3 == "DNSKEY" { getline; print $2 }' $cfile.signed > dnskey.sigs
233grep -w "$ckpublished" dnskey.sigs > /dev/null || ret=1
234if [ $ret != 0 ]; then echo "I:failed"; fi
235status=`expr $status + $ret`
236
237echo "I:exit status: $status"
238exit $status
239