From: Willem Toorop Date: Fri, 27 Sep 2013 09:26:05 +0000 (+0200) Subject: HIP rdata as RDF type X-Git-Tag: release-1.6.17rc1~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ca72b8ddea70122e106693513daaddff885b2c0;p=thirdparty%2Fldns.git HIP rdata as RDF type Todo accessor functions for algorithm, hit and pk --- diff --git a/examples/ldns-dpa.c b/examples/ldns-dpa.c index c5717b24..0bc8a840 100644 --- a/examples/ldns-dpa.c +++ b/examples/ldns-dpa.c @@ -2823,13 +2823,13 @@ int main(int argc, char *argv[]) { } #else -int main() { +int main(void) { fprintf(stderr, "ldns-dpa was not built because there is no pcap library on this system, or there was no pcap header file at compilation time. Please install pcap and rebuild.\n"); return 1; } #endif #else -int main() { +int main(void) { fprintf(stderr, "ldns-dpa was not built because there is no pcap library on this system, or there was no pcap header file at compilation time. Please install pcap and rebuild.\n"); return 1; } diff --git a/host2str.c b/host2str.c index d28da4b0..264aa11b 100644 --- a/host2str.c +++ b/host2str.c @@ -1237,6 +1237,49 @@ ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf) return ldns_buffer_status(output); } +ldns_status +ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf) +{ + uint8_t *data = ldns_rdf_data(rdf); + size_t rdf_size = ldns_rdf_size(rdf); + uint8_t hit_size; + uint16_t pk_size; + int written; + + if (rdf_size < 6) { + return LDNS_STATUS_WIRE_RDATA_ERR; + } + if ((hit_size = data[0]) == 0 || + (pk_size = ldns_read_uint16(data + 2)) == 0 || + rdf_size < (size_t) hit_size + pk_size + 4) { + + return LDNS_STATUS_WIRE_RDATA_ERR; + } + + ldns_buffer_printf(output, "%d ", (int) data[1]); + + for (data += 4; hit_size > 0; hit_size--, data++) { + + ldns_buffer_printf(output, "%02x", (int) *data); + } + ldns_buffer_write_u8(output, ' '); + + if (ldns_buffer_reserve(output, + ldns_b64_ntop_calculate_size(pk_size))) { + + written = ldns_b64_ntop(data, pk_size, + (char *) ldns_buffer_current(output), + ldns_buffer_remaining(output)); + + if (written > 0 && + written < (int) ldns_buffer_remaining(output)) { + + output->_position += written; + } + } + return ldns_buffer_status(output); +} + ldns_status ldns_rdf2buffer_str_fmt(ldns_buffer *buffer, const ldns_output_format* fmt, const ldns_rdf *rdf) @@ -1311,6 +1354,9 @@ ldns_rdf2buffer_str_fmt(ldns_buffer *buffer, case LDNS_RDF_TYPE_TIME: res = ldns_rdf2buffer_str_time(buffer, rdf); break; + case LDNS_RDF_TYPE_HIP: + res = ldns_rdf2buffer_str_hip(buffer, rdf); + break; case LDNS_RDF_TYPE_LOC: res = ldns_rdf2buffer_str_loc(buffer, rdf); break; diff --git a/host2wire.c b/host2wire.c index b529e833..8fb5c3a2 100644 --- a/host2wire.c +++ b/host2wire.c @@ -81,63 +81,6 @@ ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list) return ldns_buffer_status(buffer); } -static ldns_status -ldns_hip_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) -{ - uint16_t i; - - assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP); - - if (ldns_rr_rd_count(rr) >= 3 && - ldns_rdf_get_type(ldns_rr_rdf(rr, 0)) == LDNS_RDF_TYPE_INT8 && - ldns_rdf_get_type(ldns_rr_rdf(rr, 1)) == LDNS_RDF_TYPE_HEX && - ldns_rdf_size(ldns_rr_rdf(rr, 1)) > 0 && - ldns_rdf_size(ldns_rr_rdf(rr, 1)) <= 255 && - ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) == LDNS_RDF_TYPE_B64) { - - /* From RFC 5205 section 5. HIP RR Storage Format: - ************************************************* - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | HIT length | PK algorithm | PK length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - ~ HIT ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - +-+-+-+-+-+-+-+-+-+-+-+ + - | Public Key | - ~ ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + - | | - ~ Rendezvous Servers ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +-+-+-+-+-+-+-+ */ - - ldns_buffer_write_u8(buffer, - (uint8_t) ldns_rdf_size(ldns_rr_rdf(rr, 1))); - (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, 0)); - ldns_buffer_write_u16(buffer, - (uint16_t) ldns_rdf_size(ldns_rr_rdf(rr, 2))); - i = 1; - } else { - i = 0; - } - while (i < ldns_rr_rd_count(rr)) { - (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i)); - i++; - } - return ldns_buffer_status(buffer); -} - ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *buffer, @@ -194,18 +137,13 @@ ldns_rr2buffer_wire_canonical(ldns_buffer *buffer, rdl_pos = ldns_buffer_position(buffer); ldns_buffer_write_u16(buffer, 0); } - - if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) { - (void) ldns_hip_rdata2buffer_wire(buffer, rr); - } else { - for (i = 0; i < ldns_rr_rd_count(rr); i++) { - if (pre_rfc3597) { - (void) ldns_rdf2buffer_wire_canonical( - buffer, ldns_rr_rdf(rr, i)); - } else { - (void) ldns_rdf2buffer_wire( - buffer, ldns_rr_rdf(rr, i)); - } + for (i = 0; i < ldns_rr_rd_count(rr); i++) { + if (pre_rfc3597) { + (void) ldns_rdf2buffer_wire_canonical( + buffer, ldns_rr_rdf(rr, i)); + } else { + (void) ldns_rdf2buffer_wire( + buffer, ldns_rr_rdf(rr, i)); } } if (rdl_pos != 0) { @@ -239,13 +177,9 @@ ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section) rdl_pos = ldns_buffer_position(buffer); ldns_buffer_write_u16(buffer, 0); } - if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) { - (void) ldns_hip_rdata2buffer_wire(buffer, rr); - } else { - for (i = 0; i < ldns_rr_rd_count(rr); i++) { - (void) ldns_rdf2buffer_wire( - buffer, ldns_rr_rdf(rr, i)); - } + for (i = 0; i < ldns_rr_rd_count(rr); i++) { + (void) ldns_rdf2buffer_wire( + buffer, ldns_rr_rdf(rr, i)); } if (rdl_pos != 0) { ldns_buffer_write_u16_at(buffer, rdl_pos, @@ -269,7 +203,8 @@ ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) /* Convert all the rdfs, except the actual signature data * rdf number 8 - the last, hence: -1 */ for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) { - (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i)); + (void) ldns_rdf2buffer_wire_canonical(buffer, + ldns_rr_rdf(rr, i)); } return ldns_buffer_status(buffer); @@ -279,9 +214,6 @@ ldns_status ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) { uint16_t i; - if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) { - return ldns_hip_rdata2buffer_wire(buffer, rr); - } /* convert all the rdf's */ for (i = 0; i < ldns_rr_rd_count(rr); i++) { (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr,i)); @@ -310,7 +242,8 @@ ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) flags = ldns_pkt_ra(packet) << 7 /*| ldns_pkt_z(packet) << 6*/ | ldns_pkt_ad(packet) << 5 - | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet); + | ldns_pkt_cd(packet) << 4 + | ldns_pkt_get_rcode(packet); ldns_buffer_write_u8(buffer, flags); ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet)); diff --git a/ldns/host2str.h b/ldns/host2str.h index 18e3d15f..d9497406 100644 --- a/ldns/host2str.h +++ b/ldns/host2str.h @@ -606,6 +606,15 @@ ldns_status ldns_rdf2buffer_str_eui48(ldns_buffer *output, ldns_status ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf); +ldns_status ldns_rdf2buffer_str_tag(ldns_buffer *output, + const ldns_rdf *rdf); + +ldns_status ldns_rdf2buffer_str_long_str(ldns_buffer *output, + const ldns_rdf *rdf); + +ldns_status ldns_rdf2buffer_str_hip(ldns_buffer *output, + const ldns_rdf *rdf); + /** * Converts the data in the rdata field to presentation format and * returns that as a char *. diff --git a/ldns/str2host.h b/ldns/str2host.h index 6dbf68a5..341aa248 100644 --- a/ldns/str2host.h +++ b/ldns/str2host.h @@ -277,6 +277,17 @@ ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str); */ ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str); +/** + * Convert a " " encoding of the value field as specified + * in Section 6. of [RFC5205], encoded as wireformat as specified in Section 5. + * of [RFC5205]. + * \param[in] rd the rdf where to put the data + * \param[in] str the string to be converted + * \return ldns_status + */ +ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str); + + #ifdef __cplusplus } #endif diff --git a/rdata.c b/rdata.c index 9b3236db..2af1ee1e 100644 --- a/rdata.c +++ b/rdata.c @@ -309,6 +309,9 @@ ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str) case LDNS_RDF_TYPE_PERIOD: status = ldns_str2rdf_period(&rdf, str); break; + case LDNS_RDF_TYPE_HIP: + status = ldns_str2rdf_hip(&rdf, str); + break; case LDNS_RDF_TYPE_SERVICE: status = ldns_str2rdf_service(&rdf, str); break; diff --git a/rr.c b/rr.c index 14d3bb27..4b28f4de 100644 --- a/rr.c +++ b/rr.c @@ -127,7 +127,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, char *type = NULL; char *rdata = NULL; char *rd = NULL; - char * b64 = NULL; + char *xtok = NULL; /* For RDF types with spaces (i.e. extra tokens) */ size_t rd_strlen; const char *delimiters; ssize_t c; @@ -161,7 +161,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, rr_buf = LDNS_MALLOC(ldns_buffer); rd_buf = LDNS_MALLOC(ldns_buffer); rd = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN); - b64 = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN); + xtok = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN); if (rr_buf) { rr_buf->_data = NULL; } @@ -169,7 +169,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, rd_buf->_data = NULL; } if (!new || !owner || !ttl || !clas || !rdata || - !rr_buf || !rd_buf || !rd || !b64) { + !rr_buf || !rd_buf || !rd || !xtok) { goto memerror; } @@ -487,10 +487,10 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, * rdf types may contain spaces). */ if (r_cnt == r_max - 1) { - c = ldns_bget_token(rd_buf, b64, + c = ldns_bget_token(rd_buf, xtok, "\n", LDNS_MAX_RDFLEN); if (c != -1) { - rd = strncat(rd, b64, + (void) strncat(rd, xtok, LDNS_MAX_RDFLEN - strlen(rd) - 1); } @@ -499,6 +499,50 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, ldns_rr_descriptor_field_type( desc, r_cnt), rd); break; + + case LDNS_RDF_TYPE_HIP: + /* + * In presentation format this RDATA type has + * three tokens: An algorithm byte, then a + * variable length HIT (in hexbytes) and then + * a variable length Public Key (in base64). + * + * We have just read the algorithm, so we need + * two more tokens: HIT and Public Key. + */ + do { + /* Read and append HIT */ + if (ldns_bget_token(rd_buf, + xtok, delimiters, + LDNS_MAX_RDFLEN) == -1) + break; + + (void) strncat(rd, " ", + LDNS_MAX_RDFLEN - + strlen(rd) - 1); + (void) strncat(rd, xtok, + LDNS_MAX_RDFLEN - + strlen(rd) - 1); + + /* Read and append Public Key*/ + if (ldns_bget_token(rd_buf, + xtok, delimiters, + LDNS_MAX_RDFLEN) == -1) + break; + + (void) strncat(rd, " ", + LDNS_MAX_RDFLEN - + strlen(rd) - 1); + (void) strncat(rd, xtok, + LDNS_MAX_RDFLEN - + strlen(rd) - 1); + } while (false); + + r = ldns_rdf_new_frm_str( + ldns_rr_descriptor_field_type( + desc, r_cnt), rd); + break; + case LDNS_RDF_TYPE_DNAME: r = ldns_rdf_new_frm_str( ldns_rr_descriptor_field_type( @@ -555,7 +599,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str, } /* for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) */ LDNS_FREE(rd); - LDNS_FREE(b64); + LDNS_FREE(xtok); ldns_buffer_free(rd_buf); ldns_buffer_free(rr_buf); LDNS_FREE(rdata); @@ -594,7 +638,7 @@ error: LDNS_FREE(clas); LDNS_FREE(hex_data); LDNS_FREE(hex_data_str); - LDNS_FREE(b64); + LDNS_FREE(xtok); LDNS_FREE(rd); LDNS_FREE(rdata); ldns_rr_free(new); @@ -1928,37 +1972,9 @@ static const ldns_rdf_type type_tlsa_wireformat[] = { LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX }; - -/** - * With HIP, wire and presentation format are out of step. - * In presentation format, we have: - * - a PK algorithm presented as integer in range [0..255] - * - a variable length HIT field presented as hexstring - * - a variable length Public Key field presented as Base64 - * - * Unfortunately in the wireformat the lengths of the variable - * length HIT and Public Key fields do not directly preceed them. - * In stead we have: - * - 1 byte HIT length: h - * - 1 byte PK algorithm - * - 2 bytes Public Key length: p - * - h bytes HIT - * - p bytes Public Key - * - * In ldns those deviations from the conventions for rdata fields are best - * tackeled by letting the array refered to by the descriptor for HIP represent - * host format only. - * - * BEWARE! Unlike other RR types, actual HIP wire format does not directly - * follow the RDF types enumerated in the array pointed to by _wireformat in - * its descriptor record. - */ -static const ldns_rdf_type type_hip_hostformat[] = { - LDNS_RDF_TYPE_INT8, - LDNS_RDF_TYPE_HEX, - LDNS_RDF_TYPE_B64 +static const ldns_rdf_type type_hip_wireformat[] = { + LDNS_RDF_TYPE_HIP }; - static const ldns_rdf_type type_nid_wireformat[] = { LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ILNP64 @@ -2115,12 +2131,8 @@ static ldns_rr_descriptor rdata_field_descriptors[] = { * Hip ends with 0 or more Rendezvous Servers represented as dname's. * Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field * set to 0. - * - * BEWARE! Unlike other RR types, actual HIP wire format does not - * directly follow the RDF types enumerated in the array pointed to - * by _wireformat. For more info see type_hip_hostformat declaration. */ - {LDNS_RR_TYPE_HIP, "HIP", 3, 3, type_hip_hostformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 }, + {LDNS_RR_TYPE_HIP, "HIP", 1, 1, type_hip_wireformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 }, #ifdef DRAFT_RRTYPES /* 56 */ diff --git a/str2host.c b/str2host.c index 3c2f9584..d4c33616 100644 --- a/str2host.c +++ b/str2host.c @@ -1476,3 +1476,94 @@ ldns_str2rdf_long_str(ldns_rdf **rd, const char *str) return LDNS_STATUS_OK; } +ldns_status +ldns_str2rdf_hip(ldns_rdf **rd, const char *str) +{ + const char *hit = strchr(str, ' ') + 1; + const char *pk = hit == NULL ? NULL : strchr(hit, ' ') + 1; + size_t hit_size = hit == NULL ? 0 + : pk == NULL ? strlen(hit) : (size_t) (pk - hit) - 1; + size_t pk_size = pk == NULL ? 0 : strlen(pk); + size_t hit_wire_size = (hit_size + 1) / 2; + size_t pk_wire_size = ldns_b64_pton_calculate_size(pk_size); + size_t rdf_size = 4 + hit_wire_size + pk_wire_size; + + char *endptr; /* utility var for strtol usage */ + int algorithm = strtol(str, &endptr, 10); + + uint8_t *data, *dp; + int hi, lo, written; + + if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255 + || rdf_size > LDNS_MAX_RDFLEN + || algorithm < 0 || algorithm > 255 + || (errno != 0 && algorithm == 0) /* out of range */ + || endptr == str /* no digits */) { + + return LDNS_STATUS_SYNTAX_ERR; + } + if ((data = LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) { + + return LDNS_STATUS_MEM_ERR; + } + /* From RFC 5205 section 5. HIP RR Storage Format: + ************************************************* + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | HIT length | PK algorithm | PK length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + ~ HIT ~ + | | + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | | + +-+-+-+-+-+-+-+-+-+-+-+ + + | Public Key | + ~ ~ + | | + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + | | + ~ Rendezvous Servers ~ + | | + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +-+-+-+-+-+-+-+ */ + + data[0] = (uint8_t) hit_wire_size; + data[1] = (uint8_t) algorithm; + + for (dp = data + 4; *hit && *hit != ' '; dp++) { + + if ((hi = ldns_hexdigit_to_int(*hit++)) == -1 || + (lo = ldns_hexdigit_to_int(*hit++)) == -1) { + + LDNS_FREE(data); + return LDNS_STATUS_INVALID_HEX; + } + *dp = hi << 4 | lo; + } + if ((written = ldns_b64_pton(pk, dp, pk_wire_size)) <= 0) { + + LDNS_FREE(data); + return LDNS_STATUS_INVALID_B64; + } + + /* Because ldns_b64_pton_calculate_size isn't always correct: + * (we have to fix it at some point) + */ + pk_wire_size = (uint16_t) written; + ldns_write_uint16(data + 2, pk_wire_size); + rdf_size = 4 + hit_wire_size + pk_wire_size; + + /* Create rdf */ + if (! (*rd = ldns_rdf_new(LDNS_RDF_TYPE_HIP, rdf_size, data))) { + + LDNS_FREE(data); + return LDNS_STATUS_MEM_ERR; + } + return LDNS_STATUS_OK; +} diff --git a/wire2host.c b/wire2host.c index 40484c07..f305808c 100644 --- a/wire2host.c +++ b/wire2host.c @@ -166,8 +166,6 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos) ldns_rdf_type cur_rdf_type; const ldns_rr_descriptor *descriptor; ldns_status status; - uint8_t hip_hit_length; - uint16_t hip_pubkey_length; assert(rr != NULL); @@ -186,78 +184,7 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos) end = *pos + (size_t) rd_length; - if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) { - - /* From RFC 5205 section 5. HIP RR Storage Format: - ************************************************* - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | HIT length | PK algorithm | PK length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - ~ HIT ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - +-+-+-+-+-+-+-+-+-+-+-+ + - | Public Key | - ~ ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + - | | - ~ Rendezvous Servers ~ - | | - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +-+-+-+-+-+-+-+ */ - - /* Space for HIT length, PK algorithm, PK length available? */ - if (*pos + 4 > end) { - return LDNS_STATUS_PACKET_OVERFLOW; - } - /* Get HIT length and PK length */ - hip_hit_length = wire[*pos]; - hip_pubkey_length = ldns_read_uint16(&wire[*pos + 2]); - - /* Space for HIT length, PK algorithm, PK length, HIT and - * Public Key available? - */ - if (*pos + 4 + hip_hit_length + hip_pubkey_length > end) { - return LDNS_STATUS_PACKET_OVERFLOW; - } - /* Read PK algorithm rdf */ - cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, - 1, &wire[*pos + 1]); - if (cur_rdf) { - ldns_rr_push_rdf(rr, cur_rdf); - } - *pos += 4; - - /* Read HIT rdf */ - cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, - hip_hit_length, &wire[*pos]); - if (cur_rdf) { - ldns_rr_push_rdf(rr, cur_rdf); - } - *pos += hip_hit_length; - - /* Read Public Key rdf */ - cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, - hip_pubkey_length, &wire[*pos]); - if (cur_rdf) { - ldns_rr_push_rdf(rr, cur_rdf); - } - *pos += hip_pubkey_length; - - /* Variable number of Rendezvous Servers may follow */ - rdf_index = 3; - } else { - rdf_index = 0; - } + rdf_index = 0; while (*pos < end && rdf_index < ldns_rr_descriptor_maximum(descriptor)) { @@ -317,6 +244,14 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos) cur_rdf_length = (size_t) ldns_read_uint16(&wire[*pos]) + 2; break; + case LDNS_RDF_TYPE_HIP: + if (*pos + 4 > end) { + return LDNS_STATUS_PACKET_OVERFLOW; + } + cur_rdf_length = + (size_t) wire[*pos] + + (size_t) ldns_read_uint16(&wire[*pos + 2]) + 4; + break; case LDNS_RDF_TYPE_B32_EXT: case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: /* length is stored in first byte */