int main(int argc, char **argv) { dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t buffer; isc_region_t region; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char salt[DNS_NSEC3_SALTSIZE]; unsigned char text[1024]; unsigned int hash_alg; unsigned int length; unsigned int iterations; unsigned int salt_length; if (argc != 5) usage(); if (strcmp(argv[1], "-") == 0) { salt_length = 0; salt[0] = 0; } else { isc_buffer_init(&buffer, salt, sizeof(salt)); result = isc_hex_decodestring(argv[1], &buffer); check_result(result, "isc_hex_decodestring(salt)"); salt_length = isc_buffer_usedlength(&buffer); if (salt_length > DNS_NSEC3_SALTSIZE) fatal("salt too long"); } hash_alg = atoi(argv[2]); if (hash_alg > 255U) fatal("hash algorithm too large"); iterations = atoi(argv[3]); if (iterations > 0xffffU) fatal("iterations to large"); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); isc_buffer_init(&buffer, argv[4], strlen(argv[4])); isc_buffer_add(&buffer, strlen(argv[4])); result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext() failed"); dns_name_downcase(name, name, NULL); length = isc_iterated_hash(hash, hash_alg, iterations, salt, salt_length, name->ndata, name->length); if (length == 0) fatal("isc_iterated_hash failed"); region.base = hash; region.length = length; isc_buffer_init(&buffer, text, sizeof(text)); isc_base32hexnp_totext(®ion, 1, "", &buffer); fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n", (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations); return(0); }
isc_result_t dns_nsec3_hashname(dns_fixedname_t *result, unsigned char rethash[NSEC3_MAX_HASH_LENGTH], size_t *hash_length, dns_name_t *name, dns_name_t *origin, dns_hash_t hashalg, unsigned int iterations, const unsigned char *salt, size_t saltlength) { unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char nametext[DNS_NAME_FORMATSIZE]; dns_fixedname_t fixed; dns_name_t *downcased; isc_buffer_t namebuffer; isc_region_t region; size_t len; if (rethash == NULL) rethash = hash; memset(rethash, 0, NSEC3_MAX_HASH_LENGTH); dns_fixedname_init(&fixed); downcased = dns_fixedname_name(&fixed); dns_name_downcase(name, downcased, NULL); /* hash the node name */ len = isc_iterated_hash(rethash, hashalg, iterations, salt, saltlength, downcased->ndata, downcased->length); if (len == 0U) return (DNS_R_BADALG); if (hash_length != NULL) *hash_length = len; /* convert the hash to base32hex */ region.base = rethash; region.length = len; isc_buffer_init(&namebuffer, nametext, sizeof nametext); isc_base32hex_totext(®ion, 1, "", &namebuffer); /* convert the hex to a domain name */ dns_fixedname_init(result); return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer, origin, 0, NULL)); }
static void nsec3hash(nsec3printer *nsec3print, const char *algostr, const char *flagstr, const char *iterstr, const char *saltstr, const char *domain) { dns_fixedname_t fixed; dns_name_t *name; isc_buffer_t buffer; isc_region_t region; isc_result_t result; unsigned char hash[NSEC3_MAX_HASH_LENGTH]; unsigned char salt[DNS_NSEC3_SALTSIZE]; unsigned char text[1024]; unsigned int hash_alg; unsigned int flags; unsigned int length; unsigned int iterations; unsigned int salt_length; const char dash[] = "-"; if (strcmp(saltstr, "-") == 0) { salt_length = 0; salt[0] = 0; } else { isc_buffer_init(&buffer, salt, sizeof(salt)); result = isc_hex_decodestring(saltstr, &buffer); check_result(result, "isc_hex_decodestring(salt)"); salt_length = isc_buffer_usedlength(&buffer); if (salt_length > DNS_NSEC3_SALTSIZE) fatal("salt too long"); if (salt_length == 0) saltstr = dash; } hash_alg = atoi(algostr); if (hash_alg > 255U) fatal("hash algorithm too large"); flags = flagstr == NULL ? 0 : atoi(flagstr); if (flags > 255U) fatal("flags too large"); iterations = atoi(iterstr); if (iterations > 0xffffU) fatal("iterations to large"); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); isc_buffer_constinit(&buffer, domain, strlen(domain)); isc_buffer_add(&buffer, strlen(domain)); result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL); check_result(result, "dns_name_fromtext() failed"); dns_name_downcase(name, name, NULL); length = isc_iterated_hash(hash, hash_alg, iterations, salt, salt_length, name->ndata, name->length); if (length == 0) fatal("isc_iterated_hash failed"); region.base = hash; region.length = length; isc_buffer_init(&buffer, text, sizeof(text)); isc_base32hexnp_totext(®ion, 1, "", &buffer); isc_buffer_putuint8(&buffer, '\0'); nsec3print(hash_alg, flags, iterations, saltstr, domain, (char *)text); }