00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <string.h>
00025
00026 #include <isc/buffer.h>
00027 #include <isc/region.h>
00028 #include <isc/sha1.h>
00029 #include <isc/sha2.h>
00030 #include <isc/util.h>
00031
00032 #include <dns/ds.h>
00033 #include <dns/fixedname.h>
00034 #include <dns/name.h>
00035 #include <dns/rdata.h>
00036 #include <dns/rdatastruct.h>
00037 #include <dns/result.h>
00038
00039 #include <dst/dst.h>
00040
00041 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00042 #include "dst_gost.h"
00043 #endif
00044
00045 isc_result_t
00046 dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
00047 unsigned int digest_type, unsigned char *buffer,
00048 dns_rdata_t *rdata)
00049 {
00050 dns_fixedname_t fname;
00051 dns_name_t *name;
00052 unsigned char digest[ISC_SHA384_DIGESTLENGTH];
00053 isc_region_t r;
00054 isc_buffer_t b;
00055 dns_rdata_ds_t ds;
00056 isc_sha1_t sha1;
00057 isc_sha256_t sha256;
00058 isc_sha384_t sha384;
00059 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00060 isc_gost_t gost;
00061 #endif
00062
00063 REQUIRE(key != NULL);
00064 REQUIRE(key->type == dns_rdatatype_dnskey);
00065
00066 if (!dst_ds_digest_supported(digest_type))
00067 return (ISC_R_NOTIMPLEMENTED);
00068
00069 dns_fixedname_init(&fname);
00070 name = dns_fixedname_name(&fname);
00071 (void)dns_name_downcase(owner, name, NULL);
00072
00073 memset(buffer, 0, DNS_DS_BUFFERSIZE);
00074 isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
00075
00076 switch (digest_type) {
00077 case DNS_DSDIGEST_SHA1:
00078 isc_sha1_init(&sha1);
00079 dns_name_toregion(name, &r);
00080 isc_sha1_update(&sha1, r.base, r.length);
00081 dns_rdata_toregion(key, &r);
00082 INSIST(r.length >= 4);
00083 isc_sha1_update(&sha1, r.base, r.length);
00084 isc_sha1_final(&sha1, digest);
00085 break;
00086
00087 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00088 #define RETERR(x) do { \
00089 isc_result_t ret = (x); \
00090 if (ret != ISC_R_SUCCESS) { \
00091 isc_gost_invalidate(&gost); \
00092 return (ret); \
00093 } \
00094 } while (0)
00095
00096 case DNS_DSDIGEST_GOST:
00097 RETERR(isc_gost_init(&gost));
00098 dns_name_toregion(name, &r);
00099 RETERR(isc_gost_update(&gost, r.base, r.length));
00100 dns_rdata_toregion(key, &r);
00101 INSIST(r.length >= 4);
00102 RETERR(isc_gost_update(&gost, r.base, r.length));
00103 RETERR(isc_gost_final(&gost, digest));
00104 break;
00105 #endif
00106
00107 case DNS_DSDIGEST_SHA384:
00108 isc_sha384_init(&sha384);
00109 dns_name_toregion(name, &r);
00110 isc_sha384_update(&sha384, r.base, r.length);
00111 dns_rdata_toregion(key, &r);
00112 INSIST(r.length >= 4);
00113 isc_sha384_update(&sha384, r.base, r.length);
00114 isc_sha384_final(digest, &sha384);
00115 break;
00116
00117 case DNS_DSDIGEST_SHA256:
00118 default:
00119 isc_sha256_init(&sha256);
00120 dns_name_toregion(name, &r);
00121 isc_sha256_update(&sha256, r.base, r.length);
00122 dns_rdata_toregion(key, &r);
00123 INSIST(r.length >= 4);
00124 isc_sha256_update(&sha256, r.base, r.length);
00125 isc_sha256_final(digest, &sha256);
00126 break;
00127 }
00128
00129 ds.mctx = NULL;
00130 ds.common.rdclass = key->rdclass;
00131 ds.common.rdtype = dns_rdatatype_ds;
00132 ds.algorithm = r.base[3];
00133 ds.key_tag = dst_region_computeid(&r, ds.algorithm);
00134 ds.digest_type = digest_type;
00135 switch (digest_type) {
00136 case DNS_DSDIGEST_SHA1:
00137 ds.length = ISC_SHA1_DIGESTLENGTH;
00138 break;
00139
00140 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00141 case DNS_DSDIGEST_GOST:
00142 ds.length = ISC_GOST_DIGESTLENGTH;
00143 break;
00144 #endif
00145
00146 case DNS_DSDIGEST_SHA384:
00147 ds.length = ISC_SHA384_DIGESTLENGTH;
00148 break;
00149
00150 case DNS_DSDIGEST_SHA256:
00151 default:
00152 ds.length = ISC_SHA256_DIGESTLENGTH;
00153 break;
00154 }
00155 ds.digest = digest;
00156
00157 return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
00158 &ds, &b));
00159 }