resolved: rr - add NSEC3 support

Needed for DNSSEC.
This commit is contained in:
Tom Gundersen 2015-07-13 01:51:03 +02:00
parent 919a7f5f1c
commit 5d45a88084
4 changed files with 157 additions and 8 deletions

View file

@ -824,6 +824,40 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
if (r < 0)
goto fail;
break;
case DNS_TYPE_NSEC3:
r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
if (r < 0)
goto fail;
r = dns_packet_append_types(p, rr->nsec3.types, NULL);
if (r < 0)
goto fail;
break;
case _DNS_TYPE_INVALID: /* unparseable */
default:
@ -1560,6 +1594,60 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
}
break;
case DNS_TYPE_NSEC3: {
uint8_t size;
r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
if (r < 0)
goto fail;
r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
if (r < 0)
goto fail;
r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
if (r < 0)
goto fail;
r = dns_packet_read_uint8(p, &size, NULL);
if (r < 0)
goto fail;
rr->nsec3.salt_size = size;
r = dns_packet_read_blob(p, &d, rr->nsec3.salt_size, NULL);
if (r < 0)
goto fail;
rr->nsec3.salt = memdup(d, rr->nsec3.salt_size);
if (!rr->nsec3.salt) {
r = -ENOMEM;
goto fail;
}
r = dns_packet_read_uint8(p, &size, NULL);
if (r < 0)
goto fail;
rr->nsec3.next_hashed_name_size = size;
r = dns_packet_read(p, rr->nsec3.next_hashed_name_size, &d, NULL);
if (r < 0)
goto fail;
rr->nsec3.next_hashed_name = memdup(d, rr->nsec3.next_hashed_name_size);
if (!rr->nsec3.next_hashed_name) {
r = -ENOMEM;
goto fail;
}
r = dns_packet_append_types(p, rr->nsec3.types, NULL);
if (r < 0)
goto fail;
break;
}
default:
unparseable:
r = dns_packet_read(p, rdlength, &d, NULL);
@ -1694,13 +1782,15 @@ static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
[DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
[DNSSEC_ALGORITHM_DH] = "DH",
[DNSSEC_ALGORITHM_DSA] = "DSA",
[DNSSEC_ALGORITHM_ECC] = "ECC",
[DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
[DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
[DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
[DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
[DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
[DNSSEC_ALGORITHM_DH] = "DH",
[DNSSEC_ALGORITHM_DSA] = "DSA",
[DNSSEC_ALGORITHM_ECC] = "ECC",
[DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
[DNSSEC_ALGORITHM_DSA_NSEC3_SHA1] = "DSA-NSEC3-SHA1",
[DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1",
[DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
[DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
[DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);

View file

@ -223,6 +223,8 @@ enum {
DNSSEC_ALGORITHM_DSA,
DNSSEC_ALGORITHM_ECC,
DNSSEC_ALGORITHM_RSASHA1,
DNSSEC_ALGORITHM_DSA_NSEC3_SHA1,
DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
DNSSEC_ALGORITHM_INDIRECT = 252,
DNSSEC_ALGORITHM_PRIVATEDNS,
DNSSEC_ALGORITHM_PRIVATEOID,

View file

@ -293,6 +293,12 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
bitmap_free(rr->nsec.types);
break;
case DNS_TYPE_NSEC3:
free(rr->nsec3.next_hashed_name);
free(rr->nsec3.salt);
bitmap_free(rr->nsec3.types);
break;
case DNS_TYPE_LOC:
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
@ -457,6 +463,15 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
return dns_name_equal(a->nsec.next_domain_name, b->nsec.next_domain_name) &&
bitmap_equal(a->nsec.types, b->nsec.types);
case DNS_TYPE_NSEC3:
return a->nsec3.algorithm == b->nsec3.algorithm &&
a->nsec3.flags == b->nsec3.flags &&
a->nsec3.iterations == b->nsec3.iterations &&
a->nsec3.salt_size == b->nsec3.salt_size &&
memcmp(a->nsec3.salt, b->nsec3.salt, a->nsec3.salt_size) == 0 &&
memcmp(a->nsec3.next_hashed_name, b->nsec3.next_hashed_name, a->nsec3.next_hashed_name_size) == 0 &&
bitmap_equal(a->nsec3.types, b->nsec3.types);
default:
return a->generic.size == b->generic.size &&
memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
@ -757,6 +772,37 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
return -ENOMEM;
break;
case DNS_TYPE_NSEC3: {
_cleanup_free_ char *salt = NULL, *hash = NULL;
if (rr->nsec3.salt_size) {
salt = hexmem(rr->nsec3.salt, rr->nsec3.salt_size);
if (!salt)
return -ENOMEM;
}
hash = base32hexmem(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, false);
if (!hash)
return -ENOMEM;
t = format_types(rr->nsec3.types);
if (!t)
return -ENOMEM;
r = asprintf(&s, "%s %"PRIu8" %"PRIu8" %"PRIu16" %s %s %s",
k,
rr->nsec3.algorithm,
rr->nsec3.flags,
rr->nsec3.iterations,
rr->nsec3.salt_size ? salt : "-",
hash,
t);
if (r < 0)
return -ENOMEM;
break;
}
default:
t = hexmem(rr->generic.data, rr->generic.size);
if (!t)

View file

@ -151,6 +151,17 @@ struct DnsResourceRecord {
char *next_domain_name;
Bitmap *types;
} nsec;
struct {
uint8_t algorithm;
uint8_t flags;
uint16_t iterations;
void *salt;
size_t salt_size;
void *next_hashed_name;
size_t next_hashed_name_size;
Bitmap *types;
} nsec3;
};
};