Blame bin/dnssec/dnssec-dsfromkey.c

Packit 5ce601
/*
Packit 5ce601
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
Packit 5ce601
 *
Packit 5ce601
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit 5ce601
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit Service 704ed8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
Packit 5ce601
 *
Packit 5ce601
 * See the COPYRIGHT file distributed with this work for additional
Packit 5ce601
 * information regarding copyright ownership.
Packit 5ce601
 */
Packit 5ce601
Packit 5ce601
/*! \file */
Packit 5ce601
Packit 5ce601
#include <config.h>
Packit 5ce601
Packit 5ce601
#include <inttypes.h>
Packit 5ce601
#include <stdbool.h>
Packit 5ce601
#include <stdlib.h>
Packit 5ce601
Packit 5ce601
#include <isc/buffer.h>
Packit 5ce601
#include <isc/commandline.h>
Packit 5ce601
#include <isc/entropy.h>
Packit 5ce601
#include <isc/hash.h>
Packit 5ce601
#include <isc/mem.h>
Packit 5ce601
#include <isc/platform.h>
Packit 5ce601
#include <isc/print.h>
Packit 5ce601
#include <isc/string.h>
Packit 5ce601
#include <isc/util.h>
Packit 5ce601
Packit 5ce601
#include <dns/callbacks.h>
Packit 5ce601
#include <dns/db.h>
Packit 5ce601
#include <dns/dbiterator.h>
Packit 5ce601
#include <dns/ds.h>
Packit 5ce601
#include <dns/fixedname.h>
Packit 5ce601
#include <dns/keyvalues.h>
Packit 5ce601
#include <dns/log.h>
Packit 5ce601
#include <dns/master.h>
Packit 5ce601
#include <dns/name.h>
Packit 5ce601
#include <dns/rdata.h>
Packit 5ce601
#include <dns/rdataclass.h>
Packit 5ce601
#include <dns/rdataset.h>
Packit 5ce601
#include <dns/rdatasetiter.h>
Packit 5ce601
#include <dns/rdatatype.h>
Packit 5ce601
#include <dns/result.h>
Packit 5ce601
Packit 5ce601
#include <dst/dst.h>
Packit 5ce601
Packit 5ce601
#ifdef PKCS11CRYPTO
Packit 5ce601
#include <pk11/result.h>
Packit 5ce601
#endif
Packit 5ce601
Packit 5ce601
#include "dnssectool.h"
Packit 5ce601
Packit 5ce601
const char *program = "dnssec-dsfromkey";
Packit 5ce601
int verbose;
Packit 5ce601
Packit 5ce601
static dns_rdataclass_t rdclass;
Packit 5ce601
static dns_fixedname_t	fixed;
Packit 5ce601
static dns_name_t	*name = NULL;
Packit 5ce601
static isc_mem_t	*mctx = NULL;
Packit 5ce601
static uint32_t	ttl;
Packit 5ce601
static bool	emitttl = false;
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
initname(char *setname) {
Packit 5ce601
	isc_result_t result;
Packit 5ce601
	isc_buffer_t buf;
Packit 5ce601
Packit 5ce601
	name = dns_fixedname_initname(&fixed);
Packit 5ce601
Packit 5ce601
	isc_buffer_init(&buf, setname, strlen(setname));
Packit 5ce601
	isc_buffer_add(&buf, strlen(setname));
Packit 5ce601
	result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
Packit 5ce601
	return (result);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
db_load_from_stream(dns_db_t *db, FILE *fp) {
Packit 5ce601
	isc_result_t result;
Packit 5ce601
	dns_rdatacallbacks_t callbacks;
Packit 5ce601
Packit 5ce601
	dns_rdatacallbacks_init(&callbacks);
Packit 5ce601
	result = dns_db_beginload(db, &callbacks);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("dns_db_beginload failed: %s", isc_result_totext(result));
Packit 5ce601
Packit 5ce601
	result = dns_master_loadstream(fp, name, name, rdclass, 0,
Packit 5ce601
				       &callbacks, mctx);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't load from input: %s", isc_result_totext(result));
Packit 5ce601
Packit 5ce601
	result = dns_db_endload(db, &callbacks);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("dns_db_endload failed: %s", isc_result_totext(result));
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
loadset(const char *filename, dns_rdataset_t *rdataset) {
Packit 5ce601
	isc_result_t	 result;
Packit 5ce601
	dns_db_t	 *db = NULL;
Packit 5ce601
	dns_dbnode_t	 *node = NULL;
Packit 5ce601
	char setname[DNS_NAME_FORMATSIZE];
Packit 5ce601
Packit 5ce601
	dns_name_format(name, setname, sizeof(setname));
Packit 5ce601
Packit 5ce601
	result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
Packit 5ce601
			       rdclass, 0, NULL, &db);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't create database");
Packit 5ce601
Packit 5ce601
	if (strcmp(filename, "-") == 0) {
Packit 5ce601
		db_load_from_stream(db, stdin);
Packit 5ce601
		filename = "input";
Packit 5ce601
	} else {
Packit 5ce601
		result = dns_db_load(db, filename);
Packit 5ce601
		if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
Packit 5ce601
			fatal("can't load %s: %s", filename,
Packit 5ce601
			      isc_result_totext(result));
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	result = dns_db_findnode(db, name, false, &node);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't find %s node in %s", setname, filename);
Packit 5ce601
Packit 5ce601
	result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey,
Packit 5ce601
				     0, 0, rdataset, NULL);
Packit 5ce601
Packit 5ce601
	if (result == ISC_R_NOTFOUND)
Packit 5ce601
		fatal("no DNSKEY RR for %s in %s", setname, filename);
Packit 5ce601
	else if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("dns_db_findrdataset");
Packit 5ce601
Packit 5ce601
	if (node != NULL)
Packit 5ce601
		dns_db_detachnode(db, &node);
Packit 5ce601
	if (db != NULL)
Packit 5ce601
		dns_db_detach(&db);
Packit 5ce601
	return (result);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static isc_result_t
Packit 5ce601
loadkeyset(char *dirname, dns_rdataset_t *rdataset) {
Packit 5ce601
	isc_result_t	 result;
Packit 5ce601
	char		 filename[PATH_MAX + 1];
Packit 5ce601
	isc_buffer_t	 buf;
Packit 5ce601
Packit 5ce601
	dns_rdataset_init(rdataset);
Packit 5ce601
Packit 5ce601
	isc_buffer_init(&buf, filename, sizeof(filename));
Packit 5ce601
	if (dirname != NULL) {
Packit 5ce601
		/* allow room for a trailing slash */
Packit 5ce601
		if (strlen(dirname) >= isc_buffer_availablelength(&buf))
Packit 5ce601
			return (ISC_R_NOSPACE);
Packit 5ce601
		isc_buffer_putstr(&buf, dirname);
Packit 5ce601
		if (dirname[strlen(dirname) - 1] != '/')
Packit 5ce601
			isc_buffer_putstr(&buf, "/");
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if (isc_buffer_availablelength(&buf) < 7)
Packit 5ce601
		return (ISC_R_NOSPACE);
Packit 5ce601
	isc_buffer_putstr(&buf, "keyset-");
Packit 5ce601
Packit 5ce601
	result = dns_name_tofilenametext(name, false, &buf;;
Packit 5ce601
	check_result(result, "dns_name_tofilenametext()");
Packit 5ce601
	if (isc_buffer_availablelength(&buf) == 0)
Packit 5ce601
		return (ISC_R_NOSPACE);
Packit 5ce601
	isc_buffer_putuint8(&buf, 0);
Packit 5ce601
Packit 5ce601
	return (loadset(filename, rdataset));
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size,
Packit 5ce601
	dns_rdata_t *rdata)
Packit 5ce601
{
Packit 5ce601
	isc_result_t  result;
Packit 5ce601
	dst_key_t     *key = NULL;
Packit 5ce601
	isc_buffer_t  keyb;
Packit 5ce601
	isc_region_t  r;
Packit 5ce601
Packit 5ce601
	dns_rdata_init(rdata);
Packit 5ce601
Packit 5ce601
	isc_buffer_init(&keyb, key_buf, key_buf_size);
Packit 5ce601
Packit 5ce601
	result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC,
Packit 5ce601
				       mctx, &key);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't load %s.key: %s",
Packit 5ce601
		      filename, isc_result_totext(result));
Packit 5ce601
Packit 5ce601
	if (verbose > 2) {
Packit 5ce601
		char keystr[DST_KEY_FORMATSIZE];
Packit 5ce601
Packit 5ce601
		dst_key_format(key, keystr, sizeof(keystr));
Packit 5ce601
		fprintf(stderr, "%s: %s\n", program, keystr);
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	result = dst_key_todns(key, &keyb);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't decode key");
Packit 5ce601
Packit 5ce601
	isc_buffer_usedregion(&keyb, &r);
Packit 5ce601
	dns_rdata_fromregion(rdata, dst_key_class(key),
Packit 5ce601
			     dns_rdatatype_dnskey, &r);
Packit 5ce601
Packit 5ce601
	rdclass = dst_key_class(key);
Packit 5ce601
Packit 5ce601
	name = dns_fixedname_initname(&fixed);
Packit 5ce601
	result = dns_name_copy(dst_key_name(key), name, NULL);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't copy name");
Packit 5ce601
Packit 5ce601
	dst_key_free(&key);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
logkey(dns_rdata_t *rdata)
Packit 5ce601
{
Packit 5ce601
	isc_result_t result;
Packit 5ce601
	dst_key_t    *key = NULL;
Packit 5ce601
	isc_buffer_t buf;
Packit 5ce601
	char	     keystr[DST_KEY_FORMATSIZE];
Packit 5ce601
Packit 5ce601
	isc_buffer_init(&buf, rdata->data, rdata->length);
Packit 5ce601
	isc_buffer_add(&buf, rdata->length);
Packit 5ce601
	result = dst_key_fromdns(name, rdclass, &buf, mctx, &key);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		return;
Packit 5ce601
Packit 5ce601
	dst_key_format(key, keystr, sizeof(keystr));
Packit 5ce601
	fprintf(stderr, "%s: %s\n", program, keystr);
Packit 5ce601
Packit 5ce601
	dst_key_free(&key);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
emit(dns_dsdigest_t dtype, bool showall, char *lookaside,
Packit 5ce601
     bool cds, dns_rdata_t *rdata)
Packit 5ce601
{
Packit 5ce601
	isc_result_t result;
Packit 5ce601
	unsigned char buf[DNS_DS_BUFFERSIZE];
Packit 5ce601
	char text_buf[DST_KEY_MAXTEXTSIZE];
Packit 5ce601
	char name_buf[DNS_NAME_MAXWIRE];
Packit 5ce601
	char class_buf[10];
Packit 5ce601
	isc_buffer_t textb, nameb, classb;
Packit 5ce601
	isc_region_t r;
Packit 5ce601
	dns_rdata_t ds;
Packit 5ce601
	dns_rdata_dnskey_t dnskey;
Packit 5ce601
Packit 5ce601
	isc_buffer_init(&textb, text_buf, sizeof(text_buf));
Packit 5ce601
	isc_buffer_init(&nameb, name_buf, sizeof(name_buf));
Packit 5ce601
	isc_buffer_init(&classb, class_buf, sizeof(class_buf));
Packit 5ce601
Packit 5ce601
	dns_rdata_init(&ds);
Packit 5ce601
Packit 5ce601
	result = dns_rdata_tostruct(rdata, &dnskey, NULL);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't convert DNSKEY");
Packit 5ce601
Packit 5ce601
	if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall)
Packit 5ce601
		return;
Packit 5ce601
Packit 5ce601
	result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't build record");
Packit 5ce601
Packit 5ce601
	result = dns_name_totext(name, false, &nameb);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't print name");
Packit 5ce601
Packit 5ce601
	/* Add lookaside origin, if set */
Packit 5ce601
	if (lookaside != NULL) {
Packit 5ce601
		if (isc_buffer_availablelength(&nameb) < strlen(lookaside))
Packit 5ce601
			fatal("DLV origin '%s' is too long", lookaside);
Packit 5ce601
		isc_buffer_putstr(&nameb, lookaside);
Packit 5ce601
		if (lookaside[strlen(lookaside) - 1] != '.') {
Packit 5ce601
			if (isc_buffer_availablelength(&nameb) < 1)
Packit 5ce601
				fatal("DLV origin '%s' is too long", lookaside);
Packit 5ce601
			isc_buffer_putstr(&nameb, ".");
Packit 5ce601
		}
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	result = dns_rdata_tofmttext(&ds, (dns_name_t *) NULL, 0, 0, 0, "",
Packit 5ce601
				     &textb);
Packit 5ce601
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't print rdata");
Packit 5ce601
Packit 5ce601
	result = dns_rdataclass_totext(rdclass, &classb);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("can't print class");
Packit 5ce601
Packit 5ce601
	isc_buffer_usedregion(&nameb, &r);
Packit 5ce601
	printf("%.*s ", (int)r.length, r.base);
Packit 5ce601
Packit 5ce601
	if (emitttl)
Packit 5ce601
		printf("%u ", ttl);
Packit 5ce601
Packit 5ce601
	isc_buffer_usedregion(&classb, &r);
Packit 5ce601
	printf("%.*s", (int)r.length, r.base);
Packit 5ce601
Packit 5ce601
	if (lookaside == NULL) {
Packit 5ce601
		if (cds)
Packit 5ce601
			printf(" CDS ");
Packit 5ce601
		else
Packit 5ce601
			printf(" DS ");
Packit 5ce601
	} else
Packit 5ce601
		printf(" DLV ");
Packit 5ce601
Packit 5ce601
	isc_buffer_usedregion(&textb, &r);
Packit 5ce601
	printf("%.*s\n", (int)r.length, r.base);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
ISC_PLATFORM_NORETURN_PRE static void
Packit 5ce601
usage(void) ISC_PLATFORM_NORETURN_POST;
Packit 5ce601
Packit 5ce601
static void
Packit 5ce601
usage(void) {
Packit 5ce601
	fprintf(stderr, "Usage:\n");
Packit 5ce601
	fprintf(stderr,	"    %s [options] keyfile\n\n", program);
Packit 5ce601
	fprintf(stderr, "    %s [options] -f zonefile [zonename]\n\n", program);
Packit 5ce601
	fprintf(stderr, "    %s [options] -s dnsname\n\n", program);
Packit 5ce601
	fprintf(stderr, "    %s [-h|-V]\n\n", program);
Packit 5ce601
	fprintf(stderr, "Version: %s\n", VERSION);
Packit 5ce601
	fprintf(stderr, "Options:\n"
Packit 5ce601
"    -1: digest algorithm SHA-1\n"
Packit 5ce601
"    -2: digest algorithm SHA-256\n"
Packit 5ce601
"    -a algorithm: digest algorithm (SHA-1, SHA-256, SHA-384 or GOST)\n"
Packit 5ce601
"    -A: include all keys in DS set, not just KSKs (-f only)\n"
Packit 5ce601
"    -c class: rdata class for DS set (default IN) (-f or -s only)\n"
Packit 5ce601
"    -C: print CDS records\n"
Packit 5ce601
"    -f zonefile: read keys from a zone file\n"
Packit 5ce601
"    -h: print help information\n"
Packit 5ce601
"    -K directory: where to find key or keyset files\n"
Packit 5ce601
"    -l zone: print DLV records in the given lookaside zone\n"
Packit 5ce601
"    -s: read keys from keyset-<dnsname> file\n"
Packit 5ce601
"    -T: TTL of output records (omitted by default)\n"
Packit 5ce601
"    -v level: verbosity\n"
Packit 5ce601
"    -V: print version information\n");
Packit 5ce601
	fprintf(stderr, "Output: DS, DLV, or CDS RRs\n");
Packit 5ce601
Packit 5ce601
	exit (-1);
Packit 5ce601
}
Packit 5ce601
Packit 5ce601
int
Packit 5ce601
main(int argc, char **argv) {
Packit 5ce601
	char		*algname = NULL, *classname = NULL;
Packit 5ce601
	char		*filename = NULL, *dir = NULL, *namestr;
Packit 5ce601
	char		*lookaside = NULL;
Packit 5ce601
	char		*endp, *arg1;
Packit 5ce601
	int		ch;
Packit 5ce601
	dns_dsdigest_t	dtype = DNS_DSDIGEST_SHA1;
Packit 5ce601
	bool	cds = false;
Packit 5ce601
	bool	both = true;
Packit 5ce601
	bool	usekeyset = false;
Packit 5ce601
	bool	showall = false;
Packit 5ce601
	isc_result_t	result;
Packit 5ce601
	isc_log_t	*log = NULL;
Packit 5ce601
	isc_entropy_t	*ectx = NULL;
Packit 5ce601
	dns_rdataset_t	rdataset;
Packit 5ce601
	dns_rdata_t	rdata;
Packit 5ce601
Packit 5ce601
	dns_rdata_init(&rdata);
Packit 5ce601
Packit 5ce601
	if (argc == 1)
Packit 5ce601
		usage();
Packit 5ce601
Packit 5ce601
	result = isc_mem_create(0, 0, &mctx);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("out of memory");
Packit 5ce601
Packit 5ce601
#ifdef PKCS11CRYPTO
Packit 5ce601
	pk11_result_register();
Packit 5ce601
#endif
Packit 5ce601
	dns_result_register();
Packit 5ce601
Packit 5ce601
	isc_commandline_errprint = false;
Packit 5ce601
Packit 5ce601
#define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:hV"
Packit 5ce601
	while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) {
Packit 5ce601
		switch (ch) {
Packit 5ce601
		case '1':
Packit 5ce601
			dtype = DNS_DSDIGEST_SHA1;
Packit 5ce601
			both = false;
Packit 5ce601
			break;
Packit 5ce601
		case '2':
Packit 5ce601
			dtype = DNS_DSDIGEST_SHA256;
Packit 5ce601
			both = false;
Packit 5ce601
			break;
Packit 5ce601
		case 'A':
Packit 5ce601
			showall = true;
Packit 5ce601
			break;
Packit 5ce601
		case 'a':
Packit 5ce601
			algname = isc_commandline_argument;
Packit 5ce601
			both = false;
Packit 5ce601
			break;
Packit 5ce601
		case 'C':
Packit 5ce601
			if (lookaside != NULL)
Packit 5ce601
				fatal("lookaside and CDS are mutually"
Packit 5ce601
				      " exclusive");
Packit 5ce601
			cds = true;
Packit 5ce601
			break;
Packit 5ce601
		case 'c':
Packit 5ce601
			classname = isc_commandline_argument;
Packit 5ce601
			break;
Packit 5ce601
		case 'd':
Packit 5ce601
			fprintf(stderr, "%s: the -d option is deprecated; "
Packit 5ce601
					"use -K\n", program);
Packit 5ce601
			/* fall through */
Packit 5ce601
		case 'K':
Packit 5ce601
			dir = isc_commandline_argument;
Packit 5ce601
			if (strlen(dir) == 0U)
Packit 5ce601
				fatal("directory must be non-empty string");
Packit 5ce601
			break;
Packit 5ce601
		case 'f':
Packit 5ce601
			filename = isc_commandline_argument;
Packit 5ce601
			break;
Packit 5ce601
		case 'l':
Packit 5ce601
			if (cds)
Packit 5ce601
				fatal("lookaside and CDS are mutually"
Packit 5ce601
				      " exclusive");
Packit 5ce601
			lookaside = isc_commandline_argument;
Packit 5ce601
			if (strlen(lookaside) == 0U)
Packit 5ce601
				fatal("lookaside must be a non-empty string");
Packit 5ce601
			break;
Packit 5ce601
		case 's':
Packit 5ce601
			usekeyset = true;
Packit 5ce601
			break;
Packit 5ce601
		case 'T':
Packit 5ce601
			emitttl = true;
Packit 5ce601
			ttl = atol(isc_commandline_argument);
Packit 5ce601
			break;
Packit 5ce601
		case 'v':
Packit 5ce601
			verbose = strtol(isc_commandline_argument, &endp, 0);
Packit 5ce601
			if (*endp != '\0')
Packit 5ce601
				fatal("-v must be followed by a number");
Packit 5ce601
			break;
Packit 5ce601
		case 'F':
Packit 5ce601
			/* Reserved for FIPS mode */
Packit 5ce601
			/* FALLTHROUGH */
Packit 5ce601
		case '?':
Packit 5ce601
			if (isc_commandline_option != '?')
Packit 5ce601
				fprintf(stderr, "%s: invalid argument -%c\n",
Packit 5ce601
					program, isc_commandline_option);
Packit 5ce601
			/* FALLTHROUGH */
Packit 5ce601
		case 'h':
Packit 5ce601
			/* Does not return. */
Packit 5ce601
			usage();
Packit 5ce601
Packit 5ce601
		case 'V':
Packit 5ce601
			/* Does not return. */
Packit 5ce601
			version(program);
Packit 5ce601
Packit 5ce601
		default:
Packit 5ce601
			fprintf(stderr, "%s: unhandled option -%c\n",
Packit 5ce601
				program, isc_commandline_option);
Packit 5ce601
			exit(1);
Packit 5ce601
		}
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if (algname != NULL) {
Packit 5ce601
		if (strcasecmp(algname, "SHA1") == 0 ||
Packit 5ce601
		    strcasecmp(algname, "SHA-1") == 0)
Packit 5ce601
			dtype = DNS_DSDIGEST_SHA1;
Packit 5ce601
		else if (strcasecmp(algname, "SHA256") == 0 ||
Packit 5ce601
			 strcasecmp(algname, "SHA-256") == 0)
Packit 5ce601
			dtype = DNS_DSDIGEST_SHA256;
Packit 5ce601
#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
Packit 5ce601
		else if (strcasecmp(algname, "GOST") == 0)
Packit 5ce601
			dtype = DNS_DSDIGEST_GOST;
Packit 5ce601
#endif
Packit 5ce601
		else if (strcasecmp(algname, "SHA384") == 0 ||
Packit 5ce601
			 strcasecmp(algname, "SHA-384") == 0)
Packit 5ce601
			dtype = DNS_DSDIGEST_SHA384;
Packit 5ce601
		else
Packit 5ce601
			fatal("unknown algorithm %s", algname);
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	rdclass = strtoclass(classname);
Packit 5ce601
Packit 5ce601
	if (usekeyset && filename != NULL)
Packit 5ce601
		fatal("cannot use both -s and -f");
Packit 5ce601
Packit 5ce601
	/* When not using -f, -A is implicit */
Packit 5ce601
	if (filename == NULL)
Packit 5ce601
		showall = true;
Packit 5ce601
Packit 5ce601
	/*
Packit 5ce601
	 * Use local variable arg1 so that clang can correctly analyse
Packit 5ce601
	 * reachable paths rather than 'argc < isc_commandline_index + 1'.
Packit 5ce601
	 */
Packit 5ce601
	arg1 = argv[isc_commandline_index];
Packit 5ce601
	if (arg1 == NULL && filename == NULL) {
Packit 5ce601
		fatal("the key file name was not specified");
Packit 5ce601
	}
Packit 5ce601
	if (arg1 != NULL && argv[isc_commandline_index + 1] != NULL) {
Packit 5ce601
		fatal("extraneous arguments");
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if (ectx == NULL)
Packit 5ce601
		setup_entropy(mctx, NULL, &ectx);
Packit Service d3afd5
	result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
Packit Service d3afd5
	if (result != ISC_R_SUCCESS)
Packit Service d3afd5
		fatal("could not initialize hash");
Packit 5ce601
	result = dst_lib_init(mctx, ectx,
Packit 5ce601
			      ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
Packit 5ce601
	if (result != ISC_R_SUCCESS)
Packit 5ce601
		fatal("could not initialize dst: %s",
Packit 5ce601
		      isc_result_totext(result));
Packit 5ce601
	isc_entropy_stopcallbacksources(ectx);
Packit 5ce601
Packit 5ce601
	setup_logging(mctx, &log;;
Packit 5ce601
Packit 5ce601
	dns_rdataset_init(&rdataset);
Packit 5ce601
Packit 5ce601
	if (usekeyset || filename != NULL) {
Packit 5ce601
		if (arg1 == NULL) {
Packit 5ce601
			/* using file name as the zone name */
Packit 5ce601
			namestr = filename;
Packit 5ce601
		} else {
Packit 5ce601
			namestr = arg1;
Packit 5ce601
		}
Packit 5ce601
Packit 5ce601
		result = initname(namestr);
Packit 5ce601
		if (result != ISC_R_SUCCESS) {
Packit 5ce601
			fatal("could not initialize name %s", namestr);
Packit 5ce601
		}
Packit 5ce601
Packit 5ce601
		if (usekeyset) {
Packit 5ce601
			result = loadkeyset(dir, &rdataset);
Packit 5ce601
		} else {
Packit 5ce601
			INSIST(filename != NULL);
Packit 5ce601
			result = loadset(filename, &rdataset);
Packit 5ce601
		}
Packit 5ce601
Packit 5ce601
		if (result != ISC_R_SUCCESS) {
Packit 5ce601
			fatal("could not load DNSKEY set: %s\n",
Packit 5ce601
			      isc_result_totext(result));
Packit 5ce601
		}
Packit 5ce601
Packit 5ce601
		for (result = dns_rdataset_first(&rdataset);
Packit 5ce601
		     result == ISC_R_SUCCESS;
Packit 5ce601
		     result = dns_rdataset_next(&rdataset)) {
Packit 5ce601
			dns_rdata_init(&rdata);
Packit 5ce601
			dns_rdataset_current(&rdataset, &rdata);
Packit 5ce601
Packit 5ce601
			if (verbose > 2) {
Packit 5ce601
				logkey(&rdata);
Packit 5ce601
			}
Packit 5ce601
Packit 5ce601
			if (both) {
Packit 5ce601
				emit(DNS_DSDIGEST_SHA1, showall, lookaside,
Packit 5ce601
				     cds, &rdata);
Packit 5ce601
				emit(DNS_DSDIGEST_SHA256, showall, lookaside,
Packit 5ce601
				     cds, &rdata);
Packit 5ce601
			} else {
Packit 5ce601
				emit(dtype, showall, lookaside, cds, &rdata);
Packit 5ce601
			}
Packit 5ce601
		}
Packit 5ce601
	} else {
Packit 5ce601
		unsigned char key_buf[DST_KEY_MAXSIZE];
Packit 5ce601
Packit 5ce601
		loadkey(arg1, key_buf, DST_KEY_MAXSIZE, &rdata);
Packit 5ce601
Packit 5ce601
		if (both) {
Packit 5ce601
			emit(DNS_DSDIGEST_SHA1, showall, lookaside, cds,
Packit 5ce601
			     &rdata);
Packit 5ce601
			emit(DNS_DSDIGEST_SHA256, showall, lookaside, cds,
Packit 5ce601
			     &rdata);
Packit 5ce601
		} else {
Packit 5ce601
			emit(dtype, showall, lookaside, cds, &rdata);
Packit 5ce601
		}
Packit 5ce601
	}
Packit 5ce601
Packit 5ce601
	if (dns_rdataset_isassociated(&rdataset))
Packit 5ce601
		dns_rdataset_disassociate(&rdataset);
Packit 5ce601
	cleanup_logging(&log;;
Packit Service 111ee5
	dst_lib_destroy();
Packit Service d3afd5
	isc_hash_destroy();
Packit 5ce601
	cleanup_entropy(&ectx);
Packit 5ce601
	dns_name_destroy();
Packit 5ce601
	if (verbose > 10)
Packit 5ce601
		isc_mem_stats(mctx, stdout);
Packit 5ce601
	isc_mem_destroy(&mctx);
Packit 5ce601
Packit 5ce601
	fflush(stdout);
Packit 5ce601
	if (ferror(stdout)) {
Packit 5ce601
		fprintf(stderr, "write error\n");
Packit 5ce601
		return (1);
Packit 5ce601
	} else
Packit 5ce601
		return (0);
Packit 5ce601
}