static void list_trustedkey (const dki_t **nodep, const VISIT which, int depth) { const dki_t *dkp; if ( nodep == NULL ) return; dkp = *nodep; if ( which == INORDER || which == LEAF ) { // fprintf (stderr, "list_trustedkey order=%d(pre=0,in=1,post=2,leaf=3) depth=%d %s\n", which, depth, dkp->name); if ( labellist && !isinlist (dkp->name, labellist) ) return; if ( parent == NULL || !issubdomain (dkp->name, parent->name) ) { parent = dkp; /* loop through list */ while ( dkp ) { if ( (dki_isksk (dkp) || zskflag) ) dki_prt_trustedkey (dkp, stdout); dkp = dkp->next; } } } }
static void set_keylifetime (const dki_t **nodep, const VISIT which, int depth) { const dki_t *dkp; int ksk; if ( nodep == NULL ) return; if ( which == INORDER || which == LEAF ) for ( dkp = *nodep; dkp; dkp = dkp->next ) { ksk = dki_isksk (dkp); if ( (ksk && !kskflag) || (!ksk && !zskflag) ) continue; if ( labellist == NULL || isinlist (dkp->name, labellist) ) dki_setlifetime ((dki_t *)dkp, lifetime); } }
void zkt_list_trustedkeys (const dki_t *data) { /* print headline if list is not empty */ if ( data && headerflag ) printf ("trusted-keys {\n"); #if defined(USE_TREE) && USE_TREE twalk (data, list_trustedkey); #else for ( dkp = data; dkp; dkp = dkp->next ) /* loop through list */ if ( (dki_isksk (dkp) || zskflag) && (labellist == NULL || isinlist (dkp->name, labellist)) ) dki_prt_trustedkey (dkp, stdout); #endif /* print end of trusted-key section */ if ( data && headerflag ) printf ("};\n"); }
void zkt_setkeylifetime (dki_t *data) { #if defined(USE_TREE) && USE_TREE twalk (data, set_keylifetime); #else dki_t *dkp; int ksk; for ( dkp = data; dkp; dkp = dkp->next ) { ksk = dki_isksk (dkp); if ( (ksk && !kskflag) || (!ksk && !zskflag) ) continue; if ( labellist == NULL || isinlist (dkp->name, labellist) ) { dki_setlifetime (dkp, lifetime); } } #endif }
void zkt_list_dnskeys (const dki_t *data) { #if defined(USE_TREE) && USE_TREE twalk (data, list_dnskey); #else const dki_t *dkp; int ksk; for ( dkp = data; dkp; dkp = dkp->next ) { ksk = dki_isksk (dkp); if ( (ksk && !kskflag) || (!ksk && !zskflag) ) continue; if ( labellist == NULL || isinlist (dkp->name, labellist) ) { if ( headerflag ) dki_prt_comment (dkp, stdout); dki_prt_dnskey (dkp, stdout); } } #endif }
static void list_dnskey (const dki_t **nodep, const VISIT which, int depth) { const dki_t *dkp; int ksk; if ( nodep == NULL ) return; if ( which == INORDER || which == LEAF ) for ( dkp = *nodep; dkp; dkp = dkp->next ) { ksk = dki_isksk (dkp); if ( (ksk && !kskflag) || (!ksk && !zskflag) ) continue; if ( labellist == NULL || isinlist (dkp->name, labellist) ) { if ( headerflag ) dki_prt_comment (dkp, stdout); dki_prt_dnskey (dkp, stdout); } } }
static void printkeyinfo (const dki_t *dkp, const char *oldpath) { time_t currtime; if ( dkp == NULL ) /* print headline */ { if ( headerflag ) { tc_attr (stdout, TC_BOLD, 1); printf ("%-33.33s %5s %3s %3.3s %-7s", "Keyname", "Tag", "Typ", "Status", "Algorit"); if ( timeflag ) printf (" %-20s", "Generation Time"); if ( exptimeflag ) printf (" %-20s", "Expiration Time"); if ( ageflag ) printf (" %16s", "Age"); if ( lifetimeflag ) printf (" %4s", "LfTm"); tc_attr (stdout, TC_BOLD, 0); putchar ('\n'); } return; } time (&currtime); /* TODO: use next line if dname is dynamically allocated */ /* if ( pathflag && dkp->dname && strcmp (oldpath, dkp->dname) != 0 ) */ if ( pathflag && strcmp (oldpath, dkp->dname) != 0 ) printf ("%s/\n", dkp->dname); if ( (kskflag && dki_isksk (dkp)) || (zskflag && !dki_isksk (dkp)) ) { int color; if ( ljustflag ) printf ("%-33.33s ", dkp->name); else printf ("%33.33s ", dkp->name); printf ("%05d ", dkp->tag); printf ("%3s ", dki_isksk (dkp) ? "KSK" : "ZSK"); if ( dkp->status == DKI_ACT ) color = TC_GREEN; else if ( dkp->status == DKI_PUB ) color = TC_BLUE; else if ( dkp->status == DKI_DEP ) color = TC_RED; else color = TC_BLACK; tc_attr (stdout, color, 1); printf ("%-3.3s ", dki_statusstr (dkp) ); tc_attr (stdout, color, 0); printf ("%-7s", dki_algo2sstr(dkp->algo)); if ( currtime < dkp->time + dkp->lifetime ) color = TC_GREEN; else color = TC_BOLD|TC_RED; tc_attr (stdout, color, 1); if ( timeflag ) printf (" %-20s", time2str (dkp->gentime ? dkp->gentime: dkp->time, 's')); if ( exptimeflag ) printf (" %-20s", time2str (dkp->exptime, 's')); if ( ageflag ) printf (" %16s", age2str (dki_age (dkp, currtime))); if ( lifetimeflag && dkp->lifetime ) { if ( dkp->status == 'a' ) printf ("%c", (currtime < dkp->time + dkp->lifetime) ? '<' : '!'); else putchar (' '); printf ("%hdd", dki_lifetimedays (dkp)); } tc_attr (stdout, color, 0); putchar ('\n'); } }
static void ksk_roll (const char *keyname, int phase, const dki_t *list, const zconf_t *conf) { char path[MAX_PATHSIZE+1]; zconf_t localconf; const char *dir; dki_t *keylist; dki_t *dkp; dki_t *standby; int parent_exist; int parent_age; int parent_phase; int parent_propagation; int key_ttl; int ksk; if ( phase == 9 ) /* usage */ { fprintf (stderr, "A KSK rollover requires three consecutive steps:\n"); fprintf (stderr, "\n"); fprintf (stderr, "-1%s", loptstr ("|--ksk-roll-phase1 (--ksk-newkey)\n", "")); fprintf (stderr, "\t Create a new KSK.\n"); fprintf (stderr, "\t This step also creates a parent-<domain> file which contains only\n"); fprintf (stderr, "\t the _old_ key. This file will be copied in hierarchical mode\n"); fprintf (stderr, "\t by dnssec-signer to the parent directory as keyset-<domain> file.\n"); fprintf (stderr, "\t Wait until the new keyset is propagated, before going to the next step.\n"); fprintf (stderr, "\n"); fprintf (stderr, "-2%s", loptstr ("|--ksk-roll-phase2 (--ksk-publish)\n", "")); fprintf (stderr, "\t This step creates a parent-<domain> file with the _new_ key only.\n"); fprintf (stderr, "\t Please send this file immediately to the parent (In hierarchical\n"); fprintf (stderr, "\t mode this will be done automatically by the dnssec-signer command).\n"); fprintf (stderr, "\t Then wait until the new DS is generated by the parent and propagated\n"); fprintf (stderr, "\t to all the parent name server, plus the old DS TTL before going to step three.\n"); fprintf (stderr, "\n"); fprintf (stderr, "-3%s", loptstr ("|--ksk-roll-phase3 (--ksk-delkey)\n", "")); fprintf (stderr, "\t Remove (rename) the old KSK and the parent-<domain> file.\n"); fprintf (stderr, "\t You have to manually delete the old KSK (look at file names beginning\n"); fprintf (stderr, "\t with an lower 'k').\n"); fprintf (stderr, "\n"); fprintf (stderr, "-0%s", loptstr ("|--ksk-roll-stat (--ksk-status)\n", "")); fprintf (stderr, "\t Show the current KSK rollover state of a domain.\n"); fprintf (stderr, "\n"); return; } if ( keyname == NULL || *keyname == '\0' ) fatal ("ksk rollover: no domain!"); dbg_val2 ("ksk_roll: keyname %s, phase = %d\n", keyname, phase); /* search for already existent key to get the directory name */ if ( (keylist = (dki_t *)zkt_search (list, 0, keyname)) == NULL ) fatal ("ksk rollover: domain %s not found!\n", keyname); dkp = keylist; /* try to read local config file */ dir = dkp->dname; pathname (path, sizeof (path), dir, LOCALCONF_FILE, NULL); if ( fileexist (path) ) /* load local config file */ { dbg_val ("Load local config file \"%s\"\n", path); memcpy (&localconf, conf, sizeof (zconf_t)); conf = loadconfig (path, &localconf); } key_ttl = conf->key_ttl; /* check if parent-file already exist */ pathname (path, sizeof (path), dir, "parent-", keyname); parent_phase = parent_age = 0; if ( (parent_exist = fileexist (path)) != 0 ) { parent_phase = get_parent_phase (path); parent_age = file_age (path); } // parent_propagation = 2 * DAYSEC; parent_propagation = 5 * MINSEC; ksk = 0; /* count active(!) key signing keys */ standby = NULL; /* find standby key if available */ for ( dkp = keylist; dkp; dkp = dkp->next ) if ( dki_isksk (dkp) ) { if ( dki_status (dkp) == DKI_ACT ) ksk++; else if ( dki_status (dkp) == DKI_PUB ) standby = dkp; } switch ( phase ) { case 0: /* print status (debug) */ fprintf (stdout, "ksk_rollover:\n"); fprintf (stdout, "\t domain = %s\n", keyname); fprintf (stdout, "\t phase = %d\n", parent_phase); fprintf (stdout, "\t parent_file %s %s\n", path, parent_exist ? "exist": "not exist"); if ( parent_exist ) fprintf (stdout, "\t age of parent_file %d %s\n", parent_age, str_delspace (age2str (parent_age))); fprintf (stdout, "\t # of active key signing keys %d\n", ksk); fprintf (stdout, "\t parent_propagation %d %s\n", parent_propagation, str_delspace (age2str (parent_propagation))); fprintf (stdout, "\t keys ttl %d %s\n", key_ttl, age2str (key_ttl)); for ( dkp = keylist; dkp; dkp = dkp->next ) { /* TODO: Nur zum testen */ dki_prt_dnskey (dkp, stdout); } break; case 1: if ( parent_exist || ksk > 1 ) fatal ("Can\'t create new ksk because there is already an ksk rollover in progress\n"); fprintf (stdout, "create new ksk \n"); dkp = dki_new (dir, keyname, DKI_KSK, conf->k_algo, conf->k_bits, conf->k_random, conf->k_life / DAYSEC); if ( dkp == NULL ) fatal ("Can't create key %s: %s!\n", keyname, dki_geterrstr ()); if ( standby ) { dki_setstatus (standby, DKI_ACT); /* activate standby key */ dki_setstatus (dkp, DKI_PUB); /* new key will be the new standby */ } // dkp = keylist; /* use old key to create the parent file */ if ( (dkp = (dki_t *)dki_findalgo (keylist, 1, conf->k_algo, 'a', 1)) == NULL ) /* find the oldest active ksk to create the parent file */ fatal ("ksk_rollover phase1: Couldn't find the old active key\n"); if ( !create_parent_file (path, phase, key_ttl, dkp) ) fatal ("Couldn't create parentfile %s\n", path); break; case 2: if ( ksk < 2 ) fatal ("Can\'t publish new key because no one exist\n"); if ( !parent_exist ) fatal ("More than one KSK but no parent file found!\n"); if ( parent_phase != 1 ) fatal ("Parent file exists but is in wrong state (phase = %d)\n", parent_phase); if ( parent_age < conf->proptime + key_ttl ) fatal ("ksk_rollover (phase2): you have to wait for the propagation of the new KSK (at least %dsec or %s)\n", conf->proptime + key_ttl - parent_age, str_delspace (age2str (conf->proptime + key_ttl - parent_age))); fprintf (stdout, "save new ksk in parent file\n"); dkp = keylist->next; /* set dkp to new ksk */ if ( !create_parent_file (path, phase, key_ttl, dkp) ) fatal ("Couldn't create parentfile %s\n", path); break; case 3: if ( !parent_exist || ksk < 2 ) fatal ("ksk-delkey only allowed after ksk-publish\n"); if ( parent_phase != 2 ) fatal ("Parent file exists but is in wrong state (phase = %d)\n", parent_phase); if ( parent_age < parent_propagation + key_ttl ) fatal ("ksk_rollover (phase3): you have to wait for DS propagation (at least %dsec or %s)\n", parent_propagation + key_ttl - parent_age, str_delspace (age2str (parent_propagation + key_ttl - parent_age))); /* remove the parentfile */ fprintf (stdout, "remove parentfile \n"); unlink (path); /* remove or rename the old key */ fprintf (stdout, "old ksk renamed \n"); dkp = keylist; /* set dkp to old ksk */ dki_remove (dkp); break; default: assert (phase == 1 || phase == 2 || phase == 3); } }