/contrib/bind9/lib/dns/ds.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 160 lines · 123 code · 19 blank · 18 comment · 14 complexity · 46525e6c294c092e9b802ffe3103d26a MD5 · raw file

  1. /*
  2. * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2002, 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: ds.c,v 1.13 2010/12/23 23:47:08 tbox Exp $ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <string.h>
  21. #include <isc/buffer.h>
  22. #include <isc/region.h>
  23. #include <isc/sha1.h>
  24. #include <isc/sha2.h>
  25. #include <isc/util.h>
  26. #include <dns/ds.h>
  27. #include <dns/fixedname.h>
  28. #include <dns/name.h>
  29. #include <dns/rdata.h>
  30. #include <dns/rdatastruct.h>
  31. #include <dns/result.h>
  32. #include <dst/dst.h>
  33. #ifdef HAVE_OPENSSL_GOST
  34. #include <dst/result.h>
  35. #include <openssl/evp.h>
  36. extern const EVP_MD * EVP_gost(void);
  37. #endif
  38. isc_result_t
  39. dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
  40. unsigned int digest_type, unsigned char *buffer,
  41. dns_rdata_t *rdata)
  42. {
  43. dns_fixedname_t fname;
  44. dns_name_t *name;
  45. unsigned char digest[ISC_SHA256_DIGESTLENGTH];
  46. isc_region_t r;
  47. isc_buffer_t b;
  48. dns_rdata_ds_t ds;
  49. isc_sha1_t sha1;
  50. isc_sha256_t sha256;
  51. #ifdef HAVE_OPENSSL_GOST
  52. EVP_MD_CTX ctx;
  53. const EVP_MD *md;
  54. #endif
  55. REQUIRE(key != NULL);
  56. REQUIRE(key->type == dns_rdatatype_dnskey);
  57. if (!dns_ds_digest_supported(digest_type))
  58. return (ISC_R_NOTIMPLEMENTED);
  59. dns_fixedname_init(&fname);
  60. name = dns_fixedname_name(&fname);
  61. (void)dns_name_downcase(owner, name, NULL);
  62. memset(buffer, 0, DNS_DS_BUFFERSIZE);
  63. isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
  64. switch (digest_type) {
  65. case DNS_DSDIGEST_SHA1:
  66. isc_sha1_init(&sha1);
  67. dns_name_toregion(name, &r);
  68. isc_sha1_update(&sha1, r.base, r.length);
  69. dns_rdata_toregion(key, &r);
  70. INSIST(r.length >= 4);
  71. isc_sha1_update(&sha1, r.base, r.length);
  72. isc_sha1_final(&sha1, digest);
  73. break;
  74. #ifdef HAVE_OPENSSL_GOST
  75. #define CHECK(x) \
  76. if ((x) != 1) { \
  77. EVP_MD_CTX_cleanup(&ctx); \
  78. return (DST_R_OPENSSLFAILURE); \
  79. }
  80. case DNS_DSDIGEST_GOST:
  81. md = EVP_gost();
  82. if (md == NULL)
  83. return (DST_R_OPENSSLFAILURE);
  84. EVP_MD_CTX_init(&ctx);
  85. CHECK(EVP_DigestInit(&ctx, md));
  86. dns_name_toregion(name, &r);
  87. CHECK(EVP_DigestUpdate(&ctx,
  88. (const void *) r.base,
  89. (size_t) r.length));
  90. dns_rdata_toregion(key, &r);
  91. INSIST(r.length >= 4);
  92. CHECK(EVP_DigestUpdate(&ctx,
  93. (const void *) r.base,
  94. (size_t) r.length));
  95. CHECK(EVP_DigestFinal(&ctx, digest, NULL));
  96. break;
  97. #endif
  98. default:
  99. isc_sha256_init(&sha256);
  100. dns_name_toregion(name, &r);
  101. isc_sha256_update(&sha256, r.base, r.length);
  102. dns_rdata_toregion(key, &r);
  103. INSIST(r.length >= 4);
  104. isc_sha256_update(&sha256, r.base, r.length);
  105. isc_sha256_final(digest, &sha256);
  106. break;
  107. }
  108. ds.mctx = NULL;
  109. ds.common.rdclass = key->rdclass;
  110. ds.common.rdtype = dns_rdatatype_ds;
  111. ds.algorithm = r.base[3];
  112. ds.key_tag = dst_region_computeid(&r, ds.algorithm);
  113. ds.digest_type = digest_type;
  114. switch (digest_type) {
  115. case DNS_DSDIGEST_SHA1:
  116. ds.length = ISC_SHA1_DIGESTLENGTH;
  117. break;
  118. #ifdef HAVE_OPENSSL_GOST
  119. case DNS_DSDIGEST_GOST:
  120. ds.length = ISC_GOST_DIGESTLENGTH;
  121. break;
  122. #endif
  123. default:
  124. ds.length = ISC_SHA256_DIGESTLENGTH;
  125. break;
  126. }
  127. ds.digest = digest;
  128. return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
  129. &ds, &b));
  130. }
  131. isc_boolean_t
  132. dns_ds_digest_supported(unsigned int digest_type) {
  133. #ifdef HAVE_OPENSSL_GOST
  134. return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
  135. digest_type == DNS_DSDIGEST_SHA256 ||
  136. digest_type == DNS_DSDIGEST_GOST));
  137. #else
  138. return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
  139. digest_type == DNS_DSDIGEST_SHA256));
  140. #endif
  141. }