- sldns has type HIP.

git-svn-id: file:///svn/unbound/trunk@3071 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2014-02-06 10:57:42 +00:00
parent 4095ee4622
commit 51be201ada
8 changed files with 211 additions and 86 deletions

View file

@ -1,3 +1,6 @@
6 February 2014: Wouter
- sldns has type HIP.
5 February 2014: Wouter
- Fix sldns parse tests on osx.

View file

@ -188,37 +188,9 @@ static const sldns_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 sldns_rdf_type type_hip_hostformat[] = {
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_HEX,
LDNS_RDF_TYPE_B64
static const sldns_rdf_type type_hip_wireformat[] = {
LDNS_RDF_TYPE_HIP
};
static const sldns_rdf_type type_nid_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_ILNP64
@ -368,17 +340,12 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 55
/* 55
* 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_NONE, 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 */

View file

@ -302,10 +302,13 @@ enum sldns_enum_rdf_type
LDNS_RDF_TYPE_PERIOD,
/** tsig time 48 bits */
LDNS_RDF_TYPE_TSIGTIME,
/** skip 21 unused */
/** Represents the Public Key Algorithm, HIT and Public Key fields
for the HIP RR types. A HIP specific rdf type is used because of
the unusual layout in wireformat (see RFC 5205 Section 5) */
LDNS_RDF_TYPE_HIP,
/** variable length any type rdata where the length
is specified by the first 2 bytes */
LDNS_RDF_TYPE_INT16_DATA = 22,
LDNS_RDF_TYPE_INT16_DATA,
/** protocol and port bitmaps */
LDNS_RDF_TYPE_SERVICE,
/** location data */

View file

@ -525,6 +525,67 @@ rrinternal_parse_rdf(sldns_buffer* strbuf, char* token, size_t token_len,
return LDNS_WIREPARSE_ERR_OK;
}
/**
* Parse one rdf token. Takes care of quotes and parenthesis.
*/
static int
sldns_parse_rdf_token(sldns_buffer* strbuf, char* token, size_t token_len,
int* quoted, int* parens, int* tokquote, size_t* pre_data_pos,
const char* delimiters, sldns_rdf_type rdftype, size_t* token_strlen)
{
size_t slen;
/* skip spaces */
while(sldns_buffer_remaining(strbuf) > 0 && !*quoted &&
*(sldns_buffer_current(strbuf)) == ' ') {
sldns_buffer_skip(strbuf, 1);
}
*pre_data_pos = sldns_buffer_position(strbuf);
if(sldns_bget_token_par(strbuf, token, (*quoted)?"\"":delimiters,
token_len, parens, (*quoted)?NULL:" \t") == -1) {
return 0;
}
slen = strlen(token);
/* check if not quoted yet, and we have encountered quotes */
if(!*quoted && sldns_rdf_type_maybe_quoted(rdftype) &&
slen >= 2 &&
(token[0] == '"' || token[0] == '\'') &&
(token[slen-1] == '"' || token[slen-1] == '\'')) {
/* move token two smaller (quotes) with endnull */
memmove(token, token+1, slen-2);
token[slen-2] = 0;
slen -= 2;
*quoted = 1;
*tokquote = 1; /* do not read endquotechar from buffer */
} else if(!*quoted && sldns_rdf_type_maybe_quoted(rdftype) &&
slen >= 2 &&
(token[0] == '"' || token[0] == '\'')) {
/* got the start quote (remove it) but read remainder
* of quoted string as well into remainder of token */
memmove(token, token+1, slen-1);
token[slen-1] = 0;
slen -= 1;
*quoted = 1;
*tokquote = 0;
/* rewind buffer over skipped whitespace */
while(sldns_buffer_position(strbuf) > 0 &&
(sldns_buffer_current(strbuf)[-1] == ' ' ||
sldns_buffer_current(strbuf)[-1] == '\t')) {
sldns_buffer_skip(strbuf, -1);
}
if(sldns_bget_token_par(strbuf, token+slen,
"\"", token_len-slen,
parens, NULL) == -1) {
return 0;
}
slen = strlen(token);
} else *tokquote = 0;
*token_strlen = slen;
return 1;
}
/** parse rdata from string into rr buffer(-remainder after dname). */
static int
rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
@ -553,52 +614,10 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
delimiters = rrinternal_get_delims(rdftype, r_cnt, r_max);
quoted = rrinternal_get_quoted(strbuf, &delimiters, rdftype);
/* skip spaces */
while(sldns_buffer_remaining(strbuf) > 0 && !quoted &&
*(sldns_buffer_current(strbuf)) == ' ') {
sldns_buffer_skip(strbuf, 1);
}
pre_data_pos = sldns_buffer_position(strbuf);
if(sldns_bget_token_par(strbuf, token, quoted?"\"":delimiters,
token_len, &parens, quoted?NULL:" \t") == -1) {
if(!sldns_parse_rdf_token(strbuf, token, token_len, &quoted,
&parens, &tokquote, &pre_data_pos, delimiters, rdftype,
&token_strlen))
break;
}
token_strlen = strlen(token);
/* check if not quoted yet, and we have encountered quotes */
if(!quoted && sldns_rdf_type_maybe_quoted(rdftype) &&
token_strlen >= 2 &&
(token[0] == '"' || token[0] == '\'') &&
(token[token_strlen-1] == '"' || token[token_strlen-1] == '\'')) {
/* move token two smaller (quotes) with endnull */
memmove(token, token+1, token_strlen-2);
token[token_strlen-2] = 0;
token_strlen -= 2;
quoted = 1;
tokquote = 1; /* do not read endquotechar from buffer */
} else if(!quoted && sldns_rdf_type_maybe_quoted(rdftype) &&
token_strlen >= 2 &&
(token[0] == '"' || token[0] == '\'')) {
/* got the start quote (remove it) but read remainder
* of quoted string as well into remainder of token */
memmove(token, token+1, token_strlen-1);
token[token_strlen-1] = 0;
token_strlen -= 1;
quoted = 1;
tokquote = 0;
/* rewind buffer over skipped whitespace */
while(sldns_buffer_position(strbuf) > 0 &&
(sldns_buffer_current(strbuf)[-1] == ' ' ||
sldns_buffer_current(strbuf)[-1] == '\t')) {
sldns_buffer_skip(strbuf, -1);
}
if(sldns_bget_token_par(strbuf, token+token_strlen,
"\"", token_len-token_strlen,
&parens, NULL) == -1) {
break;
}
token_strlen = strlen(token);
} else tokquote = 0;
/* rfc3597 specifies that any type can be represented
* with \# method, which can contain spaces...
@ -613,6 +632,38 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
pre_data_pos)) != 0)
return status;
} else if(token_strlen > 0 || quoted) {
if(rdftype == LDNS_RDF_TYPE_HIP) {
/* affix the HIT and PK fields, with a space */
size_t addlen = token_len - token_strlen;
size_t addstrlen = 0;
/* add space */
if(addlen < 1) break;
token[token_strlen] = ' ';
token[++token_strlen] = 0;
/* read another token */
addlen = token_len - token_strlen;
if(!sldns_parse_rdf_token(strbuf,
token+token_strlen, addlen, &quoted,
&parens, &tokquote, &pre_data_pos,
delimiters, rdftype, &addstrlen))
break;
token_strlen += addstrlen;
/* add space */
addlen = token_len - token_strlen;
if(addlen < 1) break;
token[token_strlen] = ' ';
token[++token_strlen] = 0;
/* read another token */
addlen = token_len - token_strlen;
addstrlen = 0;
if(!sldns_parse_rdf_token(strbuf,
token+token_strlen, addlen, &quoted,
&parens, &tokquote, &pre_data_pos,
delimiters, rdftype, &addstrlen))
break;
token_strlen += addstrlen;
}
/* normal RR */
if((status=rrinternal_parse_rdf(strbuf, token,
token_len, rr, *rr_len, &rr_cur_len, rdftype,
@ -907,6 +958,8 @@ int sldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
return sldns_str2wire_tag_buf(str, rd, len);
case LDNS_RDF_TYPE_LONG_STR:
return sldns_str2wire_long_str_buf(str, rd, len);
case LDNS_RDF_TYPE_HIP:
return sldns_str2wire_hip_buf(str, rd, len);
case LDNS_RDF_TYPE_INT16_DATA:
return sldns_str2wire_int16_data_buf(str, rd, len);
case LDNS_RDF_TYPE_UNKNOWN:
@ -1863,6 +1916,56 @@ int sldns_str2wire_long_str_buf(const char* str, uint8_t* rd, size_t* len)
return LDNS_WIREPARSE_ERR_OK;
}
int sldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len)
{
char* s, *end;
int e;
size_t hitlen, pklen = 0;
/* presentation format:
* pk-algo HIThex pubkeybase64
* wireformat:
* hitlen[1byte] pkalgo[1byte] pubkeylen[2byte] [hit] [pubkey] */
if(*len < 4)
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
/* read PK algorithm */
rd[1] = (uint8_t)strtol((char*)str, &s, 10);
if(*s != ' ')
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_INT, s-(char*)str);
s++;
while(*s == ' ')
s++;
/* read HIT hex tag */
/* zero terminate the tag (replace later) */
end = strchr(s, ' ');
if(!end) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX, s-(char*)str);
*end = 0;
hitlen = *len - 4;
if((e = sldns_str2wire_hex_buf(s, rd+4, &hitlen)) != 0) {
*end = ' ';
return RET_ERR_SHIFT(e, s-(char*)str);
}
if(hitlen > 255) {
*end = ' ';
return RET_ERR(LDNS_WIREPARSE_ERR_LABEL_OVERFLOW, s-(char*)str+255*2);
}
rd[0] = (uint8_t)hitlen;
*end = ' ';
s = end+1;
/* read pubkey base64 sequence */
pklen = *len - 4 - hitlen;
if((e = sldns_str2wire_b64_buf(s, rd+4+hitlen, &pklen)) != 0)
return RET_ERR_SHIFT(e, s-(char*)str);
if(pklen > 65535)
return RET_ERR(LDNS_WIREPARSE_ERR_LABEL_OVERFLOW, s-(char*)str+65535);
sldns_write_uint16(rd+2, pklen);
*len = 4 + hitlen + pklen;
return LDNS_WIREPARSE_ERR_OK;
}
int sldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len)
{
size_t sz = sldns_b64_pton_calculate_size(strlen(str));

View file

@ -516,6 +516,15 @@ int sldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len);
*/
int sldns_str2wire_long_str_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_HIP from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int sldns_str2wire_hip_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_INT16_DATA from string to wireformat.
* @param str: the text to convert for this rdata element.

