1 /* $NetBSD: ds_43.c,v 1.7 2014/12/10 04:37:59 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007, 2009-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
24 #ifndef RDATA_GENERIC_DS_43_C
25 #define RDATA_GENERIC_DS_43_C
27 #define RRTYPE_DS_ATTRIBUTES \
28 (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
37 static inline isc_result_t
38 fromtext_ds(ARGS_FROMTEXT
) {
54 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_number
,
56 if (token
.value
.as_ulong
> 0xffffU
)
58 RETERR(uint16_tobuffer(token
.value
.as_ulong
, target
));
63 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
65 RETTOK(dns_secalg_fromtext(&c
, &token
.value
.as_textregion
));
66 RETERR(mem_tobuffer(target
, &c
, 1));
71 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
73 RETTOK(dns_dsdigest_fromtext(&c
, &token
.value
.as_textregion
));
74 RETERR(mem_tobuffer(target
, &c
, 1));
80 case DNS_DSDIGEST_SHA1
:
81 length
= ISC_SHA1_DIGESTLENGTH
;
83 case DNS_DSDIGEST_SHA256
:
84 length
= ISC_SHA256_DIGESTLENGTH
;
86 #ifdef ISC_GOST_DIGESTLENGTH
87 case DNS_DSDIGEST_GOST
:
88 length
= ISC_GOST_DIGESTLENGTH
;
91 case DNS_DSDIGEST_SHA384
:
92 length
= ISC_SHA384_DIGESTLENGTH
;
98 return (isc_hex_tobuffer(lexer
, target
, length
));
101 static inline isc_result_t
102 totext_ds(ARGS_TOTEXT
) {
104 char buf
[sizeof("64000 ")];
107 REQUIRE(rdata
->type
== 43);
108 REQUIRE(rdata
->length
!= 0);
112 dns_rdata_toregion(rdata
, &sr
);
117 n
= uint16_fromregion(&sr
);
118 isc_region_consume(&sr
, 2);
119 sprintf(buf
, "%u ", n
);
120 RETERR(str_totext(buf
, target
));
125 n
= uint8_fromregion(&sr
);
126 isc_region_consume(&sr
, 1);
127 sprintf(buf
, "%u ", n
);
128 RETERR(str_totext(buf
, target
));
133 n
= uint8_fromregion(&sr
);
134 isc_region_consume(&sr
, 1);
135 sprintf(buf
, "%u", n
);
136 RETERR(str_totext(buf
, target
));
141 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
142 RETERR(str_totext(" (", target
));
143 RETERR(str_totext(tctx
->linebreak
, target
));
144 if ((tctx
->flags
& DNS_STYLEFLAG_NOCRYPTO
) == 0) {
145 if (tctx
->width
== 0) /* No splitting */
146 RETERR(isc_hex_totext(&sr
, 0, "", target
));
148 RETERR(isc_hex_totext(&sr
, tctx
->width
- 2,
149 tctx
->linebreak
, target
));
151 RETERR(str_totext("[omitted]", target
));
152 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
153 RETERR(str_totext(" )", target
));
154 return (ISC_R_SUCCESS
);
157 static inline isc_result_t
158 fromwire_ds(ARGS_FROMWIRE
) {
168 isc_buffer_activeregion(source
, &sr
);
171 * Check digest lengths if we know them.
174 (sr
.base
[3] == DNS_DSDIGEST_SHA1
&&
175 sr
.length
< 4 + ISC_SHA1_DIGESTLENGTH
) ||
176 (sr
.base
[3] == DNS_DSDIGEST_SHA256
&&
177 sr
.length
< 4 + ISC_SHA256_DIGESTLENGTH
) ||
178 #ifdef ISC_GOST_DIGESTLENGTH
179 (sr
.base
[3] == DNS_DSDIGEST_GOST
&&
180 sr
.length
< 4 + ISC_GOST_DIGESTLENGTH
) ||
182 (sr
.base
[3] == DNS_DSDIGEST_SHA384
&&
183 sr
.length
< 4 + ISC_SHA384_DIGESTLENGTH
))
184 return (ISC_R_UNEXPECTEDEND
);
187 * Only copy digest lengths if we know them.
188 * If there is extra data dns_rdata_fromwire() will
191 if (sr
.base
[3] == DNS_DSDIGEST_SHA1
)
192 sr
.length
= 4 + ISC_SHA1_DIGESTLENGTH
;
193 else if (sr
.base
[3] == DNS_DSDIGEST_SHA256
)
194 sr
.length
= 4 + ISC_SHA256_DIGESTLENGTH
;
195 #ifdef ISC_GOST_DIGESTLENGTH
196 else if (sr
.base
[3] == DNS_DSDIGEST_GOST
)
197 sr
.length
= 4 + ISC_GOST_DIGESTLENGTH
;
199 else if (sr
.base
[3] == DNS_DSDIGEST_SHA384
)
200 sr
.length
= 4 + ISC_SHA384_DIGESTLENGTH
;
202 isc_buffer_forward(source
, sr
.length
);
203 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
206 static inline isc_result_t
207 towire_ds(ARGS_TOWIRE
) {
210 REQUIRE(rdata
->type
== 43);
211 REQUIRE(rdata
->length
!= 0);
215 dns_rdata_toregion(rdata
, &sr
);
216 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
220 compare_ds(ARGS_COMPARE
) {
224 REQUIRE(rdata1
->type
== rdata2
->type
);
225 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
226 REQUIRE(rdata1
->type
== 43);
227 REQUIRE(rdata1
->length
!= 0);
228 REQUIRE(rdata2
->length
!= 0);
230 dns_rdata_toregion(rdata1
, &r1
);
231 dns_rdata_toregion(rdata2
, &r2
);
232 return (isc_region_compare(&r1
, &r2
));
235 static inline isc_result_t
236 fromstruct_ds(ARGS_FROMSTRUCT
) {
237 dns_rdata_ds_t
*ds
= source
;
240 REQUIRE(source
!= NULL
);
241 REQUIRE(ds
->common
.rdtype
== type
);
242 REQUIRE(ds
->common
.rdclass
== rdclass
);
243 switch (ds
->digest_type
) {
244 case DNS_DSDIGEST_SHA1
:
245 REQUIRE(ds
->length
== ISC_SHA1_DIGESTLENGTH
);
247 case DNS_DSDIGEST_SHA256
:
248 REQUIRE(ds
->length
== ISC_SHA256_DIGESTLENGTH
);
250 #ifdef ISC_GOST_DIGESTLENGTH
251 case DNS_DSDIGEST_GOST
:
252 REQUIRE(ds
->length
== ISC_GOST_DIGESTLENGTH
);
255 case DNS_DSDIGEST_SHA384
:
256 REQUIRE(ds
->length
== ISC_SHA384_DIGESTLENGTH
);
263 RETERR(uint16_tobuffer(ds
->key_tag
, target
));
264 RETERR(uint8_tobuffer(ds
->algorithm
, target
));
265 RETERR(uint8_tobuffer(ds
->digest_type
, target
));
267 return (mem_tobuffer(target
, ds
->digest
, ds
->length
));
270 static inline isc_result_t
271 tostruct_ds(ARGS_TOSTRUCT
) {
272 dns_rdata_ds_t
*ds
= target
;
275 REQUIRE(rdata
->type
== 43);
276 REQUIRE(target
!= NULL
);
277 REQUIRE(rdata
->length
!= 0);
279 ds
->common
.rdclass
= rdata
->rdclass
;
280 ds
->common
.rdtype
= rdata
->type
;
281 ISC_LINK_INIT(&ds
->common
, link
);
283 dns_rdata_toregion(rdata
, ®ion
);
285 ds
->key_tag
= uint16_fromregion(®ion
);
286 isc_region_consume(®ion
, 2);
287 ds
->algorithm
= uint8_fromregion(®ion
);
288 isc_region_consume(®ion
, 1);
289 ds
->digest_type
= uint8_fromregion(®ion
);
290 isc_region_consume(®ion
, 1);
291 ds
->length
= region
.length
;
293 ds
->digest
= mem_maybedup(mctx
, region
.base
, region
.length
);
294 if (ds
->digest
== NULL
)
295 return (ISC_R_NOMEMORY
);
298 return (ISC_R_SUCCESS
);
302 freestruct_ds(ARGS_FREESTRUCT
) {
303 dns_rdata_ds_t
*ds
= source
;
306 REQUIRE(ds
->common
.rdtype
== 43);
308 if (ds
->mctx
== NULL
)
311 if (ds
->digest
!= NULL
)
312 isc_mem_free(ds
->mctx
, ds
->digest
);
316 static inline isc_result_t
317 additionaldata_ds(ARGS_ADDLDATA
) {
318 REQUIRE(rdata
->type
== 43);
324 return (ISC_R_SUCCESS
);
327 static inline isc_result_t
328 digest_ds(ARGS_DIGEST
) {
331 REQUIRE(rdata
->type
== 43);
333 dns_rdata_toregion(rdata
, &r
);
335 return ((digest
)(arg
, &r
));
338 static inline isc_boolean_t
339 checkowner_ds(ARGS_CHECKOWNER
) {
351 static inline isc_boolean_t
352 checknames_ds(ARGS_CHECKNAMES
) {
354 REQUIRE(rdata
->type
== 43);
364 casecompare_ds(ARGS_COMPARE
) {
365 return (compare_ds(rdata1
, rdata2
));
368 #endif /* RDATA_GENERIC_DS_43_C */