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 /* RFC2538 */
15
16 #ifndef RDATA_GENERIC_CERT_37_C
17 #define RDATA_GENERIC_CERT_37_C
18
19 #define RRTYPE_CERT_ATTRIBUTES (0)
20
21 static inline isc_result_t
fromtext_cert(ARGS_FROMTEXT)22 fromtext_cert(ARGS_FROMTEXT) {
23 isc_token_t token;
24 dns_secalg_t secalg;
25 dns_cert_t cert;
26
27 REQUIRE(type == dns_rdatatype_cert);
28
29 UNUSED(type);
30 UNUSED(rdclass);
31 UNUSED(origin);
32 UNUSED(options);
33 UNUSED(callbacks);
34
35 /*
36 * Cert type.
37 */
38 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
39 false));
40 RETTOK(dns_cert_fromtext(&cert, &token.value.as_textregion));
41 RETERR(uint16_tobuffer(cert, target));
42
43 /*
44 * Key tag.
45 */
46 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
47 false));
48 if (token.value.as_ulong > 0xffffU) {
49 RETTOK(ISC_R_RANGE);
50 }
51 RETERR(uint16_tobuffer(token.value.as_ulong, target));
52
53 /*
54 * Algorithm.
55 */
56 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
57 false));
58 RETTOK(dns_secalg_fromtext(&secalg, &token.value.as_textregion));
59 RETERR(mem_tobuffer(target, &secalg, 1));
60
61 return (isc_base64_tobuffer(lexer, target, -2));
62 }
63
64 static inline isc_result_t
totext_cert(ARGS_TOTEXT)65 totext_cert(ARGS_TOTEXT) {
66 isc_region_t sr;
67 char buf[sizeof("64000 ")];
68 unsigned int n;
69
70 REQUIRE(rdata->type == dns_rdatatype_cert);
71 REQUIRE(rdata->length != 0);
72
73 UNUSED(tctx);
74
75 dns_rdata_toregion(rdata, &sr);
76
77 /*
78 * Type.
79 */
80 n = uint16_fromregion(&sr);
81 isc_region_consume(&sr, 2);
82 RETERR(dns_cert_totext((dns_cert_t)n, target));
83 RETERR(str_totext(" ", target));
84
85 /*
86 * Key tag.
87 */
88 n = uint16_fromregion(&sr);
89 isc_region_consume(&sr, 2);
90 snprintf(buf, sizeof(buf), "%u ", n);
91 RETERR(str_totext(buf, target));
92
93 /*
94 * Algorithm.
95 */
96 RETERR(dns_secalg_totext(sr.base[0], target));
97 isc_region_consume(&sr, 1);
98
99 /*
100 * Cert.
101 */
102 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
103 RETERR(str_totext(" (", target));
104 }
105 RETERR(str_totext(tctx->linebreak, target));
106 if (tctx->width == 0) { /* No splitting */
107 RETERR(isc_base64_totext(&sr, 60, "", target));
108 } else {
109 RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak,
110 target));
111 }
112 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
113 RETERR(str_totext(" )", target));
114 }
115 return (ISC_R_SUCCESS);
116 }
117
118 static inline isc_result_t
fromwire_cert(ARGS_FROMWIRE)119 fromwire_cert(ARGS_FROMWIRE) {
120 isc_region_t sr;
121
122 REQUIRE(type == dns_rdatatype_cert);
123
124 UNUSED(type);
125 UNUSED(rdclass);
126 UNUSED(dctx);
127 UNUSED(options);
128
129 isc_buffer_activeregion(source, &sr);
130 if (sr.length < 6) {
131 return (ISC_R_UNEXPECTEDEND);
132 }
133
134 isc_buffer_forward(source, sr.length);
135 return (mem_tobuffer(target, sr.base, sr.length));
136 }
137
138 static inline isc_result_t
towire_cert(ARGS_TOWIRE)139 towire_cert(ARGS_TOWIRE) {
140 isc_region_t sr;
141
142 REQUIRE(rdata->type == dns_rdatatype_cert);
143 REQUIRE(rdata->length != 0);
144
145 UNUSED(cctx);
146
147 dns_rdata_toregion(rdata, &sr);
148 return (mem_tobuffer(target, sr.base, sr.length));
149 }
150
151 static inline int
compare_cert(ARGS_COMPARE)152 compare_cert(ARGS_COMPARE) {
153 isc_region_t r1;
154 isc_region_t r2;
155
156 REQUIRE(rdata1->type == rdata2->type);
157 REQUIRE(rdata1->rdclass == rdata2->rdclass);
158 REQUIRE(rdata1->type == dns_rdatatype_cert);
159 REQUIRE(rdata1->length != 0);
160 REQUIRE(rdata2->length != 0);
161
162 dns_rdata_toregion(rdata1, &r1);
163 dns_rdata_toregion(rdata2, &r2);
164 return (isc_region_compare(&r1, &r2));
165 }
166
167 static inline isc_result_t
fromstruct_cert(ARGS_FROMSTRUCT)168 fromstruct_cert(ARGS_FROMSTRUCT) {
169 dns_rdata_cert_t *cert = source;
170
171 REQUIRE(type == dns_rdatatype_cert);
172 REQUIRE(cert != NULL);
173 REQUIRE(cert->common.rdtype == type);
174 REQUIRE(cert->common.rdclass == rdclass);
175
176 UNUSED(type);
177 UNUSED(rdclass);
178
179 RETERR(uint16_tobuffer(cert->type, target));
180 RETERR(uint16_tobuffer(cert->key_tag, target));
181 RETERR(uint8_tobuffer(cert->algorithm, target));
182
183 return (mem_tobuffer(target, cert->certificate, cert->length));
184 }
185
186 static inline isc_result_t
tostruct_cert(ARGS_TOSTRUCT)187 tostruct_cert(ARGS_TOSTRUCT) {
188 dns_rdata_cert_t *cert = target;
189 isc_region_t region;
190
191 REQUIRE(rdata->type == dns_rdatatype_cert);
192 REQUIRE(cert != NULL);
193 REQUIRE(rdata->length != 0);
194
195 cert->common.rdclass = rdata->rdclass;
196 cert->common.rdtype = rdata->type;
197 ISC_LINK_INIT(&cert->common, link);
198
199 dns_rdata_toregion(rdata, ®ion);
200
201 cert->type = uint16_fromregion(®ion);
202 isc_region_consume(®ion, 2);
203 cert->key_tag = uint16_fromregion(®ion);
204 isc_region_consume(®ion, 2);
205 cert->algorithm = uint8_fromregion(®ion);
206 isc_region_consume(®ion, 1);
207 cert->length = region.length;
208
209 cert->certificate = mem_maybedup(mctx, region.base, region.length);
210 if (cert->certificate == NULL) {
211 return (ISC_R_NOMEMORY);
212 }
213
214 cert->mctx = mctx;
215 return (ISC_R_SUCCESS);
216 }
217
218 static inline void
freestruct_cert(ARGS_FREESTRUCT)219 freestruct_cert(ARGS_FREESTRUCT) {
220 dns_rdata_cert_t *cert = source;
221
222 REQUIRE(cert != NULL);
223 REQUIRE(cert->common.rdtype == dns_rdatatype_cert);
224
225 if (cert->mctx == NULL) {
226 return;
227 }
228
229 if (cert->certificate != NULL) {
230 isc_mem_free(cert->mctx, cert->certificate);
231 }
232 cert->mctx = NULL;
233 }
234
235 static inline isc_result_t
additionaldata_cert(ARGS_ADDLDATA)236 additionaldata_cert(ARGS_ADDLDATA) {
237 REQUIRE(rdata->type == dns_rdatatype_cert);
238
239 UNUSED(rdata);
240 UNUSED(add);
241 UNUSED(arg);
242
243 return (ISC_R_SUCCESS);
244 }
245
246 static inline isc_result_t
digest_cert(ARGS_DIGEST)247 digest_cert(ARGS_DIGEST) {
248 isc_region_t r;
249
250 REQUIRE(rdata->type == dns_rdatatype_cert);
251
252 dns_rdata_toregion(rdata, &r);
253
254 return ((digest)(arg, &r));
255 }
256
257 static inline bool
checkowner_cert(ARGS_CHECKOWNER)258 checkowner_cert(ARGS_CHECKOWNER) {
259 REQUIRE(type == dns_rdatatype_cert);
260
261 UNUSED(name);
262 UNUSED(type);
263 UNUSED(rdclass);
264 UNUSED(wildcard);
265
266 return (true);
267 }
268
269 static inline bool
checknames_cert(ARGS_CHECKNAMES)270 checknames_cert(ARGS_CHECKNAMES) {
271 REQUIRE(rdata->type == dns_rdatatype_cert);
272
273 UNUSED(rdata);
274 UNUSED(owner);
275 UNUSED(bad);
276
277 return (true);
278 }
279
280 static inline int
casecompare_cert(ARGS_COMPARE)281 casecompare_cert(ARGS_COMPARE) {
282 return (compare_cert(rdata1, rdata2));
283 }
284 #endif /* RDATA_GENERIC_CERT_37_C */
285