Coverage Report

Created: 2025-11-11 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/sshfp_44.c
Line
Count
Source
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
/* RFC 4255 */
15
16
#ifndef RDATA_GENERIC_SSHFP_44_C
17
#define RDATA_GENERIC_SSHFP_44_C
18
19
13.1k
#define RRTYPE_SSHFP_ATTRIBUTES (0)
20
21
static isc_result_t
22
1.22k
fromtext_sshfp(ARGS_FROMTEXT) {
23
1.22k
  isc_token_t token;
24
1.22k
  int len = -1;
25
26
1.22k
  REQUIRE(type == dns_rdatatype_sshfp);
27
28
1.22k
  UNUSED(type);
29
1.22k
  UNUSED(rdclass);
30
1.22k
  UNUSED(origin);
31
1.22k
  UNUSED(options);
32
1.22k
  UNUSED(callbacks);
33
34
  /*
35
   * Algorithm.
36
   */
37
1.22k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
38
1.22k
              false));
39
1.21k
  if (token.value.as_ulong > 0xffU) {
40
42
    RETTOK(ISC_R_RANGE);
41
42
  }
42
1.17k
  RETERR(uint8_tobuffer(token.value.as_ulong, target));
43
44
  /*
45
   * Digest type.
46
   */
47
1.17k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
48
1.17k
              false));
49
1.15k
  if (token.value.as_ulong > 0xffU) {
50
47
    RETTOK(ISC_R_RANGE);
51
47
  }
52
1.10k
  RETERR(uint8_tobuffer(token.value.as_ulong, target));
53
54
  /*
55
   * Enforce known digest lengths.
56
   */
57
1.10k
  switch (token.value.as_ulong) {
58
9
  case 1:
59
9
    len = ISC_SHA1_DIGESTLENGTH;
60
9
    break;
61
7
  case 2:
62
7
    len = ISC_SHA256_DIGESTLENGTH;
63
7
    break;
64
1.09k
  default:
65
1.09k
    break;
66
1.10k
  }
67
68
  /*
69
   * Digest.
70
   */
71
1.10k
  return isc_hex_tobuffer(lexer, target, len);
72
1.10k
}
73
74
static isc_result_t
75
1.62k
totext_sshfp(ARGS_TOTEXT) {
76
1.62k
  isc_region_t sr;
77
1.62k
  char buf[sizeof("64000 ")];
78
1.62k
  unsigned int n;
79
80
1.62k
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
81
1.62k
  REQUIRE(rdata->length != 0);
82
83
1.62k
  UNUSED(tctx);
84
85
1.62k
  dns_rdata_toregion(rdata, &sr);
86
87
  /*
88
   * Algorithm.
89
   */
90
1.62k
  n = uint8_fromregion(&sr);
91
1.62k
  isc_region_consume(&sr, 1);
92
1.62k
  snprintf(buf, sizeof(buf), "%u ", n);
93
1.62k
  RETERR(str_totext(buf, target));
94
95
  /*
96
   * Digest type.
97
   */
98
1.62k
  n = uint8_fromregion(&sr);
99
1.62k
  isc_region_consume(&sr, 1);
100
1.62k
  snprintf(buf, sizeof(buf), "%u", n);
101
1.62k
  RETERR(str_totext(buf, target));
102
103
1.62k
  if (sr.length == 0U) {
104
659
    return ISC_R_SUCCESS;
105
659
  }
106
107
  /*
108
   * Digest.
109
   */
110
963
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
111
18
    RETERR(str_totext(" (", target));
112
18
  }
113
963
  RETERR(str_totext(tctx->linebreak, target));
114
963
  if (tctx->width == 0) { /* No splitting */
115
0
    RETERR(isc_hex_totext(&sr, 0, "", target));
116
963
  } else {
117
963
    RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak,
118
963
              target));
119
963
  }
120
963
  if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
121
18
    RETERR(str_totext(" )", target));
122
18
  }
123
963
  return ISC_R_SUCCESS;
