ldnssec-keygen: rewrite and refactor to use subcommands instead of flags
This commit is contained in:
parent
aae04b2b4b
commit
46ff06341b
347
ldnssec-keygen.c
347
ldnssec-keygen.c
@ -16,6 +16,7 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <ldns/ldns.h>
|
#include <ldns/ldns.h>
|
||||||
@ -27,68 +28,57 @@ usage(void)
|
|||||||
{
|
{
|
||||||
const char *p = getprogname();
|
const char *p = getprogname();
|
||||||
|
|
||||||
fprintf(stderr, "Usage:\n"
|
fprintf(stderr, "usage:\n"
|
||||||
"\t%s [-b bits] algorithm\n"
|
"\t%s dnskey [-d domain] [-k]\n"
|
||||||
"\t%s -n [-d domain]\n"
|
"\t%s ds [-a algorithm] [-d domain]\n"
|
||||||
"\t%s -r [-a algorithm] [-d domain] [-k] ds|dnskey\n",
|
"\t%s filename [-d domain] [-k]\n"
|
||||||
p, p, p);
|
"\t%s gen [-a algorithm] [-b bits]\n",
|
||||||
|
p, p, p, p);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
print_filename_main(const char *domain, int argc, char *argv[])
|
cmd_dnskey_usage(void)
|
||||||
{
|
{
|
||||||
ldns_key *key;
|
fprintf(stderr, "usage: %s dnskey [-d domain] [-k]\n", getprogname());
|
||||||
ldns_rdf *rdf_dname;
|
exit(1);
|
||||||
ldns_status s;
|
|
||||||
char *str;
|
|
||||||
int line_nr;
|
|
||||||
|
|
||||||
if (argc != 0)
|
|
||||||
usage();
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
ldns_key_set_pubkey_owner(key, rdf_dname);
|
|
||||||
|
|
||||||
str = ldns_key_get_file_base_name(key);
|
|
||||||
if (str == NULL)
|
|
||||||
errx(1, "ldns_key_get_file_base_name");
|
|
||||||
printf("%s\n", str);
|
|
||||||
|
|
||||||
free(str);
|
|
||||||
ldns_key_deep_free(key);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
|
cmd_ds_usage(void)
|
||||||
char *argv[])
|
{
|
||||||
|
fprintf(stderr, "usage: %s ds [-a algorithm] [-d domain]\n",
|
||||||
|
getprogname());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_filename_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s filename [-d domain] [-k]\n",
|
||||||
|
getprogname());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_gen_usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s gen [-a algorithm] [-b bits]\n",
|
||||||
|
getprogname());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ds_dnskey_rr_filename_print(const char *domain, int sep, ldns_hash hash,
|
||||||
|
int do_filename)
|
||||||
{
|
{
|
||||||
ldns_key *key;
|
ldns_key *key;
|
||||||
ldns_rr *dnskey_rr, *ds_rr;
|
ldns_rr *dnskey_rr, *ds_rr = NULL;
|
||||||
ldns_rdf *rdf_dname;
|
ldns_rdf *rdf_dname;
|
||||||
ldns_status s;
|
ldns_status s;
|
||||||
const char *type;
|
|
||||||
char *str;
|
char *str;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
int line_nr, do_ds;
|
int do_ds, line_nr;
|
||||||
|
|
||||||
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);
|
s = ldns_key_new_frm_fp_l(&key, stdin, &line_nr);
|
||||||
if (s != LDNS_STATUS_OK)
|
if (s != LDNS_STATUS_OK)
|
||||||
@ -97,10 +87,11 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
|
|||||||
|
|
||||||
s = ldns_str2rdf_dname(&rdf_dname, domain);
|
s = ldns_str2rdf_dname(&rdf_dname, domain);
|
||||||
if (s != LDNS_STATUS_OK)
|
if (s != LDNS_STATUS_OK)
|
||||||
errx(1, "ldns_str2rdf_dname: %s", ldns_get_errorstr_by_id(s));
|
errx(1, "ldns_str2rdf_dname: %s: %s", domain,
|
||||||
|
ldns_get_errorstr_by_id(s));
|
||||||
|
|
||||||
flags = LDNS_KEY_ZONE_KEY;
|
flags = LDNS_KEY_ZONE_KEY;
|
||||||
if (ksk)
|
if (sep)
|
||||||
flags |= LDNS_KEY_SEP_KEY;
|
flags |= LDNS_KEY_SEP_KEY;
|
||||||
|
|
||||||
ldns_key_set_pubkey_owner(key, rdf_dname);
|
ldns_key_set_pubkey_owner(key, rdf_dname);
|
||||||
@ -110,44 +101,170 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
|
|||||||
if (dnskey_rr == NULL)
|
if (dnskey_rr == NULL)
|
||||||
errx(1, "ldns_key2rr");
|
errx(1, "ldns_key2rr");
|
||||||
|
|
||||||
ds_rr = NULL;
|
if (do_filename) {
|
||||||
if (do_ds) {
|
ldns_key_set_keytag(key, ldns_calc_keytag(dnskey_rr));
|
||||||
ds_rr = ldns_key_rr2ds(dnskey_rr, hash);
|
str = ldns_key_get_file_base_name(key);
|
||||||
if (ds_rr == NULL)
|
if (str == NULL)
|
||||||
errx(1, "ldns_key_rr2ds");
|
errx(1, "ldns_key_get_file_base_name");
|
||||||
}
|
printf("%s\n", str);
|
||||||
|
} else {
|
||||||
|
do_ds = hash != 0;
|
||||||
|
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);
|
str = ldns_rr2str(do_ds ? ds_rr : dnskey_rr);
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
errx(1, "ldns_rr2str");
|
errx(1, "ldns_rr2str");
|
||||||
fputs(str, stdout);
|
fputs(str, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
free(str);
|
free(str);
|
||||||
ldns_rr_free(dnskey_rr);
|
ldns_rr_free(dnskey_rr);
|
||||||
ldns_rr_free(ds_rr);
|
ldns_rr_free(ds_rr);
|
||||||
ldns_key_deep_free(key);
|
ldns_key_deep_free(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_dnskey_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *domain;
|
||||||
|
int ch, sep;
|
||||||
|
|
||||||
|
domain = ".";
|
||||||
|
sep = 0;
|
||||||
|
while ((ch = getopt(argc, argv, "d:k")) != -1) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'd':
|
||||||
|
domain = optarg;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
sep = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd_dnskey_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc != 0)
|
||||||
|
cmd_ds_usage();
|
||||||
|
|
||||||
|
ds_dnskey_rr_filename_print(domain, sep, 0, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keygen_main(uint16_t bits, int argc, char *argv[])
|
cmd_ds_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ldns_hash alg;
|
||||||
|
const char *domain;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
alg = LDNS_SHA256;
|
||||||
|
domain = ".";
|
||||||
|
while ((ch = getopt(argc, argv, "a:d:")) != -1) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'a':
|
||||||
|
alg = ldnssec_get_hash_algorithm_by_name(optarg);
|
||||||
|
if (ldns_lookup_by_id(ldnssec_hashes, alg) == NULL)
|
||||||
|
errx(1, "-a: unsupported algorithm %s",
|
||||||
|
optarg);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
domain = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd_ds_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc != 0)
|
||||||
|
cmd_ds_usage();
|
||||||
|
|
||||||
|
ds_dnskey_rr_filename_print(domain, 1, alg, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_filename_main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *domain;
|
||||||
|
int ch, sep;
|
||||||
|
|
||||||
|
domain = ".";
|
||||||
|
sep = 0;
|
||||||
|
while ((ch = getopt(argc, argv, "d:k")) != -1) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'd':
|
||||||
|
domain = optarg;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
sep = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd_filename_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc != 0)
|
||||||
|
cmd_filename_usage();
|
||||||
|
|
||||||
|
ds_dnskey_rr_filename_print(domain, sep, 0, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmd_gen_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ldns_key *key;
|
ldns_key *key;
|
||||||
ldns_signing_algorithm alg;
|
ldns_signing_algorithm alg;
|
||||||
|
const char *errstr;
|
||||||
char *str;
|
char *str;
|
||||||
|
long long n;
|
||||||
|
int ch;
|
||||||
|
uint16_t bits;
|
||||||
|
|
||||||
if (argc != 1)
|
alg = LDNS_SIGN_ECDSAP256SHA256;
|
||||||
usage();
|
bits = 0;
|
||||||
|
while ((ch = getopt(argc, argv, "a:b:")) != -1) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'a':
|
||||||
|
alg = ldns_get_signing_algorithm_by_name(optarg);
|
||||||
|
/*
|
||||||
|
* 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, "-a: unsupported algorithm %s",
|
||||||
|
optarg);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
n = strtonum(optarg, 0, UINT16_MAX, &errstr);
|
||||||
|
if (errstr != NULL)
|
||||||
|
errx(1, "-b: bits is %s: %s", errstr, optarg);
|
||||||
|
bits = n;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cmd_gen_usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
alg = ldns_get_signing_algorithm_by_name(argv[0]);
|
if (argc != 0)
|
||||||
/*
|
cmd_gen_usage();
|
||||||
* 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);
|
key = ldns_key_new_frm_algorithm(alg, bits);
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
@ -159,6 +276,7 @@ keygen_main(uint16_t bits, int argc, char *argv[])
|
|||||||
errx(1, "ldns_key2str");
|
errx(1, "ldns_key2str");
|
||||||
fputs(str, stdout);
|
fputs(str, stdout);
|
||||||
|
|
||||||
|
free(str);
|
||||||
ldns_key_deep_free(key);
|
ldns_key_deep_free(key);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -167,78 +285,25 @@ keygen_main(uint16_t bits, int argc, char *argv[])
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const ldns_lookup_table *lt;
|
const char *cmd;
|
||||||
ldns_key *key;
|
int rc;
|
||||||
ldns_signing_algorithm alg;
|
|
||||||
ldns_hash hash_alg;
|
|
||||||
const char *errstr, *domain;
|
|
||||||
long long n;
|
|
||||||
int ch, rc;
|
|
||||||
int aflag, bflag, dflag, kflag, nflag, rflag;
|
|
||||||
uint16_t bits;
|
|
||||||
|
|
||||||
aflag = bflag = dflag = kflag = nflag = rflag = 0;
|
if (argc < 2)
|
||||||
hash_alg = LDNS_SHA256;
|
usage();
|
||||||
bits = 0;
|
cmd = argv[1];
|
||||||
domain = ".";
|
|
||||||
while ((ch = getopt(argc, argv, "a:b:d:knr")) != -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 'n':
|
|
||||||
nflag = 1;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
rflag = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (bflag && (aflag || dflag || kflag || nflag || rflag))
|
|
||||||
errx(1, "-b is mutually exclusive with -d, -k, -n and -r");
|
|
||||||
if (aflag && !rflag)
|
|
||||||
errx(1, "can't use -a without -r");
|
|
||||||
if (aflag && nflag)
|
|
||||||
errx(1, "-a and -n are mutually exclusive");
|
|
||||||
if (dflag && !(nflag || rflag))
|
|
||||||
errx(1, "can't use -d without -n or -r");
|
|
||||||
if (kflag && !rflag)
|
|
||||||
errx(1, "can't use -k without -r");
|
|
||||||
if (kflag && nflag)
|
|
||||||
errx(1, "-k and -n are mutually exclusive");
|
|
||||||
if (nflag && rflag)
|
|
||||||
errx(1, "-n and -r are mutually exclusive");
|
|
||||||
|
|
||||||
rc = 1;
|
rc = 1;
|
||||||
if (nflag)
|
optind = 2;
|
||||||
rc = print_filename_main(domain, argc, argv);
|
if (strcmp(cmd, "ds") == 0)
|
||||||
else if (rflag)
|
rc = cmd_ds_main(argc, argv);
|
||||||
rc = print_record_main(hash_alg, kflag, domain, argc, argv);
|
else if (strcmp(cmd, "dnskey") == 0)
|
||||||
|
rc = cmd_dnskey_main(argc, argv);
|
||||||
|
else if (strcmp(cmd, "filename") == 0)
|
||||||
|
rc = cmd_filename_main(argc, argv);
|
||||||
|
else if (strcmp(cmd, "gen") == 0)
|
||||||
|
rc = cmd_gen_main(argc, argv);
|
||||||
else
|
else
|
||||||
rc = keygen_main(bits, argc, argv);
|
usage();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user