isc_buffer_t b;
isc_region_t r;
- INSIST(name != NULL);
+ INSIST(DNS_NAME_VALID(name));
INSIST(rdata != NULL);
INSIST(mctx != NULL);
INSIST(key != NULL);
isc_result_t result;
isc_buffer_t *databuf = NULL;
char data[256 + 8];
+ unsigned int labels;
unsigned int sigsize;
dns_fixedname_t fnewname;
dns_fixedname_t fsigner;
- REQUIRE(name != NULL);
- REQUIRE(dns_name_countlabels(name) <= 255);
+ REQUIRE(DNS_NAME_VALID(name));
+ labels = dns_name_countlabels(name);
+ REQUIRE(labels <= 255 && labels > 0);
REQUIRE(set != NULL);
REQUIRE(key != NULL);
REQUIRE(inception != NULL);
sig.covered = set->type;
sig.algorithm = dst_algorithm_tosecalg(dst_key_alg(key));
- sig.labels = dns_name_countlabels(name) - 1;
+ sig.labels = labels - 1;
if (dns_name_iswildcard(name)) {
sig.labels--;
}
isc_result_t result;
unsigned char data[300];
dst_context_t *ctx = NULL;
- int labels = 0;
+ unsigned int labels;
+ unsigned int siglabels;
bool downcase = false;
- REQUIRE(name != NULL);
+ REQUIRE(DNS_NAME_VALID(name));
+ labels = dns_name_countlabels(name);
+ REQUIRE(labels > 0);
REQUIRE(set != NULL);
REQUIRE(key != NULL);
REQUIRE(mctx != NULL);
return DNS_R_SIGINVALID;
}
+ /*
+ * The RRSIG labels field can't indicate fewer labels than the
+ * signer. Also the labels shouldn't be greater than that of
+ * the owner name.
+ *
+ * sig.labels doesn't include the root label, so add 1 to account
+ * for it.
+ */
+ siglabels = sig.labels + 1;
+ if (siglabels < dns_name_countlabels(&sig.signer) || siglabels > labels)
+ {
+ inc_stat(dns_dnssecstats_fail);
+ return DNS_R_SIGINVALID;
+ }
+
if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
inc_stat(dns_dnssecstats_fail);
return DNS_R_SIGINVALID;
* If the name is an expanded wildcard, use the wildcard name.
*/
dns_fixedname_init(&fnewname);
- labels = dns_name_countlabels(name) - 1;
RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname)) ==
ISC_R_SUCCESS);
- if (labels - sig.labels > 0) {
- dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
- NULL, dns_fixedname_name(&fnewname));
+ if (labels > siglabels) {
+ dns_name_split(dns_fixedname_name(&fnewname), siglabels, NULL,
+ dns_fixedname_name(&fnewname));
}
dns_name_toregion(dns_fixedname_name(&fnewname), &r);
* Create an envelope for each rdata: <name|type|class|ttl>.
*/
isc_buffer_init(&envbuf, data, sizeof(data));
- if (labels - sig.labels > 0) {
+ if (labels > siglabels) {
isc_buffer_putuint8(&envbuf, 1);
isc_buffer_putuint8(&envbuf, '*');
memmove(data + 2, r.base, r.length);
inc_stat(dns_dnssecstats_fail);
}
- if (result == ISC_R_SUCCESS && labels - sig.labels > 0) {
+ if (result == ISC_R_SUCCESS && labels > siglabels) {
if (wild != NULL) {
RUNTIME_CHECK(dns_name_concatenate(
dns_wildcardname,
static isc_result_t
fromtext_rrsig(ARGS_FROMTEXT) {
isc_token_t token;
- unsigned char alg, c;
+ unsigned char alg, labels;
long i;
dns_rdatatype_t covered;
- char *e;
+ char *e = NULL;
isc_result_t result;
isc_buffer_t buffer;
uint32_t time_signed, time_expire;
unsigned int used;
+ dns_fixedname_t fixed;
+ dns_name_t *signer = dns_fixedname_initname(&fixed);
REQUIRE(type == dns_rdatatype_rrsig);
if (token.value.as_ulong > 0xffU) {
RETTOK(ISC_R_RANGE);
}
- c = (unsigned char)token.value.as_ulong;
- RETERR(mem_tobuffer(target, &c, 1));
+ labels = (unsigned char)token.value.as_ulong;
+ RETERR(mem_tobuffer(target, &labels, 1));
/*
* Original ttl.
if (origin == NULL) {
origin = dns_rootname;
}
- RETTOK(dns_name_wirefromtext(&buffer, origin, options, target));
+ RETTOK(dns_name_fromtext(signer, &buffer, origin, options));
+
+ /*
+ * (RRSIG labels doesn't include the root label, so add one
+ * to normalize it before checking against the signer.)
+ */
+ if ((labels + 1) < dns_name_countlabels(signer)) {
+ RETTOK(ISC_R_RANGE);
+ }
+ RETERR(mem_tobuffer(target, signer->ndata, signer->length));
/*
* Sig.
isc_region_t sr;
dns_name_t name;
unsigned char algorithm;
+ unsigned char labels;
REQUIRE(type == dns_rdatatype_rrsig);
}
algorithm = sr.base[2];
+ labels = sr.base[3];
isc_buffer_forward(source, 18);
RETERR(mem_tobuffer(target, sr.base, 18));
dns_name_init(&name);
RETERR(dns_name_fromwire(&name, source, dctx, target));
+ /*
+ * (RRSIG labels doesn't include the root label, so add one
+ * to normalize it before checking against the signer.)
+ */
+ if ((labels + 1) < dns_name_countlabels(&name)) {
+ RETERR(DNS_R_FORMERR);
+ }
+
/*
* Sig.
*/