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); }
size_t fromhexstr(const char *in, unsigned char *d) { isc_buffer_t b; isc_result_t ret; isc_buffer_init(&b, d, ISC_AES256_KEYLENGTH + 1); ret = isc_hex_decodestring(in, &b); if (ret != ISC_R_SUCCESS) return 0; return isc_buffer_usedlength(&b); }
static inline isc_result_t fromtext_nsec3param(ARGS_FROMTEXT) { isc_token_t token; unsigned int flags = 0; unsigned char hashalg; REQUIRE(type == dns_rdatatype_nsec3param); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); UNUSED(origin); UNUSED(options); /* Hash. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); RETERR(uint8_tobuffer(hashalg, target)); /* Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); flags = token.value.as_ulong; if (flags > 255U) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(flags, target)); /* Iterations. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* Salt. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (token.value.as_textregion.length > (255*2)) RETTOK(DNS_R_TEXTTOOLONG); if (strcmp(DNS_AS_STR(token), "-") == 0) { RETERR(uint8_tobuffer(0, target)); } else { RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); } return (ISC_R_SUCCESS); }
static inline isc_result_t fromtext_nsec3(ARGS_FROMTEXT) { isc_token_t token; unsigned int flags; unsigned char hashalg; isc_buffer_t b; unsigned char buf[256]; REQUIRE(type == dns_rdatatype_nsec3); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); UNUSED(origin); UNUSED(options); /* Hash. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_hashalg_fromtext(&hashalg, &token.value.as_textregion)); RETERR(uint8_tobuffer(hashalg, target)); /* Flags. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); flags = token.value.as_ulong; if (flags > 255U) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(flags, target)); /* Iterations. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* salt */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); if (token.value.as_textregion.length > (255*2)) RETTOK(DNS_R_TEXTTOOLONG); if (strcmp(DNS_AS_STR(token), "-") == 0) { RETERR(uint8_tobuffer(0, target)); } else { RETERR(uint8_tobuffer(strlen(DNS_AS_STR(token)) / 2, target)); RETERR(isc_hex_decodestring(DNS_AS_STR(token), target)); } /* * Next hash a single base32hex word. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); isc_buffer_init(&b, buf, sizeof(buf)); RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b)); if (isc_buffer_usedlength(&b) > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target)); RETERR(mem_tobuffer(target, &buf, isc_buffer_usedlength(&b))); return (typemap_fromtext(lexer, target, ISC_TRUE)); }
static inline isc_result_t fromtext_hip(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; isc_buffer_t hit_len; isc_buffer_t key_len; unsigned char *start; size_t len; REQUIRE(type == dns_rdatatype_hip); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Dummy HIT len. */ hit_len = *target; RETERR(uint8_tobuffer(0, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(token.value.as_ulong, target)); /* * Dummy KEY len. */ key_len = *target; RETERR(uint16_tobuffer(0, target)); /* * HIT (base16). */ start = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(isc_hex_decodestring(DNS_AS_STR(token), target)); /* * Fill in HIT len. */ len = (unsigned char *)isc_buffer_used(target) - start; if (len > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer((isc_uint32_t)len, &hit_len)); /* * Public key (base64). */ start = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(isc_base64_decodestring(DNS_AS_STR(token), target)); /* * Fill in KEY len. */ len = (unsigned char *)isc_buffer_used(target) - start; if (len > 0xffffU) RETTOK(ISC_R_RANGE); RETERR(uint16_tobuffer((isc_uint32_t)len, &key_len)); /* * Rendezvous Servers. */ dns_name_init(&name, NULL); do { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_TRUE)); if (token.type != isc_tokentype_string) break; buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); } while (1); /* * Let upper layer handle eol/eof. */ isc_lex_ungettoken(lexer, &token); return (ISC_R_SUCCESS); }
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); }