1 /* $NetBSD: rollover.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) rollover.c -- The key rollover functions
7 ** Copyright (c) Jan 2005 - May 2008, Holger Zuleger HZnet. All rights reserved.
9 ** This software is open source.
11 ** Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions
15 ** Redistributions of source code must retain the above copyright notice,
16 ** this list of conditions and the following disclaimer.
18 ** Redistributions in binary form must reproduce the above copyright notice,
19 ** this list of conditions and the following disclaimer in the documentation
20 ** and/or other materials provided with the distribution.
22 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
23 ** be used to endorse or promote products derived from this software without
24 ** specific prior written permission.
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 ** POSSIBILITY OF SUCH DAMAGE.
38 *****************************************************************/
51 # include "config_zkt.h"
60 # include "rollover.h"
63 /*****************************************************************
64 ** local function definition
65 *****************************************************************/
67 static dki_t
*genkey (int addkey
, dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
);
69 /* generate the first (or primary) key (algorithm k_algo) */
70 static dki_t
*genfirstkey (dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
)
72 return genkey (0, listp
, dir
, domain
, ksk
, conf
, status
);
75 /* generate the additional (or second) key (algorithm k2_algo) */
76 static dki_t
*genaddkey (dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
)
78 return genkey (1, listp
, dir
, domain
, ksk
, conf
, status
);
82 /* generate a DNSKEY key */
83 static dki_t
*genkey (int addkey
, dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
)
90 if ( listp
== NULL
|| domain
== NULL
)
93 assert ( listp
!= NULL
);
94 assert ( domain
!= NULL
);
97 if ( addkey
) /* generating an additional key ? */
98 confalgo
= conf
->k2_algo
;
100 confalgo
= conf
->k_algo
;
103 if ( conf
->nsec3
!= NSEC3_OFF
) /* is nsec3 turned on ? */
105 if ( confalgo
== DK_ALGO_RSASHA1
)
106 algo
= DK_ALGO_NSEC3RSASHA1
;
107 else if ( confalgo
== DK_ALGO_DSA
)
108 algo
= DK_ALGO_NSEC3DSA
;
112 dkp
= dki_new (dir
, domain
, DKI_KSK
, algo
, conf
->k_bits
, conf
->k_random
, conf
->k_life
/ DAYSEC
);
114 dkp
= dki_new (dir
, domain
, DKI_ZSK
, algo
, conf
->z_bits
, conf
->z_random
, conf
->z_life
/ DAYSEC
);
115 dki_add (listp
, dkp
);
116 dki_setstatus (dkp
, status
);
121 /* get expiration time */
122 static time_t get_exptime (dki_t
*key
, const zconf_t
*z
)
126 exptime
= dki_exptime (key
);
129 if ( dki_lifetime (key
) )
130 exptime
= dki_time (key
) + dki_lifetime (key
);
132 exptime
= dki_time (key
) + z
->k_life
;
138 /*****************************************************************
139 ** is_parentdirsigned (name)
140 ** Check if the parent directory of the zone specified by zp
141 ** is a directory with a signed zone
143 *****************************************************************/
144 static int is_parentdirsigned (const zone_t
*zonelist
, const zone_t
*zp
)
146 char path
[MAX_PATHSIZE
+1];
151 /* check if there is a local config file to get the name of the zone file */
152 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, LOCALCONF_FILE
);
153 if ( fileexist (path
) ) /* parent dir has local config file ? */
154 conf
= loadconfig (path
, NULL
);
158 /* build the path of the .signed zone file */
159 snprintf (path
, sizeof (path
), "%s/../%s.signed", conf
->dir
, conf
->zonefile
);
160 if ( conf
!= zp
->conf
) /* if we read in a local config file.. */
161 free (conf
); /* ..free the memory used */
164 /* currently we use the signed zone file name of the
165 * current directory for checking if the file exist.
166 * TODO: Instead we have to use the name of the zone file
167 * used in the parent dir (see above)
170 ext
= strrchr (zp
->sfile
, '.');
171 if ( ext
&& strcmp (zp
->sfile
, ".dsigned") == 0 ) /* is the current zone a dynamic one ? */
172 /* hack: we are using the standard zone file name for a static zone here */
173 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, "zone.db.signed");
177 const zone_t
*parent
;
178 const char *parentname
;
180 /* find out name of parent */
181 parentname
= strchr (zp
->zone
, '.'); /* find first dot in zone name */
182 if ( parentname
== NULL
) /* no parent found! */
184 parentname
+= 1; /* skip '.' */
186 /* try to find parent zone in zonelist */
187 if ( (parent
= zone_search (zonelist
, parentname
)) == NULL
)
189 snprintf (path
, sizeof (path
), "%s/%s", parent
->dir
, parent
->sfile
);
191 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, zp
->sfile
);
195 lg_mesg (LG_DEBUG
, "%s: is_parentdirsigned = %d fileexist (%s)\n", zp
->zone
, fileexist (path
), path
);
196 return fileexist (path
); /* parent dir has zone.db.signed file ? */
199 /*****************************************************************
200 ** create_parent_file ()
201 *****************************************************************/
202 static int create_parent_file (const char *fname
, int phase
, int ttl
, const dki_t
*dkp
)
206 assert ( fname
!= NULL
);
208 if ( dkp
== NULL
|| (phase
!= 1 && phase
!= 2) )
211 if ( (fp
= fopen (fname
, "w")) == NULL
)
212 fatal ("can\'t create new parentfile \"%s\"\n", fname
);
215 fprintf (fp
, "; KSK rollover phase1 (new key generated but this is alread the old one)\n");
217 fprintf (fp
, "; KSK rollover phase2 (this is the new key)\n");
219 dki_prt_dnskeyttl (dkp
, fp
, ttl
);
225 /*****************************************************************
226 ** get_parent_phase ()
227 *****************************************************************/
228 static int get_parent_phase (const char *file
)
233 if ( (fp
= fopen (file
, "r")) == NULL
)
237 if ( fscanf (fp
, "; KSK rollover phase%d", &phase
) != 1 )
244 /*****************************************************************
246 *****************************************************************/
247 static int kskrollover (dki_t
*ksk
, zone_t
*zonelist
, zone_t
*zp
)
249 char path
[MAX_PATHSIZE
+1];
256 int parent_propagation
;
261 assert ( ksk
!= NULL
);
262 assert ( zp
!= NULL
);
265 /* check ksk lifetime */
266 if ( (lifetime
= dki_lifetime (ksk
)) == 0 ) /* if lifetime of key is not set.. */
267 lifetime
= z
->k_life
; /* ..use global configured lifetime */
269 currtime
= time (NULL
);
270 age
= dki_age (ksk
, currtime
);
272 /* build path of parent-file */
273 pathname (path
, sizeof (path
), zp
->dir
, "parent-", zp
->zone
);
275 /* check if we have to change the ksk ? */
276 if ( lifetime
> 0 && age
> lifetime
&& !fileexist (path
) ) /* lifetime is over and no kskrollover in progress */
278 /* we are in hierachical mode and the parent directory contains a signed zone ? */
279 if ( z
->keysetdir
&& strcmp (z
->keysetdir
, "..") == 0 && is_parentdirsigned (zonelist
, zp
) )
281 verbmesg (2, z
, "\t\tkskrollover: create new key signing key\n");
282 /* create a new key: this is phase one of a double signing key rollover */
283 ksk
= genfirstkey (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
286 lg_mesg (LG_ERROR
, "\"%s\": unable to generate new ksk for double signing rollover", zp
->zone
);
289 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase1: New key %d generated", zp
->zone
, ksk
->tag
);
291 /* find the oldest active ksk to create the parent file */
292 if ( (ksk
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, zp
->conf
->k_algo
, 'a', 1)) == NULL
)
293 lg_mesg (LG_ERROR
, "kskrollover phase1: Couldn't find the old active key\n");
294 if ( !create_parent_file (path
, 1, z
->key_ttl
, ksk
) )
295 lg_mesg (LG_ERROR
, "Couldn't create parentfile %s\n", path
);
298 else /* print out a warning only */
300 logmesg ("\t\tWarning: Lifetime of Key Signing Key %d exceeded: %s\n",
301 ksk
->tag
, str_delspace (age2str (age
)));
302 lg_mesg (LG_WARNING
, "\"%s\": lifetime of key signing key %d exceeded since %s",
303 zp
->zone
, ksk
->tag
, str_delspace (age2str (age
- lifetime
)));
308 /* now check if there is an ongoing key rollover */
310 /* check if parent-file already exist */
311 if ( !fileexist (path
) ) /* no parent-<zone> file found ? */
312 return 0; /* ok, that's it */
314 /* check the ksk rollover phase we are in */
315 currphase
= get_parent_phase (path
); /* this is the actual state we are in */
316 parfile_age
= file_age (path
);
318 /* TODO: Set these values to the one found in the parent dnssec.conf file */
319 parent_propagation
= PARENT_PROPAGATION
;
320 parent_resign
= z
->resign
;
321 parent_keyttl
= z
->key_ttl
;
325 case 1: /* we are currently in state one (new ksk already generated) */
326 if ( parfile_age
> z
->proptime
+ z
->key_ttl
) /* can we go to phase 2 ? */
328 verbmesg (2, z
, "\t\tkskrollover: save new ksk in parent file\n");
329 ksk
= ksk
->next
; /* set ksk to new ksk */
330 if ( !create_parent_file (path
, currphase
+1, z
->key_ttl
, ksk
) )
331 lg_mesg (LG_ERROR
, "Couldn't create parentfile %s\n", path
);
332 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase2: send new key %d to the parent zone", zp
->zone
, ksk
->tag
);
336 verbmesg (2, z
, "\t\tkskrollover: we are in state 1 and waiting for propagation of the new key (parentfile %dsec < prop %dsec + keyttl %dsec\n", parfile_age
, z
->proptime
, z
->key_ttl
);
338 case 2: /* we are currently in state two (propagation of new key to the parent) */
340 if ( parfile_age
>= parent_propagation
+ parent_resign
+ parent_keyttl
) /* can we go to phase 3 ? */
342 if ( parfile_age
>= parent_propagation
+ parent_keyttl
) /* can we go to phase 3 ? */
345 /* remove the parentfile */
348 /* remove oldest key from list and mark file as removed */
349 zp
->keys
= dki_remove (ksk
);
351 // verbmesg (2, z, "kskrollover: remove parentfile and rename old key to k<zone>+<algo>+<tag>.key\n");
352 verbmesg (2, z
, "\t\tkskrollover: remove parentfile and rename old key to k%s+%03d+%05d.key\n",
353 ksk
->name
, ksk
->algo
, ksk
->tag
);
354 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase3: Remove old key %d", zp
->zone
, ksk
->tag
);
359 verbmesg (2, z
, "\t\tkskrollover: we are in state 2 and waiting for parent propagation (parentfile %d < parentprop %d + parentresig %d + parentkeyttl %d\n", parfile_age
, parent_propagation
, parent_resign
, parent_keyttl
);
361 verbmesg (2, z
, "\t\tkskrollover: we are in state 2 and waiting for parent propagation (parentfile %dsec < parentprop %dsec + parentkeyttl %dsec\n", parfile_age
, parent_propagation
, parent_keyttl
);
365 assert ( currphase
== 1 || currphase
== 2 );
372 /*****************************************************************
373 ** global function definition
374 *****************************************************************/
376 /*****************************************************************
378 ** Check if the list of zone keys containing a revoked or a
380 ** Remove the revoked key if it is older than 30 days.
381 ** If the lifetime of the active key is reached, do a rfc5011
383 ** Returns an int with the rightmost bit set if a resigning
384 ** is required. The second rightmost bit is set, if it is an
386 *****************************************************************/
387 int ksk5011status (dki_t
**listp
, const char *dir
, const char *domain
, const zconf_t
*z
)
397 assert ( listp
!= NULL
);
398 assert ( z
!= NULL
);
400 if ( z
->k_life
== 0 )
403 verbmesg (1, z
, "\tCheck RFC5011 status\n");
406 currtime
= time (NULL
);
408 /* go through the list of key signing keys, */
409 /* remove revoked keys and set a pointer to standby and active key */
410 standbykey
= activekey
= NULL
;
412 for ( dkp
= *listp
; dkp
&& dki_isksk (dkp
); dkp
= dkp
->next
)
414 exptime
= get_exptime (dkp
, z
);
415 if ( dki_isrevoked (dkp
) )
416 lg_mesg (LG_DEBUG
, "zone \"%s\": found revoked key (id=%d exptime=%s); waiting for remove hold down time",
417 domain
, dkp
->tag
, time2str (exptime
, 's'));
419 /* revoked key is older than 30 days? */
420 if ( dki_isrevoked (dkp
) && currtime
> exptime
+ REMOVE_HOLD_DOWN
)
422 verbmesg (1, z
, "\tRemove revoked key %d which is older than 30 days\n", dkp
->tag
);
423 lg_mesg (LG_NOTICE
, "zone \"%s\": removing revoked key %d", domain
, dkp
->tag
);
425 /* remove key from list and mark file as removed */
426 if ( prev
== NULL
) /* at the beginning of the list ? */
427 *listp
= dki_remove (dkp
);
428 else /* anywhere in the middle of the list */
429 prev
->next
= dki_remove (dkp
);
431 ret
|= 01; /* from now on a resigning is necessary */
434 /* remember oldest standby and active key */
435 if ( dki_status (dkp
) == DKI_PUBLISHED
)
437 if ( dki_status (dkp
) == DKI_ACTIVE
)
440 /* no activekey or no standby key and also no revoked key found ? */
441 if ( activekey
== NULL
|| (standbykey
== NULL
&& ret
== 0) )
442 return ret
; /* Seems that this is a non rfc5011 zone! */
444 ret
|= 02; /* Zone looks like a rfc5011 zone */
446 exptime
= get_exptime (activekey
, z
);
448 lg_mesg (LG_DEBUG
, "Act Exptime: %s", time2str (exptime
, 's'));
449 lg_mesg (LG_DEBUG
, "Stb time: %s", time2str (dki_time (standbykey
), 's'));
450 lg_mesg (LG_DEBUG
, "Stb time+wait: %s", time2str (dki_time (standbykey
) + min (DAYSEC
* 30, z
->key_ttl
), 's'));
452 /* At the first time we introduce a standby key, the lifetime of the current KSK shouldn't be expired, */
453 /* otherwise we run into an (nearly) immediate key rollover! */
454 if ( currtime
> exptime
&& currtime
> dki_time (standbykey
) + min (ADD_HOLD_DOWN
, z
->key_ttl
) )
456 lg_mesg (LG_NOTICE
, "\"%s\": starting rfc5011 rollover", domain
);
457 verbmesg (1, z
, "\tLifetime of Key Signing Key %d exceeded (%s): Starting rfc5011 rollover!\n",
458 activekey
->tag
, str_delspace (age2str (dki_age (activekey
, currtime
))));
459 verbmesg (2, z
, "\t\t=>Generating new standby key signing key\n");
460 dkp
= genfirstkey (listp
, dir
, domain
, DKI_KSK
, z
, DKI_PUBLISHED
); /* gentime == now; lifetime = z->k_life; exp = 0 */
463 error ("\tcould not generate new standby KSK\n");
464 lg_mesg (LG_ERROR
, "\%s\": can't generate new standby KSK", domain
);
467 lg_mesg (LG_NOTICE
, "\"%s\": generated new standby KSK %d", domain
, dkp
->tag
);
469 /* standby key gets active */
470 verbmesg (2, z
, "\t\t=>Activating old standby key %d \n", standbykey
->tag
);
471 dki_setstatus (standbykey
, DKI_ACT
);
473 /* active key should be revoked */
474 verbmesg (2, z
, "\t\t=>Revoking old active key %d \n", activekey
->tag
);
475 dki_setstatus (activekey
, DKI_REVOKED
);
476 dki_setexptime (activekey
, currtime
); /* now the key is expired */
478 ret
|= 01; /* resigning necessary */
484 /*****************************************************************
486 ** Check the ksk status of a zone if a ksk lifetime is set.
487 ** If there is no key signing key present create a new one.
488 ** Prints out a warning message if the lifetime of the current
489 ** key signing key is over.
490 ** Returns 1 if a resigning of the zone is necessary, otherwise
491 ** the function returns 0.
492 *****************************************************************/
493 int kskstatus (zone_t
*zonelist
, zone_t
*zp
)
498 assert ( zp
!= NULL
);
501 if ( z
->k_life
== 0 )
504 verbmesg (1, z
, "\tCheck KSK status\n");
505 /* check if a key signing key exist ? */
506 akey
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, z
->k_algo
, 'a', 1);
509 verbmesg (1, z
, "\tNo active KSK found: generate new one\n");
510 akey
= genfirstkey (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
513 error ("\tcould not generate new KSK\n");
514 lg_mesg (LG_ERROR
, "\"%s\": can't generate new KSK: \"%s\"",
515 zp
->zone
, dki_geterrstr());
518 lg_mesg (LG_INFO
, "\"%s\": generated new KSK %d", zp
->zone
, akey
->tag
);
519 return akey
!= NULL
; /* return value of 1 forces a resigning of the zone */
521 else /* try to start a full automated ksk rollover */
522 kskrollover (akey
, zonelist
, zp
);
524 /* is a second algorithm requested ? (since 0.99) */
525 if ( z
->k2_algo
&& z
->k2_algo
!= z
->k_algo
)
527 /* check for ksk supporting the additional algorithm */
528 akey
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, z
->k2_algo
, 'a', 1);
531 verbmesg (1, z
, "\tNo active KSK for additional algorithm found: generate new one\n");
532 akey
= genaddkey (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
535 error ("\tcould not generate new KSK for additional algorithm\n");
536 lg_mesg (LG_ERROR
, "\"%s\": can't generate new KSK for 2nd algorithm: \"%s\"",
537 zp
->zone
, dki_geterrstr());
540 lg_mesg (LG_INFO
, "\"%s\": generated new KSK %d for additional algorithm",
541 zp
->zone
, akey
->tag
);
542 return 1; /* return value of 1 forces a resigning of the zone */
549 /*****************************************************************
551 ** Check the zsk status of a zone.
552 ** Returns 1 if a resigning of the zone is necessary, otherwise
553 ** the function returns 0.
554 *****************************************************************/
555 int zskstatus (dki_t
**listp
, const char *dir
, const char *domain
, const zconf_t
*z
)
565 assert ( listp
!= NULL
);
566 /* dir can be NULL */
567 assert ( domain
!= NULL
);
568 assert ( z
!= NULL
);
570 currtime
= time (NULL
);
572 verbmesg (1, z
, "\tCheck ZSK status\n");
573 dbg_val("zskstatus for %s \n", domain
);
575 /* Is the depreciated key expired ? */
576 /* As mentioned by olaf, this is the max_ttl of all the rr in the zone */
577 lifetime
= z
->max_ttl
+ z
->proptime
; /* draft kolkman/gieben */
581 if ( !dki_isksk (dkp
) &&
582 dki_status (dkp
) == DKI_DEPRECIATED
&&
583 dki_age (dkp
, currtime
) > lifetime
)
586 verbmesg (1, z
, "\tLifetime(%d sec) of depreciated key %d exceeded (%d sec)\n",
587 lifetime
, dkp
->tag
, dki_age (dkp
, currtime
));
588 lg_mesg (LG_INFO
, "\"%s\": old ZSK %d removed", domain
, dkp
->tag
);
589 dkp
= dki_destroy (dkp
); /* delete the keyfiles */
590 dbg_msg("zskstatus: depreciated key removed ");
595 verbmesg (1, z
, "\t\t->remove it\n");
603 /* check status of active key */
604 dbg_msg("zskstatus check status of active key ");
605 lifetime
= z
->z_life
; /* global configured lifetime for zsk */
606 akey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'a', 1);
607 if ( akey
== NULL
&& lifetime
> 0 ) /* no active key found */
609 verbmesg (1, z
, "\tNo active ZSK found: generate new one\n");
610 akey
= genfirstkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_ACTIVE
);
613 error ("\tcould not generate new ZSK\n");
614 lg_mesg (LG_ERROR
, "\%s\": can't generate new ZSK", domain
);
617 lg_mesg (LG_INFO
, "\"%s\": generated new ZSK %d", domain
, akey
->tag
);
619 else /* active key exist */
621 if ( dki_lifetime (akey
) )
622 lifetime
= dki_lifetime (akey
); /* set lifetime to lt of active key */
624 /* lifetime of active key is expired and published key exist ? */
625 age
= dki_age (akey
, currtime
);
626 if ( lifetime
> 0 && age
> lifetime
- (OFFSET
) )
628 verbmesg (1, z
, "\tLifetime(%d +/-%d sec) of active key %d exceeded (%d sec)\n",
629 lifetime
, (OFFSET
) , akey
->tag
, dki_age (akey
, currtime
) );
631 /* depreciate the key only if there is another active or published key */
632 if ( (nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'a', 2)) == NULL
||
634 nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'p', 1);
636 /* Is the published key sufficient long in the zone ? */
637 /* As mentioned by Olaf, this should be the ttl of the DNSKEY RR ! */
638 if ( nextkey
&& dki_age (nextkey
, currtime
) > z
->key_ttl
+ z
->proptime
)
641 verbmesg (1, z
, "\t\t->depreciate it\n");
642 dki_setstatus (akey
, 'd'); /* depreciate the active key */
643 verbmesg (1, z
, "\t\t->activate published key %d\n", nextkey
->tag
);
644 dki_setstatus (nextkey
, 'a'); /* activate published key */
645 lg_mesg (LG_NOTICE
, "\"%s\": lifetime of zone signing key %d exceeded: ZSK rollover done", domain
, akey
->tag
);
648 lifetime
= dki_lifetime (akey
); /* set lifetime to lt of the new active key (F. Behrens) */
652 verbmesg (1, z
, "\t\t->waiting for published key\n");
653 lg_mesg (LG_NOTICE
, "\"%s\": lifetime of zone signing key %d exceeded since %s: ZSK rollover deferred: waiting for published key",
654 domain
, akey
->tag
, str_delspace (age2str (age
- lifetime
)));
659 /* Should we add a new publish key? */
660 nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'p', 1); /* is there a published ZSK? */
661 #if defined(ALLOW_ALWAYS_PREPUBLISH_ZSK) && ALLOW_ALWAYS_PREPUBLISH_ZSK
662 if ( z
->z_always
) /* always add a pre-publish ZSK (patch from Hrant Dadivanyan) */
664 if ( nextkey
== NULL
)
666 verbmesg (1, z
, "\tNew key for pre-publishing needed\n");
667 nextkey
= genfirstkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_PUB
);
671 verbmesg (1, z
, "\t\t->creating new key %d\n", nextkey
->tag
);
672 lg_mesg (LG_INFO
, "\"%s\": new key %d generated for pre-publishing", domain
, nextkey
->tag
);
676 error ("\tcould not generate new ZSK: \"%s\"\n", dki_geterrstr());
677 lg_mesg (LG_ERROR
, "\"%s\": can't generate new ZSK: \"%s\"",
678 domain
, dki_geterrstr());
682 else /* do we need a new ZSK ? */
685 /* This is necessary if the active key will be expired at the
686 * next re-signing interval (The published time will be checked
687 * just before the active key will be removed. See above).
689 if ( nextkey
== NULL
&& lifetime
> 0 && (akey
== NULL
||
690 dki_age (akey
, currtime
+ z
->resign
) > lifetime
- (OFFSET
)) )
692 verbmesg (1, z
, "\tNew ZSK for publishing needed\n");
693 nextkey
= genfirstkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_PUB
);
697 verbmesg (1, z
, "\t\t->creating new key %d\n", nextkey
->tag
);
698 lg_mesg (LG_INFO
, "\"%s\": new zone signing key %d generated for publishing", domain
, nextkey
->tag
);
702 error ("\tcould not generate new ZSK: \"%s\"\n", dki_geterrstr());
703 lg_mesg (LG_ERROR
, "\"%s\": can't generate new ZSK: \"%s\"",
704 domain
, dki_geterrstr());
709 /* is a second algorithm requested ? (since 0.99) */
710 if ( z
->k2_algo
&& z
->k2_algo
!= z
->k_algo
)
712 /* check for zsk supporting the additional algorithm */
713 akey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k2_algo
, 'a', 1);
716 verbmesg (1, z
, "\tNo active ZSK for second algorithm found: generate new one\n");
717 akey
= genaddkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_ACTIVE
);
720 error ("\tcould not generate new ZSK for 2nd algorithm\n");
721 lg_mesg (LG_ERROR
, "\"%s\": can't generate new ZSK for 2nd algorithm: \"%s\"",
722 domain
, dki_geterrstr());
725 lg_mesg (LG_INFO
, "\"%s\": generated new ZSK %d for 2nd algorithm",
727 return 1; /* return value of 1 forces a resigning of the zone */