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

https://bitbucket.org/freebsd/freebsd-head/ · C · 590 lines · 326 code · 106 blank · 158 comment · 64 complexity · d805e5e1000b8c19e4da39d9c53be817 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2003 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. /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
  19. /* RFC2535 */
  20. #ifndef RDATA_GENERIC_RRSIG_46_C
  21. #define RDATA_GENERIC_RRSIG_46_C
  22. #define RRTYPE_RRSIG_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
  23. static inline isc_result_t
  24. fromtext_rrsig(ARGS_FROMTEXT) {
  25. isc_token_t token;
  26. unsigned char c;
  27. long i;
  28. dns_rdatatype_t covered;
  29. char *e;
  30. isc_result_t result;
  31. dns_name_t name;
  32. isc_buffer_t buffer;
  33. isc_uint32_t time_signed, time_expire;
  34. REQUIRE(type == 46);
  35. UNUSED(type);
  36. UNUSED(rdclass);
  37. UNUSED(callbacks);
  38. /*
  39. * Type covered.
  40. */
  41. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  42. ISC_FALSE));
  43. result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
  44. if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
  45. i = strtol(DNS_AS_STR(token), &e, 10);
  46. if (i < 0 || i > 65535)
  47. RETTOK(ISC_R_RANGE);
  48. if (*e != 0)
  49. RETTOK(result);
  50. covered = (dns_rdatatype_t)i;
  51. }
  52. RETERR(uint16_tobuffer(covered, target));
  53. /*
  54. * Algorithm.
  55. */
  56. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  57. ISC_FALSE));
  58. RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
  59. RETERR(mem_tobuffer(target, &c, 1));
  60. /*
  61. * Labels.
  62. */
  63. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  64. ISC_FALSE));
  65. if (token.value.as_ulong > 0xffU)
  66. RETTOK(ISC_R_RANGE);
  67. c = (unsigned char)token.value.as_ulong;
  68. RETERR(mem_tobuffer(target, &c, 1));
  69. /*
  70. * Original ttl.
  71. */
  72. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  73. ISC_FALSE));
  74. RETERR(uint32_tobuffer(token.value.as_ulong, target));
  75. /*
  76. * Signature expiration.
  77. */
  78. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  79. ISC_FALSE));
  80. RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
  81. RETERR(uint32_tobuffer(time_expire, target));
  82. /*
  83. * Time signed.
  84. */
  85. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  86. ISC_FALSE));
  87. RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
  88. RETERR(uint32_tobuffer(time_signed, target));
  89. /*
  90. * Key footprint.
  91. */
  92. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  93. ISC_FALSE));
  94. RETERR(uint16_tobuffer(token.value.as_ulong, target));
  95. /*
  96. * Signer.
  97. */
  98. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
  99. ISC_FALSE));
  100. dns_name_init(&name, NULL);
  101. buffer_fromregion(&buffer, &token.value.as_region);
  102. origin = (origin != NULL) ? origin : dns_rootname;
  103. RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
  104. /*
  105. * Sig.
  106. */
  107. return (isc_base64_tobuffer(lexer, target, -1));
  108. }
  109. static inline isc_result_t
  110. totext_rrsig(ARGS_TOTEXT) {
  111. isc_region_t sr;
  112. char buf[sizeof("4294967295")];
  113. dns_rdatatype_t covered;
  114. unsigned long ttl;
  115. unsigned long when;
  116. unsigned long exp;
  117. unsigned long foot;
  118. dns_name_t name;
  119. REQUIRE(rdata->type == 46);
  120. REQUIRE(rdata->length != 0);
  121. dns_rdata_toregion(rdata, &sr);
  122. /*
  123. * Type covered.
  124. */
  125. covered = uint16_fromregion(&sr);
  126. isc_region_consume(&sr, 2);
  127. /*
  128. * XXXAG We should have something like dns_rdatatype_isknown()
  129. * that does the right thing with type 0.
  130. */
  131. if (dns_rdatatype_isknown(covered) && covered != 0) {
  132. RETERR(dns_rdatatype_totext(covered, target));
  133. } else {
  134. char buf[sizeof("TYPE65535")];
  135. sprintf(buf, "TYPE%u", covered);
  136. RETERR(str_totext(buf, target));
  137. }
  138. RETERR(str_totext(" ", target));
  139. /*
  140. * Algorithm.
  141. */
  142. sprintf(buf, "%u", sr.base[0]);
  143. isc_region_consume(&sr, 1);
  144. RETERR(str_totext(buf, target));
  145. RETERR(str_totext(" ", target));
  146. /*
  147. * Labels.
  148. */
  149. sprintf(buf, "%u", sr.base[0]);
  150. isc_region_consume(&sr, 1);
  151. RETERR(str_totext(buf, target));
  152. RETERR(str_totext(" ", target));
  153. /*
  154. * Ttl.
  155. */
  156. ttl = uint32_fromregion(&sr);
  157. isc_region_consume(&sr, 4);
  158. sprintf(buf, "%lu", ttl);
  159. RETERR(str_totext(buf, target));
  160. RETERR(str_totext(" ", target));
  161. /*
  162. * Sig exp.
  163. */
  164. exp = uint32_fromregion(&sr);
  165. isc_region_consume(&sr, 4);
  166. RETERR(dns_time32_totext(exp, target));
  167. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  168. RETERR(str_totext(" (", target));
  169. RETERR(str_totext(tctx->linebreak, target));
  170. /*
  171. * Time signed.
  172. */
  173. when = uint32_fromregion(&sr);
  174. isc_region_consume(&sr, 4);
  175. RETERR(dns_time32_totext(when, target));
  176. RETERR(str_totext(" ", target));
  177. /*
  178. * Footprint.
  179. */
  180. foot = uint16_fromregion(&sr);
  181. isc_region_consume(&sr, 2);
  182. sprintf(buf, "%lu", foot);
  183. RETERR(str_totext(buf, target));
  184. RETERR(str_totext(" ", target));
  185. /*
  186. * Signer.
  187. */
  188. dns_name_init(&name, NULL);
  189. dns_name_fromregion(&name, &sr);
  190. isc_region_consume(&sr, name_length(&name));
  191. RETERR(dns_name_totext(&name, ISC_FALSE, target));
  192. /*
  193. * Sig.
  194. */
  195. RETERR(str_totext(tctx->linebreak, target));
  196. RETERR(isc_base64_totext(&sr, tctx->width - 2,
  197. tctx->linebreak, target));
  198. if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
  199. RETERR(str_totext(" )", target));
  200. return (ISC_R_SUCCESS);
  201. }
  202. static inline isc_result_t
  203. fromwire_rrsig(ARGS_FROMWIRE) {
  204. isc_region_t sr;
  205. dns_name_t name;
  206. REQUIRE(type == 46);
  207. UNUSED(type);
  208. UNUSED(rdclass);
  209. dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
  210. isc_buffer_activeregion(source, &sr);
  211. /*
  212. * type covered: 2
  213. * algorithm: 1
  214. * labels: 1
  215. * original ttl: 4
  216. * signature expiration: 4
  217. * time signed: 4
  218. * key footprint: 2
  219. */
  220. if (sr.length < 18)
  221. return (ISC_R_UNEXPECTEDEND);
  222. isc_buffer_forward(source, 18);
  223. RETERR(mem_tobuffer(target, sr.base, 18));
  224. /*
  225. * Signer.
  226. */
  227. dns_name_init(&name, NULL);
  228. RETERR(dns_name_fromwire(&name, source, dctx, options, target));
  229. /*
  230. * Sig.
  231. */
  232. isc_buffer_activeregion(source, &sr);
  233. isc_buffer_forward(source, sr.length);
  234. return (mem_tobuffer(target, sr.base, sr.length));
  235. }
  236. static inline isc_result_t
  237. towire_rrsig(ARGS_TOWIRE) {
  238. isc_region_t sr;
  239. dns_name_t name;
  240. dns_offsets_t offsets;
  241. REQUIRE(rdata->type == 46);
  242. REQUIRE(rdata->length != 0);
  243. dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
  244. dns_rdata_toregion(rdata, &sr);
  245. /*
  246. * type covered: 2
  247. * algorithm: 1
  248. * labels: 1
  249. * original ttl: 4
  250. * signature expiration: 4
  251. * time signed: 4
  252. * key footprint: 2
  253. */
  254. RETERR(mem_tobuffer(target, sr.base, 18));
  255. isc_region_consume(&sr, 18);
  256. /*
  257. * Signer.
  258. */
  259. dns_name_init(&name, offsets);
  260. dns_name_fromregion(&name, &sr);
  261. isc_region_consume(&sr, name_length(&name));
  262. RETERR(dns_name_towire(&name, cctx, target));
  263. /*
  264. * Signature.
  265. */
  266. return (mem_tobuffer(target, sr.base, sr.length));
  267. }
  268. static inline int
  269. compare_rrsig(ARGS_COMPARE) {
  270. isc_region_t r1;
  271. isc_region_t r2;
  272. REQUIRE(rdata1->type == rdata2->type);
  273. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  274. REQUIRE(rdata1->type == 46);
  275. REQUIRE(rdata1->length != 0);
  276. REQUIRE(rdata2->length != 0);
  277. dns_rdata_toregion(rdata1, &r1);
  278. dns_rdata_toregion(rdata2, &r2);
  279. return (isc_region_compare(&r1, &r2));
  280. }
  281. static inline isc_result_t
  282. fromstruct_rrsig(ARGS_FROMSTRUCT) {
  283. dns_rdata_rrsig_t *sig = source;
  284. REQUIRE(type == 46);
  285. REQUIRE(source != NULL);
  286. REQUIRE(sig->common.rdtype == type);
  287. REQUIRE(sig->common.rdclass == rdclass);
  288. REQUIRE(sig->signature != NULL || sig->siglen == 0);
  289. UNUSED(type);
  290. UNUSED(rdclass);
  291. /*
  292. * Type covered.
  293. */
  294. RETERR(uint16_tobuffer(sig->covered, target));
  295. /*
  296. * Algorithm.
  297. */
  298. RETERR(uint8_tobuffer(sig->algorithm, target));
  299. /*
  300. * Labels.
  301. */
  302. RETERR(uint8_tobuffer(sig->labels, target));
  303. /*
  304. * Original TTL.
  305. */
  306. RETERR(uint32_tobuffer(sig->originalttl, target));
  307. /*
  308. * Expire time.
  309. */
  310. RETERR(uint32_tobuffer(sig->timeexpire, target));
  311. /*
  312. * Time signed.
  313. */
  314. RETERR(uint32_tobuffer(sig->timesigned, target));
  315. /*
  316. * Key ID.
  317. */
  318. RETERR(uint16_tobuffer(sig->keyid, target));
  319. /*
  320. * Signer name.
  321. */
  322. RETERR(name_tobuffer(&sig->signer, target));
  323. /*
  324. * Signature.
  325. */
  326. return (mem_tobuffer(target, sig->signature, sig->siglen));
  327. }
  328. static inline isc_result_t
  329. tostruct_rrsig(ARGS_TOSTRUCT) {
  330. isc_region_t sr;
  331. dns_rdata_rrsig_t *sig = target;
  332. dns_name_t signer;
  333. REQUIRE(rdata->type == 46);
  334. REQUIRE(target != NULL);
  335. REQUIRE(rdata->length != 0);
  336. sig->common.rdclass = rdata->rdclass;
  337. sig->common.rdtype = rdata->type;
  338. ISC_LINK_INIT(&sig->common, link);
  339. dns_rdata_toregion(rdata, &sr);
  340. /*
  341. * Type covered.
  342. */
  343. sig->covered = uint16_fromregion(&sr);
  344. isc_region_consume(&sr, 2);
  345. /*
  346. * Algorithm.
  347. */
  348. sig->algorithm = uint8_fromregion(&sr);
  349. isc_region_consume(&sr, 1);
  350. /*
  351. * Labels.
  352. */
  353. sig->labels = uint8_fromregion(&sr);
  354. isc_region_consume(&sr, 1);
  355. /*
  356. * Original TTL.
  357. */
  358. sig->originalttl = uint32_fromregion(&sr);
  359. isc_region_consume(&sr, 4);
  360. /*
  361. * Expire time.
  362. */
  363. sig->timeexpire = uint32_fromregion(&sr);
  364. isc_region_consume(&sr, 4);
  365. /*
  366. * Time signed.
  367. */
  368. sig->timesigned = uint32_fromregion(&sr);
  369. isc_region_consume(&sr, 4);
  370. /*
  371. * Key ID.
  372. */
  373. sig->keyid = uint16_fromregion(&sr);
  374. isc_region_consume(&sr, 2);
  375. dns_name_init(&signer, NULL);
  376. dns_name_fromregion(&signer, &sr);
  377. dns_name_init(&sig->signer, NULL);
  378. RETERR(name_duporclone(&signer, mctx, &sig->signer));
  379. isc_region_consume(&sr, name_length(&sig->signer));
  380. /*
  381. * Signature.
  382. */
  383. sig->siglen = sr.length;
  384. sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
  385. if (sig->signature == NULL)
  386. goto cleanup;
  387. sig->mctx = mctx;
  388. return (ISC_R_SUCCESS);
  389. cleanup:
  390. if (mctx != NULL)
  391. dns_name_free(&sig->signer, mctx);
  392. return (ISC_R_NOMEMORY);
  393. }
  394. static inline void
  395. freestruct_rrsig(ARGS_FREESTRUCT) {
  396. dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *) source;
  397. REQUIRE(source != NULL);
  398. REQUIRE(sig->common.rdtype == 46);
  399. if (sig->mctx == NULL)
  400. return;
  401. dns_name_free(&sig->signer, sig->mctx);
  402. if (sig->signature != NULL)
  403. isc_mem_free(sig->mctx, sig->signature);
  404. sig->mctx = NULL;
  405. }
  406. static inline isc_result_t
  407. additionaldata_rrsig(ARGS_ADDLDATA) {
  408. REQUIRE(rdata->type == 46);
  409. UNUSED(rdata);
  410. UNUSED(add);
  411. UNUSED(arg);
  412. return (ISC_R_SUCCESS);
  413. }
  414. static inline isc_result_t
  415. digest_rrsig(ARGS_DIGEST) {
  416. REQUIRE(rdata->type == 46);
  417. UNUSED(rdata);
  418. UNUSED(digest);
  419. UNUSED(arg);
  420. return (ISC_R_NOTIMPLEMENTED);
  421. }
  422. static inline dns_rdatatype_t
  423. covers_rrsig(dns_rdata_t *rdata) {
  424. dns_rdatatype_t type;
  425. isc_region_t r;
  426. REQUIRE(rdata->type == 46);
  427. dns_rdata_toregion(rdata, &r);
  428. type = uint16_fromregion(&r);
  429. return (type);
  430. }
  431. static inline isc_boolean_t
  432. checkowner_rrsig(ARGS_CHECKOWNER) {
  433. REQUIRE(type == 46);
  434. UNUSED(name);
  435. UNUSED(type);
  436. UNUSED(rdclass);
  437. UNUSED(wildcard);
  438. return (ISC_TRUE);
  439. }
  440. static inline isc_boolean_t
  441. checknames_rrsig(ARGS_CHECKNAMES) {
  442. REQUIRE(rdata->type == 46);
  443. UNUSED(rdata);
  444. UNUSED(owner);
  445. UNUSED(bad);
  446. return (ISC_TRUE);
  447. }
  448. static inline int
  449. casecompare_rrsig(ARGS_COMPARE) {
  450. isc_region_t r1;
  451. isc_region_t r2;
  452. dns_name_t name1;
  453. dns_name_t name2;
  454. int order;
  455. REQUIRE(rdata1->type == rdata2->type);
  456. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  457. REQUIRE(rdata1->type == 46);
  458. REQUIRE(rdata1->length != 0);
  459. REQUIRE(rdata2->length != 0);
  460. dns_rdata_toregion(rdata1, &r1);
  461. dns_rdata_toregion(rdata2, &r2);
  462. INSIST(r1.length > 18);
  463. INSIST(r2.length > 18);
  464. r1.length = 18;
  465. r2.length = 18;
  466. order = isc_region_compare(&r1, &r2);
  467. if (order != 0)
  468. return (order);
  469. dns_name_init(&name1, NULL);
  470. dns_name_init(&name2, NULL);
  471. dns_rdata_toregion(rdata1, &r1);
  472. dns_rdata_toregion(rdata2, &r2);
  473. isc_region_consume(&r1, 18);
  474. isc_region_consume(&r2, 18);
  475. dns_name_fromregion(&name1, &r1);
  476. dns_name_fromregion(&name2, &r2);
  477. order = dns_name_rdatacompare(&name1, &name2);
  478. if (order != 0)
  479. return (order);
  480. isc_region_consume(&r1, name_length(&name1));
  481. isc_region_consume(&r2, name_length(&name2));
  482. return (isc_region_compare(&r1, &r2));
  483. }
  484. #endif /* RDATA_GENERIC_RRSIG_46_C */