|
|
|
@ -16,6 +16,7 @@
@@ -16,6 +16,7 @@
|
|
|
|
|
#include <err.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
#include <ldns/ldns.h> |
|
|
|
@ -27,68 +28,57 @@ usage(void)
@@ -27,68 +28,57 @@ usage(void)
|
|
|
|
|
{ |
|
|
|
|
const char *p = getprogname(); |
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Usage:\n" |
|
|
|
|
"\t%s [-b bits] algorithm\n" |
|
|
|
|
"\t%s -n [-d domain]\n" |
|
|
|
|
"\t%s -r [-a algorithm] [-d domain] [-k] ds|dnskey\n", |
|
|
|
|
p, p, p); |
|
|
|
|
fprintf(stderr, "usage:\n" |
|
|
|
|
"\t%s dnskey [-d domain] [-k]\n" |
|
|
|
|
"\t%s ds [-a algorithm] [-d domain]\n" |
|
|
|
|
"\t%s filename [-d domain] [-k]\n" |
|
|
|
|
"\t%s gen [-a algorithm] [-b bits]\n", |
|
|
|
|
p, p, p, p); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
print_filename_main(const char *domain, int argc, char *argv[]) |
|
|
|
|
static void |
|
|
|
|
cmd_dnskey_usage(void) |
|
|
|
|
{ |
|
|
|
|
ldns_key *key; |
|
|
|
|
ldns_rdf *rdf_dname; |
|
|
|
|
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); |
|
|
|
|
fprintf(stderr, "usage: %s dnskey [-d domain] [-k]\n", getprogname()); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
str = ldns_key_get_file_base_name(key); |
|
|
|
|
if (str == NULL) |
|
|
|
|
errx(1, "ldns_key_get_file_base_name"); |
|
|
|
|
printf("%s\n", str); |
|
|
|
|
static void |
|
|
|
|
cmd_ds_usage(void) |
|
|
|
|
{ |
|
|
|
|
fprintf(stderr, "usage: %s ds [-a algorithm] [-d domain]\n", |
|
|
|
|
getprogname()); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(str); |
|
|
|
|
ldns_key_deep_free(key); |
|
|
|
|
static void |
|
|
|
|
cmd_filename_usage(void) |
|
|
|
|
{ |
|
|
|
|
fprintf(stderr, "usage: %s filename [-d domain] [-k]\n", |
|
|
|
|
getprogname()); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
static void |
|
|
|
|
cmd_gen_usage(void) |
|
|
|
|
{ |
|
|
|
|
fprintf(stderr, "usage: %s gen [-a algorithm] [-b bits]\n", |
|
|
|
|
getprogname()); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
print_record_main(ldns_hash hash, int ksk, const char *domain, int argc, |
|
|
|
|
char *argv[]) |
|
|
|
|
static void |
|
|
|
|
ds_dnskey_rr_filename_print(const char *domain, int sep, ldns_hash hash, |
|
|
|
|
int do_filename) |
|
|
|
|
{ |
|
|
|
|
ldns_key *key; |
|
|
|
|
ldns_rr *dnskey_rr, *ds_rr; |
|
|
|
|
ldns_rr *dnskey_rr, *ds_rr = NULL; |
|
|
|
|
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); |
|
|
|
|
int do_ds, line_nr; |
|
|
|
|
|
|
|
|
|
s = ldns_key_new_frm_fp_l(&key, stdin, &line_nr); |
|
|
|
|
if (s != LDNS_STATUS_OK) |
|
|
|
@ -97,10 +87,11 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
@@ -97,10 +87,11 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
|
|
|
|
|
|
|
|
|
|
s = ldns_str2rdf_dname(&rdf_dname, domain); |
|
|
|
|
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; |
|
|
|
|
if (ksk) |
|
|
|
|
if (sep) |
|
|
|
|
flags |= LDNS_KEY_SEP_KEY; |
|
|
|
|
|
|
|
|
|
ldns_key_set_pubkey_owner(key, rdf_dname); |
|
|
|
@ -110,135 +101,209 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
@@ -110,135 +101,209 @@ print_record_main(ldns_hash hash, int ksk, const char *domain, int argc,
|
|
|
|
|
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"); |
|
|
|
|
} |
|
|
|
|
if (do_filename) { |
|
|
|
|
ldns_key_set_keytag(key, ldns_calc_keytag(dnskey_rr)); |
|
|
|
|
str = ldns_key_get_file_base_name(key); |
|
|
|
|
if (str == NULL) |
|
|
|
|
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); |
|
|
|
|
if (str == NULL) |
|
|
|
|
errx(1, "ldns_rr2str"); |
|
|
|
|
fputs(str, stdout); |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
keygen_main(uint16_t bits, int argc, char *argv[]) |
|
|
|
|
cmd_ds_main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
ldns_key *key; |
|
|
|
|
ldns_signing_algorithm alg; |
|
|
|
|
char *str; |
|
|
|
|
ldns_hash alg; |
|
|
|
|
const char *domain; |
|
|
|
|
int ch; |
|
|
|
|
|
|
|
|
|
if (argc != 1) |
|
|
|
|
usage(); |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
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]); |
|
|
|
|
if (argc != 0) |
|
|
|
|
cmd_ds_usage(); |
|
|
|
|
|
|
|
|
|
key = ldns_key_new_frm_algorithm(alg, bits); |
|
|
|
|
if (key == NULL) |
|
|
|
|
errx(1, "error generating key of type %s", argv[0]); |
|
|
|
|
ds_dnskey_rr_filename_print(domain, 1, alg, 0); |
|
|
|
|
|
|
|
|
|
/* ldns_key_print uses stdout to signal errors */ |
|
|
|
|
str = ldns_key2str(key); |
|
|
|
|
if (str == NULL) |
|
|
|
|
errx(1, "ldns_key2str"); |
|
|
|
|
fputs(str, stdout); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ldns_key_deep_free(key); |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
main(int argc, char *argv[]) |
|
|
|
|
static int |
|
|
|
|
cmd_gen_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; |
|
|
|
|
const char *errstr; |
|
|
|
|
char *str; |
|
|
|
|
long long n; |
|
|
|
|
int ch, rc; |
|
|
|
|
int aflag, bflag, dflag, kflag, nflag, rflag; |
|
|
|
|
int ch; |
|
|
|
|
uint16_t bits; |
|
|
|
|
|
|
|
|
|
aflag = bflag = dflag = kflag = nflag = rflag = 0; |
|
|
|
|
hash_alg = LDNS_SHA256; |
|
|
|
|
alg = LDNS_SIGN_ECDSAP256SHA256; |
|
|
|
|
bits = 0; |
|
|
|
|
domain = "."; |
|
|
|
|
while ((ch = getopt(argc, argv, "a:b:d:knr")) != -1) { |
|
|
|
|
while ((ch = getopt(argc, argv, "a:b:")) != -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", |
|
|
|
|
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': |
|
|
|
|
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(); |
|
|
|
|
cmd_gen_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"); |
|
|
|
|
if (argc != 0) |
|
|
|
|
cmd_gen_usage(); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
free(str); |
|
|
|
|
ldns_key_deep_free(key); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
const char *cmd; |
|
|
|
|
int rc; |
|
|
|
|
|
|
|
|
|
if (argc < 2) |
|
|
|
|
usage(); |
|
|
|
|
cmd = argv[1]; |
|
|
|
|
|
|
|
|
|
rc = 1; |
|
|
|
|
if (nflag) |
|
|
|
|
rc = print_filename_main(domain, argc, argv); |
|
|
|
|
else if (rflag) |
|
|
|
|
rc = print_record_main(hash_alg, kflag, domain, argc, argv); |
|
|
|
|
optind = 2; |
|
|
|
|
if (strcmp(cmd, "ds") == 0) |
|
|
|
|
rc = cmd_ds_main(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 |
|
|
|
|
rc = keygen_main(bits, argc, argv); |
|
|
|
|
usage(); |
|
|
|
|
|
|
|
|
|
return rc; |
|
|
|
|
} |
|
|
|
|