View file

@ -946,6 +946,8 @@ int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
case LDNS_RDF_TYPE_IPSECKEY:
return sldns_wire2str_ipseckey_scan(d, dlen, s, slen, pkt,
pktlen);
case LDNS_RDF_TYPE_HIP:
return sldns_wire2str_hip_scan(d, dlen, s, slen);
case LDNS_RDF_TYPE_INT16_DATA:
return sldns_wire2str_int16_data_scan(d, dlen, s, slen);
case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
@ -1531,6 +1533,31 @@ int sldns_wire2str_ipseckey_scan(uint8_t** d, size_t* dl, char** s, size_t* sl,
return w;
}
int sldns_wire2str_hip_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
{
int w;
uint8_t algo, hitlen;
uint16_t pklen;
/* read lengths */
if(*dl < 4)
return -1;
hitlen = (*d)[0];
algo = (*d)[1];
pklen = sldns_read_uint16((*d)+2);
if(*dl < (size_t)4 + (size_t)hitlen + (size_t)pklen)
return -1;
/* write: algo hit pubkey */
w = sldns_str_print(s, sl, "%u ", (unsigned)algo);
w += print_hex_buf(s, sl, (*d)+4, hitlen);
w += sldns_str_print(s, sl, " ");
(*d)+=4+hitlen;
(*dl)-= (4+hitlen);
w += sldns_wire2str_b64_scan_num(d, dl, s, sl, pklen);
return w;
}
int sldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
{
uint16_t n;

View file

@ -770,6 +770,19 @@ int sldns_wire2str_atma_scan(uint8_t** data, size_t* data_len, char** str,
int sldns_wire2str_ipseckey_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat HIP (algo, HIT, pubkey) field to string, with user buffers.
* It shifts the arguments to move along (see sldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int sldns_wire2str_hip_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat int16_data field to string, with user buffers.
* It shifts the arguments to move along (see sldns_wire2str_pkt_scan).

View file

@ -70,8 +70,8 @@ all.rr.org. 3600 IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=
ee19kl3631qol646kjjrh6lh96pduqii.all.rr.org. 3600 IN NSEC3 1 0 5 6467B16F6F36BA4D 13k9b8dv58kcn28us3fc0lqa60jeadp0 A RRSIG
03616C6C027272036F7267000033000100000E10000D01000005086467B16F6F36BA4D
all.rr.org. 3600 IN NSEC3PARAM 1 0 5 6467B16F6F36BA4D
03616C6C027272036F7267000037000100000E10009E02200100107B1A74DF365639CC39F1D57803010001B771CA136E4AEB5CE44333C53B3D2C13C22243851FC708BCCE29F7E2EB5787B5F56CCAD34F8223ACC10904DDB56B2EC4A6D6232F3B50EA094F0914B3B941BBE529AF582C36BBADEFDAF2ADAF9B4911906F5B2522603C615272B880EC8FB930CC6EE39C444DAA75B1678F005A4B2499D1DA5433F805C7A5AD3237ACC5DD5C5E43AEFB1EC5A9A995E728
all.rr.org. 3600 IN HIP \# 158 02200100107B1A74DF365639CC39F1D57803010001B771CA136E4AEB5CE44333C53B3D2C13C22243851FC708BCCE29F7E2EB5787B5F56CCAD34F8223ACC10904DDB56B2EC4A6D6232F3B50EA094F0914B3B941BBE529AF582C36BBADEFDAF2ADAF9B4911906F5B2522603C615272B880EC8FB930CC6EE39C444DAA75B1678F005A4B2499D1DA5433F805C7A5AD3237ACC5DD5C5E43AEFB1EC5A9A995E728
03616C6C027272036F7267000037000100000E1000A910020084200100107B1A74DF365639CC39F1D57803010001B771CA136E4AEB5CE44333C53B3D2C13C22243851FC708BCCE29F7E2EB5787B5F56CCAD34F8223ACC10904DDB56B2EC4A6D6232F3B50EA094F0914B3B941BBE529AF582C36BBADEFDAF2ADAF9B4911906F5B2522603C615272B880EC8FB930CC6EE39C444DAA75B1678F005A4B2499D1DA5433F805C7A5AD3237ACC5DD5C5E4303727673076578616D706C6503636F6D00
all.rr.org. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
03616C6C027272036F7267000063000100000E10002625763D73706631202B6D7820613A636F6C6F2E6578616D706C652E636F6D2F3238202D616C6C
all.rr.org. 3600 IN SPF "v=spf1 +mx a:colo.example.com/28 -all"
03616C6C027272036F7267008001000100000E10001830390301123456789ABCDEF67890123456789ABCDEF67890