/contrib/bind9/lib/dns/rdata/generic/ds_43.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 341 lines · 223 code · 68 blank · 50 comment · 53 complexity · 4c904ee5885d4afe9c4e8f5065434f1c MD5 · raw file

  1. /*
  2. * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2002 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id$ */
  18. /* draft-ietf-dnsext-delegation-signer-05.txt */
  19. #ifndef RDATA_GENERIC_DS_43_C
  20. #define RDATA_GENERIC_DS_43_C
  21. #define RRTYPE_DS_ATTRIBUTES \
  22. (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
  23. #include <isc/sha1.h>
  24. #include <isc/sha2.h>
  25. #include <dns/ds.h>
  26. static inline isc_result_t
  27. fromtext_ds(ARGS_FROMTEXT) {
  28. isc_token_t token;
  29. unsigned char c;
  30. int length;
  31. REQUIRE(type == 43);
  32. UNUSED(type);
  33. UNUSED(rdclass);
  34. UNUSED(origin);
  35. UNUSED(options);
  36. UNUSED(callbacks);
  37. /*
  38. * Key tag.
  39. */
  40. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  41. ISC_FALSE));
  42. if (token.value.as_ulong > 0xffffU)
  43. RETTOK(ISC_R_RANGE);
  44. RETERR(uint16_tobuffer(token.value.as_ulong, target));
  45. /*
  46. * Algorithm.
  47. */
  48. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  49. ISC_FALSE));
  50. RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
  51. RETERR(mem_tobuffer(target, &c, 1));
  52. /*
  53. * Digest type.
  54. */
  55. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  56. ISC_FALSE));
  57. if (token.value.as_ulong > 0xffU)
  58. RETTOK(ISC_R_RANGE);
  59. RETERR(uint8_tobuffer(token.value.as_ulong, target));
  60. c = (unsigned char) token.value.as_ulong;
  61. /*
  62. * Digest.
  63. */
  64. switch (c) {
  65. case DNS_DSDIGEST_SHA1:
  66. length = ISC_SHA1_DIGESTLENGTH;
  67. break;
  68. case DNS_DSDIGEST_SHA256:
  69. length = ISC_SHA256_DIGESTLENGTH;
  70. break;
  71. case DNS_DSDIGEST_GOST:
  72. length = ISC_GOST_DIGESTLENGTH;
  73. break;
  74. default:
  75. length = -1;
  76. break;
  77. }
  78. return (isc_hex_tobuffer(lexer, target, length));
  79. }
  80. static inline isc_result_t
  81. totext_ds(ARGS_TOTEXT) {
  82. isc_region_t sr;
  83. char buf[sizeof("64000 ")];
  84. unsigned int n;
  85. REQUIRE(rdata->type == 43);
  86. REQUIRE(rdata->length != 0);
  87. UNUSED(tctx);
  88. dns_rdata_toregion(rdata, &sr);
  89. /*
  90. * Key tag.
  91. */
  92. n = uint16_fromregion(&sr);
  93. isc_region_consume(&sr, 2);
  94. sprintf(buf, "%u ", n);
  95. RETERR(str_totext(buf, target));
  96. /*
  97. * Algorithm.
  98. */
  99. n = uint8_fromregion(&sr);
  100. isc_region_consume(&sr, 1);
  101. sprintf(buf, "%u ", n);
  102. RETERR(str_totext(buf, target));
  103. /*
  104. * Digest type.
  105. */
  106. n = uint8_fromregion(&sr);
  107. isc_region_consume(&sr, 1);
  108. sprintf(buf, "%u", n);
  109. RETERR(str_totext(buf, target));
  110. /*
  111. * Digest.
  112. */
  113. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  114. RETERR(str_totext(" (", target));
  115. RETERR(str_totext(tctx->linebreak, target));
  116. RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target));
  117. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  118. RETERR(str_totext(" )", target));
  119. return (ISC_R_SUCCESS);
  120. }
  121. static inline isc_result_t
  122. fromwire_ds(ARGS_FROMWIRE) {
  123. isc_region_t sr;
  124. REQUIRE(type == 43);
  125. UNUSED(type);
  126. UNUSED(rdclass);
  127. UNUSED(dctx);
  128. UNUSED(options);
  129. isc_buffer_activeregion(source, &sr);
  130. /*
  131. * Check digest lengths if we know them.
  132. */
  133. if (sr.length < 4 ||
  134. (sr.base[3] == DNS_DSDIGEST_SHA1 &&
  135. sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
  136. (sr.base[3] == DNS_DSDIGEST_SHA256 &&
  137. sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
  138. (sr.base[3] == DNS_DSDIGEST_GOST &&
  139. sr.length < 4 + ISC_GOST_DIGESTLENGTH))
  140. return (ISC_R_UNEXPECTEDEND);
  141. /*
  142. * Only copy digest lengths if we know them.
  143. * If there is extra data dns_rdata_fromwire() will
  144. * detect that.
  145. */
  146. if (sr.base[3] == DNS_DSDIGEST_SHA1)
  147. sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
  148. else if (sr.base[3] == DNS_DSDIGEST_SHA256)
  149. sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
  150. else if (sr.base[3] == DNS_DSDIGEST_GOST)
  151. sr.length = 4 + ISC_GOST_DIGESTLENGTH;
  152. isc_buffer_forward(source, sr.length);
  153. return (mem_tobuffer(target, sr.base, sr.length));
  154. }
  155. static inline isc_result_t
  156. towire_ds(ARGS_TOWIRE) {
  157. isc_region_t sr;
  158. REQUIRE(rdata->type == 43);
  159. REQUIRE(rdata->length != 0);
  160. UNUSED(cctx);
  161. dns_rdata_toregion(rdata, &sr);
  162. return (mem_tobuffer(target, sr.base, sr.length));
  163. }
  164. static inline int
  165. compare_ds(ARGS_COMPARE) {
  166. isc_region_t r1;
  167. isc_region_t r2;
  168. REQUIRE(rdata1->type == rdata2->type);
  169. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  170. REQUIRE(rdata1->type == 43);
  171. REQUIRE(rdata1->length != 0);
  172. REQUIRE(rdata2->length != 0);
  173. dns_rdata_toregion(rdata1, &r1);
  174. dns_rdata_toregion(rdata2, &r2);
  175. return (isc_region_compare(&r1, &r2));
  176. }
  177. static inline isc_result_t
  178. fromstruct_ds(ARGS_FROMSTRUCT) {
  179. dns_rdata_ds_t *ds = source;
  180. REQUIRE(type == 43);
  181. REQUIRE(source != NULL);
  182. REQUIRE(ds->common.rdtype == type);
  183. REQUIRE(ds->common.rdclass == rdclass);
  184. switch (ds->digest_type) {
  185. case DNS_DSDIGEST_SHA1:
  186. REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
  187. break;
  188. case DNS_DSDIGEST_SHA256:
  189. REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
  190. break;
  191. case DNS_DSDIGEST_GOST:
  192. REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
  193. break;
  194. }
  195. UNUSED(type);
  196. UNUSED(rdclass);
  197. RETERR(uint16_tobuffer(ds->key_tag, target));
  198. RETERR(uint8_tobuffer(ds->algorithm, target));
  199. RETERR(uint8_tobuffer(ds->digest_type, target));
  200. return (mem_tobuffer(target, ds->digest, ds->length));
  201. }
  202. static inline isc_result_t
  203. tostruct_ds(ARGS_TOSTRUCT) {
  204. dns_rdata_ds_t *ds = target;
  205. isc_region_t region;
  206. REQUIRE(rdata->type == 43);
  207. REQUIRE(target != NULL);
  208. REQUIRE(rdata->length != 0);
  209. ds->common.rdclass = rdata->rdclass;
  210. ds->common.rdtype = rdata->type;
  211. ISC_LINK_INIT(&ds->common, link);
  212. dns_rdata_toregion(rdata, &region);
  213. ds->key_tag = uint16_fromregion(&region);
  214. isc_region_consume(&region, 2);
  215. ds->algorithm = uint8_fromregion(&region);
  216. isc_region_consume(&region, 1);
  217. ds->digest_type = uint8_fromregion(&region);
  218. isc_region_consume(&region, 1);
  219. ds->length = region.length;
  220. ds->digest = mem_maybedup(mctx, region.base, region.length);
  221. if (ds->digest == NULL)
  222. return (ISC_R_NOMEMORY);
  223. ds->mctx = mctx;
  224. return (ISC_R_SUCCESS);
  225. }
  226. static inline void
  227. freestruct_ds(ARGS_FREESTRUCT) {
  228. dns_rdata_ds_t *ds = source;
  229. REQUIRE(ds != NULL);
  230. REQUIRE(ds->common.rdtype == 43);
  231. if (ds->mctx == NULL)
  232. return;
  233. if (ds->digest != NULL)
  234. isc_mem_free(ds->mctx, ds->digest);
  235. ds->mctx = NULL;
  236. }
  237. static inline isc_result_t
  238. additionaldata_ds(ARGS_ADDLDATA) {
  239. REQUIRE(rdata->type == 43);
  240. UNUSED(rdata);
  241. UNUSED(add);
  242. UNUSED(arg);
  243. return (ISC_R_SUCCESS);
  244. }
  245. static inline isc_result_t
  246. digest_ds(ARGS_DIGEST) {
  247. isc_region_t r;
  248. REQUIRE(rdata->type == 43);
  249. dns_rdata_toregion(rdata, &r);
  250. return ((digest)(arg, &r));
  251. }
  252. static inline isc_boolean_t
  253. checkowner_ds(ARGS_CHECKOWNER) {
  254. REQUIRE(type == 43);
  255. UNUSED(name);
  256. UNUSED(type);
  257. UNUSED(rdclass);
  258. UNUSED(wildcard);
  259. return (ISC_TRUE);
  260. }
  261. static inline isc_boolean_t
  262. checknames_ds(ARGS_CHECKNAMES) {
  263. REQUIRE(rdata->type == 43);
  264. UNUSED(rdata);
  265. UNUSED(owner);
  266. UNUSED(bad);
  267. return (ISC_TRUE);
  268. }
  269. static inline int
  270. casecompare_ds(ARGS_COMPARE) {
  271. return (compare_ds(rdata1, rdata2));
  272. }
  273. #endif /* RDATA_GENERIC_DS_43_C */