static void dh(dns_name_t *name1, int id1, dns_name_t *name2, int id2, isc_mem_t *mctx) { dst_key_t *key1 = NULL, *key2 = NULL; isc_result_t ret; isc_buffer_t b1, b2; isc_region_t r1, r2; unsigned char array1[1024], array2[1024]; int alg = DST_ALG_DH; int type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; ret = dst_key_fromfile(name1, id1, alg, type, current, mctx, &key1); printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; ret = dst_key_fromfile(name2, id2, alg, type, current, mctx, &key2); printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; ret = dst_key_tofile(key1, type, tmp); printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; ret = dst_key_tofile(key2, type, tmp); printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; isc_buffer_init(&b1, array1, sizeof(array1)); ret = dst_key_computesecret(key1, key2, &b1); printf("computesecret() returned: %s\n", isc_result_totext(ret)); if (ret != 0) return; isc_buffer_init(&b2, array2, sizeof(array2)); ret = dst_key_computesecret(key2, key1, &b2); printf("computesecret() returned: %s\n", isc_result_totext(ret)); if (ret != 0) return; isc_buffer_usedregion(&b1, &r1); isc_buffer_usedregion(&b2, &r2); if (r1.length != r2.length || memcmp(r1.base, r2.base, r1.length) != 0) { int i; printf("secrets don't match\n"); printf("secret 1: %d bytes\n", r1.length); for (i = 0; i < (int) r1.length; i++) printf("%02x ", r1.base[i]); printf("\n"); printf("secret 2: %d bytes\n", r2.length); for (i = 0; i < (int) r2.length; i++) printf("%02x ", r2.base[i]); printf("\n"); } dst_key_free(&key1); dst_key_free(&key2); }
ATF_TC_BODY(isc_dh_computesecret, tc) { dst_key_t *key = NULL; isc_buffer_t buf; unsigned char array[1024]; isc_result_t ret; dns_fixedname_t fname; dns_name_t *name; UNUSED(tc); ret = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_constinit(&buf, "dh.", 3); isc_buffer_add(&buf, 3); ret = dns_name_fromtext(name, &buf, NULL, 0, NULL); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); ret = dst_key_fromfile(name, 18602, DST_ALG_DH, DST_TYPE_PUBLIC | DST_TYPE_KEY, "./", mctx, &key); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); isc_buffer_init(&buf, array, sizeof(array)); ret = dst_key_computesecret(key, key, &buf); ATF_REQUIRE_EQ(ret, DST_R_NOTPRIVATEKEY); ret = key->func->computesecret(key, key, &buf); ATF_REQUIRE_EQ(ret, DST_R_COMPUTESECRETFAILURE); dst_key_free(&key); dns_test_end(); }
static void io(dns_name_t *name, int id, int alg, int type, isc_mem_t *mctx) { dst_key_t *key = NULL; isc_result_t ret; ret = dst_key_fromfile(name, id, alg, type, current, mctx, &key); printf("read(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; ret = dst_key_tofile(key, type, tmp); printf("write(%d) returned: %s\n", alg, isc_result_totext(ret)); if (ret != 0) return; use(key, mctx); dns(key, mctx); dst_key_free(&key); }
ATF_TC_BODY(isc_rsa_verify, tc) { isc_result_t ret; dns_fixedname_t fname; isc_buffer_t buf; dns_name_t *name; dst_key_t *key = NULL; dst_context_t *ctx = NULL; isc_region_t r; UNUSED(tc); ret = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_constinit(&buf, "rsa.", 4); isc_buffer_add(&buf, 4); ret = dns_name_fromtext(name, &buf, NULL, 0, NULL); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); ret = dst_key_fromfile(name, 29235, DST_ALG_RSASHA1, DST_TYPE_PUBLIC, "./", mctx, &key); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); /* RSASHA1 */ ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = d; r.length = 10; ret = dst_context_adddata(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = sigsha1; r.length = 256; ret = dst_context_verify(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dst_context_destroy(&ctx); /* RSAMD5 */ #ifndef PK11_MD5_DISABLE key->key_alg = DST_ALG_RSAMD5; ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = d; r.length = 10; ret = dst_context_adddata(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = sigmd5; r.length = 256; ret = dst_context_verify(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dst_context_destroy(&ctx); #endif /* RSASHA256 */ key->key_alg = DST_ALG_RSASHA256; ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = d; r.length = 10; ret = dst_context_adddata(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = sigsha256; r.length = 256; ret = dst_context_verify(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dst_context_destroy(&ctx); /* RSASHA512 */ key->key_alg = DST_ALG_RSASHA512; ret = dst_context_create3(key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = d; r.length = 10; ret = dst_context_adddata(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); r.base = sigsha512; r.length = 256; ret = dst_context_verify(ctx, &r); ATF_REQUIRE_EQ(ret, ISC_R_SUCCESS); dst_context_destroy(&ctx); dst_key_free(&key); dns_test_end(); }
isc_result_t ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) { isc_result_t result; dns_tkeyctx_t *tctx = NULL; const char *s; isc_uint32_t n; dns_fixedname_t fname; dns_name_t *name; isc_buffer_t b; const cfg_obj_t *obj; int type; result = dns_tkeyctx_create(mctx, ectx, &tctx); if (result != ISC_R_SUCCESS) return (result); obj = NULL; result = cfg_map_get(options, "tkey-dhkey", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, type, NULL, mctx, &tctx->dhkey)); } obj = NULL; result = cfg_map_get(options, "tkey-domain", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); if (tctx->domain == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(tctx->domain, NULL); RETERR(dns_name_dup(name, mctx, tctx->domain)); } obj = NULL; result = cfg_map_get(options, "tkey-gssapi-credential", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); isc_buffer_constinit(&b, s, strlen(s)); isc_buffer_add(&b, strlen(s)); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred)); } obj = NULL; result = cfg_map_get(options, "tkey-gssapi-keytab", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); tctx->gssapi_keytab = isc_mem_strdup(mctx, s); if (tctx->gssapi_keytab == NULL) { result = ISC_R_NOMEMORY; goto failure; } } *tctxp = tctx; return (ISC_R_SUCCESS); failure: dns_tkeyctx_destroy(&tctx); return (result); }
int main(int argc, char *argv[]) { isc_boolean_t verbose = ISC_FALSE; isc_socketmgr_t *socketmgr; isc_timermgr_t *timermgr; struct in_addr inaddr; dns_fixedname_t fname; dns_name_t *name; isc_buffer_t b; int ch; isc_result_t result; in_port_t port = 53; RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS); mctx = NULL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); while ((ch = isc_commandline_parse(argc, argv, "vp:")) != -1) { switch (ch) { case 'v': verbose = ISC_TRUE; break; case 'p': port = (unsigned int)atoi(isc_commandline_argument); break; } } RUNTIME_CHECK(isc_entropy_create(mctx, &ent) == ISC_R_SUCCESS); RUNTIME_CHECK(dst_lib_init(mctx, ent, 0) == ISC_R_SUCCESS); dns_result_register(); dst_result_register(); taskmgr = NULL; RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) == ISC_R_SUCCESS); task1 = NULL; RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task1) == ISC_R_SUCCESS); timermgr = NULL; RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS); socketmgr = NULL; RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_log_create(mctx, &lctx, &logconfig) == ISC_R_SUCCESS); s = NULL; RUNTIME_CHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s) == ISC_R_SUCCESS); inaddr.s_addr = htonl(INADDR_LOOPBACK); isc_sockaddr_fromin(&address, &inaddr, port); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&b, "child.example.", strlen("child.example.")); isc_buffer_add(&b, strlen("child.example.")); result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); CHECK("dns_name_fromtext", result); key = NULL; result = dst_key_fromfile(name, 4017, DNS_KEYALG_DSA, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, NULL, mctx, &key); CHECK("dst_key_fromfile", result); buildquery(); (void)isc_app_run(); isc_task_shutdown(task1); isc_task_detach(&task1); isc_taskmgr_destroy(&taskmgr); isc_socket_detach(&s); isc_socketmgr_destroy(&socketmgr); isc_timermgr_destroy(&timermgr); dst_key_free(&key); dst_lib_destroy(); isc_entropy_detach(&ent); isc_log_destroy(&lctx); if (verbose) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); DESTROYLOCK(&lock); isc_app_finish(); return (0); }
isc_result_t dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, const char *directory, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dst_key_t *pubkey = NULL; unsigned int count = 0; REQUIRE(nkeys != NULL); REQUIRE(keys != NULL); *nkeys = 0; dns_rdataset_init(&rdataset); RETERR(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL)); RETERR(dns_rdataset_first(&rdataset)); while (result == ISC_R_SUCCESS && count < maxkeys) { pubkey = NULL; dns_rdataset_current(&rdataset, &rdata); RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); if (!is_zone_key(pubkey) || (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) goto next; keys[count] = NULL; result = dst_key_fromfile(dst_key_name(pubkey), dst_key_id(pubkey), dst_key_alg(pubkey), DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, directory, mctx, &keys[count]); if (result == ISC_R_FILENOTFOUND) { keys[count] = pubkey; pubkey = NULL; count++; goto next; } if (result != ISC_R_SUCCESS) goto failure; if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) { /* We should never get here. */ dst_key_free(&keys[count]); goto next; } count++; next: if (pubkey != NULL) dst_key_free(&pubkey); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } if (result != ISC_R_NOMORE) goto failure; if (count == 0) result = ISC_R_NOTFOUND; else result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (pubkey != NULL) dst_key_free(&pubkey); if (result != ISC_R_SUCCESS) while (count > 0) dst_key_free(&keys[--count]); *nkeys = count; return (result); }
int main(int argc, char **argv) { char *algname = NULL, *nametype = NULL, *type = NULL; char *classname = NULL; char *endp; dst_key_t *key = NULL, *oldkey; dns_fixedname_t fname; dns_name_t *name; isc_uint16_t flags = 0, ksk = 0; dns_secalg_t alg; isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; isc_mem_t *mctx = NULL; int ch, rsa_exp = 0, generator = 0, param = 0; int protocol = -1, size = -1, signatory = 0; isc_result_t ret; isc_textregion_t r; char filename[255]; isc_buffer_t buf; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; dns_rdataclass_t rdclass; int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; int dbits = 0; if (argc == 1) usage(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1) { switch (ch) { case 'a': algname = isc_commandline_argument; break; case 'b': size = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || size < 0) fatal("-b requires a non-negative number"); break; case 'c': classname = isc_commandline_argument; break; case 'd': dbits = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || dbits < 0) fatal("-d requires a non-negative number"); break; case 'e': rsa_exp = 1; break; case 'f': if (strcasecmp(isc_commandline_argument, "KSK") == 0) ksk = DNS_KEYFLAG_KSK; else fatal("unknown flag '%s'", isc_commandline_argument); break; case 'g': generator = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || generator <= 0) fatal("-g requires a positive number"); break; case 'k': options |= DST_TYPE_KEY; break; case 'n': nametype = isc_commandline_argument; break; case 't': type = isc_commandline_argument; break; case 'p': protocol = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || protocol < 0 || protocol > 255) fatal("-p must be followed by a number " "[0..255]"); break; case 's': signatory = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || signatory < 0 || signatory > 15) fatal("-s must be followed by a number " "[0..15]"); break; case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); ret = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (ret != ISC_R_SUCCESS) fatal("could not initialize dst"); setup_logging(verbose, mctx, &log); if (argc < isc_commandline_index + 1) fatal("the key name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); if (algname == NULL) fatal("no algorithm was specified"); if (strcasecmp(algname, "RSA") == 0) { fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n" "If you still wish to use RSA (RSAMD5) please " "specify \"-a RSAMD5\"\n"); return (1); } else if (strcasecmp(algname, "HMAC-MD5") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACMD5; } else if (strcasecmp(algname, "HMAC-SHA1") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACSHA1; } else if (strcasecmp(algname, "HMAC-SHA224") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACSHA224; } else if (strcasecmp(algname, "HMAC-SHA256") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACSHA256; } else if (strcasecmp(algname, "HMAC-SHA384") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACSHA384; } else if (strcasecmp(algname, "HMAC-SHA512") == 0) { options |= DST_TYPE_KEY; alg = DST_ALG_HMACSHA512; } else { r.base = algname; r.length = strlen(algname); ret = dns_secalg_fromtext(&alg, &r); if (ret != ISC_R_SUCCESS) fatal("unknown algorithm %s", algname); if (alg == DST_ALG_DH) options |= DST_TYPE_KEY; } if (type != NULL && (options & DST_TYPE_KEY) != 0) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; else if (strcasecmp(type, "NOAUTHCONF") == 0) { flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); if (size < 0) size = 0; } else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else fatal("invalid type %s", type); } if (size < 0) fatal("key size not specified (-b option)"); switch (alg) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: if (size != 0 && (size < 512 || size > MAX_RSA)) fatal("RSA key size %d out of range", size); break; case DNS_KEYALG_DH: if (size != 0 && (size < 128 || size > 4096)) fatal("DH key size %d out of range", size); break; case DNS_KEYALG_DSA: if (size != 0 && !dsa_size_ok(size)) fatal("invalid DSS key size: %d", size); break; case DST_ALG_HMACMD5: if (size < 1 || size > 512) fatal("HMAC-MD5 key size %d out of range", size); if (dbits != 0 && (dbits < 80 || dbits > 128)) fatal("HMAC-MD5 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-MD5 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA1: if (size < 1 || size > 160) fatal("HMAC-SHA1 key size %d out of range", size); if (dbits != 0 && (dbits < 80 || dbits > 160)) fatal("HMAC-SHA1 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA1 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA224: if (size < 1 || size > 224) fatal("HMAC-SHA224 key size %d out of range", size); if (dbits != 0 && (dbits < 112 || dbits > 224)) fatal("HMAC-SHA224 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA224 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA256: if (size < 1 || size > 256) fatal("HMAC-SHA256 key size %d out of range", size); if (dbits != 0 && (dbits < 128 || dbits > 256)) fatal("HMAC-SHA256 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA256 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA384: if (size < 1 || size > 384) fatal("HMAC-384 key size %d out of range", size); if (dbits != 0 && (dbits < 192 || dbits > 384)) fatal("HMAC-SHA384 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA384 digest bits %d not divisible by 8", dbits); break; case DST_ALG_HMACSHA512: if (size < 1 || size > 512) fatal("HMAC-SHA512 key size %d out of range", size); if (dbits != 0 && (dbits < 256 || dbits > 512)) fatal("HMAC-SHA512 digest bits %d out of range", dbits); if ((dbits % 8) != 0) fatal("HMAC-SHA512 digest bits %d not divisible by 8", dbits); break; } if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1) && rsa_exp != 0) fatal("specified RSA exponent for a non-RSA key"); if (alg != DNS_KEYALG_DH && generator != 0) fatal("specified DH generator for a non-DH key"); if (nametype == NULL) { if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ fatal("no nametype specified"); flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ } else if (strcasecmp(nametype, "zone") == 0) flags |= DNS_KEYOWNER_ZONE; else if ((options & DST_TYPE_KEY) != 0) { /* KEY / HMAC */ if (strcasecmp(nametype, "host") == 0 || strcasecmp(nametype, "entity") == 0) flags |= DNS_KEYOWNER_ENTITY; else if (strcasecmp(nametype, "user") == 0) flags |= DNS_KEYOWNER_USER; else fatal("invalid KEY nametype %s", nametype); } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ fatal("invalid DNSKEY nametype %s", nametype); rdclass = strtoclass(classname); if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */ flags |= signatory; else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */ flags |= ksk; if (protocol == -1) protocol = DNS_KEYPROTO_DNSSEC; else if ((options & DST_TYPE_KEY) == 0 && protocol != DNS_KEYPROTO_DNSSEC) fatal("invalid DNSKEY protocol: %d", protocol); if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { if (size > 0) fatal("specified null key with non-zero size"); if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) fatal("specified null key with signing authority"); } if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && (alg == DNS_KEYALG_DH || alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512)) fatal("a key with algorithm '%s' cannot be a zone key", algname); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&buf, argv[isc_commandline_index], strlen(argv[isc_commandline_index])); isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL); if (ret != ISC_R_SUCCESS) fatal("invalid key name %s: %s", argv[isc_commandline_index], isc_result_totext(ret)); switch(alg) { case DNS_KEYALG_RSAMD5: case DNS_KEYALG_RSASHA1: param = rsa_exp; break; case DNS_KEYALG_DH: param = generator; break; case DNS_KEYALG_DSA: case DST_ALG_HMACMD5: case DST_ALG_HMACSHA1: case DST_ALG_HMACSHA224: case DST_ALG_HMACSHA256: case DST_ALG_HMACSHA384: case DST_ALG_HMACSHA512: param = 0; break; } if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) null_key = ISC_TRUE; isc_buffer_init(&buf, filename, sizeof(filename) - 1); do { conflict = ISC_FALSE; oldkey = NULL; /* generate the key */ ret = dst_key_generate(name, alg, size, param, flags, protocol, rdclass, mctx, &key); isc_entropy_stopcallbacksources(ectx); if (ret != ISC_R_SUCCESS) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[ALG_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); alg_format(alg, algstr, sizeof(algstr)); fatal("failed to generate key %s/%s: %s\n", namestr, algstr, isc_result_totext(ret)); exit(-1); } dst_key_setbits(key, dbits); /* * Try to read a key with the same name, alg and id from disk. * If there is one we must continue generating a new one * unless we were asked to generate a null key, in which * case we return failure. */ ret = dst_key_fromfile(name, dst_key_id(key), alg, DST_TYPE_PRIVATE, NULL, mctx, &oldkey); /* do not overwrite an existing key */ if (ret == ISC_R_SUCCESS) { dst_key_free(&oldkey); conflict = ISC_TRUE; if (null_key) break; } if (conflict == ISC_TRUE) { if (verbose > 0) { isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); fprintf(stderr, "%s: %s already exists, " "generating a new key\n", program, filename); } dst_key_free(&key); } } while (conflict == ISC_TRUE); if (conflict) fatal("cannot generate a null key when a key with id 0 " "already exists"); ret = dst_key_tofile(key, options, NULL); if (ret != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(key, keystr, sizeof(keystr)); fatal("failed to write key %s: %s\n", keystr, isc_result_totext(ret)); } isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); printf("%s\n", filename); dst_key_free(&key); cleanup_logging(&log); cleanup_entropy(&ectx); dst_lib_destroy(); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }
int main(int argc, char **argv) { char *algname = NULL, *nametype = NULL, *type = NULL; char *classname = NULL; char *endp; dst_key_t *key = NULL, *oldkey; dns_fixedname_t fname; dns_name_t *name; isc_uint16_t flags = 0, ksk = 0; dns_secalg_t alg; isc_boolean_t null_key = ISC_FALSE; isc_mem_t *mctx = NULL; int ch; int protocol = -1, signatory = 0; isc_result_t ret; isc_textregion_t r; char filename[255]; isc_buffer_t buf; isc_log_t *log = NULL; isc_entropy_t *ectx = NULL; dns_rdataclass_t rdclass; int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; char *label = NULL; if (argc == 1) usage(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "a:c:f:kl:n:p:t:v:h")) != -1) { switch (ch) { case 'a': algname = isc_commandline_argument; break; case 'c': classname = isc_commandline_argument; break; case 'f': if (strcasecmp(isc_commandline_argument, "KSK") == 0) ksk = DNS_KEYFLAG_KSK; else fatal("unknown flag '%s'", isc_commandline_argument); break; case 'k': options |= DST_TYPE_KEY; break; case 'l': label = isc_commandline_argument; break; case 'n': nametype = isc_commandline_argument; break; case 'p': protocol = strtol(isc_commandline_argument, &endp, 10); if (*endp != '\0' || protocol < 0 || protocol > 255) fatal("-p must be followed by a number " "[0..255]"); break; case 't': type = isc_commandline_argument; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); ret = dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (ret != ISC_R_SUCCESS) fatal("could not initialize dst"); setup_logging(verbose, mctx, &log); if (label == NULL) fatal("the key label was not specified"); if (argc < isc_commandline_index + 1) fatal("the key name was not specified"); if (argc > isc_commandline_index + 1) fatal("extraneous arguments"); if (algname == NULL) fatal("no algorithm was specified"); if (strcasecmp(algname, "RSA") == 0) { fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n" "If you still wish to use RSA (RSAMD5) please " "specify \"-a RSAMD5\"\n"); return (1); } else { r.base = algname; r.length = strlen(algname); ret = dns_secalg_fromtext(&alg, &r); if (ret != ISC_R_SUCCESS) fatal("unknown algorithm %s", algname); if (alg == DST_ALG_DH) options |= DST_TYPE_KEY; } if (type != NULL && (options & DST_TYPE_KEY) != 0) { if (strcasecmp(type, "NOAUTH") == 0) flags |= DNS_KEYTYPE_NOAUTH; else if (strcasecmp(type, "NOCONF") == 0) flags |= DNS_KEYTYPE_NOCONF; else if (strcasecmp(type, "NOAUTHCONF") == 0) { flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF); } else if (strcasecmp(type, "AUTHCONF") == 0) /* nothing */; else fatal("invalid type %s", type); } if (nametype == NULL) { if ((options & DST_TYPE_KEY) != 0) /* KEY */ fatal("no nametype specified"); flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */ } else if (strcasecmp(nametype, "zone") == 0) flags |= DNS_KEYOWNER_ZONE; else if ((options & DST_TYPE_KEY) != 0) { /* KEY */ if (strcasecmp(nametype, "host") == 0 || strcasecmp(nametype, "entity") == 0) flags |= DNS_KEYOWNER_ENTITY; else if (strcasecmp(nametype, "user") == 0) flags |= DNS_KEYOWNER_USER; else fatal("invalid KEY nametype %s", nametype); } else if (strcasecmp(nametype, "other") != 0) /* DNSKEY */ fatal("invalid DNSKEY nametype %s", nametype); rdclass = strtoclass(classname); if ((options & DST_TYPE_KEY) != 0) /* KEY */ flags |= signatory; else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */ flags |= ksk; if (protocol == -1) protocol = DNS_KEYPROTO_DNSSEC; else if ((options & DST_TYPE_KEY) == 0 && protocol != DNS_KEYPROTO_DNSSEC) fatal("invalid DNSKEY protocol: %d", protocol); if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) fatal("specified null key with signing authority"); } if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE && alg == DNS_KEYALG_DH) fatal("a key with algorithm '%s' cannot be a zone key", algname); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&buf, argv[isc_commandline_index], strlen(argv[isc_commandline_index])); isc_buffer_add(&buf, strlen(argv[isc_commandline_index])); ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL); if (ret != ISC_R_SUCCESS) fatal("invalid key name %s: %s", argv[isc_commandline_index], isc_result_totext(ret)); if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) null_key = ISC_TRUE; isc_buffer_init(&buf, filename, sizeof(filename) - 1); /* associate the key */ ret = dst_key_fromlabel(name, alg, flags, protocol, rdclass, "", label, NULL, mctx, &key); isc_entropy_stopcallbacksources(ectx); if (ret != ISC_R_SUCCESS) { char namestr[DNS_NAME_FORMATSIZE]; char algstr[ALG_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); alg_format(alg, algstr, sizeof(algstr)); fatal("failed to generate key %s/%s: %s\n", namestr, algstr, isc_result_totext(ret)); exit(-1); } /* * Try to read a key with the same name, alg and id from disk. * If there is one we must continue generating a new one * unless we were asked to generate a null key, in which * case we return failure. */ ret = dst_key_fromfile(name, dst_key_id(key), alg, DST_TYPE_PRIVATE, NULL, mctx, &oldkey); /* do not overwrite an existing key */ if (ret == ISC_R_SUCCESS) { isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); fprintf(stderr, "%s: %s already exists\n", program, filename); dst_key_free(&key); exit (1); } ret = dst_key_tofile(key, options, NULL); if (ret != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(key, keystr, sizeof(keystr)); fatal("failed to write key %s: %s\n", keystr, isc_result_totext(ret)); } isc_buffer_clear(&buf); ret = dst_key_buildfilename(key, 0, NULL, &buf); printf("%s\n", filename); dst_key_free(&key); cleanup_logging(&log); cleanup_entropy(&ectx); dst_lib_destroy(); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }