00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef RDATA_GENERIC_DS_43_C
00023 #define RDATA_GENERIC_DS_43_C
00024
00025 #define RRTYPE_DS_ATTRIBUTES \
00026 (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
00027
00028 #include <isc/sha1.h>
00029 #include <isc/sha2.h>
00030
00031 #include <dns/ds.h>
00032
00033 #include "dst_gost.h"
00034
00035 static inline isc_result_t
00036 fromtext_ds(ARGS_FROMTEXT) {
00037 isc_token_t token;
00038 unsigned char c;
00039 int length;
00040
00041 REQUIRE(type == 43);
00042
00043 UNUSED(type);
00044 UNUSED(rdclass);
00045 UNUSED(origin);
00046 UNUSED(options);
00047 UNUSED(callbacks);
00048
00049
00050
00051
00052 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00053 ISC_FALSE));
00054 if (token.value.as_ulong > 0xffffU)
00055 RETTOK(ISC_R_RANGE);
00056 RETERR(uint16_tobuffer(token.value.as_ulong, target));
00057
00058
00059
00060
00061 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00062 ISC_FALSE));
00063 RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
00064 RETERR(mem_tobuffer(target, &c, 1));
00065
00066
00067
00068
00069 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00070 ISC_FALSE));
00071 RETTOK(dns_dsdigest_fromtext(&c, &token.value.as_textregion));
00072 RETERR(mem_tobuffer(target, &c, 1));
00073
00074
00075
00076
00077 switch (c) {
00078 case DNS_DSDIGEST_SHA1:
00079 length = ISC_SHA1_DIGESTLENGTH;
00080 break;
00081 case DNS_DSDIGEST_SHA256:
00082 length = ISC_SHA256_DIGESTLENGTH;
00083 break;
00084 #ifdef ISC_GOST_DIGESTLENGTH
00085 case DNS_DSDIGEST_GOST:
00086 length = ISC_GOST_DIGESTLENGTH;
00087 break;
00088 #endif
00089 case DNS_DSDIGEST_SHA384:
00090 length = ISC_SHA384_DIGESTLENGTH;
00091 break;
00092 default:
00093 length = -1;
00094 break;
00095 }
00096 return (isc_hex_tobuffer(lexer, target, length));
00097 }
00098
00099 static inline isc_result_t
00100 totext_ds(ARGS_TOTEXT) {
00101 isc_region_t sr;
00102 char buf[sizeof("64000 ")];
00103 unsigned int n;
00104
00105 REQUIRE(rdata->type == 43);
00106 REQUIRE(rdata->length != 0);
00107
00108 UNUSED(tctx);
00109
00110 dns_rdata_toregion(rdata, &sr);
00111
00112
00113
00114
00115 n = uint16_fromregion(&sr);
00116 isc_region_consume(&sr, 2);
00117 sprintf(buf, "%u ", n);
00118 RETERR(str_totext(buf, target));
00119
00120
00121
00122
00123 n = uint8_fromregion(&sr);
00124 isc_region_consume(&sr, 1);
00125 sprintf(buf, "%u ", n);
00126 RETERR(str_totext(buf, target));
00127
00128
00129
00130
00131 n = uint8_fromregion(&sr);
00132 isc_region_consume(&sr, 1);
00133 sprintf(buf, "%u", n);
00134 RETERR(str_totext(buf, target));
00135
00136
00137
00138
00139 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00140 RETERR(str_totext(" (", target));
00141 RETERR(str_totext(tctx->linebreak, target));
00142 if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) {
00143 if (tctx->width == 0)
00144 RETERR(isc_hex_totext(&sr, 0, "", target));
00145 else
00146 RETERR(isc_hex_totext(&sr, tctx->width - 2,
00147 tctx->linebreak, target));
00148 } else
00149 RETERR(str_totext("[omitted]", target));
00150 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
00151 RETERR(str_totext(" )", target));
00152 return (ISC_R_SUCCESS);
00153 }
00154
00155 static inline isc_result_t
00156 fromwire_ds(ARGS_FROMWIRE) {
00157 isc_region_t sr;
00158
00159 REQUIRE(type == 43);
00160
00161 UNUSED(type);
00162 UNUSED(rdclass);
00163 UNUSED(dctx);
00164 UNUSED(options);
00165
00166 isc_buffer_activeregion(source, &sr);
00167
00168
00169
00170
00171 if (sr.length < 4 ||
00172 (sr.base[3] == DNS_DSDIGEST_SHA1 &&
00173 sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
00174 (sr.base[3] == DNS_DSDIGEST_SHA256 &&
00175 sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
00176 #ifdef ISC_GOST_DIGESTLENGTH
00177 (sr.base[3] == DNS_DSDIGEST_GOST &&
00178 sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
00179 #endif
00180 (sr.base[3] == DNS_DSDIGEST_SHA384 &&
00181 sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
00182 return (ISC_R_UNEXPECTEDEND);
00183
00184
00185
00186
00187
00188
00189 if (sr.base[3] == DNS_DSDIGEST_SHA1)
00190 sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
00191 else if (sr.base[3] == DNS_DSDIGEST_SHA256)
00192 sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
00193 #ifdef ISC_GOST_DIGESTLENGTH
00194 else if (sr.base[3] == DNS_DSDIGEST_GOST)
00195 sr.length = 4 + ISC_GOST_DIGESTLENGTH;
00196 #endif
00197 else if (sr.base[3] == DNS_DSDIGEST_SHA384)
00198 sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
00199
00200 isc_buffer_forward(source, sr.length);
00201 return (mem_tobuffer(target, sr.base, sr.length));
00202 }
00203
00204 static inline isc_result_t
00205 towire_ds(ARGS_TOWIRE) {
00206 isc_region_t sr;
00207
00208 REQUIRE(rdata->type == 43);
00209 REQUIRE(rdata->length != 0);
00210
00211 UNUSED(cctx);
00212
00213 dns_rdata_toregion(rdata, &sr);
00214 return (mem_tobuffer(target, sr.base, sr.length));
00215 }
00216
00217 static inline int
00218 compare_ds(ARGS_COMPARE) {
00219 isc_region_t r1;
00220 isc_region_t r2;
00221
00222 REQUIRE(rdata1->type == rdata2->type);
00223 REQUIRE(rdata1->rdclass == rdata2->rdclass);
00224 REQUIRE(rdata1->type == 43);
00225 REQUIRE(rdata1->length != 0);
00226 REQUIRE(rdata2->length != 0);
00227
00228 dns_rdata_toregion(rdata1, &r1);
00229 dns_rdata_toregion(rdata2, &r2);
00230 return (isc_region_compare(&r1, &r2));
00231 }
00232
00233 static inline isc_result_t
00234 fromstruct_ds(ARGS_FROMSTRUCT) {
00235 dns_rdata_ds_t *ds = source;
00236
00237 REQUIRE(type == 43);
00238 REQUIRE(source != NULL);
00239 REQUIRE(ds->common.rdtype == type);
00240 REQUIRE(ds->common.rdclass == rdclass);
00241 switch (ds->digest_type) {
00242 case DNS_DSDIGEST_SHA1:
00243 REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
00244 break;
00245 case DNS_DSDIGEST_SHA256:
00246 REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
00247 break;
00248 #ifdef ISC_GOST_DIGESTLENGTH
00249 case DNS_DSDIGEST_GOST:
00250 REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
00251 break;
00252 #endif
00253 case DNS_DSDIGEST_SHA384:
00254 REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
00255 break;
00256 }
00257
00258 UNUSED(type);
00259 UNUSED(rdclass);
00260
00261 RETERR(uint16_tobuffer(ds->key_tag, target));
00262 RETERR(uint8_tobuffer(ds->algorithm, target));
00263 RETERR(uint8_tobuffer(ds->digest_type, target));
00264
00265 return (mem_tobuffer(target, ds->digest, ds->length));
00266 }
00267
00268 static inline isc_result_t
00269 tostruct_ds(ARGS_TOSTRUCT) {
00270 dns_rdata_ds_t *ds = target;
00271 isc_region_t region;
00272
00273 REQUIRE(rdata->type == 43);
00274 REQUIRE(target != NULL);
00275 REQUIRE(rdata->length != 0);
00276
00277 ds->common.rdclass = rdata->rdclass;
00278 ds->common.rdtype = rdata->type;
00279 ISC_LINK_INIT(&ds->common, link);
00280
00281 dns_rdata_toregion(rdata, ®ion);
00282
00283 ds->key_tag = uint16_fromregion(®ion);
00284 isc_region_consume(®ion, 2);
00285 ds->algorithm = uint8_fromregion(®ion);
00286 isc_region_consume(®ion, 1);
00287 ds->digest_type = uint8_fromregion(®ion);
00288 isc_region_consume(®ion, 1);
00289 ds->length = region.length;
00290
00291 ds->digest = mem_maybedup(mctx, region.base, region.length);
00292 if (ds->digest == NULL)
00293 return (ISC_R_NOMEMORY);
00294
00295 ds->mctx = mctx;
00296 return (ISC_R_SUCCESS);
00297 }
00298
00299 static inline void
00300 freestruct_ds(ARGS_FREESTRUCT) {
00301 dns_rdata_ds_t *ds = source;
00302
00303 REQUIRE(ds != NULL);
00304 REQUIRE(ds->common.rdtype == 43);
00305
00306 if (ds->mctx == NULL)
00307 return;
00308
00309 if (ds->digest != NULL)
00310 isc_mem_free(ds->mctx, ds->digest);
00311 ds->mctx = NULL;
00312 }
00313
00314 static inline isc_result_t
00315 additionaldata_ds(ARGS_ADDLDATA) {
00316 REQUIRE(rdata->type == 43);
00317
00318 UNUSED(rdata);
00319 UNUSED(add);
00320 UNUSED(arg);
00321
00322 return (ISC_R_SUCCESS);
00323 }
00324
00325 static inline isc_result_t
00326 digest_ds(ARGS_DIGEST) {
00327 isc_region_t r;
00328
00329 REQUIRE(rdata->type == 43);
00330
00331 dns_rdata_toregion(rdata, &r);
00332
00333 return ((digest)(arg, &r));
00334 }
00335
00336 static inline isc_boolean_t
00337 checkowner_ds(ARGS_CHECKOWNER) {
00338
00339 REQUIRE(type == 43);
00340
00341 UNUSED(name);
00342 UNUSED(type);
00343 UNUSED(rdclass);
00344 UNUSED(wildcard);
00345
00346 return (ISC_TRUE);
00347 }
00348
00349 static inline isc_boolean_t
00350 checknames_ds(ARGS_CHECKNAMES) {
00351
00352 REQUIRE(rdata->type == 43);
00353
00354 UNUSED(rdata);
00355 UNUSED(owner);
00356 UNUSED(bad);
00357
00358 return (ISC_TRUE);
00359 }
00360
00361 static inline int
00362 casecompare_ds(ARGS_COMPARE) {
00363 return (compare_ds(rdata1, rdata2));
00364 }
00365
00366 #endif