Skip to content

Commit e4de776

Browse files
committed
Add support for HIP RR
1 parent 7e2576e commit e4de776

File tree

10 files changed

+356
-168
lines changed

10 files changed

+356
-168
lines changed

CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ target_include_directories(
136136
target_sources(zone PRIVATE
137137
src/zone.c
138138
src/log.c
139-
src/fallback/parser.c
140-
src/generic/base64.c)
139+
src/fallback/parser.c)
141140

142141
add_executable(zone-bench src/bench.c src/fallback/bench.c)
143142
target_include_directories(

src/fallback/base16.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static const uint8_t b16rmap[256] = {
6464
// digits are impractical, but supported (BIND supports uneven
6565
// sequences)
6666
zone_nonnull_all
67-
static zone_really_inline int32_t parse_base16(
67+
static zone_really_inline int32_t parse_base16_sequence(
6868
zone_parser_t *parser,
6969
const zone_type_info_t *type,
7070
const zone_field_info_t *field,
@@ -115,6 +115,39 @@ static zone_really_inline int32_t parse_base16(
115115
return ZONE_BLOB;
116116
}
117117

118+
zone_nonnull_all
119+
static zone_really_inline int32_t parse_base16(
120+
zone_parser_t *parser,
121+
const zone_type_info_t *type,
122+
const zone_field_info_t *field,
123+
const token_t *token)
124+
{
125+
int32_t r;
126+
127+
if ((r = have_contiguous(parser, type, field, token)) < 0)
128+
return r;
129+
130+
const char *p = token->data;
131+
uint8_t x0 = 0x80, x1 = 0x80;
132+
uint8_t *ws = &parser->rdata->octets[parser->rdata->length], *w = ws;
133+
const uint8_t *we = &parser->rdata->octets[ZONE_RDATA_SIZE];
134+
135+
while (w < we) {
136+
x0 = b16rmap[ (uint8_t)(p[0]) ];
137+
x1 = b16rmap[ (uint8_t)(p[1]) ];
138+
if ((x0 | x1) & 0x80)
139+
break;
140+
w[0] = (uint8_t)((x0 << 4) | x1);
141+
w += 1; p += 2;
142+
}
143+
144+
if (w - ws == 1 || w >= we || x0 != 0x80)
145+
SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type));
146+
147+
parser->rdata->length += (size_t)(w - ws);
148+
return 0;
149+
}
150+
118151
zone_nonnull_all
119152
static zone_really_inline int32_t parse_salt(
120153
zone_parser_t *parser,

src/fallback/base64.h

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/*
2+
* base64.h -- naive base64 parser
3+
*
4+
* Copyright (c) 2022, NLnet Labs. All rights reserved.
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*
8+
*/
9+
#ifndef BASE64_H
10+
#define BASE64_H
11+
12+
static uint8_t b64rmap[256] = {
13+
0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
14+
0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, /* 8 - 15 */
15+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 - 23 */
16+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 24 - 31 */
17+
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 - 39 */
18+
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* 40 - 47 */
19+
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, /* 48 - 55 */
20+
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, /* 56 - 63 */
21+
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* 64 - 71 */
22+
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /* 72 - 79 */
23+
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /* 80 - 87 */
24+
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 95 */
25+
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* 96 - 103 */
26+
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 104 - 111 */
27+
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, /* 112 - 119 */
28+
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, /* 120 - 127 */
29+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 - 135 */
30+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 136 - 143 */
31+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 144 - 151 */
32+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 152 - 159 */
33+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 160 - 167 */
34+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 168 - 175 */
35+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 176 - 183 */
36+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 184 - 191 */
37+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 192 - 199 */
38+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 200 - 207 */
39+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 208 - 215 */
40+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 216 - 223 */
41+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 224 - 231 */
42+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 232 - 239 */
43+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 240 - 247 */
44+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 248 - 255 */
45+
};
46+
47+
static const uint8_t b64rmap_special = 0xf0;
48+
49+
zone_nonnull_all
50+
static zone_really_inline int32_t parse_base64_sequence(
51+
zone_parser_t *parser,
52+
const zone_type_info_t *type,
53+
const zone_field_info_t *field,
54+
token_t *token)
55+
{
56+
int32_t r;
57+
uint32_t state = 0;
58+
59+
if ((r = have_contiguous(parser, type, field, token)) < 0)
60+
return r;
61+
62+
do {
63+
const char *p = token->data;
64+
65+
for (;; p++) {
66+
const uint8_t ofs = b64rmap[(uint8_t)*p];
67+
68+
if (ofs >= b64rmap_special)
69+
break;
70+
71+
switch (state) {
72+
case 0:
73+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)(ofs << 2);
74+
state = 1;
75+
break;
76+
case 1:
77+
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 4);
78+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x0f) << 4);
79+
state = 2;
80+
break;
81+
case 2:
82+
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 2);
83+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x03) << 6);
84+
state = 3;
85+
break;
86+
case 3:
87+
parser->rdata->octets[parser->rdata->length++] |= ofs;
88+
parser->rdata->octets[parser->rdata->length ] = 0;
89+
state = 0;
90+
break;
91+
default:
92+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
93+
}
94+
}
95+
96+
if (*p == '=') {
97+
switch (state) {
98+
case 0: // invalid, pad character in first position
99+
case 1: // invalid, pad character in second position
100+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
101+
case 2: // valid, one byte of info
102+
state = 4;
103+
if (*p++ != '=')
104+
break;
105+
// fall through
106+
case 3: // valid, two bytes of info
107+
case 4:
108+
state = 5;
109+
p++;
110+
break;
111+
default:
112+
break;
113+
}
114+
}
115+
116+
if (is_contiguous((uint8_t)*p))
117+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
118+
lex(parser, token);
119+
} while (token->code == CONTIGUOUS);
120+
121+
if ((r = have_delimiter(parser, type, token)) < 0)
122+
return r;
123+
if (state != 0 && state != 5)
124+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
125+
126+
return ZONE_BLOB;
127+
}
128+
129+
zone_nonnull_all
130+
static zone_really_inline int32_t parse_base64(
131+
zone_parser_t *parser,
132+
const zone_type_info_t *type,
133+
const zone_field_info_t *field,
134+
const token_t *token)
135+
{
136+
int32_t r;
137+
uint32_t state = 0;
138+
139+
if ((r = have_contiguous(parser, type, field, token)) < 0)
140+
return r;
141+
142+
const char *p = token->data;
143+
for (;; p++) {
144+
const uint8_t ofs = b64rmap[(uint8_t)*p];
145+
146+
if (ofs >= b64rmap_special)
147+
break;
148+
149+
switch (state) {
150+
case 0:
151+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)(ofs << 2);
152+
state = 1;
153+
break;
154+
case 1:
155+
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 4);
156+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x0f) << 4);
157+
state = 2;
158+
break;
159+
case 2:
160+
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 2);
161+
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x03) << 6);
162+
state = 3;
163+
break;
164+
case 3:
165+
parser->rdata->octets[parser->rdata->length++] |= ofs;
166+
parser->rdata->octets[parser->rdata->length ] = 0;
167+
state = 0;
168+
break;
169+
default:
170+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
171+
}
172+
}
173+
174+
if (*p == '=') {
175+
switch (state) {
176+
case 0: // invalid, pad character in first position
177+
case 1: // invalid, pad character in second position
178+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
179+
case 2: // valid, one byte of info
180+
state = 4;
181+
if (*p++ != '=')
182+
break;
183+
// fall through
184+
case 3: // valid, two bytes of info
185+
case 4:
186+
state = 5;
187+
p++;
188+
break;
189+
default:
190+
break;
191+
}
192+
}
193+
194+
if (is_contiguous((uint8_t)*p))
195+
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
196+
197+
return 0;
198+
}
199+
200+
#endif // BASE64_H

src/fallback/parser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "generic/ip6.h"
2323
#include "fallback/base16.h"
2424
#include "fallback/base32.h"
25-
#include "generic/base64.h"
25+
#include "fallback/base64.h"
2626
#include "generic/nsec.h"
2727
#include "generic/nxt.h"
2828
#include "generic/caa.h"

src/generic/base64.c

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)