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 (dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
)
71 if ( listp
== NULL
|| domain
== NULL
)
75 dkp
= dki_new (dir
, domain
, DKI_KSK
, conf
->k_algo
, conf
->k_bits
, conf
->k_random
, conf
->k_life
/ DAYSEC
);
77 dkp
= dki_new (dir
, domain
, DKI_ZSK
, conf
->k_algo
, conf
->z_bits
, conf
->z_random
, conf
->z_life
/ DAYSEC
);
79 dki_setstatus (dkp
, status
);
84 static dki_t
*genkey2 (dki_t
**listp
, const char *dir
, const char *domain
, int ksk
, const zconf_t
*conf
, int status
)
88 if ( listp
== NULL
|| domain
== NULL
)
92 dkp
= dki_new (dir
, domain
, DKI_KSK
, conf
->k2_algo
, conf
->k_bits
, conf
->k_random
, conf
->k_life
/ DAYSEC
);
94 dkp
= dki_new (dir
, domain
, DKI_ZSK
, conf
->k2_algo
, conf
->z_bits
, conf
->z_random
, conf
->z_life
/ DAYSEC
);
96 dki_setstatus (dkp
, status
);
101 static time_t get_exptime (dki_t
*key
, const zconf_t
*z
)
105 exptime
= dki_exptime (key
);
108 if ( dki_lifetime (key
) )
109 exptime
= dki_time (key
) + dki_lifetime (key
);
111 exptime
= dki_time (key
) + z
->k_life
;
117 /*****************************************************************
118 ** is_parentdirsigned (name)
119 ** Check if the parent directory of the zone specified by zp
120 ** is a directory with a signed zone
122 *****************************************************************/
123 static int is_parentdirsigned (const zone_t
*zonelist
, const zone_t
*zp
)
125 char path
[MAX_PATHSIZE
+1];
130 /* check if there is a local config file to get the name of the zone file */
131 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, LOCALCONF_FILE
);
132 if ( fileexist (path
) ) /* parent dir has local config file ? */
133 conf
= loadconfig (path
, NULL
);
137 /* build the path of the .signed zone file */
138 snprintf (path
, sizeof (path
), "%s/../%s.signed", conf
->dir
, conf
->zonefile
);
139 if ( conf
!= zp
->conf
) /* if we read in a local config file.. */
140 free (conf
); /* ..free the memory used */
143 /* currently we use the signed zone file name of the
144 * current directory for checking if the file exist.
145 * TODO: Instead we have to use the name of the zone file
146 * used in the parent dir (see above)
149 ext
= strrchr (zp
->sfile
, '.');
150 if ( ext
&& strcmp (zp
->sfile
, ".dsigned") == 0 ) /* is the current zone a dynamic one ? */
151 /* hack: we are using the standard zone file name for a static zone here */
152 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, "zone.db.signed");
156 const zone_t
*parent
;
157 const char *parentname
;
159 /* find out name of parent */
160 parentname
= strchr (zp
->zone
, '.'); /* find first dot in zone name */
161 if ( parentname
== NULL
) /* no parent found! */
163 parentname
+= 1; /* skip '.' */
165 /* try to find parent zone in zonelist */
166 if ( (parent
= zone_search (zonelist
, parentname
)) == NULL
)
168 snprintf (path
, sizeof (path
), "%s/%s", parent
->dir
, parent
->sfile
);
170 snprintf (path
, sizeof (path
), "%s/../%s", zp
->dir
, zp
->sfile
);
174 lg_mesg (LG_DEBUG
, "%s: is_parentdirsigned = %d fileexist (%s)\n", zp
->zone
, fileexist (path
), path
);
175 return fileexist (path
); /* parent dir has zone.db.signed file ? */
178 /*****************************************************************
179 ** create_parent_file ()
180 *****************************************************************/
181 static int create_parent_file (const char *fname
, int phase
, int ttl
, const dki_t
*dkp
)
185 assert ( fname
!= NULL
);
187 if ( dkp
== NULL
|| (phase
!= 1 && phase
!= 2) )
190 if ( (fp
= fopen (fname
, "w")) == NULL
)
191 fatal ("can\'t create new parentfile \"%s\"\n", fname
);
194 fprintf (fp
, "; KSK rollover phase1 (new key generated but this is alread the old one)\n");
196 fprintf (fp
, "; KSK rollover phase2 (this is the new key)\n");
198 dki_prt_dnskeyttl (dkp
, fp
, ttl
);
204 /*****************************************************************
205 ** get_parent_phase ()
206 *****************************************************************/
207 static int get_parent_phase (const char *file
)
212 if ( (fp
= fopen (file
, "r")) == NULL
)
216 if ( fscanf (fp
, "; KSK rollover phase%d", &phase
) != 1 )
223 /*****************************************************************
225 *****************************************************************/
226 static int kskrollover (dki_t
*ksk
, zone_t
*zonelist
, zone_t
*zp
)
228 char path
[MAX_PATHSIZE
+1];
235 int parent_propagation
;
240 assert ( ksk
!= NULL
);
241 assert ( zp
!= NULL
);
244 /* check ksk lifetime */
245 if ( (lifetime
= dki_lifetime (ksk
)) == 0 ) /* if lifetime of key is not set.. */
246 lifetime
= z
->k_life
; /* ..use global configured lifetime */
248 currtime
= time (NULL
);
249 age
= dki_age (ksk
, currtime
);
251 /* build path of parent-file */
252 pathname (path
, sizeof (path
), zp
->dir
, "parent-", zp
->zone
);
254 /* check if we have to change the ksk ? */
255 if ( lifetime
> 0 && age
> lifetime
&& !fileexist (path
) ) /* lifetime is over and no kskrollover in progress */
257 /* we are in hierachical mode and the parent directory contains a signed zone ? */
258 if ( z
->keysetdir
&& strcmp (z
->keysetdir
, "..") == 0 && is_parentdirsigned (zonelist
, zp
) )
260 verbmesg (2, z
, "\t\tkskrollover: create new key signing key\n");
261 /* create a new key: this is phase one of a double signing key rollover */
262 ksk
= genkey (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
265 lg_mesg (LG_ERROR
, "\"%s\": unable to generate new ksk for double signing rollover", zp
->zone
);
268 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase1: New key %d generated", zp
->zone
, ksk
->tag
);
270 /* find the oldest active ksk to create the parent file */
271 if ( (ksk
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, zp
->conf
->k_algo
, 'a', 1)) == NULL
)
272 lg_mesg (LG_ERROR
, "kskrollover phase1: Couldn't find the old active key\n");
273 if ( !create_parent_file (path
, 1, z
->key_ttl
, ksk
) )
274 lg_mesg (LG_ERROR
, "Couldn't create parentfile %s\n", path
);
277 else /* print out a warning only */
279 logmesg ("\t\tWarning: Lifetime of Key Signing Key %d exceeded: %s\n",
280 ksk
->tag
, str_delspace (age2str (age
)));
281 lg_mesg (LG_WARNING
, "\"%s\": lifetime of key signing key %d exceeded since %s",
282 zp
->zone
, ksk
->tag
, str_delspace (age2str (age
- lifetime
)));
287 /* now check if there is an ongoing key rollover */
289 /* check if parent-file already exist */
290 if ( !fileexist (path
) ) /* no parent-<zone> file found ? */
291 return 0; /* ok, that's it */
293 /* check the ksk rollover phase we are in */
294 currphase
= get_parent_phase (path
); /* this is the actual state we are in */
295 parfile_age
= file_age (path
);
297 /* TODO: Set these values to the one found in the parent dnssec.conf file */
298 parent_propagation
= PARENT_PROPAGATION
;
299 parent_resign
= z
->resign
;
300 parent_keyttl
= z
->key_ttl
;
304 case 1: /* we are currently in state one (new ksk already generated) */
305 if ( parfile_age
> z
->proptime
+ z
->key_ttl
) /* can we go to phase 2 ? */
307 verbmesg (2, z
, "\t\tkskrollover: save new ksk in parent file\n");
308 ksk
= ksk
->next
; /* set ksk to new ksk */
309 if ( !create_parent_file (path
, currphase
+1, z
->key_ttl
, ksk
) )
310 lg_mesg (LG_ERROR
, "Couldn't create parentfile %s\n", path
);
311 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase2: send new key %d to the parent zone", zp
->zone
, ksk
->tag
);
315 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
);
317 case 2: /* we are currently in state two (propagation of new key to the parent) */
319 if ( parfile_age
>= parent_propagation
+ parent_resign
+ parent_keyttl
) /* can we go to phase 3 ? */
321 if ( parfile_age
>= parent_propagation
+ parent_keyttl
) /* can we go to phase 3 ? */
324 /* remove the parentfile */
327 /* remove oldest key from list and mark file as removed */
328 zp
->keys
= dki_remove (ksk
);
330 // verbmesg (2, z, "kskrollover: remove parentfile and rename old key to k<zone>+<algo>+<tag>.key\n");
331 verbmesg (2, z
, "\t\tkskrollover: remove parentfile and rename old key to k%s+%03d+%05d.key\n",
332 ksk
->name
, ksk
->algo
, ksk
->tag
);
333 lg_mesg (LG_INFO
, "\"%s\": kskrollover phase3: Remove old key %d", zp
->zone
, ksk
->tag
);
338 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
);
340 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
);
344 assert ( currphase
== 1 || currphase
== 2 );
351 /*****************************************************************
352 ** global function definition
353 *****************************************************************/
355 /*****************************************************************
357 ** Check if the list of zone keys containing a revoked or a
359 ** Remove the revoked key if it is older than 30 days.
360 ** If the lifetime of the active key is reached, do a rfc5011
362 ** Returns an int with the rightmost bit set if a resigning
363 ** is required. The second rightmost bit is set, if it is an
365 *****************************************************************/
366 int ksk5011status (dki_t
**listp
, const char *dir
, const char *domain
, const zconf_t
*z
)
376 assert ( listp
!= NULL
);
377 assert ( z
!= NULL
);
379 if ( z
->k_life
== 0 )
382 verbmesg (1, z
, "\tCheck RFC5011 status\n");
385 currtime
= time (NULL
);
387 /* go through the list of key signing keys, */
388 /* remove revoked keys and set a pointer to standby and active key */
389 standbykey
= activekey
= NULL
;
391 for ( dkp
= *listp
; dkp
&& dki_isksk (dkp
); dkp
= dkp
->next
)
393 exptime
= get_exptime (dkp
, z
);
394 if ( dki_isrevoked (dkp
) )
395 lg_mesg (LG_DEBUG
, "zone \"%s\": found revoked key (id=%d exptime=%s); waiting for remove hold down time",
396 domain
, dkp
->tag
, time2str (exptime
, 's'));
398 /* revoked key is older than 30 days? */
399 if ( dki_isrevoked (dkp
) && currtime
> exptime
+ REMOVE_HOLD_DOWN
)
401 verbmesg (1, z
, "\tRemove revoked key %d which is older than 30 days\n", dkp
->tag
);
402 lg_mesg (LG_NOTICE
, "zone \"%s\": removing revoked key %d", domain
, dkp
->tag
);
404 /* remove key from list and mark file as removed */
405 if ( prev
== NULL
) /* at the beginning of the list ? */
406 *listp
= dki_remove (dkp
);
407 else /* anywhere in the middle of the list */
408 prev
->next
= dki_remove (dkp
);
410 ret
|= 01; /* from now on a resigning is necessary */
413 /* remember oldest standby and active key */
414 if ( dki_status (dkp
) == DKI_PUBLISHED
)
416 if ( dki_status (dkp
) == DKI_ACTIVE
)
419 /* no activekey or no standby key and also no revoked key found ? */
420 if ( activekey
== NULL
|| (standbykey
== NULL
&& ret
== 0) )
421 return ret
; /* Seems that this is a non rfc5011 zone! */
423 ret
|= 02; /* Zone looks like a rfc5011 zone */
425 exptime
= get_exptime (activekey
, z
);
427 lg_mesg (LG_DEBUG
, "Act Exptime: %s", time2str (exptime
, 's'));
428 lg_mesg (LG_DEBUG
, "Stb time: %s", time2str (dki_time (standbykey
), 's'));
429 lg_mesg (LG_DEBUG
, "Stb time+wait: %s", time2str (dki_time (standbykey
) + min (DAYSEC
* 30, z
->key_ttl
), 's'));
431 /* At the first time we introduce a standby key, the lifetime of the current KSK shouldn't be expired, */
432 /* otherwise we run into an (nearly) immediate key rollover! */
433 if ( currtime
> exptime
&& currtime
> dki_time (standbykey
) + min (ADD_HOLD_DOWN
, z
->key_ttl
) )
435 lg_mesg (LG_NOTICE
, "\"%s\": starting rfc5011 rollover", domain
);
436 verbmesg (1, z
, "\tLifetime of Key Signing Key %d exceeded (%s): Starting rfc5011 rollover!\n",
437 activekey
->tag
, str_delspace (age2str (dki_age (activekey
, currtime
))));
438 verbmesg (2, z
, "\t\t=>Generating new standby key signing key\n");
439 dkp
= genkey (listp
, dir
, domain
, DKI_KSK
, z
, DKI_PUBLISHED
); /* gentime == now; lifetime = z->k_life; exp = 0 */
442 error ("\tcould not generate new standby KSK\n");
443 lg_mesg (LG_ERROR
, "\%s\": can't generate new standby KSK", domain
);
446 lg_mesg (LG_NOTICE
, "\"%s\": generated new standby KSK %d", domain
, dkp
->tag
);
448 /* standby key gets active */
449 verbmesg (2, z
, "\t\t=>Activating old standby key %d \n", standbykey
->tag
);
450 dki_setstatus (standbykey
, DKI_ACT
);
452 /* active key should be revoked */
453 verbmesg (2, z
, "\t\t=>Revoking old active key %d \n", activekey
->tag
);
454 dki_setstatus (activekey
, DKI_REVOKED
);
455 dki_setexptime (activekey
, currtime
); /* now the key is expired */
457 ret
|= 01; /* resigning necessary */
463 /*****************************************************************
465 ** Check the ksk status of a zone if a ksk lifetime is set.
466 ** If there is no key signing key present create a new one.
467 ** Prints out a warning message if the lifetime of the current
468 ** key signing key is over.
469 ** Returns 1 if a resigning of the zone is necessary, otherwise
470 ** the function returns 0.
471 *****************************************************************/
472 int kskstatus (zone_t
*zonelist
, zone_t
*zp
)
477 assert ( zp
!= NULL
);
480 if ( z
->k_life
== 0 )
483 verbmesg (1, z
, "\tCheck KSK status\n");
484 /* check if a key signing key exist ? */
485 akey
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, z
->k_algo
, 'a', 1);
488 verbmesg (1, z
, "\tNo active KSK found: generate new one\n");
489 akey
= genkey (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
492 error ("\tcould not generate new KSK\n");
493 lg_mesg (LG_ERROR
, "\"%s\": can't generate new KSK: \"%s\"",
494 zp
->zone
, dki_geterrstr());
497 lg_mesg (LG_INFO
, "\"%s\": generated new KSK %d", zp
->zone
, akey
->tag
);
498 return akey
!= NULL
; /* return value of 1 forces a resigning of the zone */
500 else /* try to start a full automated ksk rollover */
501 kskrollover (akey
, zonelist
, zp
);
503 /* is a second algorithm requested ? (since 0.99) */
504 if ( z
->k2_algo
&& z
->k2_algo
!= z
->k_algo
)
506 /* check for ksk supporting the additional algorithm */
507 akey
= (dki_t
*)dki_findalgo (zp
->keys
, DKI_KSK
, z
->k2_algo
, 'a', 1);
510 verbmesg (1, z
, "\tNo active KSK for second algorithm found: generate new one\n");
511 akey
= genkey2 (&zp
->keys
, zp
->dir
, zp
->zone
, DKI_KSK
, z
, DKI_ACTIVE
);
514 error ("\tcould not generate new KSK for 2nd algorithm\n");
515 lg_mesg (LG_ERROR
, "\"%s\": can't generate new KSK for 2nd algorithm: \"%s\"",
516 zp
->zone
, dki_geterrstr());
519 lg_mesg (LG_INFO
, "\"%s\": generated new KSK %d for 2nd algorithm",
520 zp
->zone
, akey
->tag
);
521 return 1; /* return value of 1 forces a resigning of the zone */
528 /*****************************************************************
530 ** Check the zsk status of a zone.
531 ** Returns 1 if a resigning of the zone is necessary, otherwise
532 ** the function returns 0.
533 *****************************************************************/
534 int zskstatus (dki_t
**listp
, const char *dir
, const char *domain
, const zconf_t
*z
)
544 assert ( listp
!= NULL
);
545 /* dir can be NULL */
546 assert ( domain
!= NULL
);
547 assert ( z
!= NULL
);
549 currtime
= time (NULL
);
551 verbmesg (1, z
, "\tCheck ZSK status\n");
552 dbg_val("zskstatus for %s \n", domain
);
554 /* Is the depreciated key expired ? */
555 /* As mentioned by olaf, this is the max_ttl of all the rr in the zone */
556 lifetime
= z
->max_ttl
+ z
->proptime
; /* draft kolkman/gieben */
560 if ( !dki_isksk (dkp
) &&
561 dki_status (dkp
) == DKI_DEPRECIATED
&&
562 dki_age (dkp
, currtime
) > lifetime
)
565 verbmesg (1, z
, "\tLifetime(%d sec) of depreciated key %d exceeded (%d sec)\n",
566 lifetime
, dkp
->tag
, dki_age (dkp
, currtime
));
567 lg_mesg (LG_INFO
, "\"%s\": old ZSK %d removed", domain
, dkp
->tag
);
568 dkp
= dki_destroy (dkp
); /* delete the keyfiles */
569 dbg_msg("zskstatus: depreciated key removed ");
574 verbmesg (1, z
, "\t\t->remove it\n");
582 /* check status of active key */
583 dbg_msg("zskstatus check status of active key ");
584 lifetime
= z
->z_life
; /* global configured lifetime for zsk */
585 akey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'a', 1);
586 if ( akey
== NULL
&& lifetime
> 0 ) /* no active key found */
588 verbmesg (1, z
, "\tNo active ZSK found: generate new one\n");
589 akey
= genkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_ACTIVE
);
590 lg_mesg (LG_INFO
, "\"%s\": generated new ZSK %d", domain
, akey
->tag
);
592 else /* active key exist */
594 if ( dki_lifetime (akey
) )
595 lifetime
= dki_lifetime (akey
); /* set lifetime to lt of active key */
597 /* lifetime of active key is expired and published key exist ? */
598 age
= dki_age (akey
, currtime
);
599 if ( lifetime
> 0 && age
> lifetime
- (OFFSET
) )
601 verbmesg (1, z
, "\tLifetime(%d +/-%d sec) of active key %d exceeded (%d sec)\n",
602 lifetime
, (OFFSET
) , akey
->tag
, dki_age (akey
, currtime
) );
604 /* depreciate the key only if there is another active or published key */
605 if ( (nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'a', 2)) == NULL
||
607 nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'p', 1);
609 /* Is the published key sufficient long in the zone ? */
610 /* As mentioned by Olaf, this should be the ttl of the DNSKEY RR ! */
611 if ( nextkey
&& dki_age (nextkey
, currtime
) > z
->key_ttl
+ z
->proptime
)
614 verbmesg (1, z
, "\t\t->depreciate it\n");
615 dki_setstatus (akey
, 'd'); /* depreciate the active key */
616 verbmesg (1, z
, "\t\t->activate published key %d\n", nextkey
->tag
);
617 dki_setstatus (nextkey
, 'a'); /* activate published key */
618 lg_mesg (LG_NOTICE
, "\"%s\": lifetime of zone signing key %d exceeded: ZSK rollover done", domain
, akey
->tag
);
621 lifetime
= dki_lifetime (akey
); /* set lifetime to lt of the new active key (F. Behrens) */
625 verbmesg (1, z
, "\t\t->waiting for published key\n");
626 lg_mesg (LG_NOTICE
, "\"%s\": lifetime of zone signing key %d exceeded since %s: ZSK rollover deferred: waiting for published key",
627 domain
, akey
->tag
, str_delspace (age2str (age
- lifetime
)));
631 /* Should we add a new publish key? This is necessary if the active
632 * key will be expired at the next re-signing interval (The published
633 * time will be checked just before the active key will be removed.
636 nextkey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k_algo
, 'p', 1);
637 if ( nextkey
== NULL
&& lifetime
> 0 && (akey
== NULL
||
638 dki_age (akey
, currtime
+ z
->resign
) > lifetime
- (OFFSET
)) )
641 verbmesg (1, z
, "\tNew key for publishing needed\n");
642 nextkey
= genkey (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_PUB
);
646 verbmesg (1, z
, "\t\t->creating new key %d\n", nextkey
->tag
);
647 lg_mesg (LG_INFO
, "\"%s\": new key %d generated for publishing", domain
, nextkey
->tag
);
651 error ("\tcould not generate new ZSK: \"%s\"\n", dki_geterrstr());
652 lg_mesg (LG_ERROR
, "\"%s\": can't generate new ZSK: \"%s\"",
653 domain
, dki_geterrstr());
657 /* is a second algorithm requested ? (since 0.99) */
658 if ( z
->k2_algo
&& z
->k2_algo
!= z
->k_algo
)
660 /* check for zsk supporting the additional algorithm */
661 akey
= (dki_t
*)dki_findalgo (*listp
, DKI_ZSK
, z
->k2_algo
, 'a', 1);
664 verbmesg (1, z
, "\tNo active ZSK for second algorithm found: generate new one\n");
665 akey
= genkey2 (listp
, dir
, domain
, DKI_ZSK
, z
, DKI_ACTIVE
);
668 error ("\tcould not generate new ZSK for 2nd algorithm\n");
669 lg_mesg (LG_ERROR
, "\"%s\": can't generate new ZSK for 2nd algorithm: \"%s\"",
670 domain
, dki_geterrstr());
673 lg_mesg (LG_INFO
, "\"%s\": generated new ZSK %d for 2nd algorithm",
675 return 1; /* return value of 1 forces a resigning of the zone */