1 1.13 christos /* $NetBSD: dnssec-dsfromkey.c,v 1.14 2026/01/29 18:36:26 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.10 christos * SPDX-License-Identifier: MPL-2.0 7 1.10 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.9 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos /*! \file */ 17 1.1 christos 18 1.3 christos #include <inttypes.h> 19 1.3 christos #include <stdbool.h> 20 1.1 christos #include <stdlib.h> 21 1.1 christos 22 1.11 christos #include <isc/attributes.h> 23 1.1 christos #include <isc/buffer.h> 24 1.1 christos #include <isc/commandline.h> 25 1.11 christos #include <isc/dir.h> 26 1.1 christos #include <isc/hash.h> 27 1.1 christos #include <isc/mem.h> 28 1.11 christos #include <isc/result.h> 29 1.1 christos #include <isc/string.h> 30 1.14 christos #include <isc/urcu.h> 31 1.1 christos #include <isc/util.h> 32 1.1 christos 33 1.1 christos #include <dns/callbacks.h> 34 1.1 christos #include <dns/db.h> 35 1.1 christos #include <dns/dbiterator.h> 36 1.1 christos #include <dns/ds.h> 37 1.1 christos #include <dns/fixedname.h> 38 1.1 christos #include <dns/keyvalues.h> 39 1.1 christos #include <dns/log.h> 40 1.1 christos #include <dns/master.h> 41 1.1 christos #include <dns/name.h> 42 1.1 christos #include <dns/rdata.h> 43 1.1 christos #include <dns/rdataclass.h> 44 1.1 christos #include <dns/rdataset.h> 45 1.1 christos #include <dns/rdatasetiter.h> 46 1.1 christos #include <dns/rdatatype.h> 47 1.1 christos 48 1.1 christos #include <dst/dst.h> 49 1.1 christos 50 1.1 christos #include "dnssectool.h" 51 1.1 christos 52 1.1 christos const char *program = "dnssec-dsfromkey"; 53 1.1 christos 54 1.1 christos static dns_rdataclass_t rdclass; 55 1.8 christos static dns_fixedname_t fixed; 56 1.8 christos static dns_name_t *name = NULL; 57 1.8 christos static isc_mem_t *mctx = NULL; 58 1.8 christos static uint32_t ttl; 59 1.8 christos static bool emitttl = false; 60 1.13 christos static unsigned int split_width = 0; 61 1.1 christos 62 1.1 christos static isc_result_t 63 1.1 christos initname(char *setname) { 64 1.1 christos isc_result_t result; 65 1.1 christos isc_buffer_t buf; 66 1.1 christos 67 1.1 christos name = dns_fixedname_initname(&fixed); 68 1.1 christos 69 1.1 christos isc_buffer_init(&buf, setname, strlen(setname)); 70 1.1 christos isc_buffer_add(&buf, strlen(setname)); 71 1.1 christos result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL); 72 1.13 christos return result; 73 1.1 christos } 74 1.1 christos 75 1.1 christos static void 76 1.1 christos db_load_from_stream(dns_db_t *db, FILE *fp) { 77 1.1 christos isc_result_t result; 78 1.1 christos dns_rdatacallbacks_t callbacks; 79 1.1 christos 80 1.1 christos dns_rdatacallbacks_init(&callbacks); 81 1.1 christos result = dns_db_beginload(db, &callbacks); 82 1.8 christos if (result != ISC_R_SUCCESS) { 83 1.1 christos fatal("dns_db_beginload failed: %s", isc_result_totext(result)); 84 1.8 christos } 85 1.1 christos 86 1.8 christos result = dns_master_loadstream(fp, name, name, rdclass, 0, &callbacks, 87 1.8 christos mctx); 88 1.8 christos if (result != ISC_R_SUCCESS) { 89 1.1 christos fatal("can't load from input: %s", isc_result_totext(result)); 90 1.8 christos } 91 1.1 christos 92 1.1 christos result = dns_db_endload(db, &callbacks); 93 1.8 christos if (result != ISC_R_SUCCESS) { 94 1.1 christos fatal("dns_db_endload failed: %s", isc_result_totext(result)); 95 1.8 christos } 96 1.1 christos } 97 1.1 christos 98 1.1 christos static isc_result_t 99 1.1 christos loadset(const char *filename, dns_rdataset_t *rdataset) { 100 1.8 christos isc_result_t result; 101 1.8 christos dns_db_t *db = NULL; 102 1.8 christos dns_dbnode_t *node = NULL; 103 1.1 christos char setname[DNS_NAME_FORMATSIZE]; 104 1.1 christos 105 1.1 christos dns_name_format(name, setname, sizeof(setname)); 106 1.1 christos 107 1.13 christos result = dns_db_create(mctx, ZONEDB_DEFAULT, name, dns_dbtype_zone, 108 1.13 christos rdclass, 0, NULL, &db); 109 1.8 christos if (result != ISC_R_SUCCESS) { 110 1.1 christos fatal("can't create database"); 111 1.8 christos } 112 1.1 christos 113 1.1 christos if (strcmp(filename, "-") == 0) { 114 1.1 christos db_load_from_stream(db, stdin); 115 1.1 christos filename = "input"; 116 1.1 christos } else { 117 1.3 christos result = dns_db_load(db, filename, dns_masterformat_text, 0); 118 1.8 christos if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 119 1.1 christos fatal("can't load %s: %s", filename, 120 1.1 christos isc_result_totext(result)); 121 1.8 christos } 122 1.1 christos } 123 1.1 christos 124 1.3 christos result = dns_db_findnode(db, name, false, &node); 125 1.8 christos if (result != ISC_R_SUCCESS) { 126 1.1 christos fatal("can't find %s node in %s", setname, filename); 127 1.8 christos } 128 1.1 christos 129 1.8 christos result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, 130 1.8 christos rdataset, NULL); 131 1.1 christos 132 1.8 christos if (result == ISC_R_NOTFOUND) { 133 1.1 christos fatal("no DNSKEY RR for %s in %s", setname, filename); 134 1.8 christos } else if (result != ISC_R_SUCCESS) { 135 1.1 christos fatal("dns_db_findrdataset"); 136 1.8 christos } 137 1.1 christos 138 1.8 christos if (node != NULL) { 139 1.1 christos dns_db_detachnode(db, &node); 140 1.8 christos } 141 1.8 christos if (db != NULL) { 142 1.1 christos dns_db_detach(&db); 143 1.8 christos } 144 1.13 christos return result; 145 1.1 christos } 146 1.1 christos 147 1.1 christos static isc_result_t 148 1.1 christos loadkeyset(char *dirname, dns_rdataset_t *rdataset) { 149 1.8 christos isc_result_t result; 150 1.8 christos char filename[PATH_MAX + 1]; 151 1.8 christos isc_buffer_t buf; 152 1.1 christos 153 1.1 christos dns_rdataset_init(rdataset); 154 1.1 christos 155 1.1 christos isc_buffer_init(&buf, filename, sizeof(filename)); 156 1.1 christos if (dirname != NULL) { 157 1.1 christos /* allow room for a trailing slash */ 158 1.8 christos if (strlen(dirname) >= isc_buffer_availablelength(&buf)) { 159 1.13 christos return ISC_R_NOSPACE; 160 1.8 christos } 161 1.1 christos isc_buffer_putstr(&buf, dirname); 162 1.8 christos if (dirname[strlen(dirname) - 1] != '/') { 163 1.1 christos isc_buffer_putstr(&buf, "/"); 164 1.8 christos } 165 1.1 christos } 166 1.1 christos 167 1.8 christos if (isc_buffer_availablelength(&buf) < 7) { 168 1.13 christos return ISC_R_NOSPACE; 169 1.8 christos } 170 1.1 christos isc_buffer_putstr(&buf, "keyset-"); 171 1.1 christos 172 1.3 christos result = dns_name_tofilenametext(name, false, &buf); 173 1.1 christos check_result(result, "dns_name_tofilenametext()"); 174 1.8 christos if (isc_buffer_availablelength(&buf) == 0) { 175 1.13 christos return ISC_R_NOSPACE; 176 1.8 christos } 177 1.1 christos isc_buffer_putuint8(&buf, 0); 178 1.1 christos 179 1.13 christos return loadset(filename, rdataset); 180 1.1 christos } 181 1.1 christos 182 1.1 christos static void 183 1.1 christos loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, 184 1.8 christos dns_rdata_t *rdata) { 185 1.8 christos isc_result_t result; 186 1.8 christos dst_key_t *key = NULL; 187 1.8 christos isc_buffer_t keyb; 188 1.8 christos isc_region_t r; 189 1.1 christos 190 1.1 christos dns_rdata_init(rdata); 191 1.1 christos 192 1.1 christos isc_buffer_init(&keyb, key_buf, key_buf_size); 193 1.1 christos 194 1.8 christos result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, mctx, 195 1.8 christos &key); 196 1.8 christos if (result != ISC_R_SUCCESS) { 197 1.8 christos fatal("can't load %s.key: %s", filename, 198 1.8 christos isc_result_totext(result)); 199 1.8 christos } 200 1.1 christos 201 1.1 christos if (verbose > 2) { 202 1.1 christos char keystr[DST_KEY_FORMATSIZE]; 203 1.1 christos 204 1.1 christos dst_key_format(key, keystr, sizeof(keystr)); 205 1.1 christos fprintf(stderr, "%s: %s\n", program, keystr); 206 1.1 christos } 207 1.1 christos 208 1.1 christos result = dst_key_todns(key, &keyb); 209 1.8 christos if (result != ISC_R_SUCCESS) { 210 1.1 christos fatal("can't decode key"); 211 1.8 christos } 212 1.1 christos 213 1.1 christos isc_buffer_usedregion(&keyb, &r); 214 1.8 christos dns_rdata_fromregion(rdata, dst_key_class(key), dns_rdatatype_dnskey, 215 1.8 christos &r); 216 1.1 christos 217 1.1 christos rdclass = dst_key_class(key); 218 1.1 christos 219 1.1 christos name = dns_fixedname_initname(&fixed); 220 1.11 christos dns_name_copy(dst_key_name(key), name); 221 1.1 christos 222 1.1 christos dst_key_free(&key); 223 1.1 christos } 224 1.1 christos 225 1.1 christos static void 226 1.8 christos logkey(dns_rdata_t *rdata) { 227 1.1 christos isc_result_t result; 228 1.8 christos dst_key_t *key = NULL; 229 1.1 christos isc_buffer_t buf; 230 1.8 christos char keystr[DST_KEY_FORMATSIZE]; 231 1.1 christos 232 1.1 christos isc_buffer_init(&buf, rdata->data, rdata->length); 233 1.1 christos isc_buffer_add(&buf, rdata->length); 234 1.1 christos result = dst_key_fromdns(name, rdclass, &buf, mctx, &key); 235 1.8 christos if (result != ISC_R_SUCCESS) { 236 1.1 christos return; 237 1.8 christos } 238 1.1 christos 239 1.1 christos dst_key_format(key, keystr, sizeof(keystr)); 240 1.1 christos fprintf(stderr, "%s: %s\n", program, keystr); 241 1.1 christos 242 1.1 christos dst_key_free(&key); 243 1.1 christos } 244 1.1 christos 245 1.1 christos static void 246 1.8 christos emit(dns_dsdigest_t dt, bool showall, bool cds, dns_rdata_t *rdata) { 247 1.1 christos isc_result_t result; 248 1.1 christos unsigned char buf[DNS_DS_BUFFERSIZE]; 249 1.1 christos char text_buf[DST_KEY_MAXTEXTSIZE]; 250 1.1 christos char name_buf[DNS_NAME_MAXWIRE]; 251 1.1 christos char class_buf[10]; 252 1.1 christos isc_buffer_t textb, nameb, classb; 253 1.1 christos isc_region_t r; 254 1.1 christos dns_rdata_t ds; 255 1.1 christos dns_rdata_dnskey_t dnskey; 256 1.1 christos 257 1.1 christos isc_buffer_init(&textb, text_buf, sizeof(text_buf)); 258 1.1 christos isc_buffer_init(&nameb, name_buf, sizeof(name_buf)); 259 1.1 christos isc_buffer_init(&classb, class_buf, sizeof(class_buf)); 260 1.1 christos 261 1.1 christos dns_rdata_init(&ds); 262 1.1 christos 263 1.1 christos result = dns_rdata_tostruct(rdata, &dnskey, NULL); 264 1.8 christos if (result != ISC_R_SUCCESS) { 265 1.1 christos fatal("can't convert DNSKEY"); 266 1.8 christos } 267 1.1 christos 268 1.10 christos if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { 269 1.10 christos return; 270 1.10 christos } 271 1.10 christos 272 1.8 christos if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall) { 273 1.1 christos return; 274 1.8 christos } 275 1.1 christos 276 1.8 christos result = dns_ds_buildrdata(name, rdata, dt, buf, &ds); 277 1.8 christos if (result != ISC_R_SUCCESS) { 278 1.1 christos fatal("can't build record"); 279 1.8 christos } 280 1.1 christos 281 1.13 christos result = dns_name_totext(name, 0, &nameb); 282 1.8 christos if (result != ISC_R_SUCCESS) { 283 1.1 christos fatal("can't print name"); 284 1.1 christos } 285 1.1 christos 286 1.13 christos result = dns_rdata_tofmttext(&ds, (dns_name_t *)NULL, 0, 0, split_width, 287 1.13 christos "", &textb); 288 1.1 christos 289 1.8 christos if (result != ISC_R_SUCCESS) { 290 1.1 christos fatal("can't print rdata"); 291 1.8 christos } 292 1.1 christos 293 1.1 christos result = dns_rdataclass_totext(rdclass, &classb); 294 1.8 christos if (result != ISC_R_SUCCESS) { 295 1.1 christos fatal("can't print class"); 296 1.8 christos } 297 1.1 christos 298 1.1 christos isc_buffer_usedregion(&nameb, &r); 299 1.1 christos printf("%.*s ", (int)r.length, r.base); 300 1.1 christos 301 1.8 christos if (emitttl) { 302 1.1 christos printf("%u ", ttl); 303 1.8 christos } 304 1.1 christos 305 1.1 christos isc_buffer_usedregion(&classb, &r); 306 1.1 christos printf("%.*s", (int)r.length, r.base); 307 1.1 christos 308 1.8 christos if (cds) { 309 1.8 christos printf(" CDS "); 310 1.8 christos } else { 311 1.8 christos printf(" DS "); 312 1.8 christos } 313 1.1 christos 314 1.1 christos isc_buffer_usedregion(&textb, &r); 315 1.1 christos printf("%.*s\n", (int)r.length, r.base); 316 1.1 christos } 317 1.1 christos 318 1.8 christos static void 319 1.8 christos emits(bool showall, bool cds, dns_rdata_t *rdata) { 320 1.13 christos unsigned int i, n; 321 1.8 christos 322 1.8 christos n = sizeof(dtype) / sizeof(dtype[0]); 323 1.8 christos for (i = 0; i < n; i++) { 324 1.14 christos if (dtype[i] == DNS_DSDIGEST_SHA1) { 325 1.14 christos fprintf(stderr, 326 1.14 christos "WARNING: DS digest type %u is deprecated\n", 327 1.14 christos i); 328 1.14 christos } 329 1.8 christos if (dtype[i] != 0) { 330 1.8 christos emit(dtype[i], showall, cds, rdata); 331 1.8 christos } 332 1.8 christos } 333 1.8 christos } 334 1.8 christos 335 1.11 christos noreturn static void 336 1.14 christos usage(int ret); 337 1.1 christos 338 1.1 christos static void 339 1.14 christos usage(int ret) { 340 1.1 christos fprintf(stderr, "Usage:\n"); 341 1.8 christos fprintf(stderr, " %s [options] keyfile\n\n", program); 342 1.4 christos fprintf(stderr, " %s [options] -f zonefile [zonename]\n\n", program); 343 1.4 christos fprintf(stderr, " %s [options] -s dnsname\n\n", program); 344 1.4 christos fprintf(stderr, " %s [-h|-V]\n\n", program); 345 1.11 christos fprintf(stderr, "Version: %s\n", PACKAGE_VERSION); 346 1.4 christos fprintf(stderr, "Options:\n" 347 1.14 christos " -1: digest algorithm SHA-1 (deprecated)\n" 348 1.8 christos " -2: digest algorithm SHA-256\n" 349 1.14 christos " -a algorithm: digest algorithm (SHA-1 " 350 1.14 christos "(deprecated), SHA-256 or SHA-384)\n" 351 1.8 christos " -A: include all keys in DS set, not just KSKs (-f " 352 1.8 christos "only)\n" 353 1.8 christos " -c class: rdata class for DS set (default IN) (-f " 354 1.8 christos "or -s only)\n" 355 1.8 christos " -C: print CDS records\n" 356 1.8 christos " -f zonefile: read keys from a zone file\n" 357 1.8 christos " -h: print help information\n" 358 1.8 christos " -K directory: where to find key or keyset files\n" 359 1.13 christos " -w split base64 rdata text into chunks\n" 360 1.8 christos " -s: read keys from keyset-<dnsname> file\n" 361 1.8 christos " -T: TTL of output records (omitted by default)\n" 362 1.8 christos " -v level: verbosity\n" 363 1.8 christos " -V: print version information\n"); 364 1.8 christos fprintf(stderr, "Output: DS or CDS RRs\n"); 365 1.1 christos 366 1.14 christos exit(ret); 367 1.1 christos } 368 1.1 christos 369 1.1 christos int 370 1.1 christos main(int argc, char **argv) { 371 1.8 christos char *classname = NULL; 372 1.8 christos char *filename = NULL, *dir = NULL, *namestr; 373 1.8 christos char *endp, *arg1; 374 1.8 christos int ch; 375 1.8 christos bool cds = false; 376 1.8 christos bool usekeyset = false; 377 1.8 christos bool showall = false; 378 1.8 christos isc_result_t result; 379 1.8 christos isc_log_t *log = NULL; 380 1.8 christos dns_rdataset_t rdataset; 381 1.8 christos dns_rdata_t rdata; 382 1.1 christos 383 1.1 christos dns_rdata_init(&rdata); 384 1.1 christos 385 1.6 christos if (argc == 1) { 386 1.14 christos usage(EXIT_FAILURE); 387 1.6 christos } 388 1.1 christos 389 1.8 christos isc_mem_create(&mctx); 390 1.1 christos 391 1.3 christos isc_commandline_errprint = false; 392 1.1 christos 393 1.13 christos #define OPTIONS "12Aa:Cc:d:Ff:K:l:sT:v:whV" 394 1.1 christos while ((ch = isc_commandline_parse(argc, argv, OPTIONS)) != -1) { 395 1.1 christos switch (ch) { 396 1.1 christos case '1': 397 1.8 christos add_dtype(DNS_DSDIGEST_SHA1); 398 1.1 christos break; 399 1.1 christos case '2': 400 1.8 christos add_dtype(DNS_DSDIGEST_SHA256); 401 1.1 christos break; 402 1.1 christos case 'A': 403 1.3 christos showall = true; 404 1.1 christos break; 405 1.1 christos case 'a': 406 1.8 christos add_dtype(strtodsdigest(isc_commandline_argument)); 407 1.1 christos break; 408 1.1 christos case 'C': 409 1.3 christos cds = true; 410 1.1 christos break; 411 1.1 christos case 'c': 412 1.1 christos classname = isc_commandline_argument; 413 1.1 christos break; 414 1.1 christos case 'd': 415 1.8 christos fprintf(stderr, 416 1.8 christos "%s: the -d option is deprecated; " 417 1.8 christos "use -K\n", 418 1.8 christos program); 419 1.8 christos /* fall through */ 420 1.1 christos case 'K': 421 1.1 christos dir = isc_commandline_argument; 422 1.6 christos if (strlen(dir) == 0U) { 423 1.1 christos fatal("directory must be non-empty string"); 424 1.6 christos } 425 1.1 christos break; 426 1.1 christos case 'f': 427 1.1 christos filename = isc_commandline_argument; 428 1.1 christos break; 429 1.1 christos case 'l': 430 1.8 christos fatal("-l option (DLV lookaside) is obsolete"); 431 1.1 christos break; 432 1.1 christos case 's': 433 1.3 christos usekeyset = true; 434 1.1 christos break; 435 1.1 christos case 'T': 436 1.3 christos emitttl = true; 437 1.1 christos ttl = strtottl(isc_commandline_argument); 438 1.1 christos break; 439 1.1 christos case 'v': 440 1.1 christos verbose = strtol(isc_commandline_argument, &endp, 0); 441 1.6 christos if (*endp != '\0') { 442 1.1 christos fatal("-v must be followed by a number"); 443 1.6 christos } 444 1.1 christos break; 445 1.13 christos case 'w': 446 1.13 christos split_width = UINT_MAX; 447 1.13 christos break; 448 1.1 christos case 'F': 449 1.10 christos /* Reserved for FIPS mode */ 450 1.10 christos FALLTHROUGH; 451 1.1 christos case '?': 452 1.6 christos if (isc_commandline_option != '?') { 453 1.1 christos fprintf(stderr, "%s: invalid argument -%c\n", 454 1.1 christos program, isc_commandline_option); 455 1.6 christos } 456 1.14 christos /* Does not return. */ 457 1.14 christos usage(EXIT_FAILURE); 458 1.14 christos 459 1.1 christos case 'h': 460 1.1 christos /* Does not return. */ 461 1.14 christos usage(EXIT_SUCCESS); 462 1.1 christos 463 1.1 christos case 'V': 464 1.1 christos /* Does not return. */ 465 1.1 christos version(program); 466 1.1 christos 467 1.1 christos default: 468 1.8 christos fprintf(stderr, "%s: unhandled option -%c\n", program, 469 1.8 christos isc_commandline_option); 470 1.12 christos exit(EXIT_FAILURE); 471 1.1 christos } 472 1.1 christos } 473 1.1 christos 474 1.1 christos rdclass = strtoclass(classname); 475 1.1 christos 476 1.6 christos if (usekeyset && filename != NULL) { 477 1.1 christos fatal("cannot use both -s and -f"); 478 1.6 christos } 479 1.1 christos 480 1.1 christos /* When not using -f, -A is implicit */ 481 1.6 christos if (filename == NULL) { 482 1.3 christos showall = true; 483 1.6 christos } 484 1.1 christos 485 1.8 christos /* Default digest type if none specified. */ 486 1.8 christos if (dtype[0] == 0) { 487 1.8 christos dtype[0] = DNS_DSDIGEST_SHA256; 488 1.8 christos } 489 1.8 christos 490 1.7 christos /* 491 1.7 christos * Use local variable arg1 so that clang can correctly analyse 492 1.7 christos * reachable paths rather than 'argc < isc_commandline_index + 1'. 493 1.7 christos */ 494 1.7 christos arg1 = argv[isc_commandline_index]; 495 1.7 christos if (arg1 == NULL && filename == NULL) { 496 1.1 christos fatal("the key file name was not specified"); 497 1.6 christos } 498 1.7 christos if (arg1 != NULL && argv[isc_commandline_index + 1] != NULL) { 499 1.1 christos fatal("extraneous arguments"); 500 1.6 christos } 501 1.1 christos 502 1.3 christos result = dst_lib_init(mctx, NULL); 503 1.6 christos if (result != ISC_R_SUCCESS) { 504 1.1 christos fatal("could not initialize dst: %s", 505 1.1 christos isc_result_totext(result)); 506 1.6 christos } 507 1.1 christos 508 1.1 christos setup_logging(mctx, &log); 509 1.1 christos 510 1.1 christos dns_rdataset_init(&rdataset); 511 1.1 christos 512 1.1 christos if (usekeyset || filename != NULL) { 513 1.7 christos if (arg1 == NULL) { 514 1.7 christos /* using file name as the zone name */ 515 1.1 christos namestr = filename; 516 1.6 christos } else { 517 1.7 christos namestr = arg1; 518 1.6 christos } 519 1.1 christos 520 1.1 christos result = initname(namestr); 521 1.6 christos if (result != ISC_R_SUCCESS) { 522 1.1 christos fatal("could not initialize name %s", namestr); 523 1.6 christos } 524 1.1 christos 525 1.6 christos if (usekeyset) { 526 1.1 christos result = loadkeyset(dir, &rdataset); 527 1.6 christos } else { 528 1.6 christos INSIST(filename != NULL); 529 1.1 christos result = loadset(filename, &rdataset); 530 1.6 christos } 531 1.1 christos 532 1.6 christos if (result != ISC_R_SUCCESS) { 533 1.1 christos fatal("could not load DNSKEY set: %s\n", 534 1.1 christos isc_result_totext(result)); 535 1.6 christos } 536 1.1 christos 537 1.1 christos for (result = dns_rdataset_first(&rdataset); 538 1.1 christos result == ISC_R_SUCCESS; 539 1.8 christos result = dns_rdataset_next(&rdataset)) 540 1.8 christos { 541 1.1 christos dns_rdata_init(&rdata); 542 1.1 christos dns_rdataset_current(&rdataset, &rdata); 543 1.1 christos 544 1.6 christos if (verbose > 2) { 545 1.1 christos logkey(&rdata); 546 1.6 christos } 547 1.1 christos 548 1.8 christos emits(showall, cds, &rdata); 549 1.1 christos } 550 1.1 christos } else { 551 1.1 christos unsigned char key_buf[DST_KEY_MAXSIZE]; 552 1.1 christos 553 1.7 christos loadkey(arg1, key_buf, DST_KEY_MAXSIZE, &rdata); 554 1.1 christos 555 1.8 christos emits(showall, cds, &rdata); 556 1.1 christos } 557 1.1 christos 558 1.8 christos if (dns_rdataset_isassociated(&rdataset)) { 559 1.1 christos dns_rdataset_disassociate(&rdataset); 560 1.8 christos } 561 1.1 christos cleanup_logging(&log); 562 1.1 christos dst_lib_destroy(); 563 1.6 christos if (verbose > 10) { 564 1.1 christos isc_mem_stats(mctx, stdout); 565 1.6 christos } 566 1.1 christos isc_mem_destroy(&mctx); 567 1.1 christos 568 1.14 christos rcu_barrier(); 569 1.14 christos 570 1.1 christos fflush(stdout); 571 1.1 christos if (ferror(stdout)) { 572 1.1 christos fprintf(stderr, "write error\n"); 573 1.13 christos return 1; 574 1.6 christos } else { 575 1.13 christos return 0; 576 1.6 christos } 577 1.1 christos } 578