diff --git a/src/dns.c b/src/dns.c index 9b55bfcb..c9fe6394 100644 --- a/src/dns.c +++ b/src/dns.c @@ -2222,16 +2222,28 @@ hsk_dns_name_serialize( int size; int i; char *s; - int size_byte = 0; + int size_adjust = 0; for (s = (char *)name, i = 0; *s; s++, i++) { + if (name[i] == '\\') { + if (!isdigit(name[++i]) || + !isdigit(name[++i]) || + !isdigit(name[++i])) { + *len = off; + return false; + } + + size_adjust += 3; + s += 3; + } + if (name[i] == '.') { if (i > 0 && name[i - 1] == '.') { *len = off; return false; } - size = i - begin; + size = i - begin - size_adjust; if (size > HSK_DNS_MAX_LABEL) { *len = off; @@ -2243,8 +2255,7 @@ hsk_dns_name_serialize( *len = off; return false; } - // Size will be written here once we know what size is - size_byte = off; + data[off] = size; } if (cmp) { @@ -2274,13 +2285,6 @@ hsk_dns_name_serialize( char ch = name[j]; if (ch == '\\') { // Read the next three digits and form a single byte - if (!isdigit(name[j + 1]) || - !isdigit(name[j + 2]) || - !isdigit(name[j + 3])) { - *len = off; - return false; - } - uint16_t value = (name[++j] - 0x30) * 100; value += (name[++j] - 0x30) * 10; value += (name[++j] - 0x30); @@ -2305,13 +2309,12 @@ hsk_dns_name_serialize( data[off++] = ch; } - - data[size_byte] = size; } else { off += size; } begin = i + 1; + size_adjust = 0; } } diff --git a/src/resource.c b/src/resource.c index e38b0b8f..7d474d90 100644 --- a/src/resource.c +++ b/src/resource.c @@ -929,6 +929,9 @@ hsk_resource_to_dns(const hsk_resource_t *rs, const char *name, uint16_t type) { hsk_dns_rrs_t *ns = &msg->ns; // authority hsk_dns_rrs_t *ar = &msg->ar; // additional + // Even though the name here is a single label (the TLD) + // we use a larger buffer size of 255 (instead of 63) + // to allow escaped byte codes like /000 char next[HSK_DNS_MAX_NAME]; next_name(tld, next); @@ -1160,7 +1163,10 @@ hsk_resource_to_nx(const char *tld) { hsk_dns_rr_t *rr1 = hsk_dns_rrs_pop(ns); hsk_dns_rr_t *rr2 = hsk_dns_rrs_pop(ns); - // Prove the name doesn't exist + // Prove the name doesn't exist. + // Even though the name here is a single label (the TLD) + // we use a larger buffer size of 255 (instead of 63) + // to allow escaped byte codes like /000 char next[HSK_DNS_MAX_NAME]; char prev[HSK_DNS_MAX_NAME]; next_name(tld, next); @@ -1245,6 +1251,7 @@ next_name(const char *name, char *next) { memcpy(&next[len], "\\000.", 6); } else { next[len - 1]++; + memcpy(&next[len], ".", 2); } } diff --git a/test/data/name_serialization_vectors.h b/test/data/name_serialization_vectors.h index 860aaddd..eb392200 100644 --- a/test/data/name_serialization_vectors.h +++ b/test/data/name_serialization_vectors.h @@ -50,17 +50,15 @@ static const name_serializtion_vector_t name_serializtion_vectors[7] = { { "abcdef\\256.", { - 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }, 7, false }, { "abcdef\\LOL.", - { - 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 - }, - 7, + {}, + 0, false }, {