124
963
}
125
126
static isc_result_t
127
2.90k
fromwire_sshfp(ARGS_FROMWIRE) {
128
2.90k
  isc_region_t sr;
129
130
2.90k
  REQUIRE(type == dns_rdatatype_sshfp);
131
132
2.90k
  UNUSED(type);
133
2.90k
  UNUSED(rdclass);
134
2.90k
  UNUSED(dctx);
135
136
2.90k
  isc_buffer_activeregion(source, &sr);
137
2.90k
  if (sr.length < 2) {
138
10
    return ISC_R_UNEXPECTEDEND;
139
10
  }
140
141
2.89k
  if ((sr.base[1] == 1 && sr.length != ISC_SHA1_DIGESTLENGTH + 2) ||
142
2.87k
      (sr.base[1] == 2 && sr.length != ISC_SHA256_DIGESTLENGTH + 2))
143
45
  {
144
45
    return DNS_R_FORMERR;
145
45
  }
146
147
2.84k
  isc_buffer_forward(source, sr.length);
148
2.84k
  return mem_tobuffer(target, sr.base, sr.length);
149
2.89k
}
150
151
static isc_result_t
152
885
towire_sshfp(ARGS_TOWIRE) {
153
885
  isc_region_t sr;
154
155
885
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
156
885
  REQUIRE(rdata->length != 0);
157
158
885
  UNUSED(cctx);
159
160
885
  dns_rdata_toregion(rdata, &sr);
161
885
  return mem_tobuffer(target, sr.base, sr.length);
162
885
}
163
164
static int
165
6.21k
compare_sshfp(ARGS_COMPARE) {
166
6.21k
  isc_region_t r1;
167
6.21k
  isc_region_t r2;
168
169
6.21k
  REQUIRE(rdata1->type == rdata2->type);
170
6.21k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
171
6.21k
  REQUIRE(rdata1->type == dns_rdatatype_sshfp);
172
6.21k
  REQUIRE(rdata1->length != 0);
173
6.21k
  REQUIRE(rdata2->length != 0);
174
175
6.21k
  dns_rdata_toregion(rdata1, &r1);
176
6.21k
  dns_rdata_toregion(rdata2, &r2);
177
6.21k
  return isc_region_compare(&r1, &r2);
178
6.21k
}
179
180
static isc_result_t
181
0
fromstruct_sshfp(ARGS_FROMSTRUCT) {
182
0
  dns_rdata_sshfp_t *sshfp = source;
183
184
0
  REQUIRE(type == dns_rdatatype_sshfp);
185
0
  REQUIRE(sshfp != NULL);
186
0
  REQUIRE(sshfp->common.rdtype == type);
187
0
  REQUIRE(sshfp->common.rdclass == rdclass);
188
189
0
  UNUSED(type);
190
0
  UNUSED(rdclass);
191
192
0
  RETERR(uint8_tobuffer(sshfp->algorithm, target));
193
0
  RETERR(uint8_tobuffer(sshfp->digest_type, target));
194
195
0
  return mem_tobuffer(target, sshfp->digest, sshfp->length);
196
0
}
197
198
static isc_result_t
199
0
tostruct_sshfp(ARGS_TOSTRUCT) {
200
0
  dns_rdata_sshfp_t *sshfp = target;
201
0
  isc_region_t region;
202
203
0
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
204
0
  REQUIRE(sshfp != NULL);
205
0
  REQUIRE(rdata->length != 0);
206
207
0
  DNS_RDATACOMMON_INIT(sshfp, rdata->type, rdata->rdclass);
208
209
0
  dns_rdata_toregion(rdata, &region);
210
211
0
  sshfp->algorithm = uint8_fromregion(&region);
212
0
  isc_region_consume(&region, 1);
213
0
  sshfp->digest_type = uint8_fromregion(&region);
214
0
  isc_region_consume(&region, 1);
215
0
  sshfp->length = region.length;
216
217
0
  sshfp->digest = mem_maybedup(mctx, region.base, region.length);
218
0
  sshfp->mctx = mctx;
219
0
  return ISC_R_SUCCESS;
220
0
}
221
222
static void
223
0
freestruct_sshfp(ARGS_FREESTRUCT) {
224
0
  dns_rdata_sshfp_t *sshfp = source;
225
226
0
  REQUIRE(sshfp != NULL);
227
0
  REQUIRE(sshfp->common.rdtype == dns_rdatatype_sshfp);
228
229
0
  if (sshfp->mctx == NULL) {
230
0
    return;
231
0
  }
232
233
0
  if (sshfp->digest != NULL) {
234
0
    isc_mem_free(sshfp->mctx, sshfp->digest);
235
0
  }
236
0
  sshfp->mctx = NULL;
237
0
}
238
239
static isc_result_t
240
0
additionaldata_sshfp(ARGS_ADDLDATA) {
241
0
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
242
243
0
  UNUSED(rdata);
244
0
  UNUSED(owner);
245
0
  UNUSED(add);
246
0
  UNUSED(arg);
247
248
0
  return ISC_R_SUCCESS;
249
0
}
250
251
static isc_result_t
252
0
digest_sshfp(ARGS_DIGEST) {
253
0
  isc_region_t r;
254
255
0
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
256
257
0
  dns_rdata_toregion(rdata, &r);
258
259
0
  return (digest)(arg, &r);
260
0
}
261
262
static bool
263
0
checkowner_sshfp(ARGS_CHECKOWNER) {
264
0
  REQUIRE(type == dns_rdatatype_sshfp);
265
266
0
  UNUSED(name);
267
0
  UNUSED(type);
268
0
  UNUSED(rdclass);
269
0
  UNUSED(wildcard);
270
271
0
  return true;
272
0
}
273
274
static bool
275
0
checknames_sshfp(ARGS_CHECKNAMES) {
276
0
  REQUIRE(rdata->type == dns_rdatatype_sshfp);
277
278
0
  UNUSED(rdata);
279
0
  UNUSED(owner);
280
0
  UNUSED(bad);
281
282
0
  return true;
283
0
}
284
285
static int
286
0
casecompare_sshfp(ARGS_COMPARE) {
287
0
  return compare_sshfp(rdata1, rdata2);
288
0
}
289
290
#endif /* RDATA_GENERIC_SSHFP_44_C */