 |
ldns
1.7.0
|
Go to the documentation of this file.
20 #include <openssl/conf.h>
21 #include <openssl/engine.h>
24 #define MAX_FILENAME_LEN 250
28 #include <openssl/err.h>
31 usage(FILE *fp,
const char *prog) {
32 fprintf(fp,
"%s [OPTIONS] zonefile key [key [key]]\n", prog);
33 fprintf(fp,
" signs the zone with the given key(s)\n");
34 fprintf(fp,
" -b\t\tuse layout in signed zone and print comments DNSSEC records\n");
35 fprintf(fp,
" -d\t\tused keys are not added to the zone\n");
36 fprintf(fp,
" -e <date>\texpiration date\n");
37 fprintf(fp,
" -f <file>\toutput zone to file (default <name>.signed)\n");
38 fprintf(fp,
" -i <date>\tinception date\n");
39 fprintf(fp,
" -o <domain>\torigin for the zone\n");
40 fprintf(fp,
" -v\t\tprint version and exit\n");
41 fprintf(fp,
" -A\t\tsign DNSKEY with all keys instead of minimal\n");
42 fprintf(fp,
" -U\t\tSign with every unique algorithm in the provided keys\n");
43 fprintf(fp,
" -E <name>\tuse <name> as the crypto engine for signing\n");
44 fprintf(fp,
" \tThis can have a lot of extra options, see the manual page for more info\n");
45 fprintf(fp,
" -k <id>,<int>\tuse key id with algorithm int from engine\n");
46 fprintf(fp,
" -K <id>,<int>\tuse key id with algorithm int from engine as KSK\n");
47 fprintf(fp,
"\t\tif no key is given (but an external one is used through the engine support, it might be necessary to provide the right algorithm number.\n");
48 fprintf(fp,
" -n\t\tuse NSEC3 instead of NSEC.\n");
49 fprintf(fp,
"\t\tIf you use NSEC3, you can specify the following extra options:\n");
50 fprintf(fp,
"\t\t-a [algorithm] hashing algorithm\n");
51 fprintf(fp,
"\t\t-t [number] number of hash iterations\n");
52 fprintf(fp,
"\t\t-s [string] salt\n");
53 fprintf(fp,
"\t\t-p set the opt-out flag on all nsec3 rrs\n");
55 fprintf(fp,
" keys must be specified by their base name (usually K<name>+<alg>+<id>),\n");
56 fprintf(fp,
" i.e. WITHOUT the .private extension.\n");
57 fprintf(fp,
" If the public part of the key is not present in the zone, the DNSKEY RR\n");
58 fprintf(fp,
" will be read from the file called <base name>.key. If that does not exist,\n");
59 fprintf(fp,
" a default DNSKEY will be generated from the private key and added to the zone.\n");
60 fprintf(fp,
" A date can be a timestamp (seconds since the epoch), or of\n the form <YYYYMMdd[hhmmss]>\n");
63 static void check_tm(
struct tm tm)
65 if (tm.tm_year < 70) {
66 fprintf(stderr,
"You cannot specify dates before 1970\n");
69 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
70 fprintf(stderr,
"The month must be in the range 1 to 12\n");
73 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
74 fprintf(stderr,
"The day must be in the range 1 to 31\n");
78 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
79 fprintf(stderr,
"The hour must be in the range 0-23\n");
83 if (tm.tm_min < 0 || tm.tm_min > 59) {
84 fprintf(stderr,
"The minute must be in the range 0-59\n");
88 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
89 fprintf(stderr,
"The second must be in the range 0-59\n");
111 if (ttl1 == default_ttl) {
113 }
else if (ttl2 == default_ttl) {
118 "warning: changing non-default TTL %u to %u\n",
119 (
unsigned int) ttl2, (
unsigned int) ttl1);
133 equalize_ttls(cur_rr, rr, default_ttl);
157 fprintf(stderr,
"Found it in the zone!\n");
172 uint32_t default_ttl = zone_ttl;
176 strlen(keyfile_name_base) + 5);
177 snprintf(keyfile_name,
178 strlen(keyfile_name_base) + 5,
182 fprintf(stderr,
"Trying to read %s\n", keyfile_name);
184 keyfile = fopen(keyfile_name,
"r");
195 printf(
"Key found in file: %s\n", keyfile_name);
214 find_or_create_pubkey(
const char *keyfile_name_base,
ldns_key *key,
ldns_zone *orig_zone,
bool add_keys, uint32_t default_ttl) {
244 "Looking for key with keytag %u or %u\n",
250 pubkey = find_key_in_zone(pubkey_gen, orig_zone);
255 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
259 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
266 fprintf(stderr,
"Error %s.key has wrong name: %s\n",
277 fprintf(stderr,
"Not in zone, no .key file, generating ZSK DNSKEY from private key data\n");
285 if (add_keys && !key_in_zone) {
286 equalize_ttls_rr_list(
ldns_zone_rrs(orig_zone), pubkey, default_ttl);
294 const char *zonefile_name;
295 FILE *zonefile = NULL;
299 ENGINE *engine = NULL;
306 char *keyfile_name_base;
307 char *keyfile_name = NULL;
308 FILE *keyfile = NULL;
315 char *outputfile_name = NULL;
320 size_t eng_key_id_len;
324 bool use_nsec3 =
false;
328 bool add_keys =
true;
329 uint8_t nsec3_algorithm = 1;
330 uint8_t nsec3_flags = 0;
331 size_t nsec3_iterations_cmd = 1;
332 uint16_t nsec3_iterations = 1;
333 uint8_t nsec3_salt_length = 0;
334 uint8_t *nsec3_salt = NULL;
346 char *prog = strdup(argv[0]);
357 while ((c = getopt(argc, argv,
"a:bde:f:i:k:no:ps:t:vAUE:K:")) != -1) {
360 nsec3_algorithm = (uint8_t) atoi(optarg);
361 if (nsec3_algorithm != 1) {
362 fprintf(stderr,
"Bad NSEC3 algorithm, only RSASHA1 allowed\n");
380 memset(&tm, 0,
sizeof(tm));
382 if (strlen(optarg) == 8 &&
383 sscanf(optarg,
"%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
390 }
else if (strlen(optarg) == 14 &&
391 sscanf(optarg,
"%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
399 expiration = (uint32_t) atol(optarg);
407 memset(&tm, 0,
sizeof(tm));
409 if (strlen(optarg) == 8 &&
410 sscanf(optarg,
"%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
417 }
else if (strlen(optarg) == 14 &&
418 sscanf(optarg,
"%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
426 inception = (uint32_t) atol(optarg);
434 fprintf(stderr,
"Bad origin, not a correct domain name\n");
450 ENGINE_load_builtin_engines();
451 ENGINE_load_dynamic();
452 #ifdef HAVE_ENGINE_LOAD_CRYPTODEV
453 ENGINE_load_cryptodev();
455 engine = ENGINE_by_id(optarg);
457 printf(
"No such engine: %s\n", optarg);
458 engine = ENGINE_get_first();
459 printf(
"Available engines:\n");
461 printf(
"%s\n", ENGINE_get_id(engine));
462 engine = ENGINE_get_next(engine);
466 if (!ENGINE_init(engine)) {
467 printf(
"The engine couldn't initialize\n");
470 ENGINE_set_default_RSA(engine);
471 ENGINE_set_default_DSA(engine);
472 ENGINE_set_default(engine, 0);
476 eng_key_l = strchr(optarg,
',');
477 if (eng_key_l && strlen(eng_key_l) > 1) {
478 if (eng_key_l > optarg) {
479 eng_key_id_len = (size_t) (eng_key_l - optarg);
480 eng_key_id = malloc(eng_key_id_len + 1);
481 memcpy(eng_key_id, optarg, eng_key_id_len);
482 eng_key_id[eng_key_id_len] =
'\0';
488 eng_key_algo = atoi(eng_key_l + 1);
490 printf(
"Engine key id: %s, algo %d\n", eng_key_id, eng_key_algo);
513 fprintf(stderr,
"Warning, key not suitable for signing, ignoring key with algorithm %u\n",
ldns_key_algorithm(key));
516 if (expiration != 0) {
520 if (inception != 0) {
527 if (ERR_peek_error()) {
528 ERR_load_crypto_strings();
529 ERR_print_errors_fp(stderr);
540 printf(
"Error: bad engine key specification (should be: -k <id>,<algorithm>)).\n");
545 printf(
"Not implemented yet\n");
552 if (strlen(optarg) % 2 != 0) {
553 fprintf(stderr,
"Salt value is not valid hex data, not a multiple of 2 characters\n");
556 nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
558 for (c = 0; c < (int) strlen(optarg); c += 2) {
559 if (isxdigit((
int) optarg[c]) && isxdigit((
int) optarg[c+1])) {
563 fprintf(stderr,
"Salt value is not valid hex data.\n");
570 nsec3_iterations_cmd = (size_t) atol(optarg);
575 nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
587 printf(
"Error: not enough arguments\n");
591 zonefile_name = argv[0];
596 if (strncmp(zonefile_name,
"-", 2) == 0) {
604 fprintf(stderr,
"Zone not read, error: %s at stdin line %d\n",
612 "Error reading zonefile: missing SOA record\n");
618 "Error reading zonefile: no resource records\n");
623 zonefile = fopen(zonefile_name,
"r");
627 "Error: unable to read %s (%s)\n",
639 fprintf(stderr,
"Zone not read, error: %s at %s line %d\n",
641 zonefile_name, line_nr);
647 "Error reading zonefile: missing SOA record\n");
653 "Error reading zonefile: no resource records\n");
663 while (argi < argc) {
664 keyfile_name_base = argv[argi];
665 keyfile_name =
LDNS_XMALLOC(
char, strlen(keyfile_name_base) + 9);
666 snprintf(keyfile_name,
667 strlen(keyfile_name_base) + 9,
670 keyfile = fopen(keyfile_name,
"r");
674 "Error: unable to read %s: %s\n",
684 if (expiration != 0) {
687 if (inception != 0) {
695 fprintf(stderr,
"Error reading key from %s at line %d: %s\n", argv[argi], line_nr,
ldns_get_errorstr_by_id(s));
700 find_or_create_pubkey(keyfile_name_base, key,
701 orig_zone, add_keys, ttl);
707 fprintf(stderr,
"Error: no keys to sign with. Aborting.\n\n");
716 "Error adding SOA to dnssec zone, skipping record\n");
727 "Error adding RR to dnssec zone");
728 fprintf(stderr,
", skipping record:\n");
759 fprintf(stderr,
"Error signing zone: %s\n",
763 if (!outputfile_name) {
769 if (strncmp(outputfile_name,
"-", 2) == 0) {
772 outputfile = fopen(outputfile_name,
"w");
774 fprintf(stderr,
"Unable to open %s for writing: %s\n",
775 outputfile_name, strerror(errno));
778 outputfile, fmt, signed_zone);
783 fprintf(stderr,
"Error signing zone.\n");
786 if (ERR_peek_error()) {
787 ERR_load_crypto_strings();
788 ERR_print_errors_fp(stderr);
807 CRYPTO_cleanup_all_ex_data();
814 main(
int argc,
char **argv)
816 fprintf(stderr,
"ldns-signzone needs OpenSSL support, which has not been compiled in\n");
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
#define LDNS_COMMENT_NSEC3_CHAIN
Show the unhashed owner and next owner names for NSEC3 RR's as comment.
List or Set of Resource Records.
enum ldns_enum_rr_class ldns_rr_class
#define LDNS_NSEC3_VARS_OPTOUT_MASK
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
#define LDNS_COMMENT_LAYOUT
Print mark up.
ldns_rr * ldns_key2rr(const ldns_key *k)
converts a ldns_key to a public key rr If the key data exists at an external point,...
void ldns_key_set_inception(ldns_key *k, uint32_t i)
Set the key's inception date (seconds after epoch)
void ldns_key_set_keytag(ldns_key *k, uint16_t tag)
Set the key's key tag.
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
const char * ldns_version(void)
Show the internal library version.
bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
push an single rr to a zone structure.
#define LDNS_COMMENT_FLAGS
Show when a NSEC3 RR has the optout flag set as comment.
bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
pushes a key to a keylist
void ldns_rr_print(FILE *output, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format)
Same as rr_list, but now for keys.
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
@ LDNS_RR_CLASS_IN
the Internet
@ LDNS_SIGN_ECDSAP256SHA256
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, int flags)
signs the given zone with the given keys
ldns_key_list * ldns_key_list_new(void)
Creates a new empty key list.
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
void ldns_key_set_expiration(ldns_key *k, uint32_t e)
Set the key's expiration date (seconds after epoch)
char * ldns_rdf2str(const ldns_rdf *rdf)
Converts the data in the rdata field to presentation format and returns that as a char *.
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
Structure containing a dnssec zone.
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
Set the key's pubkey owner.
General key structure, can contain all types of keys that are used in DNSSEC.
size_t ldns_key_list_key_count(const ldns_key_list *key_list)
returns the number of keys in the key list
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
uint16_t ldns_calc_keytag(const ldns_rr *key)
calculates a keytag of a key for use in DNSSEC.
enum ldns_enum_status ldns_status
#define LDNS_NSEC3_MAX_ITERATIONS
#define LDNS_XMALLOC(type, count)
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Resource record data field.
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
ldns_rdf * ldns_key_pubkey_owner(const ldns_key *k)
return the public key's owner
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, int signflags, ldns_rbtree_t **map)
signs the given zone with the given new zone, with NSEC3
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
int ldns_dnssec_default_replace_signatures(ldns_rr *sig __attribute__((unused)), void *n __attribute__((unused)))
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
int main(int argc, char *argv[])
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
ldns_status ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
Creates a new private key based on the contents of the file pointed by fp.
void ldns_key_set_flags(ldns_key *k, uint16_t f)
Set the key's flags.
#define LDNS_SIGN_WITH_ALL_ALGORITHMS
#define LDNS_COMMENT_BUBBLEBABBLE
Provide bubblebabble representation for DS RR's as comment.
void ldns_zone_deep_free(ldns_zone *zone)
Frees the allocated memory for the zone, the soa rr in it, and the rr_list structure in it,...
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
@ LDNS_SIGN_RSASHA1_NSEC3
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
#define LDNS_SIGN_DNSKEY_WITH_ZSK
dnssec_verify
void ldns_key_list_free(ldns_key_list *key_list)
Frees a key list structure.
ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k)
return the signing alg of the key
ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
Read the key with the given id from the given engine and store it in the given ldns_key structure.
@ LDNS_SIGN_ECDSAP384SHA384
int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs, up to the rdata.
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
creates a new rr from a file containing a string.
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.