dki.c revision e2d635d630f6f61fefd3d4475c45b097b16b8a2a
/*****************************************************************
**
** @(#) dki.c (c) Jan 2005 Holger Zuleger hznet.de
**
** A library for managing BIND dnssec key files.
**
** Copyright (c) Jan 2005, Holger Zuleger HZnet. All rights reserved.
**
** This software is open source.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
**
** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
**
*****************************************************************/
# include <stdio.h>
# include <string.h>
# include <ctype.h> /* tolower(), ... */
# include <unistd.h> /* link(), unlink(), ... */
# include <stdlib.h>
# include <dirent.h>
# include <assert.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "config_zkt.h"
# include "debug.h"
# include "domaincmp.h"
# include "misc.h"
# include "zconf.h"
#define extern
# include "dki.h"
#undef extern
/*****************************************************************
** private (static) function declaration and definition
*****************************************************************/
{
dki_estr[0] = '\0';
{
return dkp;
}
"dki_alloc: Out of memory");
return NULL;
}
{
int c;
char *p;
{
{
;
/* then try to read in the creation, expire and lifetime */
{
{
}
}
}
else
;
}
return -1;
return -2;
#if defined(TTL_IN_KEYFILE_ALLOWED) && TTL_IN_KEYFILE_ALLOWED
/* skip optional TTL value */
;
if ( isdigit (c) ) /* skip ttl */
else
#endif
return -3;
return -4; /* no DNSKEY or algorithm mismatch */
return -5; /* no ZONE key */
return -6;
*--p = '\0'; /* delete trailing \n */
/* delete leading ws */
;
return 0;
}
{
return 0;
return 0;
return 1;
}
/*****************************************************************
** public function definition
*****************************************************************/
/*****************************************************************
** dki_free ()
*****************************************************************/
{
}
/*****************************************************************
** dki_freelist ()
*****************************************************************/
{
while ( curr )
{
}
if ( *listp )
}
/*****************************************************************
** dki_tfree ()
*****************************************************************/
{
// TODO: tdestroy is a GNU extension
// tdestroy (*tree, dki_free);
}
#endif
#else
# define KEYGEN_COMPMODE ""
#endif
/*****************************************************************
** dki_new ()
** create new keyfile
** allocate memory for new dki key and init with keyfile
*****************************************************************/
dki_t *dki_new (const char *dir, const char *name, int ksk, int algo, int bitsize, const char *rfile, int lf_days)
{
int len;
char *flag = "";
char *expflag = "";
if ( ksk )
flag = "-f KSK";
randfile[0] = '\0';
if ( algo == DK_ALGO_RSA || algo == DK_ALGO_RSASHA1 || algo == DK_ALGO_RSASHA256 || algo == DK_ALGO_RSASHA512 )
expflag = "-e ";
else
return NULL;
if ( new )
return new;
}
/*****************************************************************
** dki_read ()
** read key from file 'filename' (independed of the extension)
*****************************************************************/
{
int len;
int err;
dki_estr[0] = '\0';
return (NULL);
dbg_line ();
dbg_line ();
{
"dki_read: Filename don't match expected format (%s)", fname);
return (NULL);
}
{
"dki_read: Can\'t open file \"%s\" for reading", path);
return (NULL);
}
dbg_line ();
{
dbg_line ();
return (NULL);
}
dbg_line ();
{
"dki_read: Can\'t stat file %s", fname);
return (NULL);
}
dbg_line ();
{
if ( dki_isrevoked (dkp) )
else
}
else
{
else
{
else
}
}
dbg_line ();
dbg_line ();
return dkp;
}
/*****************************************************************
** dki_readdir ()
** read key files from directory 'dir' and, if recursive is
** true, from all directorys below that.
*****************************************************************/
{
return 0;
{
continue;
{
}
}
return 1;
}
/*****************************************************************
** dki_setstatus_preservetime ()
** set status of key and change extension to
** ".published", ".private" or ".depreciated"
*****************************************************************/
{
}
/*****************************************************************
** dki_setstatus ()
** set status of key and change extension to
** ".published", ".private" or ".depreciated"
*****************************************************************/
{
}
/*****************************************************************
** dki_setstat ()
** low level function of dki_setstatus and dki_setstatus_preservetime
*****************************************************************/
{
return 0;
{
case 'r':
if ( status == 'r' )
return 1;
break;
case 'a':
if ( status == 'a' )
return 1;
break;
case 'd':
if ( status == 'd' )
return 1;
break;
case 'p': /* or 's' */
return 1;
break;
default:
/* TODO: set error code */
return 0;
}
/* a state change could result in different things: */
/* 1) write a new keyfile when the REVOKE bit is set or unset */
{
if ( status == 'r' )
else
if ( !preserve_time )
return 0;
}
/* 2) change the filename of the private key in all other cases */
totime = 0L;
if ( preserve_time )
topath[0] = '\0';
switch ( status )
{
case 'a':
break;
case 'd':
break;
case 's': /* standby means a "published KSK" */
return 2;
status = 'p';
/* fall through */
case 'p':
break;
}
if ( topath[0] )
{
if ( !totime )
}
return 0;
}
/*****************************************************************
** dki_remove ()
** rename files associated with key, so that the keys are not
** recognized by the zkt tools e.g.
** Kdo.ma.in.+001+12345.key ==> kdo.ma.in.+001+12345.key
** (second one starts with a lower case 'k')
*****************************************************************/
{
const char **pext;
static const char *ext[] = {
};
return NULL;
{
{
}
}
return next;
}
/*****************************************************************
** dki_destroy ()
** delete files associated with key and free allocated memory
*****************************************************************/
{
const char **pext;
static const char *ext[] = {
};
return NULL;
{
{
}
}
return next;
}
/*****************************************************************
** dki_algo2str ()
** return a string describing the key algorithm
*****************************************************************/
char *dki_algo2str (int algo)
{
switch ( algo )
{
case DK_ALGO_RSA: return ("RSAMD5");
case DK_ALGO_DH: return ("DH");
case DK_ALGO_DSA: return ("DSA");
case DK_ALGO_EC: return ("EC");
case DK_ALGO_RSASHA1: return ("RSASHA1");
case DK_ALGO_NSEC3DSA: return ("NSEC3DSA");
case DK_ALGO_NSEC3RSASHA1: return ("NSEC3RSASHA1");
case DK_ALGO_RSASHA256: return ("RSASHA256");
case DK_ALGO_RSASHA512: return ("RSASHA512");
}
return ("unknown");
}
/*****************************************************************
** dki_algo2sstr ()
** return a short string describing the key algorithm
*****************************************************************/
char *dki_algo2sstr (int algo)
{
switch ( algo )
{
case DK_ALGO_RSA: return ("RSAMD5");
case DK_ALGO_DH: return ("DH");
case DK_ALGO_DSA: return ("DSA");
case DK_ALGO_EC: return ("EC");
case DK_ALGO_RSASHA1: return ("RSASHA1");
case DK_ALGO_NSEC3DSA: return ("N3DSA");
case DK_ALGO_NSEC3RSASHA1: return ("N3RSA1");
case DK_ALGO_RSASHA256: return ("RSASHA2");
case DK_ALGO_RSASHA512: return ("RSASHA5");
}
return ("unknown");
}
/*****************************************************************
** dki_geterrstr ()
** return error string
*****************************************************************/
const char *dki_geterrstr ()
{
return dki_estr;
}
/*****************************************************************
** dki_prt_dnskey ()
*****************************************************************/
{
}
/*****************************************************************
** dki_prt_dnskeyttl ()
*****************************************************************/
{
char *p;
return 0;
if ( ttl > 0 )
if ( *p == ' ' )
else
if ( dki_isrevoked (dkp) )
else
return 1;
}
/*****************************************************************
** dki_prt_dnskey_raw ()
*****************************************************************/
{
int days;
return 0;
#if 0
if ( ttl > 0 )
#endif
return 1;
}
/*****************************************************************
** dki_prt_comment ()
*****************************************************************/
{
int len = 0;
return len;
return len;
}
/*****************************************************************
** dki_prt_trustedkey ()
*****************************************************************/
{
char *p;
int spaces;
int len = 0;
return len;
if ( spaces < 0 )
if ( *p == ' ' )
else
if ( dki_isrevoked (dkp) )
len += fprintf (fp, "\" ; # key id = %u (original key id = %u)\n\n", (dkp->tag + 128) % 65535, dkp->tag);
else
return len;
}
/*****************************************************************
** dki_prt_managedkey ()
*****************************************************************/
{
char *p;
int spaces;
int len = 0;
return len;
spaces -= 13;
if ( spaces < 0 )
if ( *p == ' ' )
else
if ( dki_isrevoked (dkp) )
len += fprintf (fp, "\" ; # key id = %u (original key id = %u)\n\n", (dkp->tag + 128) % 65535, dkp->tag);
else
return len;
}
/*****************************************************************
** dki_cmp () return <0 | 0 | >0
*****************************************************************/
{
int res;
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
/* sort by domain name, */
return res;
/* then by key type, */
return res;
/* and last by creation time, */
}
/*****************************************************************
** dki_allcmp () return <0 | 0 | >0
*****************************************************************/
{
int res;
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
// fprintf (stderr, "dki_allcmp %s, %s)\n", a->name, b->name);
/* sort by domain name, */
return res;
/* then by key type, */
return res;
/* creation time, */
return res;
/* and last by tag */
}
/*****************************************************************
** dki_namecmp () return <0 | 0 | >0
*****************************************************************/
{
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
}
/*****************************************************************
** dki_revnamecmp () return <0 | 0 | >0
*****************************************************************/
{
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
}
/*****************************************************************
** dki_tagcmp () return <0 | 0 | >0
*****************************************************************/
{
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
}
#endif
/*****************************************************************
** dki_timecmp ()
*****************************************************************/
{
if ( a == NULL ) return -1;
if ( b == NULL ) return 1;
}
/*****************************************************************
** dki_algo () return the algorithm of the key
*****************************************************************/
{
}
/*****************************************************************
** dki_time () return the timestamp of the key
*****************************************************************/
{
}
/*****************************************************************
** dki_exptime () return the expiration timestamp of the key
*****************************************************************/
{
}
/*****************************************************************
** dki_lifetime (dkp) return the lifetime of the key in sec!
*****************************************************************/
{
}
/*****************************************************************
** dki_lifetimedays (dkp) return the lifetime of the key in days!
*****************************************************************/
{
}
/*****************************************************************
** dki_gentime (dkp) return the generation timestamp of the key
*****************************************************************/
{
}
/*****************************************************************
** dki_setlifetime (dkp, int days)
** set the lifetime in days (and also the gentime if not set)
** return the old lifetime of the key in days!
*****************************************************************/
{
if ( lifetsec == 0 ) /* initial setup (old lifetime was zero)? */
}
/*****************************************************************
** dki_setexptime (dkp, time_t sec)
** set the expiration time of the key in seconds since the epoch
** return the old exptime
*****************************************************************/
{
#if 0 /* not necessary ? */
#endif
return (oldexptime);
}
/*****************************************************************
** dki_age () return age of key in seconds since 'curr'
*****************************************************************/
{
}
/*****************************************************************
** dki_getflag () return the flags field of a key
*****************************************************************/
{
}
/*****************************************************************
** dki_setflag () set a flag of a key
*****************************************************************/
{
}
/*****************************************************************
** dki_unsetflag () unset a flag of a key
*****************************************************************/
{
}
/*****************************************************************
** dki_isksk ()
*****************************************************************/
{
}
/*****************************************************************
** dki_isrevoked ()
*****************************************************************/
{
}
/*****************************************************************
** dki_isdepreciated ()
*****************************************************************/
{
}
/*****************************************************************
** dki_isactive ()
*****************************************************************/
{
}
/*****************************************************************
** dki_ispublished ()
*****************************************************************/
{
}
/*****************************************************************
** dki_status () return key status
*****************************************************************/
{
}
/*****************************************************************
** dki_statusstr () return key status as string
*****************************************************************/
{
{
case DKI_ACT: return "active";
return "standby";
else
return "published";
case DKI_DEP: return "depreciated";
case DKI_REV: return "revoked";
case DKI_SEP: return "sep";
}
return "unknown";
}
/*****************************************************************
** dki_add () add a key to the given list
*****************************************************************/
{
return NULL;
return *list;
{
}
else /* add node at end or between two nodes */
return *list;
}
/*****************************************************************
** dki_search () search a key with the given tag, or the first
** occurence of a key with the given name
*****************************************************************/
{
if ( tag )
else
return curr;
}
/*****************************************************************
** dki_tadd () add a key to the given tree
*****************************************************************/
{
dki_t **p;
if ( sub_before )
else
if ( *p == new )
else
{
}
return *p;
}
/*****************************************************************
** dki_tsearch () search a key with the given tag, or the first
** occurence of a key with the given name
*****************************************************************/
{
dki_t **p;
if ( p == NULL )
return NULL;
}
#endif
/*****************************************************************
** dki_find () find the n'th ksk or zsk key with given status
*****************************************************************/
{
{
no--;
}
return last;
}
/*****************************************************************
** dki_findalgo () find the n'th ksk or zsk key with given
** algorithm and status
*****************************************************************/
{
{
no--;
}
return last;
}