1224090Sdougb/* 2254897Serwin * Copyright (C) 2006, 2008, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") 3224090Sdougb * 4224090Sdougb * Permission to use, copy, modify, and/or distribute this software for any 5224090Sdougb * purpose with or without fee is hereby granted, provided that the above 6224090Sdougb * copyright notice and this permission notice appear in all copies. 7224090Sdougb * 8224090Sdougb * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9224090Sdougb * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10224090Sdougb * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11224090Sdougb * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12224090Sdougb * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13224090Sdougb * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14224090Sdougb * PERFORMANCE OF THIS SOFTWARE. 15224090Sdougb */ 16224090Sdougb 17254897Serwin/* $Id: nsec3hash.c,v 1.8 2011/11/02 23:46:24 tbox Exp $ */ 18224090Sdougb 19224090Sdougb#include <config.h> 20224090Sdougb 21224090Sdougb#include <stdlib.h> 22224090Sdougb#include <stdarg.h> 23224090Sdougb 24224090Sdougb#include <isc/base32.h> 25224090Sdougb#include <isc/buffer.h> 26224090Sdougb#include <isc/hex.h> 27224090Sdougb#include <isc/iterated_hash.h> 28224090Sdougb#include <isc/print.h> 29224090Sdougb#include <isc/result.h> 30224090Sdougb#include <isc/string.h> 31224090Sdougb#include <isc/types.h> 32224090Sdougb 33224090Sdougb#include <dns/fixedname.h> 34224090Sdougb#include <dns/name.h> 35224090Sdougb#include <dns/nsec3.h> 36224090Sdougb#include <dns/types.h> 37224090Sdougb 38224090Sdougbconst char *program = "nsec3hash"; 39224090Sdougb 40224090SdougbISC_PLATFORM_NORETURN_PRE static void 41224090Sdougbfatal(const char *format, ...) ISC_PLATFORM_NORETURN_POST; 42224090Sdougb 43224090Sdougbstatic void 44224090Sdougbfatal(const char *format, ...) { 45224090Sdougb va_list args; 46224090Sdougb 47224090Sdougb fprintf(stderr, "%s: ", program); 48224090Sdougb va_start(args, format); 49224090Sdougb vfprintf(stderr, format, args); 50224090Sdougb va_end(args); 51224090Sdougb fprintf(stderr, "\n"); 52224090Sdougb exit(1); 53224090Sdougb} 54224090Sdougb 55224090Sdougbstatic void 56224090Sdougbcheck_result(isc_result_t result, const char *message) { 57224090Sdougb if (result != ISC_R_SUCCESS) 58224090Sdougb fatal("%s: %s", message, isc_result_totext(result)); 59224090Sdougb} 60224090Sdougb 61224090Sdougbstatic void 62224090Sdougbusage() { 63234010Sdougb printf("Usage: %s salt algorithm iterations domain\n", program); 64234010Sdougb exit(1); 65224090Sdougb} 66224090Sdougb 67224090Sdougbint 68224090Sdougbmain(int argc, char **argv) { 69224090Sdougb dns_fixedname_t fixed; 70224090Sdougb dns_name_t *name; 71224090Sdougb isc_buffer_t buffer; 72224090Sdougb isc_region_t region; 73224090Sdougb isc_result_t result; 74224090Sdougb unsigned char hash[NSEC3_MAX_HASH_LENGTH]; 75224090Sdougb unsigned char salt[DNS_NSEC3_SALTSIZE]; 76224090Sdougb unsigned char text[1024]; 77224090Sdougb unsigned int hash_alg; 78224090Sdougb unsigned int length; 79224090Sdougb unsigned int iterations; 80224090Sdougb unsigned int salt_length; 81224090Sdougb 82224090Sdougb if (argc != 5) 83224090Sdougb usage(); 84224090Sdougb 85224090Sdougb if (strcmp(argv[1], "-") == 0) { 86224090Sdougb salt_length = 0; 87224090Sdougb salt[0] = 0; 88224090Sdougb } else { 89224090Sdougb isc_buffer_init(&buffer, salt, sizeof(salt)); 90224090Sdougb result = isc_hex_decodestring(argv[1], &buffer); 91224090Sdougb check_result(result, "isc_hex_decodestring(salt)"); 92224090Sdougb salt_length = isc_buffer_usedlength(&buffer); 93224090Sdougb if (salt_length > DNS_NSEC3_SALTSIZE) 94224090Sdougb fatal("salt too long"); 95224090Sdougb } 96224090Sdougb hash_alg = atoi(argv[2]); 97224090Sdougb if (hash_alg > 255U) 98224090Sdougb fatal("hash algorithm too large"); 99224090Sdougb iterations = atoi(argv[3]); 100224090Sdougb if (iterations > 0xffffU) 101224090Sdougb fatal("iterations to large"); 102224090Sdougb 103224090Sdougb dns_fixedname_init(&fixed); 104224090Sdougb name = dns_fixedname_name(&fixed); 105224090Sdougb isc_buffer_init(&buffer, argv[4], strlen(argv[4])); 106224090Sdougb isc_buffer_add(&buffer, strlen(argv[4])); 107224090Sdougb result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL); 108224090Sdougb check_result(result, "dns_name_fromtext() failed"); 109224090Sdougb 110224090Sdougb dns_name_downcase(name, name, NULL); 111224090Sdougb length = isc_iterated_hash(hash, hash_alg, iterations, salt, 112224090Sdougb salt_length, name->ndata, name->length); 113224090Sdougb if (length == 0) 114224090Sdougb fatal("isc_iterated_hash failed"); 115224090Sdougb region.base = hash; 116224090Sdougb region.length = length; 117224090Sdougb isc_buffer_init(&buffer, text, sizeof(text)); 118224090Sdougb isc_base32hex_totext(®ion, 1, "", &buffer); 119224090Sdougb fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n", 120224090Sdougb (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations); 121224090Sdougb return(0); 122224090Sdougb} 123