ldns-signzone.c
Go to the documentation of this file.
/*
* ldns-signzone signs a zone file
*
* (c) NLnet Labs, 2005 - 2008
* See the file LICENSE for the license
*/
#include <stdio.h>
#include "config.h"
#ifdef HAVE_SSL
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <ldns/ldns.h>
#include <ldns/keys.h>
#include <openssl/conf.h>
#if defined(HAVE_OPENSSL_ENGINE_H) && !defined(OPENSSL_NO_ENGINE)
#include <openssl/engine.h>
#else
# ifndef OPENSSL_NO_ENGINE
# define OPENSSL_NO_ENGINE
# endif
#endif
#include <openssl/err.h>
#define MAX_FILENAME_LEN 250
char *prog;
int verbosity = 1;
static void
usage(FILE *fp, const char *prog) {
fprintf(fp, "%s [OPTIONS] zonefile key [key [key]]\n", prog);
fprintf(fp, " signs the zone with the given key(s)\n");
fprintf(fp, " -b\t\tuse layout in signed zone and print comments DNSSEC records\n");
fprintf(fp, " -d\t\tused keys are not added to the zone\n");
fprintf(fp, " -e <date>\texpiration date\n");
fprintf(fp, " -f <file>\toutput zone to file (default <name>.signed)\n");
fprintf(fp, " -i <date>\tinception date\n");
fprintf(fp, " -o <domain>\torigin for the zone\n");
fprintf(fp, " -u\t\tset SOA serial to the number of seconds since 1-1-1970\n");
fprintf(fp, " -v\t\tprint version and exit\n");
fprintf(fp, " -z <[scheme:]hash>\tAdd ZONEMD resource record\n");
fprintf(fp, "\t\t<scheme> should be \"simple\" (or 1)\n");
fprintf(fp, "\t\t<hash> should be \"sha384\" or \"sha512\" (or 1 or 2)\n");
fprintf(fp, "\t\tthis option can be given more than once\n");
fprintf(fp, " -Z\t\tAllow ZONEMDs to be added without signing\n");
fprintf(fp, " -A\t\tsign DNSKEY with all keys instead of minimal\n");
fprintf(fp, " -U\t\tSign with every unique algorithm in the provided keys\n");
#ifndef OPENSSL_NO_ENGINE
fprintf(fp, " -E <name>\tuse <name> as the crypto engine for signing\n");
fprintf(fp, " \tThis can have a lot of extra options, see the manual page for more info\n");
fprintf(fp, " -k <algorithm>,<key>\tuse `key' with `algorithm' from engine as ZSK\n");
fprintf(fp, " -K <algorithm>,<key>\tuse `key' with `algorithm' from engine as KSK\n");
#endif
fprintf(fp, " -n\t\tuse NSEC3 instead of NSEC.\n");
fprintf(fp, "\t\tIf you use NSEC3, you can specify the following extra options:\n");
fprintf(fp, "\t\t-a [algorithm] hashing algorithm\n");
fprintf(fp, "\t\t-t [number] number of hash iterations\n");
fprintf(fp, "\t\t-s [string] salt\n");
fprintf(fp, "\t\t-p set the opt-out flag on all nsec3 rrs\n");
fprintf(fp, "\n");
fprintf(fp, " keys must be specified by their base name (usually K<name>+<alg>+<id>),\n");
fprintf(fp, " i.e. WITHOUT the .private extension.\n");
fprintf(fp, " If the public part of the key is not present in the zone, the DNSKEY RR\n");
fprintf(fp, " will be read from the file called <base name>.key. If that does not exist,\n");
fprintf(fp, " a default DNSKEY will be generated from the private key and added to the zone.\n");
fprintf(fp, " A date can be a timestamp (seconds since the epoch), or of\n the form <YYYYMMdd[hhmmss]>\n");
#ifndef OPENSSL_NO_ENGINE
fprintf(fp, " For -k or -K, the algorithm can be specified as an integer or a symbolic name:" );
#define __LIST(x) fprintf ( fp, " %3d: %-15s", LDNS_SIGN_ ## x, # x )
fprintf ( fp, "\n " );
__LIST ( RSAMD5 );
#ifdef USE_DSA
__LIST ( DSA );
#endif
__LIST ( RSASHA1 );
fprintf ( fp, "\n " );
#ifdef USE_DSA
__LIST ( DSA_NSEC3 );
#endif
__LIST ( RSASHA1_NSEC3 );
__LIST ( RSASHA256 );
fprintf ( fp, "\n " );
__LIST ( RSASHA512 );
__LIST ( ECC_GOST );
__LIST ( ECDSAP256SHA256 );
fprintf ( fp, "\n " );
__LIST ( ECDSAP384SHA384 );
#ifdef USE_ED25519
__LIST ( ED25519 );
#endif
#ifdef USE_ED448
__LIST ( ED448 );
#endif
fprintf ( fp, "\n" );
#undef __LIST
#endif
}
static void check_tm(struct tm tm)
{
if (tm.tm_year < 70) {
fprintf(stderr, "You cannot specify dates before 1970\n");
exit(EXIT_FAILURE);
}
if (tm.tm_mon < 0 || tm.tm_mon > 11) {
fprintf(stderr, "The month must be in the range 1 to 12\n");
exit(EXIT_FAILURE);
}
if (tm.tm_mday < 1 || tm.tm_mday > 31) {
fprintf(stderr, "The day must be in the range 1 to 31\n");
exit(EXIT_FAILURE);
}
if (tm.tm_hour < 0 || tm.tm_hour > 23) {
fprintf(stderr, "The hour must be in the range 0-23\n");
exit(EXIT_FAILURE);
}
if (tm.tm_min < 0 || tm.tm_min > 59) {
fprintf(stderr, "The minute must be in the range 0-59\n");
exit(EXIT_FAILURE);
}
if (tm.tm_sec < 0 || tm.tm_sec > 59) {
fprintf(stderr, "The second must be in the range 0-59\n");
exit(EXIT_FAILURE);
}
}
/*
* if the ttls are different, make them equal
* if one of the ttls equals LDNS_DEFAULT_TTL, that one is changed
* otherwise, rr2 will get the ttl of rr1
*
* prints a warning if a non-default TTL is changed
*/
static void
equalize_ttls(ldns_rr *rr1, ldns_rr *rr2, uint32_t default_ttl)
{
uint32_t ttl1, ttl2;
ttl1 = ldns_rr_ttl(rr1);
ttl2 = ldns_rr_ttl(rr2);
if (ttl1 != ttl2) {
if (ttl1 == default_ttl) {
ldns_rr_set_ttl(rr1, ttl2);
} else if (ttl2 == default_ttl) {
ldns_rr_set_ttl(rr2, ttl1);
} else {
ldns_rr_set_ttl(rr2, ttl1);
fprintf(stderr,
"warning: changing non-default TTL %u to %u\n",
(unsigned int) ttl2, (unsigned int) ttl1);
}
}
}
static void
equalize_ttls_rr_list(ldns_rr_list *rr_list, ldns_rr *rr, uint32_t default_ttl)
{
size_t i;
ldns_rr *cur_rr;
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
cur_rr = ldns_rr_list_rr(rr_list, i);
if (ldns_rr_compare_no_rdata(cur_rr, rr) == 0) {
equalize_ttls(cur_rr, rr, default_ttl);
}
}
}
static ldns_rr *
find_key_in_zone(ldns_rr *pubkey_gen, ldns_zone *zone) {
size_t key_i;
ldns_rr *pubkey;
for (key_i = 0;
key_i < ldns_rr_list_rr_count(ldns_zone_rrs(zone));
key_i++) {
pubkey = ldns_rr_list_rr(ldns_zone_rrs(zone), key_i);
if (ldns_rr_get_type(pubkey) == LDNS_RR_TYPE_DNSKEY &&
(ldns_calc_keytag(pubkey)
==
ldns_calc_keytag(pubkey_gen) ||
/* KSK has gen-keytag + 1 */
ldns_calc_keytag(pubkey)
==
ldns_calc_keytag(pubkey_gen) + 1)
) {
if (verbosity >= 2) {
fprintf(stderr, "Found it in the zone!\n");
}
return pubkey;
}
}
return NULL;
}
static ldns_rr *
find_key_in_file(const char *keyfile_name_base, ldns_key* ATTR_UNUSED(key),
uint32_t zone_ttl)
{
char *keyfile_name;
FILE *keyfile;
int line_nr;
uint32_t default_ttl = zone_ttl;
ldns_rr *pubkey = NULL;
keyfile_name = LDNS_XMALLOC(char,
strlen(keyfile_name_base) + 5);
snprintf(keyfile_name,
strlen(keyfile_name_base) + 5,
"%s.key",
keyfile_name_base);
if (verbosity >= 2) {
fprintf(stderr, "Trying to read %s\n", keyfile_name);
}
keyfile = fopen(keyfile_name, "r");
line_nr = 0;
if (keyfile) {
if (ldns_rr_new_frm_fp_l(&pubkey,
keyfile,
&default_ttl,
NULL,
NULL,
&line_nr) ==
LDNS_STATUS_OK) {
if (verbosity >= 2) {
printf("Key found in file: %s\n", keyfile_name);
}
}
fclose(keyfile);
}
LDNS_FREE(keyfile_name);
return pubkey;
}
/* this function tries to find the specified keys either in the zone that
* has been read, or in a <basename>.key file. If the key is not found,
* a public key is generated, and it is assumed the key is a ZSK
*
* if add_keys is true; the DNSKEYs are added to the zone prior to signing
* if it is false, they are not added.
* Even if keys are not added, the function is still needed, to check
* whether keys of which we only have key data are KSKs or ZSKS
*/
static void
find_or_create_pubkey(const char *keyfile_name_base, ldns_key *key, ldns_zone *orig_zone, bool add_keys, uint32_t default_ttl) {
ldns_rr *pubkey_gen, *pubkey;
int key_in_zone;
if (default_ttl == LDNS_DEFAULT_TTL) {
default_ttl = ldns_rr_ttl(ldns_zone_soa(orig_zone));
}
if (!ldns_key_pubkey_owner(key)) {
ldns_key_set_pubkey_owner(key, ldns_rdf_clone(ldns_rr_owner(ldns_zone_soa(orig_zone))));
}
/* find the public key in the zone, or in a
* separate file
* we 'generate' one anyway,
* then match that to any present in the zone,
* if it matches, we drop our own. If not,
* we try to see if there is a .key file present.
* If not, we use our own generated one, with
* some default values
*
* Even if -d (do-not-add-keys) is specified,
* we still need to do this, because we need
* to have any key flags that are set this way
*/
pubkey_gen = ldns_key2rr(key);
ldns_rr_set_ttl(pubkey_gen, default_ttl);
if (verbosity >= 2) {
fprintf(stderr,
"Looking for key with keytag %u or %u\n",
(unsigned int) ldns_calc_keytag(pubkey_gen),
(unsigned int) ldns_calc_keytag(pubkey_gen)+1
);
}
pubkey = find_key_in_zone(pubkey_gen, orig_zone);
key_in_zone = 1;
if (!pubkey) {
key_in_zone = 0;
/* it was not in the zone, try to read a .key file */
pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
if (!pubkey && !(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
/* maybe it is a ksk? */
ldns_key_set_keytag(key, ldns_key_keytag(key) + 1);
pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
if (!pubkey) {
/* ok, no file, set back to ZSK */
ldns_key_set_keytag(key, ldns_key_keytag(key) - 1);
}
}
if(pubkey && ldns_dname_compare(ldns_rr_owner(pubkey), ldns_rr_owner(ldns_zone_soa(orig_zone))) != 0) {
fprintf(stderr, "Error %s.key has wrong name: %s\n",
keyfile_name_base, ldns_rdf2str(ldns_rr_owner(pubkey)));
exit(EXIT_FAILURE); /* leak rdf2str, but we exit */
}
}
if (!pubkey) {
/* okay, no public key found,
just use our generated one */
pubkey = pubkey_gen;
if (verbosity >= 2) {
fprintf(stderr, "Not in zone, no .key file, generating ZSK DNSKEY from private key data\n");
}
} else {
ldns_rr_free(pubkey_gen);
}
ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
if (add_keys && !key_in_zone) {
equalize_ttls_rr_list(ldns_zone_rrs(orig_zone), pubkey, default_ttl);
ldns_zone_push_rr(orig_zone, pubkey);
}
}
#ifndef OPENSSL_NO_ENGINE
/*
* For keys coming from the engine (-k or -K), parse algorithm specification.
*/
static enum ldns_enum_signing_algorithm
parse_algspec ( const char * const p )
{
if ( p == NULL )
return 0;
if ( isdigit ( (const unsigned char)*p ) ) {
const char *nptr = NULL;
const long id = strtol ( p, (char **) &nptr, 10 );
return id > 0 && nptr != NULL && *nptr == ',' ? id : 0;
}
#define __MATCH(x) \
if ( !memcmp ( # x, p, sizeof ( # x ) - 1 ) \
&& p [ sizeof ( # x ) - 1 ] == ',' ) { \
return LDNS_SIGN_ ## x; \
}
__MATCH ( RSAMD5 );
__MATCH ( RSASHA1 );
#ifdef USE_DSA
__MATCH ( DSA );
#endif
__MATCH ( RSASHA1_NSEC3 );
__MATCH ( RSASHA256 );
__MATCH ( RSASHA512 );
#ifdef USE_DSA
__MATCH ( DSA_NSEC3 );
#endif
__MATCH ( ECC_GOST );
__MATCH ( ECDSAP256SHA256 );
__MATCH ( ECDSAP384SHA384 );
#ifdef USE_ED25519
__MATCH ( ED25519 );
#endif
#ifdef USE_ED448
__MATCH ( ED448 );
#endif
#undef __MATCH
return 0;
}
/*
* For keys coming from the engine (-k or -K), parse key specification
* in the form of <algorithm>,<key-id>. No whitespace is allowed
* between <algorithm> and the comma, and between the comma and
* <key-id>. <key-id> format is specific to the engine at hand, i.e.
* it can be the old OpenSC syntax or a PKCS #11 URI as defined in RFC 7512
* and (partially) supported by OpenSC (as of 20180312).
*/
static const char *
parse_keyspec ( const char * const p,
enum ldns_enum_signing_algorithm * const algorithm,
const char ** const id )
{
const char * const comma = strchr ( p, ',' );
if ( comma == NULL || !(*algorithm = parse_algspec ( p )) )
return NULL;
return comma [ 1 ] ? *id = comma + 1 : NULL;
}
/*
* Load a key from the engine.
*/
static ldns_key *
load_key ( const char * const p, ENGINE * const e )
{
enum ldns_enum_signing_algorithm alg = 0;
const char *id = NULL;
ldns_status status = LDNS_STATUS_ERR;
ldns_key *key = NULL;
/* Parse key specification. */
if ( parse_keyspec ( p, &alg, &id ) == NULL ) {
fprintf ( stderr,
"Failed to parse key specification `%s'.\n",
p );
usage ( stderr, prog );
exit ( EXIT_FAILURE );
}
/* Validate that the algorithm can be used for signing. */
switch ( alg ) {
case LDNS_SIGN_RSAMD5:
case LDNS_SIGN_RSASHA1:
case LDNS_SIGN_RSASHA1_NSEC3:
case LDNS_SIGN_RSASHA256:
case LDNS_SIGN_RSASHA512:
#ifdef USE_DSA
case LDNS_SIGN_DSA:
case LDNS_SIGN_DSA_NSEC3:
#endif
case LDNS_SIGN_ECC_GOST:
#ifdef USE_ECDSA
case LDNS_SIGN_ECDSAP256SHA256:
case LDNS_SIGN_ECDSAP384SHA384:
#endif
break;
default:
fprintf ( stderr,
"Algorithm %d cannot be used for signing.\n",
alg );
usage ( stderr, prog );
exit ( EXIT_FAILURE );
}
printf ( "Engine key id: %s, algo %d\n", id, alg );
/* Attempt to load the key from the engine. */
status = ldns_key_new_frm_engine (
&key, e, (char *) id, (ldns_algorithm)alg );
if ( status != LDNS_STATUS_OK ) {
ERR_print_errors_fp ( stderr );
exit ( EXIT_FAILURE );
}
return key;
}
/*
* For keys coming from the engine (-k or -K), set key parameters
* and determine whether the key is listed in the zone file.
*/
static void
post_process_engine_key ( ldns_key_list * const keys,
ldns_key * const key,
ldns_zone * const zone,
const bool add_keys,
const uint32_t ttl,
const uint32_t inception,
const uint32_t expiration )
{
if ( key == NULL ) return;
if ( expiration ) ldns_key_set_expiration ( key, expiration );
if ( inception ) ldns_key_set_inception ( key, inception );
ldns_key_list_push_key ( keys, key );
find_or_create_pubkey ( "", key, zone, add_keys, ttl );
}
/*
* Initialize OpenSSL, for versions 1.1 and newer.
*/
static ENGINE *
init_openssl_engine ( const char * const id )
{
ENGINE *e = NULL;
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
ERR_load_crypto_strings();
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) || !defined(HAVE_OPENSSL_INIT_CRYPTO)
OpenSSL_add_all_algorithms();
#else
if ( !OPENSSL_init_crypto ( OPENSSL_INIT_LOAD_CONFIG, NULL ) ) {
fprintf ( stderr, "OPENSSL_init_crypto(3) failed.\n" );
ERR_print_errors_fp ( stderr );
exit ( EXIT_FAILURE );
}
#endif
if ( (e = ENGINE_by_id ( id )) == NULL ) {
fprintf ( stderr, "ENGINE_by_id(3) failed.\n" );
ERR_print_errors_fp ( stderr );
exit ( EXIT_FAILURE );
}
if ( !ENGINE_set_default_DSA ( e ) ) {
fprintf ( stderr, "ENGINE_set_default_DSA(3) failed.\n" );
ERR_print_errors_fp ( stderr );
exit ( EXIT_FAILURE );
}
if ( !ENGINE_set_default_RSA ( e ) ) {
fprintf ( stderr, "ENGINE_set_default_RSA(3) failed.\n" );
ERR_print_errors_fp ( stderr );
exit ( EXIT_FAILURE );
}
return e;
}
/*
* De-initialize OpenSSL, for versions 1.1 and newer.
*
* All of that is not strictly necessary because the process exits
* anyway, however, when an engine is used, this is the only hope
* of letting the engine's driver know that the program terminates
* (for the fear that the driver's reference counting may go awry, etc.)
* Still, there is no guarantee that this function helps...
*/
static void
shutdown_openssl ( ENGINE * const e )
{
if ( e != NULL ) {
#ifdef HAVE_ENGINE_FREE
ENGINE_free ( e );
#endif
#ifdef HAVE_ENGINE_CLEANUP
ENGINE_cleanup ();
#endif
}
#ifdef HAVE_CONF_MODULES_UNLOAD
CONF_modules_unload ( 1 );
#endif
#ifdef HAVE_EVP_CLEANUP
EVP_cleanup ();
#endif
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
CRYPTO_cleanup_all_ex_data ();
#endif
#ifdef HAVE_ERR_FREE_STRINGS
ERR_free_strings ();
#endif
}
#endif
int str2zonemd_signflag(const char *str, const char **reason)
{
char *colon;
static const char *reasons[] = {
"Unknown <scheme>, should be \"simple\""
, "Syntax error in <hash>, should be \"sha384\" or \"sha512\""
, "Unknown <hash>, should be \"sha384\" or \"sha512\""
};
if (!str)
return LDNS_STATUS_NULL;
if ((colon = strchr(str, ':'))) {
if ((colon - str != 1 || str[0] != '1')
&& (colon - str != 6 || strncasecmp(str, "simple", 6))) {
if (reason) *reason = reasons[0];
return 0;
}
if (strchr(colon + 1, ':')) {
if (reason) *reason = reasons[1];
return 0;
}
return str2zonemd_signflag(colon + 1, reason);
}
if (!strcasecmp(str, "1") || !strcasecmp(str, "sha384"))
return LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384;
if (!strcasecmp(str, "2") || !strcasecmp(str, "sha512"))
return LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512;
if (reason) *reason = reasons[2];
return 0;
}
int
main(int argc, char *argv[])
{
const char *zonefile_name;
FILE *zonefile = NULL;
int line_nr = 0;
int c;
int argi;
#ifndef OPENSSL_NO_ENGINE
ENGINE *engine = NULL;
#endif
ldns_zone *orig_zone;
ldns_rr_list *orig_rrs = NULL;
ldns_rr *orig_soa = NULL;
ldns_dnssec_zone *signed_zone;
char *keyfile_name_base;
char *keyfile_name = NULL;
FILE *keyfile = NULL;
ldns_key *key = NULL;
#ifndef OPENSSL_NO_ENGINE
ldns_key *eng_ksk = NULL; /* KSK specified with -K */
ldns_key *eng_zsk = NULL; /* ZSK specified with -k */
#endif
ldns_key_list *keys;
ldns_status s;
size_t i;
ldns_rr_list *added_rrs;
char *outputfile_name = NULL;
FILE *outputfile;
bool use_nsec3 = false;
int signflags = 0;
bool unixtime_serial = false;
/* Add the given keys to the zone if they are not yet present */
bool add_keys = true;
uint8_t nsec3_algorithm = 1;
uint8_t nsec3_flags = 0;
size_t nsec3_iterations_cmd = 1;
uint16_t nsec3_iterations = 1;
uint8_t nsec3_salt_length = 0;
uint8_t *nsec3_salt = NULL;
/* we need to know the origin before reading ksk's,
* so keep an array of filenames until we know it
*/
struct tm tm;
uint32_t inception;
uint32_t expiration;
ldns_rdf *origin = NULL;
uint32_t ttl = LDNS_DEFAULT_TTL;
ldns_rr_class class = LDNS_RR_CLASS_IN;
ldns_status result;
ldns_output_format_storage fmt_st;
ldns_output_format* fmt = ldns_output_format_init(&fmt_st);
/* For parson zone digest parameters */
int flag;
const char *reason = NULL;
prog = strdup(argv[0]);
inception = 0;
expiration = 0;
keys = ldns_key_list_new();
while ((c = getopt(argc, argv, "a:bde:f:i:k:no:ps:t:uvz:ZAUE:K:")) != -1) {
switch (c) {
case 'a':
nsec3_algorithm = (uint8_t) atoi(optarg);
if (nsec3_algorithm != 1) {
fprintf(stderr, "Bad NSEC3 algorithm, only RSASHA1 allowed\n");
exit(EXIT_FAILURE);
}
break;
case 'b':
ldns_output_format_set(fmt, LDNS_COMMENT_FLAGS
| LDNS_COMMENT_LAYOUT
| LDNS_COMMENT_NSEC3_CHAIN
| LDNS_COMMENT_BUBBLEBABBLE);
break;
case 'd':
add_keys = false;
break;
case 'e':
/* try to parse YYYYMMDD first,
* if that doesn't work, it
* should be a timestamp (seconds since epoch)
*/
memset(&tm, 0, sizeof(tm));
if (strlen(optarg) == 8 &&
sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
) {
tm.tm_year -= 1900;
tm.tm_mon--;
check_tm(tm);
expiration =
(uint32_t) ldns_mktime_from_utc(&tm);
} else if (strlen(optarg) == 14 &&
sscanf(optarg, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
) {
tm.tm_year -= 1900;
tm.tm_mon--;
check_tm(tm);
expiration =
(uint32_t) ldns_mktime_from_utc(&tm);
} else {
expiration = (uint32_t) atol(optarg);
}
break;
case 'f':
outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN + 1);
strncpy(outputfile_name, optarg, MAX_FILENAME_LEN);
break;
case 'i':
memset(&tm, 0, sizeof(tm));
if (strlen(optarg) == 8 &&
sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
) {
tm.tm_year -= 1900;
tm.tm_mon--;
check_tm(tm);
inception =
(uint32_t) ldns_mktime_from_utc(&tm);
} else if (strlen(optarg) == 14 &&
sscanf(optarg, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
) {
tm.tm_year -= 1900;
tm.tm_mon--;
check_tm(tm);
inception =
(uint32_t) ldns_mktime_from_utc(&tm);
} else {
inception = (uint32_t) atol(optarg);
}
break;
case 'n':
use_nsec3 = true;
break;
case 'o':
if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
fprintf(stderr, "Bad origin, not a correct domain name\n");
usage(stderr, prog);
exit(EXIT_FAILURE);
}
break;
case 'p':
nsec3_flags = nsec3_flags | LDNS_NSEC3_VARS_OPTOUT_MASK;
break;
case 'u':
unixtime_serial = true;
break;
case 'v':
printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
exit(EXIT_SUCCESS);
break;
case 'z':
flag = str2zonemd_signflag(optarg, &reason);
if (flag)
signflags |= flag;
else {
fprintf( stderr
, "%s\nwith zone digest parameters:"
" \"%s\"\n"
, reason, optarg);
exit(EXIT_FAILURE);
}
break;
case 'Z':
signflags |= LDNS_SIGN_NO_KEYS_NO_NSECS;
break;
case 'A':
signflags |= LDNS_SIGN_DNSKEY_WITH_ZSK;
break;
case 'E':
#ifndef OPENSSL_NO_ENGINE
engine = init_openssl_engine ( optarg );
break;
#else
/* fallthrough */
#endif
case 'k':
#ifndef OPENSSL_NO_ENGINE
eng_zsk = load_key ( optarg, engine );
break;
#else
/* fallthrough */
#endif
case 'K':
#ifndef OPENSSL_NO_ENGINE
eng_ksk = load_key ( optarg, engine );
/* I apologize for that, there is no API. */
eng_ksk -> _extra.dnssec.flags |= LDNS_KEY_SEP_KEY;
#else
fprintf(stderr, "%s compiled without engine support\n"
, prog);
exit(EXIT_FAILURE);
#endif
break;
case 'U':
signflags |= LDNS_SIGN_WITH_ALL_ALGORITHMS;
break;
case 's':
if (strlen(optarg) % 2 != 0) {
fprintf(stderr, "Salt value is not valid hex data, not a multiple of 2 characters\n");
exit(EXIT_FAILURE);
}
nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
nsec3_salt = LDNS_XMALLOC(uint8_t, nsec3_salt_length);
for (c = 0; c < (int) strlen(optarg); c += 2) {
if (isxdigit((int) optarg[c]) && isxdigit((int) optarg[c+1])) {
nsec3_salt[c/2] = (uint8_t) ldns_hexdigit_to_int(optarg[c]) * 16 +
ldns_hexdigit_to_int(optarg[c+1]);
} else {
fprintf(stderr, "Salt value is not valid hex data.\n");
exit(EXIT_FAILURE);
}
}
break;
case 't':
nsec3_iterations_cmd = (size_t) atol(optarg);
if (nsec3_iterations_cmd > LDNS_NSEC3_MAX_ITERATIONS) {
fprintf(stderr, "Iterations count can not exceed %u, quitting\n", LDNS_NSEC3_MAX_ITERATIONS);
exit(EXIT_FAILURE);
}
nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
break;
default:
usage(stderr, prog);
exit(EXIT_SUCCESS);
}
}
argc -= optind;
argv += optind;
if (argc < 1) {
printf("Error: not enough arguments\n");
usage(stdout, prog);
exit(EXIT_FAILURE);
} else {
zonefile_name = argv[0];
}
/* read zonefile first to find origin if not specified */
if (strncmp(zonefile_name, "-", 2) == 0) {
s = ldns_zone_new_frm_fp_l(&orig_zone,
stdin,
origin,
ttl,
class,
&line_nr);
if (s != LDNS_STATUS_OK) {
fprintf(stderr, "Zone not read, error: %s at stdin line %d\n",
ldns_get_errorstr_by_id(s),
line_nr);
exit(EXIT_FAILURE);
} else {
orig_soa = ldns_zone_soa(orig_zone);
if (!orig_soa) {
fprintf(stderr,
"Error reading zonefile: missing SOA record\n");
exit(EXIT_FAILURE);
}
orig_rrs = ldns_zone_rrs(orig_zone);
if (!orig_rrs) {
fprintf(stderr,
"Error reading zonefile: no resource records\n");
exit(EXIT_FAILURE);
}
}
} else {
zonefile = fopen(zonefile_name, "r");
if (!zonefile) {
fprintf(stderr,
"Error: unable to read %s (%s)\n",
zonefile_name,
strerror(errno));
exit(EXIT_FAILURE);
} else {
s = ldns_zone_new_frm_fp_l(&orig_zone,
zonefile,
origin,
ttl,
class,
&line_nr);
if (s != LDNS_STATUS_OK) {
fprintf(stderr, "Zone not read, error: %s at %s line %d\n",
ldns_get_errorstr_by_id(s),
zonefile_name, line_nr);
exit(EXIT_FAILURE);
} else {
orig_soa = ldns_zone_soa(orig_zone);
if (!orig_soa) {
fprintf(stderr,
"Error reading zonefile: missing SOA record\n");
exit(EXIT_FAILURE);
}
orig_rrs = ldns_zone_rrs(orig_zone);
if (!orig_rrs) {
fprintf(stderr,
"Error reading zonefile: no resource records\n");
exit(EXIT_FAILURE);
}
}
fclose(zonefile);
}
}
/* read the ZSKs */
argi = 1;
while (argi < argc) {
keyfile_name_base = argv[argi];
keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
snprintf(keyfile_name,
strlen(keyfile_name_base) + 9,
"%s.private",
keyfile_name_base);
keyfile = fopen(keyfile_name, "r");
line_nr = 0;
if (!keyfile) {
fprintf(stderr,
"Error: unable to read %s: %s\n",
keyfile_name,
strerror(errno));
} else {
s = ldns_key_new_frm_fp_l(&key, keyfile, &line_nr);
fclose(keyfile);
if (s == LDNS_STATUS_OK) {
/* set times in key? they will end up
in the rrsigs
*/
if (expiration != 0) {
ldns_key_set_expiration(key, expiration);
}
if (inception != 0) {
ldns_key_set_inception(key, inception);
}
LDNS_FREE(keyfile_name);
ldns_key_list_push_key(keys, key);
} else {
fprintf(stderr, "Error reading key from %s at line %d: %s\n", argv[argi], line_nr, ldns_get_errorstr_by_id(s));
}
}
/* and, if not unset by -p, find or create the corresponding DNSKEY record */
if (key) {
find_or_create_pubkey(keyfile_name_base, key,
orig_zone, add_keys, ttl);
}
argi++;
}
#ifndef OPENSSL_NO_ENGINE
/*
* The user may have loaded a KSK and a ZSK from the engine.
* Since these keys carry no meta-information which is
* relevant to DNS (origin, TTL, etc), and because that
* information becomes known only after the command line
* and the zone file are parsed completely, the program
* needs to post-process these keys before they become usable.
*/
/* The engine's KSK. */
post_process_engine_key ( keys,
eng_ksk,
orig_zone,
add_keys,
ttl,
inception,
expiration );
/* The engine's ZSK. */
post_process_engine_key ( keys,
eng_zsk,
orig_zone,
add_keys,
ttl,
inception,
expiration );
#endif
if (ldns_key_list_key_count(keys) < 1
&& !(signflags & LDNS_SIGN_NO_KEYS_NO_NSECS)) {
fprintf(stderr, "Error: no keys to sign with. Aborting.\n\n");
usage(stderr, prog);
exit(EXIT_FAILURE);
}
signed_zone = ldns_dnssec_zone_new();
if (unixtime_serial) {
ldns_rr_soa_increment_func_int(ldns_zone_soa(orig_zone),
ldns_soa_serial_unixtime, 0);
}
if (ldns_dnssec_zone_add_rr(signed_zone, ldns_zone_soa(orig_zone)) !=
LDNS_STATUS_OK) {
fprintf(stderr,
"Error adding SOA to dnssec zone, skipping record\n");
}
for (i = 0;
i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone));
i++) {
if (ldns_dnssec_zone_add_rr(signed_zone,
ldns_rr_list_rr(ldns_zone_rrs(orig_zone),
i)) !=
LDNS_STATUS_OK) {
fprintf(stderr,
"Error adding RR to dnssec zone");
fprintf(stderr, ", skipping record:\n");
ldns_rr_print(stderr,
ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i));
}
}
/* list to store newly created rrs, so we can free them later */
added_rrs = ldns_rr_list_new();
if (use_nsec3) {
if (verbosity < 1)
; /* pass */
else if (nsec3_iterations > 500)
fprintf(stderr, "Warning! NSEC3 iterations larger than "
"500 may cause validating resolvers to return "
"SERVFAIL!\n"
"See: https://datatracker.ietf.org/doc/html/"
"draft-hardaker-dnsop-nsec3-guidance-03#section-4\n");
else if (nsec3_iterations > 100)
fprintf(stderr, "Warning! NSEC3 iterations larger than "
"100 may cause validating resolvers to return "
"insecure responses!\n"
"See: https://datatracker.ietf.org/doc/html/"
"draft-hardaker-dnsop-nsec3-guidance-03#section-4\n");
result = ldns_dnssec_zone_sign_nsec3_flg_mkmap(signed_zone,
added_rrs,
keys,
ldns_dnssec_default_replace_signatures,
NULL,
nsec3_algorithm,
nsec3_flags,
nsec3_iterations,
nsec3_salt_length,
nsec3_salt,
signflags,
&fmt_st.hashmap);
} else {
result = ldns_dnssec_zone_sign_flg(signed_zone,
added_rrs,
keys,
ldns_dnssec_default_replace_signatures,
NULL,
signflags);
}
if (result != LDNS_STATUS_OK) {
fprintf(stderr, "Error signing zone: %s\n",
ldns_get_errorstr_by_id(result));
}
if (!outputfile_name) {
outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
}
if (signed_zone) {
if (strncmp(outputfile_name, "-", 2) == 0) {
ldns_dnssec_zone_print(stdout, signed_zone);
} else {
outputfile = fopen(outputfile_name, "w");
if (!outputfile) {
fprintf(stderr, "Unable to open %s for writing: %s\n",
outputfile_name, strerror(errno));
} else {
ldns_dnssec_zone_print_fmt(
outputfile, fmt, signed_zone);
fclose(outputfile);
}
}
} else {
fprintf(stderr, "Error signing zone.\n");
#ifdef HAVE_SSL
if (ERR_peek_error()) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
ERR_load_crypto_strings();
#endif
#endif
ERR_print_errors_fp(stderr);
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
#ifdef HAVE_ERR_FREE_STRINGS
ERR_free_strings ();
#endif
#endif
}
#endif
exit(EXIT_FAILURE);
}
ldns_key_list_free(keys);
/* since the ldns_rr records are pointed to in both the ldns_zone
* and the ldns_dnssec_zone, we can either deep_free the
* dnssec_zone and 'shallow' free the original zone and added
* records, or the other way around
*/
ldns_dnssec_zone_free(signed_zone);
ldns_zone_deep_free(orig_zone);
ldns_rr_list_deep_free(added_rrs);
ldns_rdf_deep_free(origin);
LDNS_FREE(outputfile_name);
#ifndef OPENSSL_NO_ENGINE
shutdown_openssl ( engine );
#else
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
CRYPTO_cleanup_all_ex_data ();
#endif
#endif
#endif
free(prog);
exit(EXIT_SUCCESS);
}
#else /* !HAVE_SSL */
int
main(int argc __attribute__((unused)),
char **argv __attribute__((unused)))
{
fprintf(stderr, "ldns-signzone needs OpenSSL support, which has not been compiled in\n");
return 1;
}
#endif /* HAVE_SSL */
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition common.h:72
ldns_dname_compare
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
Definition dname.c:359
LDNS_NSEC3_MAX_ITERATIONS
#define LDNS_NSEC3_MAX_ITERATIONS
Definition dnssec.h:87
ldns_calc_keytag
uint16_t ldns_calc_keytag(const ldns_rr *key)
calculates a keytag of a key for use in DNSSEC.
Definition dnssec.c:277
ldns_dnssec_default_replace_signatures
int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n)
Default callback function to always leave present signatures, and add new ones.
LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384
Definition dnssec_sign.h:18
LDNS_SIGN_DNSKEY_WITH_ZSK
#define LDNS_SIGN_DNSKEY_WITH_ZSK
dnssec_verify
Definition dnssec_sign.h:15
LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512
Definition dnssec_sign.h:19
LDNS_SIGN_WITH_ALL_ALGORITHMS
#define LDNS_SIGN_WITH_ALL_ALGORITHMS
Definition dnssec_sign.h:16
ldns_dnssec_zone_sign_nsec3_flg_mkmap
ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, int signflags, ldns_rbtree_t **map)
signs the given zone with the given new zone, with NSEC3
Definition dnssec_sign.c:1463
LDNS_SIGN_NO_KEYS_NO_NSECS
#define LDNS_SIGN_NO_KEYS_NO_NSECS
Definition dnssec_sign.h:17
ldns_dnssec_zone_sign_flg
ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, int flags)
signs the given zone with the given keys
Definition dnssec_sign.c:1376
ldns_dnssec_zone_print_fmt
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition dnssec_zone.c:1081
ldns_dnssec_zone_new
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition dnssec_zone.c:570
ldns_dnssec_zone_print
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition dnssec_zone.c:1109
ldns_dnssec_zone_add_rr
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
Definition dnssec_zone.c:1002
ldns_dnssec_zone_free
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition dnssec_zone.c:865
ldns_dnssec_zone
struct ldns_struct_dnssec_zone ldns_dnssec_zone
Definition dnssec_zone.h:104
LDNS_STATUS_NULL
@ LDNS_STATUS_NULL
Definition error.h:51
LDNS_STATUS_ERR
@ LDNS_STATUS_ERR
Definition error.h:37
LDNS_STATUS_OK
@ LDNS_STATUS_OK
Definition error.h:26
ldns_status
enum ldns_enum_status ldns_status
Definition error.h:148
ldns_get_errorstr_by_id
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition error.c:196
LDNS_COMMENT_BUBBLEBABBLE
#define LDNS_COMMENT_BUBBLEBABBLE
Provide bubblebabble representation for DS RR's as comment.
Definition host2str.h:56
ldns_rr_print
void ldns_rr_print(FILE *output, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format).
Definition host2str.c:3419
LDNS_COMMENT_FLAGS
#define LDNS_COMMENT_FLAGS
Show when a NSEC3 RR has the optout flag set as comment.
Definition host2str.h:58
ldns_output_format_storage
struct ldns_struct_output_format_storage ldns_output_format_storage
Definition host2str.h:107
ldns_rdf2str
char * ldns_rdf2str(const ldns_rdf *rdf)
Converts the data in the rdata field to presentation format and returns that as a char *.
Definition host2str.c:3276
LDNS_COMMENT_NSEC3_CHAIN
#define LDNS_COMMENT_NSEC3_CHAIN
Show the unhashed owner and next owner names for NSEC3 RR's as comment.
Definition host2str.h:60
ldns_output_format
struct ldns_struct_output_format ldns_output_format
Definition host2str.h:95
LDNS_COMMENT_LAYOUT
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition host2str.h:62
keys.h
Addendum to dnssec.h, this module contains key and algorithm definitions and functions.
ldns_key_list_free
void ldns_key_list_free(ldns_key_list *key_list)
Frees a key list structure.
Definition keys.c:2073
ldns_key_new_frm_engine
ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm a)
Read the key with the given id from the given engine and store it in the given ldns_key structure.
Definition keys.c:116
ldns_key_new_frm_fp_l
ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr)
Creates a new private key based on the contents of the file pointed by fp.
Definition keys.c:417
ldns_key_set_expiration
void ldns_key_set_expiration(ldns_key *k, uint32_t e)
Set the key's expiration date (seconds after epoch).
Definition keys.c:1428
LDNS_KEY_SEP_KEY
#define LDNS_KEY_SEP_KEY
Definition keys.h:38
ldns_key_list_new
ldns_key_list * ldns_key_list_new(void)
Creates a new empty key list.
Definition keys.c:70
ldns_key_set_pubkey_owner
void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
Set the key's pubkey owner.
Definition keys.c:1434
ldns_key_list_push_key
signed char ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
pushes a key to a keylist
Definition keys.c:1600
ldns_key
struct ldns_struct_key ldns_key
Definition keys.h:167
ldns_key_keytag
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
Definition keys.c:1571
ldns_key_list
struct ldns_struct_key_list ldns_key_list
Definition keys.h:177
ldns_key_set_keytag
void ldns_key_set_keytag(ldns_key *k, uint16_t tag)
Set the key's key tag.
Definition keys.c:1440
ldns_key2rr
ldns_rr * ldns_key2rr(const ldns_key *k)
converts a ldns_key to a public key rr If the key data exists at an external point,...
Definition keys.c:1803
ldns_key_set_flags
void ldns_key_set_flags(ldns_key *k, uint16_t flags)
Set the key's flags.
Definition keys.c:1342
ldns_enum_signing_algorithm
ldns_enum_signing_algorithm
Algorithms used in dns for signing.
Definition keys.h:82
LDNS_SIGN_RSASHA1
@ LDNS_SIGN_RSASHA1
Definition keys.h:84
LDNS_SIGN_ECDSAP256SHA256
@ LDNS_SIGN_ECDSAP256SHA256
Definition keys.h:95
LDNS_SIGN_DSA_NSEC3
@ LDNS_SIGN_DSA_NSEC3
Definition keys.h:92
LDNS_SIGN_ECC_GOST
@ LDNS_SIGN_ECC_GOST
Definition keys.h:94
LDNS_SIGN_RSASHA1_NSEC3
@ LDNS_SIGN_RSASHA1_NSEC3
Definition keys.h:88
LDNS_SIGN_ECDSAP384SHA384
@ LDNS_SIGN_ECDSAP384SHA384
Definition keys.h:96
LDNS_SIGN_RSAMD5
@ LDNS_SIGN_RSAMD5
Definition keys.h:83
LDNS_SIGN_RSASHA512
@ LDNS_SIGN_RSASHA512
Definition keys.h:90
LDNS_SIGN_DSA
@ LDNS_SIGN_DSA
Definition keys.h:86
LDNS_SIGN_RSASHA256
@ LDNS_SIGN_RSASHA256
Definition keys.h:89
ldns_key_pubkey_owner
ldns_rdf * ldns_key_pubkey_owner(const ldns_key *k)
return the public key's owner
Definition keys.c:1577
ldns_key_flags
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
Definition keys.c:1553
ldns_key_list_key_count
size_t ldns_key_list_key_count(const ldns_key_list *key_list)
returns the number of keys in the key list
Definition keys.c:1447
ldns_key_set_inception
void ldns_key_set_inception(ldns_key *k, uint32_t i)
Set the key's inception date (seconds after epoch).
Definition keys.c:1422
ldns_algorithm
enum ldns_enum_algorithm ldns_algorithm
Definition keys.h:64
verbosity
int verbosity
Definition ldns-signzone.c:37
str2zonemd_signflag
int str2zonemd_signflag(const char *str, const char **reason)
Definition ldns-signzone.c:571
__LIST
#define __LIST(x)
__MATCH
#define __MATCH(x)
prog
char * prog
Definition ldns-signzone.c:36
MAX_FILENAME_LEN
#define MAX_FILENAME_LEN
Definition ldns-signzone.c:34
ldns.h
Including this file will include all ldns files, and define some lookup tables.
LDNS_DEFAULT_TTL
#define LDNS_DEFAULT_TTL
Definition ldns.h:136
main
int main(void)
Definition linktest.c:6
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition rdata.c:222
ldns_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition rdata.c:230
ldns_rdf2native_int16
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition rdata.c:84
ldns_rdf
struct ldns_struct_rdf ldns_rdf
Definition rdata.h:205
LDNS_NSEC3_VARS_OPTOUT_MASK
#define LDNS_NSEC3_VARS_OPTOUT_MASK
Definition rdata.h:40
ldns_rr_ttl
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition rr.c:935
ldns_rr_list_deep_free
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition rr.c:1024
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition rr.c:81
ldns_rr
struct ldns_struct_rr ldns_rr
Definition rr.h:337
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition rr.c:1004
LDNS_RR_TYPE_DNSKEY
@ LDNS_RR_TYPE_DNSKEY
Definition rr.h:172
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition rr.c:913
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition rr.c:961
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition rr.c:947
ldns_rr_set_ttl
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition rr.c:820
ldns_rr_compare_no_rdata
int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs, up to the rdata.
Definition rr.c:1563
ldns_rr_list
struct ldns_struct_rr_list ldns_rr_list
Definition rr.h:351
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition rr.h:61
ldns_rr_list_rr
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition rr.c:994
ldns_rr_new_frm_fp_l
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
creates a new rr from a file containing a string.
Definition rr.c:800
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition rr.c:923
LDNS_RR_CLASS_IN
@ LDNS_RR_CLASS_IN
the Internet
Definition rr.h:47
ldns_soa_serial_unixtime
uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
Function to be used with ldns_rr_soa_increment_func or ldns_rr_soa_increment_func_int to set the soa ...
Definition rr_functions.c:383
ldns_rr_soa_increment_func_int
void ldns_rr_soa_increment_func_int(ldns_rr *soa, ldns_soa_serial_increment_func_t f, int data)
Increment the serial number of the given SOA with the given function using data as an argument for th...
Definition rr_functions.c:426
ldns_str2rdf_dname
ldns_status ldns_str2rdf_dname(ldns_rdf **rd, const char *str)
convert a dname string into wireformat
Definition str2host.c:311
ldns_struct_key::dnssec
struct ldns_struct_key::@255146050066044151006044066003104264243153374162::@304227235342031273100354051336321016123171221006 dnssec
Some values that influence generated signatures.
ldns_struct_key::flags
uint16_t flags
The dnssec key flags as specified in RFC4035, like ZSK and KSK.
Definition keys.h:161
ldns_struct_output_format_storage::hashmap
ldns_rbtree_t * hashmap
Definition host2str.h:104
ldns_hexdigit_to_int
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
Definition util.c:88
ldns_mktime_from_utc
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
Definition util.c:194
LDNS_FREE
#define LDNS_FREE(ptr)
Definition util.h:60
ldns_version
const char * ldns_version(void)
Show the internal library version.
Definition util.c:160
LDNS_VERSION
#define LDNS_VERSION
Definition util.h:30
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition util.h:51
ldns_zone_soa
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition zone.c:17
ldns_zone_push_rr
signed char ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
push an single rr to a zone structure.
Definition zone.c:53
ldns_zone_rrs
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition zone.c:35
ldns_zone_deep_free
void ldns_zone_deep_free(ldns_zone *zone)
Frees the allocated memory for the zone, the soa rr in it, and the rr_list structure in it,...
Definition zone.c:376
ldns_zone_new_frm_fp_l
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr)
Create a new zone from a file, keep track of the line numbering.
ldns_zone
struct ldns_struct_zone ldns_zone
Definition zone.h:50