1 /* $NetBSD: cdnskey_60.c,v 1.1.1.4 2015/07/08 15:38:03 christos Exp $ */
4 * Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* draft-ietf-dnsop-delegation-trust-maintainance-14 */
21 #ifndef RDATA_GENERIC_CDNSKEY_60_C
22 #define RDATA_GENERIC_CDNSKEY_60_C
26 #define RRTYPE_CDNSKEY_ATTRIBUTES 0
28 static inline isc_result_t
29 fromtext_cdnskey(ARGS_FROMTEXT
) {
45 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
47 RETTOK(dns_keyflags_fromtext(&flags
, &token
.value
.as_textregion
));
48 RETERR(uint16_tobuffer(flags
, target
));
51 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
53 RETTOK(dns_secproto_fromtext(&proto
, &token
.value
.as_textregion
));
54 RETERR(mem_tobuffer(target
, &proto
, 1));
57 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
59 RETTOK(dns_secalg_fromtext(&alg
, &token
.value
.as_textregion
));
60 RETERR(mem_tobuffer(target
, &alg
, 1));
63 if ((flags
& 0xc000) == 0xc000)
64 return (ISC_R_SUCCESS
);
66 result
= isc_base64_tobuffer(lexer
, target
, -1);
67 if (result
!= ISC_R_SUCCESS
)
70 /* Ensure there's at least enough data to compute a key ID for MD5 */
71 if (alg
== DST_ALG_RSAMD5
&& isc_buffer_usedlength(target
) < 7)
72 return (ISC_R_UNEXPECTEDEND
);
74 return (ISC_R_SUCCESS
);
77 static inline isc_result_t
78 totext_cdnskey(ARGS_TOTEXT
) {
80 char buf
[sizeof("[key id = 64000]")];
82 unsigned char algorithm
;
83 char algbuf
[DNS_NAME_FORMATSIZE
];
87 REQUIRE(rdata
->type
== 60);
88 REQUIRE(rdata
->length
!= 0);
90 dns_rdata_toregion(rdata
, &sr
);
93 flags
= uint16_fromregion(&sr
);
94 isc_region_consume(&sr
, 2);
95 sprintf(buf
, "%u", flags
);
96 RETERR(str_totext(buf
, target
));
97 RETERR(str_totext(" ", target
));
98 if ((flags
& DNS_KEYFLAG_KSK
) != 0) {
99 if (flags
& DNS_KEYFLAG_REVOKE
)
100 keyinfo
= "revoked KSK";
107 sprintf(buf
, "%u", sr
.base
[0]);
108 isc_region_consume(&sr
, 1);
109 RETERR(str_totext(buf
, target
));
110 RETERR(str_totext(" ", target
));
113 algorithm
= sr
.base
[0];
114 sprintf(buf
, "%u", algorithm
);
115 isc_region_consume(&sr
, 1);
116 RETERR(str_totext(buf
, target
));
119 if ((flags
& 0xc000) == 0xc000)
120 return (ISC_R_SUCCESS
);
122 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0 &&
123 algorithm
== DNS_KEYALG_PRIVATEDNS
) {
125 dns_name_init(&name
, NULL
);
126 dns_name_fromregion(&name
, &sr
);
127 dns_name_format(&name
, algbuf
, sizeof(algbuf
));
129 dns_secalg_format((dns_secalg_t
) algorithm
, algbuf
,
134 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
135 RETERR(str_totext(" (", target
));
136 RETERR(str_totext(tctx
->linebreak
, target
));
138 if ((tctx
->flags
& DNS_STYLEFLAG_NOCRYPTO
) == 0) {
139 if (tctx
->width
== 0) /* No splitting */
140 RETERR(isc_base64_totext(&sr
, 0, "", target
));
142 RETERR(isc_base64_totext(&sr
, tctx
->width
- 2,
143 tctx
->linebreak
, target
));
145 dns_rdata_toregion(rdata
, &tmpr
);
146 snprintf(buf
, sizeof(buf
), "[key id = %u]",
147 dst_region_computeid(&tmpr
, algorithm
));
148 RETERR(str_totext(buf
, target
));
151 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0)
152 RETERR(str_totext(tctx
->linebreak
, target
));
153 else if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
154 RETERR(str_totext(" ", target
));
156 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
157 RETERR(str_totext(")", target
));
159 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0) {
161 RETERR(str_totext(" ; ", target
));
162 RETERR(str_totext(keyinfo
, target
));
163 RETERR(str_totext("; alg = ", target
));
164 RETERR(str_totext(algbuf
, target
));
165 RETERR(str_totext("; key id = ", target
));
166 dns_rdata_toregion(rdata
, &tmpr
);
167 sprintf(buf
, "%u", dst_region_computeid(&tmpr
, algorithm
));
168 RETERR(str_totext(buf
, target
));
170 return (ISC_R_SUCCESS
);
173 static inline isc_result_t
174 fromwire_cdnskey(ARGS_FROMWIRE
) {
175 unsigned char algorithm
;
185 isc_buffer_activeregion(source
, &sr
);
187 return (ISC_R_UNEXPECTEDEND
);
189 algorithm
= sr
.base
[3];
190 RETERR(mem_tobuffer(target
, sr
.base
, 4));
191 isc_region_consume(&sr
, 4);
192 isc_buffer_forward(source
, 4);
194 if (algorithm
== DNS_KEYALG_PRIVATEDNS
) {
196 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
197 dns_name_init(&name
, NULL
);
198 RETERR(dns_name_fromwire(&name
, source
, dctx
, options
, target
));
202 * RSAMD5 computes key ID differently from other
203 * algorithms: we need to ensure there's enough data
204 * present for the computation
206 if (algorithm
== DST_ALG_RSAMD5
&& sr
.length
< 3)
207 return (ISC_R_UNEXPECTEDEND
);
209 isc_buffer_activeregion(source
, &sr
);
210 isc_buffer_forward(source
, sr
.length
);
211 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
214 static inline isc_result_t
215 towire_cdnskey(ARGS_TOWIRE
) {
218 REQUIRE(rdata
->type
== 60);
219 REQUIRE(rdata
->length
!= 0);
223 dns_rdata_toregion(rdata
, &sr
);
224 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
228 compare_cdnskey(ARGS_COMPARE
) {
232 REQUIRE(rdata1
->type
== rdata2
->type
);
233 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
234 REQUIRE(rdata1
->type
== 60);
235 REQUIRE(rdata1
->length
!= 0);
236 REQUIRE(rdata2
->length
!= 0);
238 dns_rdata_toregion(rdata1
, &r1
);
239 dns_rdata_toregion(rdata2
, &r2
);
240 return (isc_region_compare(&r1
, &r2
));
243 static inline isc_result_t
244 fromstruct_cdnskey(ARGS_FROMSTRUCT
) {
245 dns_rdata_cdnskey_t
*dnskey
= source
;
248 REQUIRE(source
!= NULL
);
249 REQUIRE(dnskey
->common
.rdtype
== type
);
250 REQUIRE(dnskey
->common
.rdclass
== rdclass
);
256 RETERR(uint16_tobuffer(dnskey
->flags
, target
));
259 RETERR(uint8_tobuffer(dnskey
->protocol
, target
));
262 RETERR(uint8_tobuffer(dnskey
->algorithm
, target
));
265 return (mem_tobuffer(target
, dnskey
->data
, dnskey
->datalen
));
268 static inline isc_result_t
269 tostruct_cdnskey(ARGS_TOSTRUCT
) {
270 dns_rdata_cdnskey_t
*dnskey
= target
;
273 REQUIRE(rdata
->type
== 60);
274 REQUIRE(target
!= NULL
);
275 REQUIRE(rdata
->length
!= 0);
277 dnskey
->common
.rdclass
= rdata
->rdclass
;
278 dnskey
->common
.rdtype
= rdata
->type
;
279 ISC_LINK_INIT(&dnskey
->common
, link
);
281 dns_rdata_toregion(rdata
, &sr
);
285 return (ISC_R_UNEXPECTEDEND
);
286 dnskey
->flags
= uint16_fromregion(&sr
);
287 isc_region_consume(&sr
, 2);
291 return (ISC_R_UNEXPECTEDEND
);
292 dnskey
->protocol
= uint8_fromregion(&sr
);
293 isc_region_consume(&sr
, 1);
297 return (ISC_R_UNEXPECTEDEND
);
298 dnskey
->algorithm
= uint8_fromregion(&sr
);
299 isc_region_consume(&sr
, 1);
302 dnskey
->datalen
= sr
.length
;
303 dnskey
->data
= mem_maybedup(mctx
, sr
.base
, dnskey
->datalen
);
304 if (dnskey
->data
== NULL
)
305 return (ISC_R_NOMEMORY
);
308 return (ISC_R_SUCCESS
);
312 freestruct_cdnskey(ARGS_FREESTRUCT
) {
313 dns_rdata_cdnskey_t
*dnskey
= (dns_rdata_cdnskey_t
*) source
;
315 REQUIRE(source
!= NULL
);
316 REQUIRE(dnskey
->common
.rdtype
== 60);
318 if (dnskey
->mctx
== NULL
)
321 if (dnskey
->data
!= NULL
)
322 isc_mem_free(dnskey
->mctx
, dnskey
->data
);
326 static inline isc_result_t
327 additionaldata_cdnskey(ARGS_ADDLDATA
) {
328 REQUIRE(rdata
->type
== 60);
334 return (ISC_R_SUCCESS
);
337 static inline isc_result_t
338 digest_cdnskey(ARGS_DIGEST
) {
341 REQUIRE(rdata
->type
== 60);
343 dns_rdata_toregion(rdata
, &r
);
345 return ((digest
)(arg
, &r
));
348 static inline isc_boolean_t
349 checkowner_cdnskey(ARGS_CHECKOWNER
) {
361 static inline isc_boolean_t
362 checknames_cdnskey(ARGS_CHECKNAMES
) {
364 REQUIRE(rdata
->type
== 60);
374 casecompare_cdnskey(ARGS_COMPARE
) {
377 * Treat ALG 253 (private DNS) subtype name case sensistively.
379 return (compare_cdnskey(rdata1
, rdata2
));
382 #endif /* RDATA_GENERIC_CDNSKEY_60_C */