resolved: dnssec - factor out hashed domain generation
authorTom Gundersen <teg@jklm.no>
Sun, 3 Jan 2016 08:49:58 +0000 (09:49 +0100)
committerTom Gundersen <teg@jklm.no>
Sun, 3 Jan 2016 08:59:13 +0000 (09:59 +0100)
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-dns-dnssec.h

index 98d1c6f..46dcae6 100644 (file)
@@ -1071,7 +1071,7 @@ static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) {
         }
 }
 
-int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
+int dnssec_nsec3_hash(const DnsResourceRecord *nsec3, const char *name, void *ret) {
         uint8_t wire_format[DNS_WIRE_FOMAT_HOSTNAME_MAX];
         gcry_md_hd_t md = NULL;
         size_t hash_size;
@@ -1192,10 +1192,37 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsAnswerFlags flags, DnsResourc
         return dns_name_equal(a, b);
 }
 
+static int nsec3_hashed_domain(const DnsResourceRecord *nsec3, const char *domain, const char *zone, char **ret) {
+        _cleanup_free_ char *l = NULL, *hashed_domain = NULL;
+        uint8_t hashed[DNSSEC_HASH_SIZE_MAX];
+        int hashed_size;
+
+        assert(nsec3);
+        assert(domain);
+        assert(zone);
+        assert(ret);
+
+        hashed_size = dnssec_nsec3_hash(nsec3, domain, hashed);
+        if (hashed_size < 0)
+                return hashed_size;
+
+        l = base32hexmem(hashed, hashed_size, false);
+        if (!l)
+                return -ENOMEM;
+
+        hashed_domain = strjoin(l, ".", zone, NULL);
+        if (!hashed_domain)
+                return -ENOMEM;
+
+        *ret = hashed_domain;
+        hashed_domain = NULL;
+
+        return hashed_size;
+}
+
 /* See RFC 5155, Section 8 */
 static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated) {
-        _cleanup_free_ char *next_closer_domain = NULL, *l = NULL;
-        uint8_t hashed[DNSSEC_HASH_SIZE_MAX];
+        _cleanup_free_ char *next_closer_domain = NULL;
         const char *zone, *p, *pp = NULL;
         DnsResourceRecord *rr, *enclosure_rr, *suffix_rr;
         DnsAnswerFlags flags;
@@ -1242,9 +1269,9 @@ found_zone:
         /* Second step, find the closest encloser NSEC3 RR in 'answer' that matches 'key' */
         p = DNS_RESOURCE_KEY_NAME(key);
         for (;;) {
-                _cleanup_free_ char *hashed_domain = NULL, *label = NULL;
+                _cleanup_free_ char *hashed_domain = NULL;
 
-                hashed_size = dnssec_nsec3_hash(suffix_rr, p, hashed);
+                hashed_size = nsec3_hashed_domain(suffix_rr, p, zone, &hashed_domain);
                 if (hashed_size == -EOPNOTSUPP) {
                         *result = DNSSEC_NSEC_UNSUPPORTED_ALGORITHM;
                         return 0;
@@ -1252,14 +1279,6 @@ found_zone:
                 if (hashed_size < 0)
                         return hashed_size;
 
-                label = base32hexmem(hashed, hashed_size, false);
-                if (!label)
-                        return -ENOMEM;
-
-                hashed_domain = strjoin(label, ".", zone, NULL);
-                if (!hashed_domain)
-                        return -ENOMEM;
-
                 DNS_ANSWER_FOREACH_FLAGS(enclosure_rr, flags, answer) {
 
                         r = nsec3_is_good(enclosure_rr, flags, suffix_rr);
@@ -1326,20 +1345,12 @@ found_closest_encloser:
                 return 0;
         }
 
-        r = dnssec_nsec3_hash(enclosure_rr, pp, hashed);
+        r = nsec3_hashed_domain(enclosure_rr, pp, zone, &next_closer_domain);
         if (r < 0)
                 return r;
         if (r != hashed_size)
                 return -EBADMSG;
 
-        l = base32hexmem(hashed, hashed_size, false);
-        if (!l)
-                return -ENOMEM;
-
-        next_closer_domain = strjoin(l, ".", zone, NULL);
-        if (!next_closer_domain)
-                return -ENOMEM;
-
         DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
                 _cleanup_free_ char *label = NULL, *next_hashed_domain = NULL;
 
index 57858d0..f106875 100644 (file)
@@ -87,7 +87,7 @@ uint16_t dnssec_keytag(DnsResourceRecord *dnskey);
 
 int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max);
 
-int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret);
+int dnssec_nsec3_hash(const DnsResourceRecord *nsec3, const char *name, void *ret);
 
 typedef enum DnssecNsecResult {
         DNSSEC_NSEC_NO_RR,     /* No suitable NSEC/NSEC3 RR found */