1 /* 2 * caa.h -- CAA (RFC8659) parser 3 * 4 * Copyright (c) 2023, NLnet Labs. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 * 8 */ 9 #ifndef CAA_H 10 #define CAA_H 11 12 static const uint8_t bad_caa_chars[256] = { 13 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x00 - 0x07 14 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x08 - 0x0f 15 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x10 - 0x17 16 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x18 - 0x10f 17 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x20 - 0x27 18 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x28 - 0x2f 19 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 - 0x37 20 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x38 - 0x3f 21 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 - 0x47 22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4f 23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57 24 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x58 - 0x5f 25 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 - 0x67 26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6f 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77 28 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x78 - 0x7f 29 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x80 - 0x87 30 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x88 - 0x8f 31 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x90 - 0x97 32 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0x98 - 0x9f 33 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xa0 - 0xa7 34 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xa8 - 0xaf 35 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xb0 - 0xb7 36 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xb8 - 0xbf 37 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xc0 - 0xc7 38 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xc8 - 0xcf 39 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xd0 - 0xd7 40 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xd8 - 0xdf 41 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xe0 - 0xe7 42 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xe0 - 0xe7 43 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xf8 - 0xff 44 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xf8 - 0xff 45 }; 46 47 nonnull_all 48 static really_inline int32_t parse_caa_tag( 49 parser_t *parser, 50 const type_info_t *type, 51 const rdata_info_t *field, 52 rdata_t *rdata, 53 const token_t *token) 54 { 55 // RFC8659 section 4.1 56 // https://datatracker.ietf.org/doc/html/rfc8659 57 // 58 // Certification Authority Restriction Properties registered by IANA 59 // https://www.iana.org/assignments/pkix-parameters/pkix-parameters.xhtml 60 61 if (token->length > 255) 62 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 63 *rdata->octets++ = (uint8_t)token->length; 64 65 uint32_t bad_chars = 0; 66 for (size_t count=0; count < token->length; count++) { 67 const uint8_t octet = (uint8_t)token->data[count]; 68 *rdata->octets++ = octet; 69 bad_chars |= bad_caa_chars[octet]; 70 } 71 72 // Tags MAY contain ASCII characters "a" through "z", "A" through "Z", 73 // and the numbers 0 through 9. Tags MUST NOT contain any other 74 // characters. Matching of tags is case insensitive. 75 if (bad_chars) 76 SEMANTIC_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); 77 78 return 0; 79 } 80 81 #endif // CAA_H 82