1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file
*
* \addtogroup nsec
*
* \brief NSEC bitmap and NSEC3 hash computation API.
*
* The module provides interface for computation of NSEC3 hashes and for
* construction of bit maps used in NSEC and NSEC3 records.
*
* Example of NSEC3 hash computation:
*
* ~~~~~ {.c}
*
* int result;
*
* // NSEC3 parameters for hashing
* nssec_nsec3_params_t params = {
* .algorithm = DNSSEC_NSEC3_ALGORITHM_SHA1,
* .flags = 0,
* .iterations = 10,
* .salt = {
* .size = 4,
* .data = (uint8_t *){ 0xc0, 0x1d, 0xca, 0xfe }
* }
* };
*
* // domain name (in wire format)
* uint8_t *dname = "\0x08""knot-dns""\0x02""cz";
*
* // resulting hash
* dnssec_binary_t hash = { 0 };
*
* result = dnssec_nsec3_hash(&dname, ¶ms, &hash);
* if (result != DNSSEC_EOK) {
* return result;
* }
*
* assert(hash.size == 20);
* // hash.data contains binary data, which encoded in Base32 would be:
* // 7PTVGE7QV67EM61ROS9238P5RAKR2DM7
*
* dnssec_binary_free(&hash);
*
* ~~~~~
*
* Example of NSEC/NSEC3 bitmap construction.
*
* ~~~~~ {.c}
*
* int result;
* dnssec_nsec_bitmap_t *ctx;
* dnssec_binary_t bitmap;
*
* // create encoding context
* ctx = dnssec_nsec_bitmap_new();
* if (ctx == NULL) {
* return KNOT_ENOMEM;
* }
*
* // add resource records into the bitmap
* dnssec_nsec_bitmap_add(ctx, 1); // A RR type
* dnssec_nsec_bitmap_add(ctx, 28); // AAAA RR type
*
* // allocate space for the encoded bitmap
* size_t size = dnssec_nsec_bitmap_size(ctx);
* result = dnssec_binary_alloc(&bitmap, size);
* if (result != DNSSEC_EOK) {
* dnssec_nsec_bitmap_free(ctx);
* return result;
* }
*
* // write the encoded bitmap and free the context
* dnssec_nsec_bitmap_write(ctx, &bitmap);
* dnssec_nsec_bitmap_free(ctx);
*
* // use the bitmap ...
*
* dnssec_binary_free(&bitmap);
* ~~~~~
*
* @{
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <libdnssec/binary.h>
/*!
* DNSSEC NSEC3 algorithm numbers.
*/
typedef enum dnssec_nsec_algorithm {
DNSSEC_NSEC3_ALGORITHM_UNKNOWN = 0,
DNSSEC_NSEC3_ALGORITHM_SHA1 = 1,
} dnssec_nsec3_algorithm_t;
/*!
* DNSSEC NSEC3 parameters.
*/
typedef struct dnssec_nsec3_params {
dnssec_nsec3_algorithm_t algorithm; /*!< NSEC3 algorithm. */
uint8_t flags; /*!< NSEC3 flags. */
uint16_t iterations; /*!< NSEC3 iterations count. */
dnssec_binary_t salt; /*!< NSEC3 salt. */
} dnssec_nsec3_params_t;
/*!
* Free NSEC3 parameters.
*/
void dnssec_nsec3_params_free(dnssec_nsec3_params_t *params);
/*!
* Parse NSEC3 parameters from NSEC3PARAM RDATA.
*
* \param params Output parameters.
* \param rdata NSEC3PARAM RDATA.
*
* \return Error code, DNSSEC_EOK if successful.
*/
int dnssec_nsec3_params_from_rdata(dnssec_nsec3_params_t *params,
const dnssec_binary_t *rdata);
/*!
* Check whether a given NSEC bitmap contains a given RR type.
*
* \param bitmap Bitmap of an NSEC record.
* \param size Size of the bitmap.
* \param type RR type to check for.
*
* \return true if bitmap contains type, false otherwise.
*/
bool dnssec_nsec_bitmap_contains(const uint8_t *bitmap, uint16_t size, uint16_t type);
/*!
* Compute NSEC3 hash for given data.
*
* \todo Input data must be converted to lowercase!
*
* \param[in] data Data to be hashed (usually domain name).
* \param[in] params NSEC3 parameters.
* \param[out] hash Computed hash (will be allocated or resized).
*
* \return Error code, DNSSEC_EOK if successful.
*/
int dnssec_nsec3_hash(const dnssec_binary_t *data,
const dnssec_nsec3_params_t *params,
dnssec_binary_t *hash);
/*!
* Get length of raw NSEC3 hash for a given algorithm.
*
* \param algorithm NSEC3 algorithm number.
*
* \return Length of raw NSEC3 hash, zero on error.
*/
size_t dnssec_nsec3_hash_length(dnssec_nsec3_algorithm_t algorithm);
struct dnssec_nsec_bitmap;
/*!
* Context for encoding of RR types bitmap used in NSEC/NSEC3.
*/
typedef struct dnssec_nsec_bitmap dnssec_nsec_bitmap_t;
/*!
* Allocate new bit map encoding context.
*/
dnssec_nsec_bitmap_t *dnssec_nsec_bitmap_new(void);
/*!
* Clear existing bit map encoding context.
*/
void dnssec_nsec_bitmap_clear(dnssec_nsec_bitmap_t *bitmap);
/*!
* Free bit map encoding context.
*/
void dnssec_nsec_bitmap_free(dnssec_nsec_bitmap_t *bitmap);
/*!
* Add one RR type into the bitmap.
*/
void dnssec_nsec_bitmap_add(dnssec_nsec_bitmap_t *bitmap, uint16_t type);
/*!
* Compute the size of the encoded bitmap.
*/
size_t dnssec_nsec_bitmap_size(const dnssec_nsec_bitmap_t *bitmap);
/*!
* Write encoded bitmap into the given buffer.
*/
void dnssec_nsec_bitmap_write(const dnssec_nsec_bitmap_t *bitmap, uint8_t *output);
/*! @} */
|