resolved: TLSA records
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 2 Feb 2015 00:17:24 +0000 (19:17 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 28 Jan 2016 23:35:01 +0000 (18:35 -0500)
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h

index 032e719..ee3d151 100644 (file)
@@ -1058,6 +1058,22 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star
 
                 break;
 
+        case DNS_TYPE_TLSA:
+                r = dns_packet_append_uint8(p, rr->tlsa.cert_usage, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->tlsa.selector, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->tlsa.matching_type, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
+                break;
+
         case DNS_TYPE_OPT:
         case _DNS_TYPE_INVALID: /* unparseable */
         default:
@@ -1976,6 +1992,31 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
                 break;
         }
 
+        case DNS_TYPE_TLSA:
+                r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_memdup(p, rdlength - 3,
+                                           &rr->tlsa.data, &rr->tlsa.data_size,
+                                           NULL);
+                if (rr->tlsa.data_size <= 0) {
+                        /* the accepted size depends on the algorithm, but for now
+                           just ensure that the value is greater than zero */
+                        r = -EBADMSG;
+                        goto fail;
+                }
+
+                break;
+
         case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
         default:
         unparseable:
index a3df8d5..1db5099 100644 (file)
@@ -487,6 +487,10 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
                 case DNS_TYPE_AAAA:
                         break;
 
+                case DNS_TYPE_TLSA:
+                        free(rr->tlsa.data);
+                        break;
+
                 default:
                         free(rr->generic.data);
                 }
@@ -690,6 +694,13 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
                     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);
 
+        case DNS_TYPE_TLSA:
+                return a->tlsa.cert_usage == b->tlsa.cert_usage &&
+                       a->tlsa.selector == b->tlsa.selector &&
+                       a->tlsa.matching_type == b->tlsa.matching_type &&
+                       a->tlsa.data_size == b->tlsa.data_size &&
+                       memcmp(a->tlsa.data, b->tlsa.data, a->tlsa.data_size) == 0;
+
         default:
                 return a->generic.size == b->generic.size &&
                         memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
@@ -1074,6 +1085,26 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 break;
         }
 
+        case DNS_TYPE_TLSA: {
+                int n;
+
+                r = asprintf(&s, "%s %u %u %u %n",
+                             k,
+                             rr->tlsa.cert_usage,
+                             rr->tlsa.selector,
+                             rr->tlsa.matching_type,
+                             &n);
+                if (r < 0)
+                        return NULL;
+
+                r = base64_append(&s, n,
+                                  rr->tlsa.data, rr->tlsa.data_size,
+                                  8, columns());
+                if (r < 0)
+                        return NULL;
+                break;
+        }
+
         default:
                 t = hexmem(rr->generic.data, rr->generic.size);
                 if (!t)
@@ -1340,6 +1371,13 @@ static void dns_resource_record_hash_func(const void *i, struct siphash *state)
                 /* FIXME: We leave the bitmaps out */
                 break;
 
+        case DNS_TYPE_TLSA:
+                siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state);
+                siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state);
+                siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state);
+                siphash24_compress(&rr->tlsa.data, rr->tlsa.data_size, state);
+                break;
+
         default:
                 siphash24_compress(rr->generic.data, rr->generic.size, state);
                 break;
index d9c31e8..d42d38c 100644 (file)
@@ -242,6 +242,15 @@ struct DnsResourceRecord {
                         size_t next_hashed_name_size;
                         Bitmap *types;
                 } nsec3;
+
+                /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23 */
+                struct {
+                        uint8_t cert_usage;
+                        uint8_t selector;
+                        uint8_t matching_type;
+                        void *data;
+                        size_t data_size;
+                } tlsa;
         };
 };