/src/bind9/lib/dns/rdata/generic/rrsig_46.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) Internet Systems Consortium, Inc. ("ISC") |
3 | | * |
4 | | * SPDX-License-Identifier: MPL-2.0 |
5 | | * |
6 | | * This Source Code Form is subject to the terms of the Mozilla Public |
7 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 | | * file, you can obtain one at https://mozilla.org/MPL/2.0/. |
9 | | * |
10 | | * See the COPYRIGHT file distributed with this work for additional |
11 | | * information regarding copyright ownership. |
12 | | */ |
13 | | |
14 | | /* RFC2535 */ |
15 | | |
16 | | #ifndef RDATA_GENERIC_RRSIG_46_C |
17 | | #define RDATA_GENERIC_RRSIG_46_C |
18 | | |
19 | | #define RRTYPE_RRSIG_ATTRIBUTES \ |
20 | 70.7k | (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH | \ |
21 | 70.7k | DNS_RDATATYPEATTR_ATCNAME) |
22 | | |
23 | | static isc_result_t |
24 | 26.6k | fromtext_rrsig(ARGS_FROMTEXT) { |
25 | 26.6k | isc_token_t token; |
26 | 26.6k | unsigned char alg, c; |
27 | 26.6k | long i; |
28 | 26.6k | dns_rdatatype_t covered; |
29 | 26.6k | char *e; |
30 | 26.6k | isc_result_t result; |
31 | 26.6k | isc_buffer_t buffer; |
32 | 26.6k | uint32_t time_signed, time_expire; |
33 | 26.6k | unsigned int used; |
34 | | |
35 | 26.6k | REQUIRE(type == dns_rdatatype_rrsig); |
36 | | |
37 | 26.6k | UNUSED(type); |
38 | 26.6k | UNUSED(rdclass); |
39 | 26.6k | UNUSED(callbacks); |
40 | | |
41 | | /* |
42 | | * Type covered. |
43 | | */ |
44 | 26.6k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, |
45 | 26.6k | false)); |
46 | 26.6k | result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); |
47 | 26.6k | if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { |
48 | 22.8k | i = strtol(DNS_AS_STR(token), &e, 10); |
49 | 22.8k | if (i < 0 || i > 65535) { |
50 | 254 | RETTOK(ISC_R_RANGE); |
51 | 254 | } |
52 | 22.6k | if (*e != 0) { |
53 | 91 | RETTOK(result); |
54 | 91 | } |
55 | 22.5k | covered = (dns_rdatatype_t)i; |
56 | 22.5k | } |
57 | 26.2k | RETERR(uint16_tobuffer(covered, target)); |
58 | | |
59 | | /* |
60 | | * Algorithm. |
61 | | */ |
62 | 26.2k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, |
63 | 26.2k | false)); |
64 | 26.2k | RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); |
65 | 26.0k | RETERR(mem_tobuffer(target, &alg, 1)); |
66 | | |
67 | | /* |
68 | | * Labels. |
69 | | */ |
70 | 26.0k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, |
71 | 26.0k | false)); |
72 | 25.9k | if (token.value.as_ulong > 0xffU) { |
73 | 46 | RETTOK(ISC_R_RANGE); |
74 | 46 | } |
75 | 25.9k | c = (unsigned char)token.value.as_ulong; |
76 | 25.9k | RETERR(mem_tobuffer(target, &c, 1)); |
77 | | |
78 | | /* |
79 | | * Original ttl. |
80 | | */ |
81 | 25.9k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, |
82 | 25.9k | false)); |
83 | 25.8k | RETERR(uint32_tobuffer(token.value.as_ulong, target)); |
84 | | |
85 | | /* |
86 | | * Signature expiration. |
87 | | */ |
88 | 25.8k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, |
89 | 25.8k | false)); |
90 | 25.8k | if (strlen(DNS_AS_STR(token)) <= 10U && *DNS_AS_STR(token) != '-' && |
91 | 25.4k | *DNS_AS_STR(token) != '+') |
92 | 25.4k | { |
93 | 25.4k | char *end; |
94 | 25.4k | unsigned long u; |
95 | 25.4k | uint64_t u64; |
96 | | |
97 | 25.4k | u64 = u = strtoul(DNS_AS_STR(token), &end, 10); |
98 | 25.4k | if (u == ULONG_MAX || *end != 0) { |
99 | 51 | RETTOK(DNS_R_SYNTAX); |
100 | 51 | } |
101 | 25.3k | if (u64 > 0xffffffffUL) { |
102 | 43 | RETTOK(ISC_R_RANGE); |
103 | 43 | } |
104 | 25.3k | time_expire = u; |
105 | 25.3k | } else { |
106 | 405 | RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); |
107 | 405 | } |
108 | 25.7k | RETERR(uint32_tobuffer(time_expire, target)); |
109 | | |
110 | | /* |
111 | | * Time signed. |
112 | | */ |
113 | 25.7k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, |
114 | 25.7k | false)); |
115 | 25.6k | if (strlen(DNS_AS_STR(token)) <= 10U && *DNS_AS_STR(token) != '-' && |
116 | 25.2k | *DNS_AS_STR(token) != '+') |
117 | 25.2k | { |
118 | 25.2k | char *end; |
119 | 25.2k | unsigned long u; |
120 | 25.2k | uint64_t u64; |
121 | | |
122 | 25.2k | u64 = u = strtoul(DNS_AS_STR(token), &end, 10); |
123 | 25.2k | if (u == ULONG_MAX || *end != 0) { |
124 | 31 | RETTOK(DNS_R_SYNTAX); |
125 | 31 | } |
126 | 25.2k | if (u64 > 0xffffffffUL) { |
127 | 62 | RETTOK(ISC_R_RANGE); |
128 | 62 | } |
129 | 25.1k | time_signed = u; |
130 | 25.1k | } else { |
131 | 410 | RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); |
132 | 410 | } |
133 | 25.5k | RETERR(uint32_tobuffer(time_signed, target)); |
134 | | |
135 | | /* |
136 | | * Key footprint. |
137 | | */ |
138 | 25.5k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, |
139 | 25.5k | false)); |
140 | 25.4k | RETERR(uint16_tobuffer(token.value.as_ulong, target)); |
141 | | |
142 | | /* |
143 | | * Signer. |
144 | | */ |
145 | 25.3k | RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, |
146 | 25.3k | false)); |
147 | 25.3k | buffer_fromregion(&buffer, &token.value.as_region); |
148 | 25.3k | if (origin == NULL) { |
149 | 21 | origin = dns_rootname; |
150 | 21 | } |
151 | 25.3k | RETTOK(dns_name_wirefromtext(&buffer, origin, options, target)); |
152 | | |
153 | | /* |
154 | | * Sig. |
155 | | */ |
156 | 25.3k | used = isc_buffer_usedlength(target); |
157 | | |
158 | 25.3k | RETERR(isc_base64_tobuffer(lexer, target, -2)); |
159 | | |
160 | 25.2k | if (alg == DNS_KEYALG_PRIVATEDNS || alg == DNS_KEYALG_PRIVATEOID) { |
161 | 11 | isc_buffer_t b; |
162 | | |
163 | | /* |
164 | | * Set up 'b' so that the signature data can be parsed. |
165 | | */ |
166 | 11 | b = *target; |
167 | 11 | b.active = b.used; |
168 | 11 | b.current = used; |
169 | | |
170 | 11 | RETERR(check_private(&b, alg)); |
171 | 3 | } |
172 | | |
173 | 25.2k | return ISC_R_SUCCESS; |
174 | 25.2k | } |
175 | | |
176 | | static isc_result_t |
177 | 5.11k | totext_rrsig(ARGS_TOTEXT) { |
178 | 5.11k | isc_region_t sr; |
179 | 5.11k | char buf[sizeof("4294967295")]; /* Also TYPE65000. */ |
180 | 5.11k | dns_rdatatype_t covered; |
181 | 5.11k | unsigned long ttl; |
182 | 5.11k | unsigned long when; |
183 | 5.11k | unsigned long exp; |
184 | 5.11k | unsigned long foot; |
185 | 5.11k | dns_name_t name; |
186 | | |
187 | 5.11k | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
188 | 5.11k | REQUIRE(rdata->length != 0); |
189 | | |
190 | 5.11k | dns_rdata_toregion(rdata, &sr); |
191 | | |
192 | | /* |
193 | | * Type covered. |
194 | | */ |
195 | 5.11k | covered = uint16_fromregion(&sr); |
196 | 5.11k | isc_region_consume(&sr, 2); |
197 | | /* |
198 | | * XXXAG We should have something like dns_rdatatype_isknown() |
199 | | * that does the right thing with type 0. |
200 | | */ |
201 | 5.11k | if (dns_rdatatype_isknown(covered) && covered != 0) { |
202 | 2.44k | RETERR(dns_rdatatype_totext(covered, target)); |
203 | 2.67k | } else { |
204 | 2.67k | snprintf(buf, sizeof(buf), "TYPE%u", covered); |
205 | 2.67k | RETERR(str_totext(buf, target)); |
206 | 2.67k | } |
207 | 5.11k | RETERR(str_totext(" ", target)); |
208 | | |
209 | | /* |
210 | | * Algorithm. |
211 | | */ |
212 | 5.11k | snprintf(buf, sizeof(buf), "%u", sr.base[0]); |
213 | 5.11k | isc_region_consume(&sr, 1); |
214 | 5.11k | RETERR(str_totext(buf, target)); |
215 | 5.11k | RETERR(str_totext(" ", target)); |
216 | | |
217 | | /* |
218 | | * Labels. |
219 | | */ |
220 | 5.11k | snprintf(buf, sizeof(buf), "%u", sr.base[0]); |
221 | 5.11k | isc_region_consume(&sr, 1); |
222 | 5.11k | RETERR(str_totext(buf, target)); |
223 | 5.11k | RETERR(str_totext(" ", target)); |
224 | | |
225 | | /* |
226 | | * Ttl. |
227 | | */ |
228 | 5.11k | ttl = uint32_fromregion(&sr); |
229 | 5.11k | isc_region_consume(&sr, 4); |
230 | 5.11k | snprintf(buf, sizeof(buf), "%lu", ttl); |
231 | 5.11k | RETERR(str_totext(buf, target)); |
232 | | |
233 | 5.11k | if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { |
234 | 72 | RETERR(str_totext(" (", target)); |
235 | 72 | } |
236 | 5.11k | RETERR(str_totext(tctx->linebreak, target)); |
237 | | |
238 | | /* |
239 | | * Sig exp. |
240 | | */ |
241 | 5.11k | exp = uint32_fromregion(&sr); |
242 | 5.11k | isc_region_consume(&sr, 4); |
243 | 5.11k | RETERR(dns_time32_totext(exp, target)); |
244 | 5.11k | RETERR(str_totext(" ", target)); |
245 | | |
246 | | /* |
247 | | * Time signed. |
248 | | */ |
249 | 5.11k | when = uint32_fromregion(&sr); |
250 | 5.11k | isc_region_consume(&sr, 4); |
251 | 5.11k | RETERR(dns_time32_totext(when, target)); |
252 | 5.11k | RETERR(str_totext(" ", target)); |
253 | | |
254 | | /* |
255 | | * Footprint. |
256 | | */ |
257 | 5.11k | foot = uint16_fromregion(&sr); |
258 | 5.11k | isc_region_consume(&sr, 2); |
259 | 5.11k | snprintf(buf, sizeof(buf), "%lu", foot); |
260 | 5.11k | RETERR(str_totext(buf, target)); |
261 | 5.11k | RETERR(str_totext(" ", target)); |
262 | | |
263 | | /* |
264 | | * Signer. |
265 | | */ |
266 | 5.11k | dns_name_init(&name); |
267 | 5.11k | dns_name_fromregion(&name, &sr); |
268 | 5.11k | isc_region_consume(&sr, name_length(&name)); |
269 | 5.11k | RETERR(dns_name_totext(&name, 0, target)); |
270 | | |
271 | | /* |
272 | | * Sig. |
273 | | */ |
274 | 5.11k | RETERR(str_totext(tctx->linebreak, target)); |
275 | 5.11k | if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { |
276 | 5.11k | if (tctx->width == 0) { /* No splitting */ |
277 | 0 | RETERR(isc_base64_totext(&sr, 60, "", target)); |
278 | 5.11k | } else { |
279 | 5.11k | RETERR(isc_base64_totext(&sr, tctx->width - 2, |
280 | 5.11k | tctx->linebreak, target)); |
281 | 5.11k | } |
282 | 5.11k | } else { |
283 | 0 | RETERR(str_totext("[omitted]", target)); |
284 | 0 | } |
285 | | |
286 | 5.11k | if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { |
287 | 72 | RETERR(str_totext(" )", target)); |
288 | 72 | } |
289 | | |
290 | 5.11k | return ISC_R_SUCCESS; |
291 | 5.11k | } |
292 | | |
293 | | static isc_result_t |
294 | 6.69k | fromwire_rrsig(ARGS_FROMWIRE) { |
295 | 6.69k | isc_region_t sr; |
296 | 6.69k | dns_name_t name; |
297 | 6.69k | unsigned char algorithm; |
298 | | |
299 | 6.69k | REQUIRE(type == dns_rdatatype_rrsig); |
300 | | |
301 | 6.69k | UNUSED(type); |
302 | 6.69k | UNUSED(rdclass); |
303 | | |
304 | 6.69k | dctx = dns_decompress_setpermitted(dctx, false); |
305 | | |
306 | 6.69k | isc_buffer_activeregion(source, &sr); |
307 | | /* |
308 | | * type covered: 2 |
309 | | * algorithm: 1 |
310 | | * labels: 1 |
311 | | * original ttl: 4 |
312 | | * signature expiration: 4 |
313 | | * time signed: 4 |
314 | | * key footprint: 2 |
315 | | */ |
316 | 6.69k | if (sr.length < 18) { |
317 | 12 | return ISC_R_UNEXPECTEDEND; |
318 | 12 | } |
319 | | |
320 | 6.68k | algorithm = sr.base[2]; |
321 | | |
322 | 6.68k | isc_buffer_forward(source, 18); |
323 | 6.68k | RETERR(mem_tobuffer(target, sr.base, 18)); |
324 | | |
325 | | /* |
326 | | * Signer. |
327 | | */ |
328 | 6.43k | dns_name_init(&name); |
329 | 6.43k | RETERR(dns_name_fromwire(&name, source, dctx, target)); |
330 | | |
331 | | /* |
332 | | * Sig. |
333 | | */ |
334 | 6.33k | isc_buffer_activeregion(source, &sr); |
335 | 6.33k | if (sr.length < 1) { |
336 | 9 | return DNS_R_FORMERR; |
337 | 9 | } |
338 | | |
339 | 6.33k | if (algorithm == DNS_KEYALG_PRIVATEDNS || |
340 | 5.78k | algorithm == DNS_KEYALG_PRIVATEOID) |
341 | 1.58k | { |
342 | 1.58k | isc_buffer_t b = *source; |
343 | 1.58k | RETERR(check_private(&b, algorithm)); |
344 | 1.56k | } |
345 | | |
346 | 6.30k | isc_buffer_forward(source, sr.length); |
347 | 6.30k | return mem_tobuffer(target, sr.base, sr.length); |
348 | 6.33k | } |
349 | | |
350 | | static isc_result_t |
351 | 2.51k | towire_rrsig(ARGS_TOWIRE) { |
352 | 2.51k | isc_region_t sr; |
353 | 2.51k | dns_name_t name; |
354 | | |
355 | 2.51k | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
356 | 2.51k | REQUIRE(rdata->length != 0); |
357 | | |
358 | 2.51k | dns_compress_setpermitted(cctx, false); |
359 | 2.51k | dns_rdata_toregion(rdata, &sr); |
360 | | /* |
361 | | * type covered: 2 |
362 | | * algorithm: 1 |
363 | | * labels: 1 |
364 | | * original ttl: 4 |
365 | | * signature expiration: 4 |
366 | | * time signed: 4 |
367 | | * key footprint: 2 |
368 | | */ |
369 | 2.51k | RETERR(mem_tobuffer(target, sr.base, 18)); |
370 | 2.51k | isc_region_consume(&sr, 18); |
371 | | |
372 | | /* |
373 | | * Signer. |
374 | | */ |
375 | 2.51k | dns_name_init(&name); |
376 | 2.51k | dns_name_fromregion(&name, &sr); |
377 | 2.51k | isc_region_consume(&sr, name_length(&name)); |
378 | 2.51k | RETERR(dns_name_towire(&name, cctx, target)); |
379 | | |
380 | | /* |
381 | | * Signature. |
382 | | */ |
383 | 2.51k | return mem_tobuffer(target, sr.base, sr.length); |
384 | 2.51k | } |
385 | | |
386 | | static int |
387 | 56.7k | compare_rrsig(ARGS_COMPARE) { |
388 | 56.7k | isc_region_t r1; |
389 | 56.7k | isc_region_t r2; |
390 | 56.7k | dns_name_t name1; |
391 | 56.7k | dns_name_t name2; |
392 | 56.7k | int order; |
393 | | |
394 | 56.7k | REQUIRE(rdata1->type == rdata2->type); |
395 | 56.7k | REQUIRE(rdata1->rdclass == rdata2->rdclass); |
396 | 56.7k | REQUIRE(rdata1->type == dns_rdatatype_rrsig); |
397 | 56.7k | REQUIRE(rdata1->length != 0); |
398 | 56.7k | REQUIRE(rdata2->length != 0); |
399 | | |
400 | 56.7k | dns_rdata_toregion(rdata1, &r1); |
401 | 56.7k | dns_rdata_toregion(rdata2, &r2); |
402 | | |
403 | 56.7k | INSIST(r1.length > 18); |
404 | 56.7k | INSIST(r2.length > 18); |
405 | 56.7k | r1.length = 18; |
406 | 56.7k | r2.length = 18; |
407 | 56.7k | order = isc_region_compare(&r1, &r2); |
408 | 56.7k | if (order != 0) { |
409 | 16.3k | return order; |
410 | 16.3k | } |
411 | | |
412 | 40.3k | dns_name_init(&name1); |
413 | 40.3k | dns_name_init(&name2); |
414 | 40.3k | dns_rdata_toregion(rdata1, &r1); |
415 | 40.3k | dns_rdata_toregion(rdata2, &r2); |
416 | 40.3k | isc_region_consume(&r1, 18); |
417 | 40.3k | isc_region_consume(&r2, 18); |
418 | 40.3k | dns_name_fromregion(&name1, &r1); |
419 | 40.3k | dns_name_fromregion(&name2, &r2); |
420 | 40.3k | order = dns_name_rdatacompare(&name1, &name2); |
421 | 40.3k | if (order != 0) { |
422 | 6.39k | return order; |
423 | 6.39k | } |
424 | | |
425 | 33.9k | isc_region_consume(&r1, name_length(&name1)); |
426 | 33.9k | isc_region_consume(&r2, name_length(&name2)); |
427 | | |
428 | 33.9k | return isc_region_compare(&r1, &r2); |
429 | 40.3k | } |
430 | | |
431 | | static isc_result_t |
432 | 0 | fromstruct_rrsig(ARGS_FROMSTRUCT) { |
433 | 0 | dns_rdata_rrsig_t *sig = source; |
434 | |
|
435 | 0 | REQUIRE(type == dns_rdatatype_rrsig); |
436 | 0 | REQUIRE(sig != NULL); |
437 | 0 | REQUIRE(sig->common.rdtype == type); |
438 | 0 | REQUIRE(sig->common.rdclass == rdclass); |
439 | 0 | REQUIRE(sig->signature != NULL || sig->siglen == 0); |
440 | |
|
441 | 0 | UNUSED(type); |
442 | 0 | UNUSED(rdclass); |
443 | | |
444 | | /* |
445 | | * Type covered. |
446 | | */ |
447 | 0 | RETERR(uint16_tobuffer(sig->covered, target)); |
448 | | |
449 | | /* |
450 | | * Algorithm. |
451 | | */ |
452 | 0 | RETERR(uint8_tobuffer(sig->algorithm, target)); |
453 | | |
454 | | /* |
455 | | * Labels. |
456 | | */ |
457 | 0 | RETERR(uint8_tobuffer(sig->labels, target)); |
458 | | |
459 | | /* |
460 | | * Original TTL. |
461 | | */ |
462 | 0 | RETERR(uint32_tobuffer(sig->originalttl, target)); |
463 | | |
464 | | /* |
465 | | * Expire time. |
466 | | */ |
467 | 0 | RETERR(uint32_tobuffer(sig->timeexpire, target)); |
468 | | |
469 | | /* |
470 | | * Time signed. |
471 | | */ |
472 | 0 | RETERR(uint32_tobuffer(sig->timesigned, target)); |
473 | | |
474 | | /* |
475 | | * Key ID. |
476 | | */ |
477 | 0 | RETERR(uint16_tobuffer(sig->keyid, target)); |
478 | | |
479 | | /* |
480 | | * Signer name. |
481 | | */ |
482 | 0 | RETERR(name_tobuffer(&sig->signer, target)); |
483 | | |
484 | | /* |
485 | | * Signature. |
486 | | */ |
487 | 0 | return mem_tobuffer(target, sig->signature, sig->siglen); |
488 | 0 | } |
489 | | |
490 | | static isc_result_t |
491 | 1.56k | tostruct_rrsig(ARGS_TOSTRUCT) { |
492 | 1.56k | isc_region_t sr; |
493 | 1.56k | dns_rdata_rrsig_t *sig = target; |
494 | 1.56k | dns_name_t signer; |
495 | | |
496 | 1.56k | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
497 | 1.56k | REQUIRE(sig != NULL); |
498 | 1.56k | REQUIRE(rdata->length != 0); |
499 | | |
500 | 1.56k | DNS_RDATACOMMON_INIT(sig, rdata->type, rdata->rdclass); |
501 | | |
502 | 1.56k | dns_rdata_toregion(rdata, &sr); |
503 | | |
504 | | /* |
505 | | * Type covered. |
506 | | */ |
507 | 1.56k | sig->covered = uint16_fromregion(&sr); |
508 | 1.56k | isc_region_consume(&sr, 2); |
509 | | |
510 | | /* |
511 | | * Algorithm. |
512 | | */ |
513 | 1.56k | sig->algorithm = uint8_fromregion(&sr); |
514 | 1.56k | isc_region_consume(&sr, 1); |
515 | | |
516 | | /* |
517 | | * Labels. |
518 | | */ |
519 | 1.56k | sig->labels = uint8_fromregion(&sr); |
520 | 1.56k | isc_region_consume(&sr, 1); |
521 | | |
522 | | /* |
523 | | * Original TTL. |
524 | | */ |
525 | 1.56k | sig->originalttl = uint32_fromregion(&sr); |
526 | 1.56k | isc_region_consume(&sr, 4); |
527 | | |
528 | | /* |
529 | | * Expire time. |
530 | | */ |
531 | 1.56k | sig->timeexpire = uint32_fromregion(&sr); |
532 | 1.56k | isc_region_consume(&sr, 4); |
533 | | |
534 | | /* |
535 | | * Time signed. |
536 | | */ |
537 | 1.56k | sig->timesigned = uint32_fromregion(&sr); |
538 | 1.56k | isc_region_consume(&sr, 4); |
539 | | |
540 | | /* |
541 | | * Key ID. |
542 | | */ |
543 | 1.56k | sig->keyid = uint16_fromregion(&sr); |
544 | 1.56k | isc_region_consume(&sr, 2); |
545 | | |
546 | 1.56k | dns_name_init(&signer); |
547 | 1.56k | dns_name_fromregion(&signer, &sr); |
548 | 1.56k | dns_name_init(&sig->signer); |
549 | 1.56k | name_duporclone(&signer, mctx, &sig->signer); |
550 | 1.56k | isc_region_consume(&sr, name_length(&sig->signer)); |
551 | | |
552 | | /* |
553 | | * Signature. |
554 | | */ |
555 | 1.56k | sig->siglen = sr.length; |
556 | 1.56k | sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); |
557 | 1.56k | sig->mctx = mctx; |
558 | 1.56k | return ISC_R_SUCCESS; |
559 | 1.56k | } |
560 | | |
561 | | static void |
562 | 0 | freestruct_rrsig(ARGS_FREESTRUCT) { |
563 | 0 | dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *)source; |
564 | |
|
565 | 0 | REQUIRE(sig != NULL); |
566 | 0 | REQUIRE(sig->common.rdtype == dns_rdatatype_rrsig); |
567 | |
|
568 | 0 | if (sig->mctx == NULL) { |
569 | 0 | return; |
570 | 0 | } |
571 | | |
572 | 0 | dns_name_free(&sig->signer, sig->mctx); |
573 | 0 | if (sig->signature != NULL) { |
574 | 0 | isc_mem_free(sig->mctx, sig->signature); |
575 | 0 | } |
576 | 0 | sig->mctx = NULL; |
577 | 0 | } |
578 | | |
579 | | static isc_result_t |
580 | 0 | additionaldata_rrsig(ARGS_ADDLDATA) { |
581 | 0 | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
582 | |
|
583 | 0 | UNUSED(rdata); |
584 | 0 | UNUSED(owner); |
585 | 0 | UNUSED(add); |
586 | 0 | UNUSED(arg); |
587 | |
|
588 | 0 | return ISC_R_SUCCESS; |
589 | 0 | } |
590 | | |
591 | | static isc_result_t |
592 | 0 | digest_rrsig(ARGS_DIGEST) { |
593 | 0 | isc_region_t r1, r2; |
594 | 0 | dns_name_t name; |
595 | |
|
596 | 0 | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
597 | |
|
598 | 0 | dns_rdata_toregion(rdata, &r1); |
599 | 0 | r2 = r1; |
600 | | |
601 | | /* |
602 | | * Type covered (2) + Algorithm (1) + |
603 | | * Labels (1) + Original TTL (4) + |
604 | | * Expire time (4) + Time signed (4) + |
605 | | * Key ID (2). |
606 | | */ |
607 | 0 | isc_region_consume(&r2, 18); |
608 | 0 | r1.length = 18; |
609 | 0 | RETERR((digest)(arg, &r1)); |
610 | | |
611 | | /* Signer */ |
612 | 0 | dns_name_init(&name); |
613 | 0 | dns_name_fromregion(&name, &r2); |
614 | 0 | RETERR(dns_name_digest(&name, digest, arg)); |
615 | 0 | isc_region_consume(&r2, name_length(&name)); |
616 | | |
617 | | /* Signature */ |
618 | 0 | return (digest)(arg, &r2); |
619 | 0 | } |
620 | | |
621 | | static dns_rdatatype_t |
622 | 31.1k | covers_rrsig(dns_rdata_t *rdata) { |
623 | 31.1k | dns_rdatatype_t type; |
624 | 31.1k | isc_region_t r; |
625 | | |
626 | 31.1k | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
627 | | |
628 | 31.1k | dns_rdata_toregion(rdata, &r); |
629 | 31.1k | type = uint16_fromregion(&r); |
630 | | |
631 | 31.1k | return type; |
632 | 31.1k | } |
633 | | |
634 | | static bool |
635 | 0 | checkowner_rrsig(ARGS_CHECKOWNER) { |
636 | 0 | REQUIRE(type == dns_rdatatype_rrsig); |
637 | |
|
638 | 0 | UNUSED(name); |
639 | 0 | UNUSED(type); |
640 | 0 | UNUSED(rdclass); |
641 | 0 | UNUSED(wildcard); |
642 | |
|
643 | 0 | return true; |
644 | 0 | } |
645 | | |
646 | | static bool |
647 | 0 | checknames_rrsig(ARGS_CHECKNAMES) { |
648 | 0 | REQUIRE(rdata->type == dns_rdatatype_rrsig); |
649 | |
|
650 | 0 | UNUSED(rdata); |
651 | 0 | UNUSED(owner); |
652 | 0 | UNUSED(bad); |
653 | |
|
654 | 0 | return true; |
655 | 0 | } |
656 | | |
657 | | static int |
658 | 0 | casecompare_rrsig(ARGS_COMPARE) { |
659 | 0 | return compare_rrsig(rdata1, rdata2); |
660 | 0 | } |
661 | | |
662 | | #endif /* RDATA_GENERIC_RRSIG_46_C */ |