Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ target_include_directories(
target_sources(zone PRIVATE
src/zone.c
src/log.c
src/fallback/parser.c
src/generic/base64.c)
src/fallback/parser.c)

add_executable(zone-bench src/bench.c src/fallback/bench.c)
target_include_directories(
Expand Down
35 changes: 34 additions & 1 deletion src/fallback/base16.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static const uint8_t b16rmap[256] = {
// digits are impractical, but supported (BIND supports uneven
// sequences)
zone_nonnull_all
static zone_really_inline int32_t parse_base16(
static zone_really_inline int32_t parse_base16_sequence(
zone_parser_t *parser,
const zone_type_info_t *type,
const zone_field_info_t *field,
Expand Down Expand Up @@ -115,6 +115,39 @@ static zone_really_inline int32_t parse_base16(
return ZONE_BLOB;
}

zone_nonnull_all
static zone_really_inline int32_t parse_base16(
zone_parser_t *parser,
const zone_type_info_t *type,
const zone_field_info_t *field,
const token_t *token)
{
int32_t r;

if ((r = have_contiguous(parser, type, field, token)) < 0)
return r;

const char *p = token->data;
uint8_t x0 = 0x80, x1 = 0x80;
uint8_t *ws = &parser->rdata->octets[parser->rdata->length], *w = ws;
const uint8_t *we = &parser->rdata->octets[ZONE_RDATA_SIZE];

while (w < we) {
x0 = b16rmap[ (uint8_t)(p[0]) ];
x1 = b16rmap[ (uint8_t)(p[1]) ];
if ((x0 | x1) & 0x80)
break;
w[0] = (uint8_t)((x0 << 4) | x1);
w += 1; p += 2;
}

if (w - ws == 1 || w >= we || x0 != 0x80)
SYNTAX_ERROR(parser, "Invalid %s in %s record", NAME(field), TNAME(type));

parser->rdata->length += (size_t)(w - ws);
return 0;
}

zone_nonnull_all
static zone_really_inline int32_t parse_salt(
zone_parser_t *parser,
Expand Down
200 changes: 200 additions & 0 deletions src/fallback/base64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* base64.h -- naive base64 parser
*
* Copyright (c) 2022, NLnet Labs. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef BASE64_H
#define BASE64_H

static uint8_t b64rmap[256] = {
0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, /* 8 - 15 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 - 23 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 24 - 31 */
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 - 39 */
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* 40 - 47 */
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, /* 48 - 55 */
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, /* 56 - 63 */
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* 64 - 71 */
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /* 72 - 79 */
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /* 80 - 87 */
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 95 */
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* 96 - 103 */
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 104 - 111 */
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, /* 112 - 119 */
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, /* 120 - 127 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 - 135 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 136 - 143 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 144 - 151 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 152 - 159 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 160 - 167 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 168 - 175 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 176 - 183 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 184 - 191 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 192 - 199 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 200 - 207 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 208 - 215 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 216 - 223 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 224 - 231 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 232 - 239 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 240 - 247 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 248 - 255 */
};

static const uint8_t b64rmap_special = 0xf0;

zone_nonnull_all
static zone_really_inline int32_t parse_base64_sequence(
zone_parser_t *parser,
const zone_type_info_t *type,
const zone_field_info_t *field,
token_t *token)
{
int32_t r;
uint32_t state = 0;

if ((r = have_contiguous(parser, type, field, token)) < 0)
return r;

do {
const char *p = token->data;

for (;; p++) {
const uint8_t ofs = b64rmap[(uint8_t)*p];

if (ofs >= b64rmap_special)
break;

switch (state) {
case 0:
parser->rdata->octets[parser->rdata->length ] = (uint8_t)(ofs << 2);
state = 1;
break;
case 1:
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 4);
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x0f) << 4);
state = 2;
break;
case 2:
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 2);
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x03) << 6);
state = 3;
break;
case 3:
parser->rdata->octets[parser->rdata->length++] |= ofs;
parser->rdata->octets[parser->rdata->length ] = 0;
state = 0;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
}
}

if (*p == '=') {
switch (state) {
case 0: // invalid, pad character in first position
case 1: // invalid, pad character in second position
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
case 2: // valid, one byte of info
state = 4;
if (*p++ != '=')
break;
// fall through
case 3: // valid, two bytes of info
case 4:
state = 5;
p++;
break;
default:
break;
}
}

if (is_contiguous((uint8_t)*p))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
lex(parser, token);
} while (token->code == CONTIGUOUS);

if ((r = have_delimiter(parser, type, token)) < 0)
return r;
if (state != 0 && state != 5)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));

return ZONE_BLOB;
}

zone_nonnull_all
static zone_really_inline int32_t parse_base64(
zone_parser_t *parser,
const zone_type_info_t *type,
const zone_field_info_t *field,
const token_t *token)
{
int32_t r;
uint32_t state = 0;

if ((r = have_contiguous(parser, type, field, token)) < 0)
return r;

const char *p = token->data;
for (;; p++) {
const uint8_t ofs = b64rmap[(uint8_t)*p];

if (ofs >= b64rmap_special)
break;

switch (state) {
case 0:
parser->rdata->octets[parser->rdata->length ] = (uint8_t)(ofs << 2);
state = 1;
break;
case 1:
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 4);
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x0f) << 4);
state = 2;
break;
case 2:
parser->rdata->octets[parser->rdata->length++] |= (uint8_t)(ofs >> 2);
parser->rdata->octets[parser->rdata->length ] = (uint8_t)((ofs & 0x03) << 6);
state = 3;
break;
case 3:
parser->rdata->octets[parser->rdata->length++] |= ofs;
parser->rdata->octets[parser->rdata->length ] = 0;
state = 0;
break;
default:
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
}
}

if (*p == '=') {
switch (state) {
case 0: // invalid, pad character in first position
case 1: // invalid, pad character in second position
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));
case 2: // valid, one byte of info
state = 4;
if (*p++ != '=')
break;
// fall through
case 3: // valid, two bytes of info
case 4:
state = 5;
p++;
break;
default:
break;
}
}

if (is_contiguous((uint8_t)*p))
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), TNAME(type));

return 0;
}

#endif // BASE64_H
2 changes: 1 addition & 1 deletion src/fallback/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "generic/ip6.h"
#include "fallback/base16.h"
#include "fallback/base32.h"
#include "generic/base64.h"
#include "fallback/base64.h"
#include "generic/nsec.h"
#include "generic/nxt.h"
#include "generic/caa.h"
Expand Down
46 changes: 0 additions & 46 deletions src/generic/base64.c

This file was deleted.

Loading