1 /* $NetBSD: dki.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) dki.c (c) Jan 2005 Holger Zuleger hznet.de
7 ** A library for managing BIND dnssec key files.
9 ** Copyright (c) Jan 2005, Holger Zuleger HZnet. All rights reserved.
11 ** This software is open source.
13 ** Redistribution and use in source and binary forms, with or without
14 ** modification, are permitted provided that the following conditions
17 ** Redistributions of source code must retain the above copyright notice,
18 ** this list of conditions and the following disclaimer.
20 ** Redistributions in binary form must reproduce the above copyright notice,
21 ** this list of conditions and the following disclaimer in the documentation
22 ** and/or other materials provided with the distribution.
24 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
25 ** be used to endorse or promote products derived from this software without
26 ** specific prior written permission.
28 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
32 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 ** POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************/
45 # include <ctype.h> /* tolower(), ... */
46 # include <unistd.h> /* link(), unlink(), ... */
48 # include <sys/types.h>
49 # include <sys/time.h>
50 # include <sys/stat.h>
56 # include "config_zkt.h"
58 # include "domaincmp.h"
65 /*****************************************************************
66 ** private (static) function declaration and definition
67 *****************************************************************/
68 static char dki_estr
[255+1];
70 static dki_t
*dki_alloc ()
73 dki_t
*dkp
= malloc (sizeof (dki_t
));
75 if ( (dkp
= malloc (sizeof (dki_t
))) )
77 memset (dkp
, 0, sizeof (dki_t
));
81 snprintf (dki_estr
, sizeof (dki_estr
),
82 "dki_alloc: Out of memory");
86 static int dki_readfile (FILE *fp
, dki_t
*dkp
)
88 int algo
, flags
, type
;
93 char val
[14+1]; /* e.g. "YYYYMMDDhhmmss" | "60d" */
98 while ( (c
= getc (fp
)) == ';' ) /* line start with comment ? */
100 tag
[0] = val
[0] = '\0';
101 if ( (c
= getc (fp
)) == '%' ) /* special comment? */
103 while ( (c
= getc (fp
)) == ' ' || c
== '\t' )
106 /* then try to read in the creation, expire and lifetime */
107 if ( fscanf (fp
, "%25[a-zA-Z]=%14s", tag
, val
) == 2 )
109 dbg_val2 ("dki_readfile: tag=%s val=%s \n", tag
, val
);
110 switch ( tolower (tag
[0]) )
112 case 'g': dkp
->gentime
= timestr2time (val
); break;
113 case 'e': dkp
->exptime
= timestr2time (val
); break;
114 case 'l': dkp
->lifetime
= atoi (val
) * DAYSEC
; break;
120 while ( (c
= getc (fp
)) != EOF
&& c
!= '\n' ) /* eat up rest of the line */
123 ungetc (c
, fp
); /* push back last char */
125 if ( fscanf (fp
, "%4095s", buf
) != 1 ) /* read label */
128 if ( strcmp (buf
, dkp
->name
) != 0 )
131 #if defined(TTL_IN_KEYFILE_ALLOWED) && TTL_IN_KEYFILE_ALLOWED
132 /* skip optional TTL value */
133 while ( (c
= getc (fp
)) != EOF
&& isspace (c
) ) /* skip spaces */
135 if ( isdigit (c
) ) /* skip ttl */
138 ungetc (c
, fp
); /* oops, no ttl */
141 if ( (c
= fscanf (fp
, " IN DNSKEY %d %d %d", &flags
, &type
, &algo
)) != 3 &&
142 (c
= fscanf (fp
, "KEY %d %d %d", &flags
, &type
, &algo
)) != 3 )
144 if ( type
!= 3 || algo
!= dkp
->algo
)
145 return -4; /* no DNSKEY or algorithm mismatch */
146 if ( ((flags
>> 8) & 0xFF) != 01 )
147 return -5; /* no ZONE key */
150 if ( fgets (buf
, sizeof buf
, fp
) == NULL
|| buf
[0] == '\0' )
152 p
= buf
+ strlen (buf
);
153 *--p
= '\0'; /* delete trailing \n */
154 /* delete leading ws */
155 for ( p
= buf
; *p
&& isspace (*p
); p
++ )
158 dkp
->pubkey
= strdup (p
);
163 static int dki_writeinfo (const dki_t
*dkp
, const char *path
)
167 assert (dkp
!= NULL
);
168 assert (path
!= NULL
&& path
[0] != '\0');
170 if ( (fp
= fopen (path
, "w")) == NULL
)
172 dbg_val1 ("dki_writeinfo %s\n", path
);
173 if ( dki_prt_dnskey_raw (dkp
, fp
) == 0 )
176 touch (path
, dkp
->time
); /* restore time of key file */
181 static int dki_setstat (dki_t
*dkp
, int status
, int preserve_time
);
183 /*****************************************************************
184 ** public function definition
185 *****************************************************************/
187 /*****************************************************************
189 *****************************************************************/
190 void dki_free (dki_t
*dkp
)
192 assert (dkp
!= NULL
);
199 /*****************************************************************
201 *****************************************************************/
202 void dki_freelist (dki_t
**listp
)
207 assert (listp
!= NULL
);
220 #if defined(USE_TREE) && USE_TREE
221 /*****************************************************************
223 *****************************************************************/
224 void dki_tfree (dki_t
**tree
)
226 assert (tree
!= NULL
);
227 // TODO: tdestroy is a GNU extension
228 // tdestroy (*tree, dki_free);
232 # define KEYGEN_COMPMODE "-C -q " /* this is the compability mode needed since BIND 9.7 */
233 /*****************************************************************
235 ** create new keyfile
236 ** allocate memory for new dki key and init with keyfile
237 *****************************************************************/
238 dki_t
*dki_new (const char *dir
, const char *name
, int ksk
, int algo
, int bitsize
, const char *rfile
, int lf_days
)
242 char randfile
[254+1];
253 if ( rfile
&& *rfile
)
254 snprintf (randfile
, sizeof (randfile
), "-r %.250s ", rfile
);
256 #if defined(BIND_VERSION) && BIND_VERSION < 90902
257 if ( algo
== DK_ALGO_RSA
|| algo
== DK_ALGO_RSASHA1
|| algo
== DK_ALGO_RSASHA256
|| algo
== DK_ALGO_RSASHA512
)
261 snprintf (cmdline
, sizeof (cmdline
), "cd %s ; %s %s%s%s-n ZONE -a %s -b %d %s %s",
262 dir
, KEYGENCMD
, KEYGEN_COMPMODE
, randfile
, expflag
, dki_algo2str(algo
), bitsize
, flag
, name
);
264 snprintf (cmdline
, sizeof (cmdline
), "%s %s%s%s-n ZONE -a %s -b %d %s %s",
265 KEYGENCMD
, KEYGEN_COMPMODE
, randfile
, expflag
, dki_algo2str(algo
), bitsize
, flag
, name
);
269 if ( (fp
= popen (cmdline
, "r")) == NULL
|| fgets (fname
, sizeof fname
, fp
) == NULL
)
273 len
= strlen (fname
) - 1;
274 if ( len
>= 0 && fname
[len
] == '\n' )
277 new = dki_read (dir
, fname
);
279 dki_setlifetime (new, lf_days
); /* sets gentime + proposed lifetime */
284 /*****************************************************************
286 ** read key from file 'filename' (independed of the extension)
287 *****************************************************************/
288 dki_t
*dki_read (const char *dirname
, const char *filename
)
295 char fname
[MAX_FNAMESIZE
+1];
296 char path
[MAX_PATHSIZE
+1];
299 if ( (dkp
= dki_alloc ()) == NULL
)
302 len
= sizeof (fname
) - 1;
304 strncpy (fname
, filename
, len
);
306 len
= strlen (fname
); /* delete extension */
307 if ( len
> 4 && strcmp (&fname
[len
- 4], DKI_KEY_FILEEXT
) == 0 )
308 fname
[len
- 4] = '\0';
309 else if ( len
> 10 && strcmp (&fname
[len
- 10], DKI_PUB_FILEEXT
) == 0 )
310 fname
[len
- 10] = '\0';
311 else if ( len
> 8 && strcmp (&fname
[len
- 8], DKI_ACT_FILEEXT
) == 0 )
312 fname
[len
- 8] = '\0';
313 else if ( len
> 12 && strcmp (&fname
[len
- 12], DKI_DEP_FILEEXT
) == 0 )
314 fname
[len
- 12] = '\0';
317 assert (strlen (dirname
)+1 < sizeof (dkp
->dname
));
318 strcpy (dkp
->dname
, dirname
);
320 assert (strlen (fname
)+1 < sizeof (dkp
->fname
));
321 strcpy (dkp
->fname
, fname
);
323 if ( sscanf (fname
, "K%254[^+]+%hd+%d", dkp
->name
, &dkp
->algo
, &dkp
->tag
) != 3 )
325 snprintf (dki_estr
, sizeof (dki_estr
),
326 "dki_read: Filename don't match expected format (%s)", fname
);
330 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_KEY_FILEEXT
);
331 dbg_val ("dki_read: path \"%s\"\n", path
);
332 if ( (fp
= fopen (path
, "r")) == NULL
)
334 snprintf (dki_estr
, sizeof (dki_estr
),
335 "dki_read: Can\'t open file \"%s\" for reading", path
);
340 if ( (err
= dki_readfile (fp
, dkp
)) != 0 )
343 snprintf (dki_estr
, sizeof (dki_estr
),
344 "dki_read: Can\'t read key from file %s (errno %d)", path
, err
);
350 if ( fstat (fileno(fp
), &st
) )
352 snprintf (dki_estr
, sizeof (dki_estr
),
353 "dki_read: Can\'t stat file %s", fname
);
356 dkp
->time
= st
.st_mtime
;
359 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_ACT_FILEEXT
);
360 if ( fileexist (path
) )
362 if ( dki_isrevoked (dkp
) )
363 dkp
->status
= DKI_REV
;
365 dkp
->status
= DKI_ACT
;
369 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_PUB_FILEEXT
);
370 if ( fileexist (path
) )
371 dkp
->status
= DKI_PUB
;
374 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_DEP_FILEEXT
);
375 if ( fileexist (path
) )
376 dkp
->status
= DKI_DEP
;
378 dkp
->status
= DKI_SEP
;
389 /*****************************************************************
391 ** read key files from directory 'dir' and, if recursive is
392 ** true, from all directorys below that.
393 *****************************************************************/
394 int dki_readdir (const char *dir
, dki_t
**listp
, int recursive
)
398 struct dirent
*dentp
;
399 char path
[MAX_PATHSIZE
+1];
401 dbg_val ("directory: opendir(%s)\n", dir
);
402 if ( (dirp
= opendir (dir
)) == NULL
)
405 while ( (dentp
= readdir (dirp
)) != NULL
)
407 if ( is_dotfilename (dentp
->d_name
) )
410 dbg_val ("directory: check %s\n", dentp
->d_name
);
411 pathname (path
, sizeof (path
), dir
, dentp
->d_name
, NULL
);
412 if ( is_directory (path
) && recursive
)
414 dbg_val ("directory: recursive %s\n", path
);
415 dki_readdir (path
, listp
, recursive
);
417 else if ( is_keyfilename (dentp
->d_name
) )
418 if ( (dkp
= dki_read (dir
, dentp
->d_name
)) )
419 dki_add (listp
, dkp
);
425 /*****************************************************************
426 ** dki_setstatus_preservetime ()
427 ** set status of key and change extension to
428 ** ".published", ".private" or ".depreciated"
429 *****************************************************************/
430 int dki_setstatus_preservetime (dki_t
*dkp
, int status
)
432 return dki_setstat (dkp
, status
, 1);
435 /*****************************************************************
437 ** set status of key and change extension to
438 ** ".published", ".private" or ".depreciated"
439 *****************************************************************/
440 int dki_setstatus (dki_t
*dkp
, int status
)
442 return dki_setstat (dkp
, status
, 0);
445 /*****************************************************************
447 ** low level function of dki_setstatus and dki_setstatus_preservetime
448 *****************************************************************/
449 static int dki_setstat (dki_t
*dkp
, int status
, int preserve_time
)
451 char frompath
[MAX_PATHSIZE
+1];
452 char topath
[MAX_PATHSIZE
+1];
458 status
= tolower (status
);
459 switch ( dkp
->status
) /* look at old status */
468 pathname (frompath
, sizeof (frompath
), dkp
->dname
, dkp
->fname
, DKI_ACT_FILEEXT
);
473 pathname (frompath
, sizeof (frompath
), dkp
->dname
, dkp
->fname
, DKI_DEP_FILEEXT
);
475 case 'p': /* or 's' */
476 if ( status
== 'p' || status
== 's' )
478 pathname (frompath
, sizeof (frompath
), dkp
->dname
, dkp
->fname
, DKI_PUB_FILEEXT
);
481 /* TODO: set error code */
485 dbg_val ("dki_setstat: \"%s\"\n", frompath
);
486 dbg_val ("dki_setstat: to status \"%c\"\n", status
);
488 /* a state change could result in different things: */
489 /* 1) write a new keyfile when the REVOKE bit is set or unset */
490 if ( status
== 'r' || (status
== 'a' && dki_isrevoked (dkp
)) )
492 pathname (topath
, sizeof (topath
), dkp
->dname
, dkp
->fname
, DKI_KEY_FILEEXT
);
495 dki_setflag (dkp
, DK_FLAG_REVOKE
); /* set REVOKE bit */
497 dki_unsetflag (dkp
, DK_FLAG_REVOKE
); /* clear REVOKE bit */
500 dki_writeinfo (dkp
, topath
); /* ..and write it to the key file */
502 if ( !preserve_time
)
503 touch (topath
, time (NULL
));
509 /* 2) change the filename of the private key in all other cases */
512 totime
= file_mtime (frompath
); /* get original timestamp */
517 pathname (topath
, sizeof (topath
), dkp
->dname
, dkp
->fname
, DKI_ACT_FILEEXT
);
520 pathname (topath
, sizeof (topath
), dkp
->dname
, dkp
->fname
, DKI_DEP_FILEEXT
);
522 case 's': /* standby means a "published KSK" */
523 if ( !dki_isksk (dkp
) )
528 pathname (topath
, sizeof (topath
), dkp
->dname
, dkp
->fname
, DKI_PUB_FILEEXT
);
534 dbg_val ("dki_setstat: to \"%s\"\n", topath
);
535 if ( link (frompath
, topath
) == 0 )
537 dkp
->status
= status
;
539 totime
= time (NULL
); /* set .key file to current time */
540 pathname (topath
, sizeof (topath
), dkp
->dname
, dkp
->fname
, DKI_KEY_FILEEXT
);
541 touch (topath
, totime
); /* store/restore time of status change */
547 /*****************************************************************
549 ** rename files associated with key, so that the keys are not
550 ** recognized by the zkt tools e.g.
551 ** Kdo.ma.in.+001+12345.key ==> kdo.ma.in.+001+12345.key
552 ** (second one starts with a lower case 'k')
553 *****************************************************************/
554 dki_t
*dki_remove (dki_t
*dkp
)
556 char path
[MAX_PATHSIZE
+1];
557 char newpath
[MAX_PATHSIZE
+1];
558 char newfile
[MAX_FNAMESIZE
+1];
561 static const char *ext
[] = {
562 DKI_KEY_FILEEXT
, DKI_PUB_FILEEXT
,
563 DKI_ACT_FILEEXT
, DKI_DEP_FILEEXT
,
570 strncpy (newfile
, dkp
->fname
, sizeof (newfile
));
571 *newfile
= tolower (*newfile
);
572 for ( pext
= ext
; *pext
; pext
++ )
574 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, *pext
);
575 if ( fileexist (path
) )
577 pathname (newpath
, sizeof (newpath
), dkp
->dname
, newfile
, *pext
);
579 dbg_val2 ("dki_remove: %s ==> %s \n", path
, newpath
);
580 rename (path
, newpath
);
589 /*****************************************************************
591 ** delete files associated with key and free allocated memory
592 *****************************************************************/
593 dki_t
*dki_destroy (dki_t
*dkp
)
595 char path
[MAX_PATHSIZE
+1];
598 static const char *ext
[] = {
599 DKI_KEY_FILEEXT
, DKI_PUB_FILEEXT
,
600 DKI_ACT_FILEEXT
, DKI_DEP_FILEEXT
,
607 for ( pext
= ext
; *pext
; pext
++ )
609 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, *pext
);
610 if ( fileexist (path
) )
612 dbg_val ("dki_remove: %s \n", path
);
622 /*****************************************************************
624 ** return a string describing the key algorithm
625 *****************************************************************/
626 char *dki_algo2str (int algo
)
630 case DK_ALGO_RSA
: return ("RSAMD5");
631 case DK_ALGO_DH
: return ("DH");
632 case DK_ALGO_DSA
: return ("DSA");
633 case DK_ALGO_EC
: return ("EC");
634 case DK_ALGO_RSASHA1
: return ("RSASHA1");
635 case DK_ALGO_NSEC3DSA
: return ("NSEC3DSA");
636 case DK_ALGO_NSEC3RSASHA1
: return ("NSEC3RSASHA1");
637 case DK_ALGO_RSASHA256
: return ("RSASHA256");
638 case DK_ALGO_RSASHA512
: return ("RSASHA512");
643 /*****************************************************************
645 ** return a short string describing the key algorithm
646 *****************************************************************/
647 char *dki_algo2sstr (int algo
)
651 case DK_ALGO_RSA
: return ("RSAMD5");
652 case DK_ALGO_DH
: return ("DH");
653 case DK_ALGO_DSA
: return ("DSA");
654 case DK_ALGO_EC
: return ("EC");
655 case DK_ALGO_RSASHA1
: return ("RSASHA1");
656 case DK_ALGO_NSEC3DSA
: return ("N3DSA");
657 case DK_ALGO_NSEC3RSASHA1
: return ("N3RSA1");
658 case DK_ALGO_RSASHA256
: return ("RSASHA2");
659 case DK_ALGO_RSASHA512
: return ("RSASHA5");
664 /*****************************************************************
666 ** return error string
667 *****************************************************************/
668 const char *dki_geterrstr ()
673 /*****************************************************************
675 *****************************************************************/
676 int dki_prt_dnskey (const dki_t
*dkp
, FILE *fp
)
678 return dki_prt_dnskeyttl (dkp
, fp
, 0);
681 /*****************************************************************
682 ** dki_prt_dnskeyttl ()
683 *****************************************************************/
684 int dki_prt_dnskeyttl (const dki_t
*dkp
, FILE *fp
, int ttl
)
691 fprintf (fp
, "%s ", dkp
->name
);
693 fprintf (fp
, "%d ", ttl
);
694 fprintf (fp
, "IN DNSKEY ");
695 fprintf (fp
, "%d 3 %d (", dkp
->flags
, dkp
->algo
);
696 fprintf (fp
, "\n\t\t\t");
697 for ( p
= dkp
->pubkey
; *p
; p
++ )
699 fprintf (fp
, "\n\t\t\t");
702 fprintf (fp
, "\n\t\t");
703 if ( dki_isrevoked (dkp
) )
704 fprintf (fp
, ") ; key id = %u (original key id = %u)", (dkp
->tag
+ 128) % 65535, dkp
->tag
);
706 fprintf (fp
, ") ; key id = %u", dkp
->tag
);
712 /*****************************************************************
713 ** dki_prt_dnskey_raw ()
714 *****************************************************************/
715 int dki_prt_dnskey_raw (const dki_t
*dkp
, FILE *fp
)
723 fprintf (fp
, ";%%\tgenerationtime=%s\n", time2isostr (dkp
->gentime
, 's'));
724 if ( (days
= dki_lifetimedays (dkp
)) )
725 fprintf (fp
, ";%%\tlifetime=%dd\n", days
);
727 fprintf (fp
, ";%%\texpirationtime=%s\n", time2isostr (dkp
->exptime
, 's'));
729 fprintf (fp
, "%s ", dkp
->name
);
732 fprintf (fp
, "%d ", ttl
);
734 fprintf (fp
, "IN DNSKEY ");
735 fprintf (fp
, "%d 3 %d ", dkp
->flags
, dkp
->algo
);
736 fprintf (fp
, "%s\n", dkp
->pubkey
);
741 /*****************************************************************
742 ** dki_prt_comment ()
743 *****************************************************************/
744 int dki_prt_comment (const dki_t
*dkp
, FILE *fp
)
750 len
+= fprintf (fp
, "; %s ", dkp
->name
);
751 len
+= fprintf (fp
, "tag=%u ", dkp
->tag
);
752 len
+= fprintf (fp
, "algo=%s ", dki_algo2str(dkp
->algo
));
753 len
+= fprintf (fp
, "generated %s\n", time2str (dkp
->time
, 's'));
758 /*****************************************************************
759 ** dki_prt_trustedkey ()
760 *****************************************************************/
761 int dki_prt_trustedkey (const dki_t
*dkp
, FILE *fp
)
769 len
+= fprintf (fp
, "\"%s\" ", dkp
->name
);
770 spaces
= 22 - (strlen (dkp
->name
) + 3);
771 len
+= fprintf (fp
, "%*s", spaces
> 0 ? spaces
: 0 , " ");
772 len
+= fprintf (fp
, "%d 3 %d ", dkp
->flags
, dkp
->algo
);
774 len
+= fprintf (fp
, "\n\t\t\t%7s", " ");
775 len
+= fprintf (fp
, "\"");
776 for ( p
= dkp
->pubkey
; *p
; p
++ )
778 len
+= fprintf (fp
, "\n\t\t\t\t");
780 putc (*p
, fp
), len
+= 1;
782 if ( dki_isrevoked (dkp
) )
783 len
+= fprintf (fp
, "\" ; # key id = %u (original key id = %u)\n\n", (dkp
->tag
+ 128) % 65535, dkp
->tag
);
785 len
+= fprintf (fp
, "\" ; # key id = %u\n\n", dkp
->tag
);
789 /*****************************************************************
790 ** dki_prt_managedkey ()
791 *****************************************************************/
792 int dki_prt_managedkey (const dki_t
*dkp
, FILE *fp
)
800 len
+= fprintf (fp
, "\"%s\" ", dkp
->name
);
801 spaces
= 22 - (strlen (dkp
->name
) + 3);
802 len
+= fprintf (fp
, "initial-key ");
804 len
+= fprintf (fp
, "%*s", spaces
> 0 ? spaces
: 0 , " ");
805 len
+= fprintf (fp
, "%d 3 %d ", dkp
->flags
, dkp
->algo
);
807 len
+= fprintf (fp
, "\n\t\t\t%7s", " ");
808 len
+= fprintf (fp
, "\"");
809 for ( p
= dkp
->pubkey
; *p
; p
++ )
811 len
+= fprintf (fp
, "\n\t\t\t\t");
813 putc (*p
, fp
), len
+= 1;
815 if ( dki_isrevoked (dkp
) )
816 len
+= fprintf (fp
, "\" ; # key id = %u (original key id = %u)\n\n", (dkp
->tag
+ 128) % 65535, dkp
->tag
);
818 len
+= fprintf (fp
, "\" ; # key id = %u\n\n", dkp
->tag
);
823 /*****************************************************************
824 ** dki_cmp () return <0 | 0 | >0
825 *****************************************************************/
826 int dki_cmp (const dki_t
*a
, const dki_t
*b
)
830 if ( a
== NULL
) return -1;
831 if ( b
== NULL
) return 1;
833 /* sort by domain name, */
834 if ( (res
= domaincmp (a
->name
, b
->name
)) != 0 )
837 /* then by key type, */
838 if ( (res
= dki_isksk (b
) - dki_isksk (a
)) != 0 )
841 /* and last by creation time, */
842 return (ulong
)a
->time
- (ulong
)b
->time
;
845 #if defined(USE_TREE) && USE_TREE
846 /*****************************************************************
847 ** dki_allcmp () return <0 | 0 | >0
848 *****************************************************************/
849 int dki_allcmp (const dki_t
*a
, const dki_t
*b
)
853 if ( a
== NULL
) return -1;
854 if ( b
== NULL
) return 1;
856 // fprintf (stderr, "dki_allcmp %s, %s)\n", a->name, b->name);
857 /* sort by domain name, */
858 if ( (res
= domaincmp (a
->name
, b
->name
)) != 0 )
861 /* then by key type, */
862 if ( (res
= dki_isksk (b
) - dki_isksk (a
)) != 0 )
866 if ( (res
= (ulong
)a
->time
- (ulong
)b
->time
) != 0 )
869 /* and last by tag */
870 return a
->tag
- b
->tag
;
873 /*****************************************************************
874 ** dki_namecmp () return <0 | 0 | >0
875 *****************************************************************/
876 int dki_namecmp (const dki_t
*a
, const dki_t
*b
)
878 if ( a
== NULL
) return -1;
879 if ( b
== NULL
) return 1;
881 return domaincmp (a
->name
, b
->name
);
884 /*****************************************************************
885 ** dki_revnamecmp () return <0 | 0 | >0
886 *****************************************************************/
887 int dki_revnamecmp (const dki_t
*a
, const dki_t
*b
)
889 if ( a
== NULL
) return -1;
890 if ( b
== NULL
) return 1;
892 return domaincmp_dir (a
->name
, b
->name
, 0);
895 /*****************************************************************
896 ** dki_tagcmp () return <0 | 0 | >0
897 *****************************************************************/
898 int dki_tagcmp (const dki_t
*a
, const dki_t
*b
)
900 if ( a
== NULL
) return -1;
901 if ( b
== NULL
) return 1;
903 return a
->tag
- b
->tag
;
907 /*****************************************************************
909 *****************************************************************/
910 int dki_timecmp (const dki_t
*a
, const dki_t
*b
)
912 if ( a
== NULL
) return -1;
913 if ( b
== NULL
) return 1;
915 return ((ulong
)a
->time
- (ulong
)b
->time
);
918 /*****************************************************************
919 ** dki_algo () return the algorithm of the key
920 *****************************************************************/
921 time_t dki_algo (const dki_t
*dkp
)
923 assert (dkp
!= NULL
);
927 /*****************************************************************
928 ** dki_time () return the timestamp of the key
929 *****************************************************************/
930 time_t dki_time (const dki_t
*dkp
)
932 assert (dkp
!= NULL
);
936 /*****************************************************************
937 ** dki_exptime () return the expiration timestamp of the key
938 *****************************************************************/
939 time_t dki_exptime (const dki_t
*dkp
)
941 assert (dkp
!= NULL
);
942 return (dkp
->exptime
);
945 /*****************************************************************
946 ** dki_lifetime (dkp) return the lifetime of the key in sec!
947 *****************************************************************/
948 time_t dki_lifetime (const dki_t
*dkp
)
950 assert (dkp
!= NULL
);
951 return (dkp
->lifetime
);
954 /*****************************************************************
955 ** dki_lifetimedays (dkp) return the lifetime of the key in days!
956 *****************************************************************/
957 ushort
dki_lifetimedays (const dki_t
*dkp
)
959 assert (dkp
!= NULL
);
960 return (dkp
->lifetime
/ DAYSEC
);
963 /*****************************************************************
964 ** dki_gentime (dkp) return the generation timestamp of the key
965 *****************************************************************/
966 time_t dki_gentime (const dki_t
*dkp
)
968 assert (dkp
!= NULL
);
969 return (dkp
->gentime
> 0L ? dkp
->gentime
: dkp
->time
);
972 /*****************************************************************
973 ** dki_setlifetime (dkp, int days)
974 ** set the lifetime in days (and also the gentime if not set)
975 ** return the old lifetime of the key in days!
976 *****************************************************************/
977 ushort
dki_setlifetime (dki_t
*dkp
, int days
)
980 char path
[MAX_PATHSIZE
+1];
982 assert (dkp
!= NULL
);
984 lifetsec
= dkp
->lifetime
; /* old lifetime */
985 dkp
->lifetime
= days
* DAYSEC
; /* set new lifetime */
987 dbg_val1 ("dki_setlifetime (%d)\n", days
);
988 if ( lifetsec
== 0 ) /* initial setup (old lifetime was zero)? */
989 dkp
->gentime
= dkp
->time
;
991 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_KEY_FILEEXT
);
992 dki_writeinfo (dkp
, path
);
994 return (lifetsec
/ DAYSEC
);
997 /*****************************************************************
998 ** dki_setexptime (dkp, time_t sec)
999 ** set the expiration time of the key in seconds since the epoch
1000 ** return the old exptime
1001 *****************************************************************/
1002 time_t dki_setexptime (dki_t
*dkp
, time_t sec
)
1004 char path
[MAX_PATHSIZE
+1];
1007 assert (dkp
!= NULL
);
1009 dbg_val1 ("dki_setexptime (%ld)\n", sec
);
1010 oldexptime
= dkp
->exptime
;
1013 pathname (path
, sizeof (path
), dkp
->dname
, dkp
->fname
, DKI_KEY_FILEEXT
);
1014 dki_writeinfo (dkp
, path
);
1016 #if 0 /* not necessary ? */
1017 touch (path
, time (NULL
));
1019 return (oldexptime
);
1022 /*****************************************************************
1023 ** dki_age () return age of key in seconds since 'curr'
1024 *****************************************************************/
1025 int dki_age (const dki_t
*dkp
, time_t curr
)
1027 assert (dkp
!= NULL
);
1028 return ((ulong
)curr
- (ulong
)dkp
->time
);
1031 /*****************************************************************
1032 ** dki_getflag () return the flags field of a key
1033 *****************************************************************/
1034 dk_flag_t
dki_getflag (const dki_t
*dkp
, time_t curr
)
1039 /*****************************************************************
1040 ** dki_setflag () set a flag of a key
1041 *****************************************************************/
1042 dk_flag_t
dki_setflag (dki_t
*dkp
, dk_flag_t flag
)
1044 return dkp
->flags
|= (ushort
)flag
;
1047 /*****************************************************************
1048 ** dki_unsetflag () unset a flag of a key
1049 *****************************************************************/
1050 dk_flag_t
dki_unsetflag (dki_t
*dkp
, dk_flag_t flag
)
1052 return dkp
->flags
&= ~((ushort
)flag
);
1055 /*****************************************************************
1057 *****************************************************************/
1058 int dki_isksk (const dki_t
*dkp
)
1060 assert (dkp
!= NULL
);
1061 return (dkp
->flags
& DK_FLAG_KSK
) == DK_FLAG_KSK
;
1064 /*****************************************************************
1066 *****************************************************************/
1067 int dki_isrevoked (const dki_t
*dkp
)
1069 assert (dkp
!= NULL
);
1070 return (dkp
->flags
& DK_FLAG_REVOKE
) == DK_FLAG_REVOKE
;
1073 /*****************************************************************
1074 ** dki_isdepreciated ()
1075 *****************************************************************/
1076 int dki_isdepreciated (const dki_t
*dkp
)
1078 return dki_status (dkp
) == DKI_DEPRECIATED
;
1081 /*****************************************************************
1083 *****************************************************************/
1084 int dki_isactive (const dki_t
*dkp
)
1086 return dki_status (dkp
) == DKI_ACTIVE
;
1089 /*****************************************************************
1090 ** dki_ispublished ()
1091 *****************************************************************/
1092 int dki_ispublished (const dki_t
*dkp
)
1094 return dki_status (dkp
) == DKI_PUBLISHED
;
1098 /*****************************************************************
1099 ** dki_status () return key status
1100 *****************************************************************/
1101 dk_status_t
dki_status (const dki_t
*dkp
)
1103 assert (dkp
!= NULL
);
1104 return (dkp
->status
);
1107 /*****************************************************************
1108 ** dki_statusstr () return key status as string
1109 *****************************************************************/
1110 const char *dki_statusstr (const dki_t
*dkp
)
1112 assert (dkp
!= NULL
);
1113 switch ( dkp
->status
)
1115 case DKI_ACT
: return "active";
1116 case DKI_PUB
: if ( dki_isksk (dkp
) )
1120 case DKI_DEP
: return "depreciated";
1121 case DKI_REV
: return "revoked";
1122 case DKI_SEP
: return "sep";
1127 /*****************************************************************
1128 ** dki_add () add a key to the given list
1129 *****************************************************************/
1130 dki_t
*dki_add (dki_t
**list
, dki_t
*new)
1140 last
= curr
= *list
;
1141 while ( curr
&& dki_cmp (curr
, new) < 0 )
1147 if ( curr
== *list
) /* add node at start of list */
1149 else /* add node at end or between two nodes */
1156 /*****************************************************************
1157 ** dki_search () search a key with the given tag, or the first
1158 ** occurence of a key with the given name
1159 *****************************************************************/
1160 const dki_t
*dki_search (const dki_t
*list
, int tag
, const char *name
)
1166 while ( curr
&& (tag
!= curr
->tag
||
1167 (name
&& *name
&& strcmp (name
, curr
->name
) != 0)) )
1169 else if ( name
&& *name
)
1170 while ( curr
&& strcmp (name
, curr
->name
) != 0 )
1178 #if defined(USE_TREE) && USE_TREE
1179 /*****************************************************************
1180 ** dki_tadd () add a key to the given tree
1181 *****************************************************************/
1182 dki_t
*dki_tadd (dki_t
**tree
, dki_t
*new, int sub_before
)
1187 p
= tsearch (new, tree
, dki_namecmp
);
1189 p
= tsearch (new, tree
, dki_revnamecmp
);
1191 dbg_val ("dki_tadd: New entry %s added\n", new->name
);
1194 dbg_val ("dki_tadd: New key added to %s\n", new->name
);
1201 /*****************************************************************
1202 ** dki_tsearch () search a key with the given tag, or the first
1203 ** occurence of a key with the given name
1204 *****************************************************************/
1205 const dki_t
*dki_tsearch (const dki_t
*tree
, int tag
, const char *name
)
1211 snprintf (search
.name
, sizeof (search
.name
), "%s", name
);
1212 p
= tfind (&search
, &tree
, dki_namecmp
);
1216 return dki_search (*p
, tag
, name
);
1220 /*****************************************************************
1221 ** dki_find () find the n'th ksk or zsk key with given status
1222 *****************************************************************/
1223 const dki_t
*dki_find (const dki_t
*list
, int ksk
, int status
, int no
)
1229 for ( dkp
= list
; no
> 0 && dkp
; dkp
= dkp
->next
)
1230 if ( dki_isksk (dkp
) == ksk
&& dki_status (dkp
) == status
)
1239 /*****************************************************************
1240 ** dki_findalgo () find the n'th ksk or zsk key with given
1241 ** algorithm and status
1242 *****************************************************************/
1243 const dki_t
*dki_findalgo (const dki_t
*list
, int ksk
, int alg
, int status
, int no
)
1249 for ( dkp
= list
; no
> 0 && dkp
; dkp
= dkp
->next
)
1250 if ( dki_isksk (dkp
) == ksk
&& dki_algo (dkp
) == alg
&&
1251 dki_status (dkp
) == status
)