1 /* $NetBSD: dnskey_48.c,v 1.7 2014/12/10 04:37:59 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2003 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.
23 * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
28 #ifndef RDATA_GENERIC_DNSKEY_48_C
29 #define RDATA_GENERIC_DNSKEY_48_C
33 #define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
35 static inline isc_result_t
36 fromtext_dnskey(ARGS_FROMTEXT
) {
52 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
54 RETTOK(dns_keyflags_fromtext(&flags
, &token
.value
.as_textregion
));
55 RETERR(uint16_tobuffer(flags
, target
));
58 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
60 RETTOK(dns_secproto_fromtext(&proto
, &token
.value
.as_textregion
));
61 RETERR(mem_tobuffer(target
, &proto
, 1));
64 RETERR(isc_lex_getmastertoken(lexer
, &token
, isc_tokentype_string
,
66 RETTOK(dns_secalg_fromtext(&alg
, &token
.value
.as_textregion
));
67 RETERR(mem_tobuffer(target
, &alg
, 1));
70 if ((flags
& 0xc000) == 0xc000)
71 return (ISC_R_SUCCESS
);
73 result
= isc_base64_tobuffer(lexer
, target
, -1);
74 if (result
!= ISC_R_SUCCESS
)
77 /* Ensure there's at least enough data to compute a key ID for MD5 */
78 if (alg
== DST_ALG_RSAMD5
&& isc_buffer_usedlength(target
) < 7)
79 return (ISC_R_UNEXPECTEDEND
);
81 return (ISC_R_SUCCESS
);
84 static inline isc_result_t
85 totext_dnskey(ARGS_TOTEXT
) {
87 char buf
[sizeof("[key id = 64000]")];
89 unsigned char algorithm
;
90 char algbuf
[DNS_NAME_FORMATSIZE
];
94 REQUIRE(rdata
->type
== 48);
95 REQUIRE(rdata
->length
!= 0);
97 dns_rdata_toregion(rdata
, &sr
);
100 flags
= uint16_fromregion(&sr
);
101 isc_region_consume(&sr
, 2);
102 sprintf(buf
, "%u", flags
);
103 RETERR(str_totext(buf
, target
));
104 RETERR(str_totext(" ", target
));
105 if ((flags
& DNS_KEYFLAG_KSK
) != 0) {
106 if (flags
& DNS_KEYFLAG_REVOKE
)
107 keyinfo
= "revoked KSK";
114 sprintf(buf
, "%u", sr
.base
[0]);
115 isc_region_consume(&sr
, 1);
116 RETERR(str_totext(buf
, target
));
117 RETERR(str_totext(" ", target
));
120 algorithm
= sr
.base
[0];
121 sprintf(buf
, "%u", algorithm
);
122 isc_region_consume(&sr
, 1);
123 RETERR(str_totext(buf
, target
));
126 if ((flags
& 0xc000) == 0xc000)
127 return (ISC_R_SUCCESS
);
129 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0 &&
130 algorithm
== DNS_KEYALG_PRIVATEDNS
) {
132 dns_name_init(&name
, NULL
);
133 dns_name_fromregion(&name
, &sr
);
134 dns_name_format(&name
, algbuf
, sizeof(algbuf
));
136 dns_secalg_format((dns_secalg_t
) algorithm
, algbuf
,
141 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
142 RETERR(str_totext(" (", target
));
143 RETERR(str_totext(tctx
->linebreak
, target
));
145 if ((tctx
->flags
& DNS_STYLEFLAG_NOCRYPTO
) == 0) {
146 if (tctx
->width
== 0) /* No splitting */
147 RETERR(isc_base64_totext(&sr
, 0, "", target
));
149 RETERR(isc_base64_totext(&sr
, tctx
->width
- 2,
150 tctx
->linebreak
, target
));
152 dns_rdata_toregion(rdata
, &tmpr
);
153 snprintf(buf
, sizeof(buf
), "[key id = %u]",
154 dst_region_computeid(&tmpr
, algorithm
));
155 RETERR(str_totext(buf
, target
));
158 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0)
159 RETERR(str_totext(tctx
->linebreak
, target
));
160 else if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
161 RETERR(str_totext(" ", target
));
163 if ((tctx
->flags
& DNS_STYLEFLAG_MULTILINE
) != 0)
164 RETERR(str_totext(")", target
));
166 if ((tctx
->flags
& DNS_STYLEFLAG_RRCOMMENT
) != 0) {
168 RETERR(str_totext(" ; ", target
));
169 RETERR(str_totext(keyinfo
, target
));
170 RETERR(str_totext("; alg = ", target
));
171 RETERR(str_totext(algbuf
, target
));
172 RETERR(str_totext("; key id = ", target
));
173 dns_rdata_toregion(rdata
, &tmpr
);
174 sprintf(buf
, "%u", dst_region_computeid(&tmpr
, algorithm
));
175 RETERR(str_totext(buf
, target
));
177 return (ISC_R_SUCCESS
);
180 static inline isc_result_t
181 fromwire_dnskey(ARGS_FROMWIRE
) {
182 unsigned char algorithm
;
192 isc_buffer_activeregion(source
, &sr
);
194 return (ISC_R_UNEXPECTEDEND
);
196 algorithm
= sr
.base
[3];
197 RETERR(mem_tobuffer(target
, sr
.base
, 4));
198 isc_region_consume(&sr
, 4);
199 isc_buffer_forward(source
, 4);
201 if (algorithm
== DNS_KEYALG_PRIVATEDNS
) {
203 dns_decompress_setmethods(dctx
, DNS_COMPRESS_NONE
);
204 dns_name_init(&name
, NULL
);
205 RETERR(dns_name_fromwire(&name
, source
, dctx
, options
, target
));
209 * RSAMD5 computes key ID differently from other
210 * algorithms: we need to ensure there's enough data
211 * present for the computation
213 if (algorithm
== DST_ALG_RSAMD5
&& sr
.length
< 3)
214 return (ISC_R_UNEXPECTEDEND
);
216 isc_buffer_activeregion(source
, &sr
);
217 isc_buffer_forward(source
, sr
.length
);
218 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
221 static inline isc_result_t
222 towire_dnskey(ARGS_TOWIRE
) {
225 REQUIRE(rdata
->type
== 48);
226 REQUIRE(rdata
->length
!= 0);
230 dns_rdata_toregion(rdata
, &sr
);
231 return (mem_tobuffer(target
, sr
.base
, sr
.length
));
235 compare_dnskey(ARGS_COMPARE
) {
239 REQUIRE(rdata1
->type
== rdata2
->type
);
240 REQUIRE(rdata1
->rdclass
== rdata2
->rdclass
);
241 REQUIRE(rdata1
->type
== 48);
242 REQUIRE(rdata1
->length
!= 0);
243 REQUIRE(rdata2
->length
!= 0);
245 dns_rdata_toregion(rdata1
, &r1
);
246 dns_rdata_toregion(rdata2
, &r2
);
247 return (isc_region_compare(&r1
, &r2
));
250 static inline isc_result_t
251 fromstruct_dnskey(ARGS_FROMSTRUCT
) {
252 dns_rdata_dnskey_t
*dnskey
= source
;
255 REQUIRE(source
!= NULL
);
256 REQUIRE(dnskey
->common
.rdtype
== type
);
257 REQUIRE(dnskey
->common
.rdclass
== rdclass
);
263 RETERR(uint16_tobuffer(dnskey
->flags
, target
));
266 RETERR(uint8_tobuffer(dnskey
->protocol
, target
));
269 RETERR(uint8_tobuffer(dnskey
->algorithm
, target
));
272 return (mem_tobuffer(target
, dnskey
->data
, dnskey
->datalen
));
275 static inline isc_result_t
276 tostruct_dnskey(ARGS_TOSTRUCT
) {
277 dns_rdata_dnskey_t
*dnskey
= target
;
280 REQUIRE(rdata
->type
== 48);
281 REQUIRE(target
!= NULL
);
282 REQUIRE(rdata
->length
!= 0);
284 dnskey
->common
.rdclass
= rdata
->rdclass
;
285 dnskey
->common
.rdtype
= rdata
->type
;
286 ISC_LINK_INIT(&dnskey
->common
, link
);
288 dns_rdata_toregion(rdata
, &sr
);
292 return (ISC_R_UNEXPECTEDEND
);
293 dnskey
->flags
= uint16_fromregion(&sr
);
294 isc_region_consume(&sr
, 2);
298 return (ISC_R_UNEXPECTEDEND
);
299 dnskey
->protocol
= uint8_fromregion(&sr
);
300 isc_region_consume(&sr
, 1);
304 return (ISC_R_UNEXPECTEDEND
);
305 dnskey
->algorithm
= uint8_fromregion(&sr
);
306 isc_region_consume(&sr
, 1);
309 dnskey
->datalen
= sr
.length
;
310 dnskey
->data
= mem_maybedup(mctx
, sr
.base
, dnskey
->datalen
);
311 if (dnskey
->data
== NULL
)
312 return (ISC_R_NOMEMORY
);
315 return (ISC_R_SUCCESS
);
319 freestruct_dnskey(ARGS_FREESTRUCT
) {
320 dns_rdata_dnskey_t
*dnskey
= (dns_rdata_dnskey_t
*) source
;
322 REQUIRE(source
!= NULL
);
323 REQUIRE(dnskey
->common
.rdtype
== 48);
325 if (dnskey
->mctx
== NULL
)
328 if (dnskey
->data
!= NULL
)
329 isc_mem_free(dnskey
->mctx
, dnskey
->data
);
333 static inline isc_result_t
334 additionaldata_dnskey(ARGS_ADDLDATA
) {
335 REQUIRE(rdata
->type
== 48);
341 return (ISC_R_SUCCESS
);
344 static inline isc_result_t
345 digest_dnskey(ARGS_DIGEST
) {
348 REQUIRE(rdata
->type
== 48);
350 dns_rdata_toregion(rdata
, &r
);
352 return ((digest
)(arg
, &r
));
355 static inline isc_boolean_t
356 checkowner_dnskey(ARGS_CHECKOWNER
) {
368 static inline isc_boolean_t
369 checknames_dnskey(ARGS_CHECKNAMES
) {
371 REQUIRE(rdata
->type
== 48);
381 casecompare_dnskey(ARGS_COMPARE
) {
384 * Treat ALG 253 (private DNS) subtype name case sensistively.
386 return (compare_dnskey(rdata1
, rdata2
));
389 #endif /* RDATA_GENERIC_DNSKEY_48_C */