Initial import
This commit is contained in:
commit
6f48d8b947
121
COPYING
Normal file
121
COPYING
Normal file
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
58
Makefile
Normal file
58
Makefile
Normal file
@ -0,0 +1,58 @@
|
||||
# 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
|
||||
# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
.POSIX:
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .o .c
|
||||
|
||||
P = ldnssec-utils
|
||||
V = 0.0
|
||||
|
||||
LIBHDR = util.h
|
||||
LIBOBJ = util.o
|
||||
|
||||
BIN = ldnssec-keygen ldnssec-sign-dnskey
|
||||
BINEX = ex-print-zone
|
||||
OBJ = ${BIN:=.o} ${BINEX:=.o} ${LIBOBJ}
|
||||
SRC = ${OBJ:.o=.c}
|
||||
DIST = COPYING Makefile ${LIBHDR} ${SRC}
|
||||
|
||||
LDNS_INCS = -I/usr/local/include
|
||||
LDNS_LIBS = -L/usr/local/lib -lldns
|
||||
|
||||
.o:
|
||||
${CC} ${LDFLAGS} -o $@ $@.o ${LIBOBJ} ${LDNS_LIBS}
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} ${LDNS_INCS} -c $<
|
||||
|
||||
all: ${BINEX} ${BIN}
|
||||
|
||||
clean:
|
||||
rm -f ${BIN} ${BINEX} ${OBJ} ${P}-${V}.tgz
|
||||
|
||||
dist: clean
|
||||
pax -ws ',^,${P}-${V}/,' ${DIST} | gzip >${P}-${V}.tgz
|
||||
|
||||
install: all
|
||||
mkdir -p ${PREFIX}/bin
|
||||
cp -f ${BIN} ${PREFIX}/bin
|
||||
cd ${PREFIX}/bin && chmod 555 ${BIN}
|
||||
|
||||
uninstall:
|
||||
cd ${PREFIX}/bin && rm -f ${BIN}
|
||||
|
||||
util.o: util.h
|
||||
|
||||
ldnssec-keygen: ldnssec-keygen.o ${LIBOBJ}
|
||||
ldnssec-sign-dnskey: ldnssec-sign-dnskey.o ${LIBOBJ}
|
||||
ex-print-zone: ex-print-zone.o ${LIBOBJ}
|
6
README
Normal file
6
README
Normal file
@ -0,0 +1,6 @@
|
||||
ldnssec-utils
|
||||
=============
|
||||
|
||||
Lucas' DNSSEC utils, built around LDNS[0].
|
||||
|
||||
[0]: https://nlnetlabs.nl/projects/ldns/about/
|
1
data/Kexample.+013+38127.ds
Normal file
1
data/Kexample.+013+38127.ds
Normal file
@ -0,0 +1 @@
|
||||
example. IN DS 38127 13 2 45e1fdf3338cedce4676be9014a6b46604e00688be95f7a8854f541930be65b4
|
1
data/Kexample.+013+38127.key
Normal file
1
data/Kexample.+013+38127.key
Normal file
@ -0,0 +1 @@
|
||||
example. IN DNSKEY 257 3 13 r84HU+lP18H53xF6ZsOUGCGmvon0Gfkr5BgIof4KBFQ7hluFqnf0gF45xEzxr/o+NxksGmOeOKRVzNEABP3mLw== ;{id = 38127 (ksk), size = 256b}
|
3
data/Kexample.+013+38127.private
Normal file
3
data/Kexample.+013+38127.private
Normal file
@ -0,0 +1,3 @@
|
||||
Private-key-format: v1.2
|
||||
Algorithm: 13 (ECDSAP256SHA256)
|
||||
PrivateKey: lM2XFN/WiR0wWTrpC7oDAYbQoDV8DGcA/w/kHq9F5pw=
|
1
data/Kexample.+013+57357.ds
Normal file
1
data/Kexample.+013+57357.ds
Normal file
@ -0,0 +1 @@
|
||||
example. IN DS 57357 13 2 d65b3fd9c6a5d30eb9a5ab83149216116de9ab9e1f1c15255b37d79a8d64b8a9
|
1
data/Kexample.+013+57357.key
Normal file
1
data/Kexample.+013+57357.key
Normal file
@ -0,0 +1 @@
|
||||
example. IN DNSKEY 257 3 13 1egQYIooCJBCelV2nEvGGn+YnSQlb4Hv6vdahRgsnnFTRlOCDk8YHN01E86tT+Q3weB4wmjiSlvu6hRfPC4rWA== ;{id = 57357 (ksk), size = 256b}
|
3
data/Kexample.+013+57357.private
Normal file
3
data/Kexample.+013+57357.private
Normal file
@ -0,0 +1,3 @@
|
||||
Private-key-format: v1.2
|
||||
Algorithm: 13 (ECDSAP256SHA256)
|
||||
PrivateKey: GuF9VrZ71HDIlLIEyeGthrab8q1rlm4A5cMMPPMAQwk=
|
1
data/Kexample.+013+58312.key
Normal file
1
data/Kexample.+013+58312.key
Normal file
@ -0,0 +1 @@
|
||||
example. IN DNSKEY 256 3 13 t5+0WPq6TFtVmrmvLH6EOYftEFPyz1/M+gRA8NGwlqKzoCSjQ66TuM73c5DohVql/KUqdqfiVm/Hw7sT12Ypew== ;{id = 58312 (zsk), size = 256b}
|
3
data/Kexample.+013+58312.private
Normal file
3
data/Kexample.+013+58312.private
Normal file
@ -0,0 +1,3 @@
|
||||
Private-key-format: v1.2
|
||||
Algorithm: 13 (ECDSAP256SHA256)
|
||||
PrivateKey: ECpe5kwRfHNVeiTLl+VbFMnOiQqW65LgVNwv7N3qu/g=
|
14
data/example.zone
Normal file
14
data/example.zone
Normal file
@ -0,0 +1,14 @@
|
||||
$ORIGIN example.
|
||||
@ 86400 IN SOA ns1.example. hostmaster.example. 2021120701 2h 15m 1w 30m
|
||||
86400 IN NS ns1.example.
|
||||
86400 IN NS ns2.example.
|
||||
86400 IN MX 0 .
|
||||
86400 IN TXT "v=spf1 -all"
|
||||
86400 IN DNSKEY 257 3 13 1egQYIooCJBCelV2nEvGGn+YnSQlb4Hv6vdahRgsnnFTRlOCDk8YHN01E86tT+Q3weB4wmjiSlvu6hRfPC4rWA== ;{id = 57357 (ksk), size = 256b}
|
||||
86400 IN DNSKEY 257 3 13 r84HU+lP18H53xF6ZsOUGCGmvon0Gfkr5BgIof4KBFQ7hluFqnf0gF45xEzxr/o+NxksGmOeOKRVzNEABP3mLw== ;{id = 38127 (ksk), size = 256b}
|
||||
86400 IN DNSKEY 256 3 13 t5+0WPq6TFtVmrmvLH6EOYftEFPyz1/M+gRA8NGwlqKzoCSjQ66TuM73c5DohVql/KUqdqfiVm/Hw7sT12Ypew== ;{id = 58312 (zsk), size = 256b}
|
||||
|
||||
ns1 86400 IN A 192.0.2.1
|
||||
86400 IN AAAA 2001:db8::6af:4864:a096:eb76
|
||||
ns2 86400 IN A 198.51.100.1
|
||||
86400 IN AAAA 2001:db8::5e7f:b183:4f08:217f
|
80
ex-print-zone.c
Normal file
80
ex-print-zone.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-f zone]\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
ldns_zone *zone;
|
||||
ldns_status s;
|
||||
FILE *fp;
|
||||
char *filename;
|
||||
int ch, line_nr;
|
||||
|
||||
fp = NULL;
|
||||
filename = NULL;
|
||||
while ((ch = getopt(argc, argv, "f:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
if (fp != NULL)
|
||||
errx(1, "-f can be used only once");
|
||||
filename = optarg;
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL)
|
||||
err(1, "fopen");
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (fp == NULL) {
|
||||
filename = "(stdin)";
|
||||
fp = stdin;
|
||||
}
|
||||
|
||||
fatal_check_minimum_ldns_revision();
|
||||
|
||||
s = ldns_zone_new_frm_fp_l(&zone, fp, NULL, LDNS_DEFAULT_TTL,
|
||||
LDNS_RR_CLASS_IN, &line_nr);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_zone_new_frm_fp_l: file %s line %d: %s",
|
||||
filename, line_nr, ldns_get_errorstr_by_id(s));
|
||||
if (fp != stdin)
|
||||
(void)fclose(fp);
|
||||
|
||||
ldns_zone_print(stdout, zone);
|
||||
|
||||
ldns_zone_deep_free(zone);
|
||||
|
||||
return 0;
|
||||
}
|
198
ldnssec-keygen.c
Normal file
198
ldnssec-keygen.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#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;
|
||||
}
|
272
ldnssec-sign-dnskey.c
Normal file
272
ldnssec-sign-dnskey.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define DEFAULT_DURATION (30 * 86400) /* 30 days */
|
||||
|
||||
static int
|
||||
extend_key_from_zone(ldns_key *k, const ldns_zone *z)
|
||||
{
|
||||
ldns_rr_list *rrs;
|
||||
ldns_rr *soa, *key_rr;
|
||||
size_t i;
|
||||
int match = 0;
|
||||
|
||||
soa = ldns_zone_soa(z);
|
||||
rrs = ldns_zone_rrs(z);
|
||||
key_rr = ldns_key2rr(k);
|
||||
if (key_rr == NULL)
|
||||
errx(1, "ldns_key2rr");
|
||||
for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
|
||||
ldns_rr *rr;
|
||||
ldns_rdf *owner_rdf;
|
||||
|
||||
rr = ldns_rr_list_rr(rrs, i);
|
||||
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY ||
|
||||
ldns_rdf_compare(ldns_rr_dnskey_protocol(rr),
|
||||
ldns_rr_dnskey_protocol(key_rr)) != 0 ||
|
||||
ldns_rdf_compare(ldns_rr_dnskey_algorithm(rr),
|
||||
ldns_rr_dnskey_algorithm(key_rr)) != 0 ||
|
||||
ldns_rdf_compare(ldns_rr_dnskey_key(rr),
|
||||
ldns_rr_dnskey_key(key_rr)) != 0)
|
||||
continue;
|
||||
|
||||
/* key and DNSKEY have the same pubkey and algorithm */
|
||||
owner_rdf = ldns_rdf_clone(ldns_rr_owner(rr));
|
||||
if (owner_rdf == NULL)
|
||||
errx(1, "ldns_rdf_clone");
|
||||
ldns_key_set_pubkey_owner(k, owner_rdf);
|
||||
ldns_key_set_origttl(k, ldns_rr_ttl(rr));
|
||||
ldns_key_set_keytag(k, ldns_calc_keytag(rr));
|
||||
ldns_key_set_flags(k,
|
||||
ldns_rdf2native_int16(ldns_rr_dnskey_flags(rr)));
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
ldns_rr_free(key_rr);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_datetime(const char *buf, struct tm *tm)
|
||||
{
|
||||
char *s;
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
if (t == (time_t)-1)
|
||||
err(1, "time");
|
||||
if (gmtime_r(&t, tm) == NULL)
|
||||
errx(1, "gmtime_r");
|
||||
|
||||
/* attempt to parse as YYYYMMDDhhmmss */
|
||||
s = strptime(buf, "%Y %m %d %H %M %S", tm);
|
||||
if (s != NULL && *s == '\0')
|
||||
return 1;
|
||||
|
||||
/* failed; attemp to parse as YYYYMMDD */
|
||||
s = strptime(buf, "%Y %m %d", tm);
|
||||
if (s != NULL && *s == '\0')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
const char *p = getprogname();
|
||||
|
||||
fprintf(stderr, "Usage:\n"
|
||||
"\t%s [-d duration] [-i inception] key [key ...]\n"
|
||||
"\t%s [-e expiration] [-i inception] key [key ...]\n",
|
||||
p, p);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
ldns_zone *zone = NULL;
|
||||
ldns_dnssec_zone *dnssec_zone;
|
||||
ldns_key_list *keys;
|
||||
ldns_rr_list *added_rrs, *origin_rrs;
|
||||
ldns_rr *origin_soa;
|
||||
ldns_status s;
|
||||
const char *errstr;
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
size_t i;
|
||||
long long n;
|
||||
uint32_t expiration, inception, duration;
|
||||
int ch, line_nr;
|
||||
int dflag, eflag, iflag;
|
||||
|
||||
dflag = eflag = iflag = 0;
|
||||
duration = DEFAULT_DURATION;
|
||||
while ((ch = getopt(argc, argv, "d:e:i:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
n = strtonum(optarg, 0, UINT32_MAX, &errstr);
|
||||
if (errstr != NULL)
|
||||
errx(1, "-d: duration is %s: %s", errstr,
|
||||
optarg);
|
||||
duration = n;
|
||||
break;
|
||||
case 'e':
|
||||
eflag = 1;
|
||||
if (!parse_datetime(optarg, &tm))
|
||||
errx(1, "-e: not in YYYYMMDDhhmmss or "
|
||||
"YYYYMMDD format");
|
||||
t = mktime(&tm);
|
||||
if (t == (time_t)-1)
|
||||
errx(1, "mktime");
|
||||
expiration = t & 0xffffffff;
|
||||
break;
|
||||
case 'i':
|
||||
iflag = 1;
|
||||
if (!parse_datetime(optarg, &tm))
|
||||
errx(1, "-i: not in YYYYMMDDhhmmss or "
|
||||
"YYYYMMDD format");
|
||||
t = mktime(&tm);
|
||||
if (t == (time_t)-1)
|
||||
errx(1, "mktime");
|
||||
inception = t & 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (dflag && eflag)
|
||||
errx(1, "-d and -e are mutually exclusive");
|
||||
if (argc == 0)
|
||||
usage();
|
||||
|
||||
if (!iflag) {
|
||||
t = time(NULL);
|
||||
if (t == (time_t)-1)
|
||||
err(1, "time");
|
||||
inception = t & 0xffffffff;
|
||||
}
|
||||
if (!eflag)
|
||||
expiration = inception + duration;
|
||||
|
||||
fatal_check_minimum_ldns_revision();
|
||||
|
||||
s = ldns_zone_new_frm_fp_l(&zone, stdin, NULL, LDNS_DEFAULT_TTL,
|
||||
LDNS_RR_CLASS_IN, &line_nr);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_zone_new_frm_fp_l: (stdin) line %d: %s",
|
||||
line_nr, ldns_get_errorstr_by_id(s));
|
||||
|
||||
origin_soa = ldns_zone_soa(zone);
|
||||
if (origin_soa == NULL)
|
||||
errx(1, "no SOA in zone");
|
||||
origin_rrs = ldns_zone_rrs(zone);
|
||||
|
||||
dnssec_zone = ldns_dnssec_zone_new();
|
||||
if (dnssec_zone == NULL)
|
||||
err(1, "ldns_dnssec_zone_new");
|
||||
s = ldns_dnssec_zone_add_rr(dnssec_zone, origin_soa);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_dnssec_zone_add_rr: %s",
|
||||
ldns_get_errorstr_by_id(s));
|
||||
for (i = 0; i < ldns_rr_list_rr_count(origin_rrs); i++) {
|
||||
ldns_rr *rr;
|
||||
|
||||
rr = ldns_rr_list_rr(origin_rrs, i);
|
||||
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY ||
|
||||
ldns_rdf_compare(ldns_rr_owner(rr),
|
||||
ldns_rr_owner(origin_soa)) != 0)
|
||||
continue;
|
||||
|
||||
s = ldns_dnssec_zone_add_rr(dnssec_zone, rr);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_dnssec_zone_add_rr: %s",
|
||||
ldns_get_errorstr_by_id(s));
|
||||
}
|
||||
|
||||
keys = ldns_key_list_new();
|
||||
if (keys == NULL)
|
||||
err(1, "ldns_key_list_new");
|
||||
for (; *argv != NULL; argv++) {
|
||||
ldns_key *k = NULL;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(*argv, "r");
|
||||
if (fp == NULL)
|
||||
err(1, "fopen: %s", *argv);
|
||||
s = ldns_key_new_frm_fp_l(&k, fp, &line_nr);
|
||||
(void)fclose(fp);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_key_new_frm_fp_l: %s line %d: %s",
|
||||
*argv, line_nr, ldns_get_errorstr_by_id(s));
|
||||
|
||||
if (!extend_key_from_zone(k, zone))
|
||||
errx(1, "no DNSKEY in zone for private key \"%s\"",
|
||||
*argv);
|
||||
ldns_key_set_expiration(k, expiration);
|
||||
ldns_key_set_inception(k, inception);
|
||||
|
||||
if (!ldns_key_list_push_key(keys, k))
|
||||
err(1, "ldns_key_list_push_key");
|
||||
}
|
||||
|
||||
added_rrs = ldns_rr_list_new();
|
||||
if (added_rrs == NULL)
|
||||
err(1, "ldns_rr_list_new");
|
||||
s = ldns_dnssec_zone_create_rrsigs_flg(dnssec_zone, added_rrs, keys,
|
||||
ldns_dnssec_default_replace_signatures, NULL, 0);
|
||||
if (s != LDNS_STATUS_OK)
|
||||
errx(1, "ldns_dnssec_zone_create_rrsigs_flg: %s",
|
||||
ldns_get_errorstr_by_id(s));
|
||||
|
||||
for (i = 0; i < ldns_rr_list_rr_count(added_rrs); i++) {
|
||||
ldns_rr *rr;
|
||||
char *str;
|
||||
|
||||
rr = ldns_rr_list_rr(added_rrs, i);
|
||||
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG ||
|
||||
ldns_rdf2native_int16(ldns_rr_rrsig_typecovered(rr)) !=
|
||||
LDNS_RR_TYPE_DNSKEY)
|
||||
continue;
|
||||
|
||||
str = ldns_rr2str(rr);
|
||||
if (str == NULL)
|
||||
errx(1, "ldns_rr2str");
|
||||
fputs(str, stdout);
|
||||
free(str);
|
||||
}
|
||||
|
||||
ldns_key_list_free(keys);
|
||||
ldns_dnssec_zone_free(dnssec_zone);
|
||||
ldns_zone_deep_free(zone);
|
||||
ldns_rr_list_deep_free(added_rrs);
|
||||
|
||||
return 0;
|
||||
}
|
66
util.c
Normal file
66
util.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define MINIMUM_LDNS_VERSION "1.7.1"
|
||||
#define MINIMUM_LDNS_REVISION ((1<<16)|(7<<8)|(1))
|
||||
|
||||
ldns_lookup_table ldnssec_hashes[] = {
|
||||
{ LDNS_SHA1, "SHA1" },
|
||||
{ LDNS_SHA256, "SHA256" },
|
||||
{ LDNS_HASH_GOST, "GOST" },
|
||||
{ LDNS_SHA384, "SHA384" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
ldns_hash
|
||||
ldnssec_get_hash_algorithm_by_name(const char *name)
|
||||
{
|
||||
static ldns_lookup_table aliases[] = {
|
||||
{ LDNS_SHA1, "SHA-1" },
|
||||
{ LDNS_SHA256, "SHA-256" },
|
||||
{ LDNS_SHA384, "SHA-384" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
ldns_lookup_table *lt;
|
||||
const char *errstr;
|
||||
long long n;
|
||||
|
||||
lt = ldns_lookup_by_name(ldnssec_hashes, name);
|
||||
if (lt != NULL)
|
||||
return lt->id;
|
||||
lt = ldns_lookup_by_name(aliases, name);
|
||||
if (lt != NULL)
|
||||
return lt->id;
|
||||
|
||||
n = strtonum(name, 0, UINT8_MAX, &errstr);
|
||||
if (errstr == NULL)
|
||||
return n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fatal_check_minimum_ldns_revision(void)
|
||||
{
|
||||
if (MINIMUM_LDNS_REVISION > LDNS_REVISION)
|
||||
errx(1, "ldns version should be greater or equal than "
|
||||
MINIMUM_LDNS_VERSION "; got %s instead\n", ldns_version());
|
||||
}
|
25
util.h
Normal file
25
util.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H_INCLUDED
|
||||
#define _UTIL_H_INCLUDED
|
||||
|
||||
extern ldns_lookup_table ldnssec_hashes[];
|
||||
|
||||
ldns_hash ldnssec_get_hash_algorithm_by_name(const char *);
|
||||
|
||||
void fatal_check_minimum_ldns_revision(void);
|
||||
|
||||
#endif /* !_UTIL_H_INCLUDED */
|
Loading…
Reference in New Issue
Block a user