/* * ldnssec-utils * * Written in 2021 by Lucas * * To the extent possible under law, the author(s) have dedicated all * copyright and related and neighboring rights to this software to the * public domain worldwide. This software is distributed without any * warranty. * * You should have received a copy of the CC0 Public Domain Dedication * along with this software. If not, see * . */ #include #include #include #include #include #include "util.h" static void usage(void) { const char *p = getprogname(); fprintf(stderr, "Usage:\n" "\t%s [-b bits] algorithm\n" "\t%s [-a algorithm] [-d domain] [-k] -r ds|dnskey\n", p, p); exit(1); } static int print_record_main(ldns_hash hash, int ksk, const char *domain, int argc, char *argv[]) { ldns_key *key; ldns_rr *dnskey_rr, *ds_rr; ldns_rdf *rdf_dname; ldns_status s; const char *type; char *str; uint16_t flags; int line_nr, do_ds; if (argc != 1) usage(); type = argv[0]; do_ds = strcasecmp(type, "DS") == 0; if (strcasecmp(type, "DNSKEY") != 0 && !do_ds) errx(1, "unsupport RR type %s", type); s = ldns_key_new_frm_fp_l(&key, stdin, &line_nr); if (s != LDNS_STATUS_OK) errx(1, "ldns_key_new_frm_fp_l: (stdin) line %d: %s", line_nr, ldns_get_errorstr_by_id(s)); s = ldns_str2rdf_dname(&rdf_dname, domain); if (s != LDNS_STATUS_OK) errx(1, "ldns_str2rdf_dname: %s", ldns_get_errorstr_by_id(s)); flags = LDNS_KEY_ZONE_KEY; if (ksk) flags |= LDNS_KEY_SEP_KEY; ldns_key_set_pubkey_owner(key, rdf_dname); ldns_key_set_flags(key, flags); dnskey_rr = ldns_key2rr(key); if (dnskey_rr == NULL) errx(1, "ldns_key2rr"); ds_rr = NULL; if (do_ds) { ds_rr = ldns_key_rr2ds(dnskey_rr, hash); if (ds_rr == NULL) errx(1, "ldns_key_rr2ds"); } str = ldns_rr2str(do_ds ? ds_rr : dnskey_rr); if (str == NULL) errx(1, "ldns_rr2str"); fputs(str, stdout); free(str); ldns_rr_free(dnskey_rr); ldns_rr_free(ds_rr); ldns_key_deep_free(key); return 1; } static int keygen_main(uint16_t bits, int argc, char *argv[]) { ldns_key *key; ldns_signing_algorithm alg; char *str; if (argc != 1) usage(); alg = ldns_get_signing_algorithm_by_name(argv[0]); /* * ldns_key_algo_supported can't be used here as it uses * ldns_signing_algorithms lookup table, which includes algorithms for * TSIG. */ if (ldns_lookup_by_id(ldns_algorithms, alg) == NULL) errx(1, "unsupported algorithm %s", argv[0]); key = ldns_key_new_frm_algorithm(alg, bits); if (key == NULL) errx(1, "error generating key of type %s", argv[0]); /* ldns_key_print uses stdout to signal errors */ str = ldns_key2str(key); if (str == NULL) errx(1, "ldns_key2str"); fputs(str, stdout); ldns_key_deep_free(key); return 0; } int main(int argc, char *argv[]) { const ldns_lookup_table *lt; ldns_key *key; ldns_signing_algorithm alg; ldns_hash hash_alg; const char *errstr, *domain; long long n; int ch, rc; int aflag, bflag, dflag, kflag, rflag; uint16_t bits; aflag = bflag = dflag = kflag = rflag = 0; hash_alg = LDNS_SHA256; bits = 0; domain = "."; while ((ch = getopt(argc, argv, "a:b:d:kr")) != -1) { switch (ch) { case 'a': aflag = 1; hash_alg = ldnssec_get_hash_algorithm_by_name(optarg); if (!ldns_lookup_by_id(ldnssec_hashes, hash_alg)) errx(1, "-a: unsupported algorithm: %s", optarg); break; case 'b': bflag = 1; n = strtonum(optarg, 0, UINT16_MAX, &errstr); if (errstr != NULL) errx(1, "-b: bits is %s: %s", errstr, optarg); bits = n; break; case 'd': dflag = 1; domain = optarg; break; case 'k': kflag = 1; break; case 'r': rflag = 1; break; default: usage(); } } argc -= optind; argv += optind; if (bflag && (aflag || dflag || rflag || kflag)) errx(1, "-b is mutually exclusive with -d, -k and -r"); if (aflag && !rflag) errx(1, "can't use -a without -r"); if (dflag && !rflag) errx(1, "can't use -d without -r"); if (kflag && !rflag) errx(1, "can't use -k without -r"); rc = 1; if (rflag) rc = print_record_main(hash_alg, kflag, domain, argc, argv); else rc = keygen_main(bits, argc, argv); return rc; }