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