exit(ret);
}
+static isc_stdtime_t
+between(isc_stdtime_t t, isc_stdtime_t start, isc_stdtime_t end) {
+ isc_stdtime_t r = end;
+ if (t > 0 && t > start && t < end) {
+ r = t;
+ }
+ return (r);
+}
+
static void
checkparams(ksr_ctx_t *ksr, const char *command) {
if (ksr->configfile == NULL) {
bool conflict = false;
bool freekey = false;
bool show_progress = true;
- bool first = true;
char algstr[DNS_SECALG_FORMATSIZE];
char filename[PATH_MAX + 1];
char timestr[26]; /* Minimal buf as per ctime_r() spec. */
"Selecting key pair for bundle %s: ", timestr);
fflush(stderr);
}
- first = false;
key = dk->key;
*expiration = inact;
goto output;
dst_key_settime(key, DST_TIME_PUBLISH, (active - prepub));
dst_key_settime(key, DST_TIME_ACTIVATE, active);
if (ksr->ksk) {
- dns_keymgr_settime_syncpublish(key, kasp, first);
+ dns_keymgr_settime_syncpublish(key, kasp,
+ (inception == ksr->start));
}
if (ksr->lifetime > 0) {
isc_result_totext(ret));
}
- first = false;
-
output:
isc_buffer_clear(&buf);
ret = dst_key_buildfilename(key, 0, NULL, &buf);
return (next_bundle);
}
-static void
+static isc_stdtime_t
sign_rrset(ksr_ctx_t *ksr, isc_stdtime_t inception, isc_stdtime_t expiration,
dns_rdataset_t *rrset, dns_dnsseckeylist_t *keys) {
dns_rdatalist_t *rrsiglist = NULL;
dns_rdataset_t rrsigset = DNS_RDATASET_INIT;
isc_result_t ret;
+ isc_stdtime_t next_bundle = expiration;
UNUSED(ksr);
unsigned char rdatabuf[SIG_FORMATSIZE];
isc_stdtime_t clockskew = inception - 3600;
+ isc_stdtime_t pub = 0, act = 0, inact = 0, del = 0;
+
+ /* Determine next bundle. */
+ (void)dst_key_gettime(dk->key, DST_TIME_PUBLISH, &pub);
+ (void)dst_key_gettime(dk->key, DST_TIME_ACTIVATE, &act);
+ (void)dst_key_gettime(dk->key, DST_TIME_INACTIVE, &inact);
+ (void)dst_key_gettime(dk->key, DST_TIME_DELETE, &del);
+ next_bundle = between(pub, inception, next_bundle);
+ next_bundle = between(act, inception, next_bundle);
+ next_bundle = between(inact, inception, next_bundle);
+ next_bundle = between(del, inception, next_bundle);
+
+ if (act > inception) {
+ continue;
+ }
+ if (inact != 0 && inception >= inact) {
+ continue;
+ }
+
rrsig = isc_mem_get(mctx, sizeof(*rrsig));
dns_rdata_init(rrsig);
isc_buffer_init(&buf, rdatabuf, sizeof(rdatabuf));
dns_rdatalist_tordataset(rrsiglist, &rrsigset);
print_rdata(&rrsigset);
freerrset(&rrsigset);
+
+ return (next_bundle);
}
/*
* Create the DNSKEY, CDS, and CDNSKEY records beloing to the KSKs
* listed in 'keys'.
*/
-static void
-create_ksk(ksr_ctx_t *ksr, dns_kasp_t *kasp, dns_dnsseckeylist_t *keys,
- dns_rdataset_t *dnskeyset, dns_rdataset_t *cdnskeyset,
- dns_rdataset_t *cdsset) {
+static isc_stdtime_t
+get_keymaterial(ksr_ctx_t *ksr, dns_kasp_t *kasp, isc_stdtime_t inception,
+ isc_stdtime_t next_inception, dns_dnsseckeylist_t *keys,
+ dns_rdataset_t *dnskeyset, dns_rdataset_t *cdnskeyset,
+ dns_rdataset_t *cdsset) {
+ dns_kasp_digestlist_t digests = dns_kasp_digests(kasp);
dns_rdatalist_t *dnskeylist = isc_mem_get(mctx, sizeof(*dnskeylist));
dns_rdatalist_t *cdnskeylist = isc_mem_get(mctx, sizeof(*cdnskeylist));
dns_rdatalist_t *cdslist = isc_mem_get(mctx, sizeof(*cdslist));
isc_result_t ret = ISC_R_SUCCESS;
- dns_kasp_digestlist_t digests = dns_kasp_digests(kasp);
+ isc_stdtime_t next_bundle = next_inception;
dns_rdatalist_init(dnskeylist);
dnskeylist->rdclass = dns_rdataclass_in;
for (dns_dnsseckey_t *dk = ISC_LIST_HEAD(*keys); dk != NULL;
dk = ISC_LIST_NEXT(dk, link))
{
+ bool published = true;
isc_buffer_t buf;
isc_buffer_t *newbuf;
dns_rdata_t *rdata;
isc_region_t r;
isc_region_t rcds;
+ isc_stdtime_t pub = 0, del = 0;
unsigned char kskbuf[DST_KEY_MAXSIZE];
unsigned char cdnskeybuf[DST_KEY_MAXSIZE];
unsigned char cdsbuf[DNS_DS_BUFFERSIZE];
/* KSK */
- newbuf = NULL;
- rdata = isc_mem_get(mctx, sizeof(*rdata));
- dns_rdata_init(rdata);
+ (void)dst_key_gettime(dk->key, DST_TIME_PUBLISH, &pub);
+ (void)dst_key_gettime(dk->key, DST_TIME_DELETE, &del);
+ next_bundle = between(pub, inception, next_bundle);
+ next_bundle = between(del, inception, next_bundle);
- isc_buffer_init(&buf, kskbuf, sizeof(kskbuf));
- CHECK(dst_key_todns(dk->key, &buf));
- isc_buffer_usedregion(&buf, &r);
- isc_buffer_allocate(mctx, &newbuf, r.length);
- isc_buffer_putmem(newbuf, r.base, r.length);
- isc_buffer_usedregion(newbuf, &r);
- dns_rdata_fromregion(rdata, dns_rdataclass_in,
- dns_rdatatype_dnskey, &r);
- ISC_LIST_APPEND(dnskeylist->rdata, rdata, link);
- ISC_LIST_APPEND(cleanup_list, newbuf, link);
- isc_buffer_clear(newbuf);
+ if (pub > inception) {
+ published = false;
+ }
+ if (del != 0 && inception >= del) {
+ published = false;
+ }
+
+ if (published) {
+ newbuf = NULL;
+ rdata = isc_mem_get(mctx, sizeof(*rdata));
+ dns_rdata_init(rdata);
+
+ isc_buffer_init(&buf, kskbuf, sizeof(kskbuf));
+ CHECK(dst_key_todns(dk->key, &buf));
+ isc_buffer_usedregion(&buf, &r);
+ isc_buffer_allocate(mctx, &newbuf, r.length);
+ isc_buffer_putmem(newbuf, r.base, r.length);
+ isc_buffer_usedregion(newbuf, &r);
+ dns_rdata_fromregion(rdata, dns_rdataclass_in,
+ dns_rdatatype_dnskey, &r);
+ ISC_LIST_APPEND(dnskeylist->rdata, rdata, link);
+ ISC_LIST_APPEND(cleanup_list, newbuf, link);
+ isc_buffer_clear(newbuf);
+ }
+
+ published = true;
+ if (dns_kasp_cdnskey(kasp) || !ISC_LIST_EMPTY(digests)) {
+ pub = 0;
+ del = 0;
+ (void)dst_key_gettime(dk->key, DST_TIME_SYNCPUBLISH,
+ &pub);
+ (void)dst_key_gettime(dk->key, DST_TIME_SYNCDELETE,
+ &del);
+
+ next_bundle = between(pub, inception, next_bundle);
+ next_bundle = between(del, inception, next_bundle);
+
+ if (pub != 0 && pub > inception) {
+ published = false;
+ }
+ if (del != 0 && inception >= del) {
+ published = false;
+ }
+ } else {
+ published = false;
+ }
+
+ if (!published) {
+ continue;
+ }
/* CDNSKEY */
newbuf = NULL;
dns_rdatalist_tordataset(dnskeylist, dnskeyset);
dns_rdatalist_tordataset(cdnskeylist, cdnskeyset);
dns_rdatalist_tordataset(cdslist, cdsset);
- return;
+
+ return (next_bundle);
fail:
fatal("failed to create KSK/CDS/CDNSKEY");
+ return (0);
}
static void
-sign_bundle(ksr_ctx_t *ksr, isc_stdtime_t inception,
- isc_stdtime_t next_inception, dns_rdatalist_t *rdatalist,
- dns_rdataset_t *cds, dns_rdataset_t *cdnskey,
+sign_bundle(ksr_ctx_t *ksr, dns_kasp_t *kasp, isc_stdtime_t inception,
+ isc_stdtime_t next_inception, dns_rdatalist_t *zsklist,
dns_dnsseckeylist_t *keys) {
- dns_rdataset_t rrset = DNS_RDATASET_INIT;
- isc_stdtime_t expiration;
+ isc_stdtime_t expiration = inception + ksr->sigvalidity;
+ isc_stdtime_t next_bundle = next_inception;
+ dns_rdataset_t zsk;
+
+ dns_rdataset_init(&zsk);
+ dns_rdatalist_tordataset(zsklist, &zsk);
- dns_rdataset_init(&rrset);
- dns_rdatalist_tordataset(rdatalist, &rrset);
- expiration = inception + ksr->sigvalidity;
while (inception <= next_inception) {
- sign_rrset(ksr, inception, expiration, &rrset, keys);
- if (dns_rdataset_count(cdnskey) > 0) {
- sign_rrset(ksr, inception, expiration, cdnskey, keys);
+ isc_stdtime_t next_time = next_bundle;
+
+ /* DNSKEY RRset */
+ dns_rdatalist_t *dnskeylist;
+ dnskeylist = isc_mem_get(mctx, sizeof(*dnskeylist));
+ dns_rdatalist_init(dnskeylist);
+ dnskeylist->rdclass = dns_rdataclass_in;
+ dnskeylist->type = dns_rdatatype_dnskey;
+ dnskeylist->ttl = ksr->ttl;
+
+ dns_rdataset_t ksk, cdnskey, cds, rrset;
+ dns_rdataset_init(&ksk);
+ dns_rdataset_init(&cdnskey);
+ dns_rdataset_init(&cds);
+ dns_rdataset_init(&rrset);
+ next_time = get_keymaterial(ksr, kasp, inception, next_time,
+ keys, &ksk, &cdnskey, &cds);
+ if (next_bundle > next_time) {
+ next_bundle = next_time;
+ }
+
+ for (isc_result_t r = dns_rdatalist_first(&ksk);
+ r == ISC_R_SUCCESS; r = dns_rdatalist_next(&ksk))
+ {
+ dns_rdata_t *clone = isc_mem_get(mctx, sizeof(*clone));
+ dns_rdata_init(clone);
+ dns_rdatalist_current(&ksk, clone);
+ ISC_LIST_APPEND(dnskeylist->rdata, clone, link);
+ }
+
+ for (isc_result_t r = dns_rdatalist_first(&zsk);
+ r == ISC_R_SUCCESS; r = dns_rdatalist_next(&zsk))
+ {
+ dns_rdata_t *clone = isc_mem_get(mctx, sizeof(*clone));
+ dns_rdata_init(clone);
+ dns_rdatalist_current(&zsk, clone);
+ ISC_LIST_APPEND(dnskeylist->rdata, clone, link);
+ }
+
+ dns_rdatalist_tordataset(dnskeylist, &rrset);
+ next_time = sign_rrset(ksr, inception, expiration, &rrset,
+ keys);
+ if (next_bundle > next_time) {
+ next_bundle = next_time;
}
- if (dns_rdataset_count(cds) > 0) {
- sign_rrset(ksr, inception, expiration, cds, keys);
+ freerrset(&ksk);
+ freerrset(&rrset);
+
+ /* CDNSKEY */
+ if (dns_rdataset_count(&cdnskey) > 0) {
+ (void)sign_rrset(ksr, inception, expiration, &cdnskey,
+ keys);
}
+ freerrset(&cdnskey);
+
+ /* CDS */
+ if (dns_rdataset_count(&cds) > 0) {
+ (void)sign_rrset(ksr, inception, expiration, &cds,
+ keys);
+ }
+ freerrset(&cds);
+
+ /* Next response bundle. */
inception = expiration - ksr->sigrefresh;
+ if (inception > next_bundle) {
+ inception = next_bundle;
+ }
expiration = inception + ksr->sigvalidity;
+ next_bundle = expiration;
}
- freerrset(&rrset);
+
+ freerrset(&zsk);
}
static isc_result_t
dns_dnsseckeylist_t keys;
dns_kasp_t *kasp = NULL;
dns_rdatalist_t *rdatalist = NULL;
- dns_rdataset_t ksk = DNS_RDATASET_INIT;
- dns_rdataset_t cdnskey = DNS_RDATASET_INIT;
- dns_rdataset_t cds = DNS_RDATASET_INIT;
isc_result_t ret;
isc_stdtime_t inception;
isc_lex_t *lex = NULL;
isc_result_totext(ret));
}
- /* KSK, CDS and CDNSKEY */
- create_ksk(ksr, kasp, &keys, &ksk, &cdnskey, &cds);
-
for (ret = isc_lex_gettoken(lex, opt, &token); ret == ISC_R_SUCCESS;
ret = isc_lex_gettoken(lex, opt, &token))
{
if (have_bundle) {
/* Sign previous bundle */
- sign_bundle(ksr, inception, next_inception,
- rdatalist, &cds, &cdnskey, &keys);
+ sign_bundle(ksr, kasp, inception,
+ next_inception, rdatalist, &keys);
fprintf(stdout, "\n");
}
rdatalist->rdclass = dns_rdataclass_in;
rdatalist->type = dns_rdatatype_dnskey;
rdatalist->ttl = ksr->ttl;
- for (isc_result_t r = dns_rdatalist_first(&ksk);
- r == ISC_R_SUCCESS; r = dns_rdatalist_next(&ksk))
- {
- dns_rdata_t *clone =
- isc_mem_get(mctx, sizeof(*clone));
- dns_rdata_init(clone);
- dns_rdatalist_current(&ksk, clone);
- ISC_LIST_APPEND(rdatalist->rdata, clone, link);
- }
+
inception = next_inception;
have_bundle = true;
/* Final bundle */
if (have_bundle && rdatalist != NULL) {
- sign_bundle(ksr, inception, ksr->end, rdatalist, &cds, &cdnskey,
- &keys);
+ sign_bundle(ksr, kasp, inception, ksr->end, rdatalist, &keys);
} else {
fatal("bad KSR file %s(%lu): no bundles", ksr->file,
isc_lex_getsourceline(lex));
timestr, PACKAGE_VERSION);
fail:
- /* Clean up */
- freerrset(&ksk);
- freerrset(&cdnskey);
- freerrset(&cds);
-
isc_lex_destroy(&lex);
cleanup(&keys, kasp);
}