1/* 2 * Copyright (C) 2006, 2008, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id: nsec3hash.c,v 1.8 2011/11/02 23:46:24 tbox Exp $ */ 18 19#include <config.h> 20 21#include <stdlib.h> 22#include <stdarg.h> 23 24#include <isc/base32.h> 25#include <isc/buffer.h> 26#include <isc/hex.h> 27#include <isc/iterated_hash.h> 28#include <isc/print.h> 29#include <isc/result.h> 30#include <isc/string.h> 31#include <isc/types.h> 32 33#include <dns/fixedname.h> 34#include <dns/name.h> 35#include <dns/nsec3.h> 36#include <dns/types.h> 37 38const char *program = "nsec3hash"; 39 40ISC_PLATFORM_NORETURN_PRE static void 41fatal(const char *format, ...) ISC_PLATFORM_NORETURN_POST; 42 43static void 44fatal(const char *format, ...) { 45 va_list args; 46 47 fprintf(stderr, "%s: ", program); 48 va_start(args, format); 49 vfprintf(stderr, format, args); 50 va_end(args); 51 fprintf(stderr, "\n"); 52 exit(1); 53} 54 55static void 56check_result(isc_result_t result, const char *message) { 57 if (result != ISC_R_SUCCESS) 58 fatal("%s: %s", message, isc_result_totext(result)); 59} 60 61static void 62usage() { 63 printf("Usage: %s salt algorithm iterations domain\n", program); 64 exit(1); 65} 66 67int 68main(int argc, char **argv) { 69 dns_fixedname_t fixed; 70 dns_name_t *name; 71 isc_buffer_t buffer; 72 isc_region_t region; 73 isc_result_t result; 74 unsigned char hash[NSEC3_MAX_HASH_LENGTH]; 75 unsigned char salt[DNS_NSEC3_SALTSIZE]; 76 unsigned char text[1024]; 77 unsigned int hash_alg; 78 unsigned int length; 79 unsigned int iterations; 80 unsigned int salt_length; 81 82 if (argc != 5) 83 usage(); 84 85 if (strcmp(argv[1], "-") == 0) { 86 salt_length = 0; 87 salt[0] = 0; 88 } else { 89 isc_buffer_init(&buffer, salt, sizeof(salt)); 90 result = isc_hex_decodestring(argv[1], &buffer); 91 check_result(result, "isc_hex_decodestring(salt)"); 92 salt_length = isc_buffer_usedlength(&buffer); 93 if (salt_length > DNS_NSEC3_SALTSIZE) 94 fatal("salt too long"); 95 } 96 hash_alg = atoi(argv[2]); 97 if (hash_alg > 255U) 98 fatal("hash algorithm too large"); 99 iterations = atoi(argv[3]); 100 if (iterations > 0xffffU) 101 fatal("iterations to large"); 102 103 dns_fixedname_init(&fixed); 104 name = dns_fixedname_name(&fixed); 105 isc_buffer_init(&buffer, argv[4], strlen(argv[4])); 106 isc_buffer_add(&buffer, strlen(argv[4])); 107 result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL); 108 check_result(result, "dns_name_fromtext() failed"); 109 110 dns_name_downcase(name, name, NULL); 111 length = isc_iterated_hash(hash, hash_alg, iterations, salt, 112 salt_length, name->ndata, name->length); 113 if (length == 0) 114 fatal("isc_iterated_hash failed"); 115 region.base = hash; 116 region.length = length; 117 isc_buffer_init(&buffer, text, sizeof(text)); 118 isc_base32hex_totext(®ion, 1, "", &buffer); 119 fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n", 120 (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations); 121 return(0); 122} 123