isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; char filename[ISC_DIR_NAMEMAX]; isc_buffer_t buf; dst_key_t *key; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); key = NULL; isc_buffer_init(&buf, filename, ISC_DIR_NAMEMAX); result = dst_key_getfilename(name, id, alg, type, NULL, mctx, &buf); if (result != ISC_R_SUCCESS) goto out; result = dst_key_fromnamedfile(filename, directory, type, mctx, &key); if (result != ISC_R_SUCCESS) goto out; result = computeid(key); if (result != ISC_R_SUCCESS) goto out; if (!dns_name_equal(name, key->key_name) || id != key->key_id || alg != key->key_alg) { result = DST_R_INVALIDPRIVATEKEY; goto out; } *keyp = key; result = ISC_R_SUCCESS; out: if ((key != NULL) && (result != ISC_R_SUCCESS)) dst_key_free(&key); return (result); }
isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp) { char filename[ISC_DIR_NAMEMAX]; isc_buffer_t b; dst_key_t *key; isc_result_t result; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(dns_name_isabsolute(name)); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); CHECKALG(alg); isc_buffer_init(&b, filename, sizeof(filename)); result = buildfilename(name, id, alg, type, directory, &b); if (result != ISC_R_SUCCESS) return (result); key = NULL; result = dst_key_fromnamedfile(filename, type, mctx, &key); if (result != ISC_R_SUCCESS) return (result); result = computeid(key); if (result != ISC_R_SUCCESS) { dst_key_free(&key); return (result); } if (!dns_name_equal(name, key->key_name) || id != key->key_id || alg != key->key_alg) { dst_key_free(&key); return (DST_R_INVALIDPRIVATEKEY); } key->key_id = id; *keyp = key; return (ISC_R_SUCCESS); }
static void loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size, dns_rdata_t *rdata) { isc_result_t result; dst_key_t *key = NULL; isc_buffer_t keyb; isc_region_t r; dns_rdata_init(rdata); isc_buffer_init(&keyb, key_buf, key_buf_size); result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("invalid keyfile name %s: %s", filename, isc_result_totext(result)); if (verbose > 2) { char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key, keystr, sizeof(keystr)); fprintf(stderr, "%s: %s\n", program, keystr); } result = dst_key_todns(key, &keyb); if (result != ISC_R_SUCCESS) fatal("can't decode key"); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(rdata, dst_key_class(key), dns_rdatatype_dnskey, &r); rdclass = dst_key_class(key); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_name_copy(dst_key_name(key), name, NULL); if (result != ISC_R_SUCCESS) fatal("can't copy name"); dst_key_free(&key); }
int main(int argc, char *argv[]) { char *ourkeyname; isc_taskmgr_t *taskmgr; isc_timermgr_t *timermgr; isc_socketmgr_t *socketmgr; isc_socket_t *sock; unsigned int attrs, attrmask; isc_sockaddr_t bind_any; dns_dispatchmgr_t *dispatchmgr; dns_dispatch_t *dispatchv4; dns_view_t *view; isc_entropy_t *ectx; dns_tkeyctx_t *tctx; isc_log_t *log; isc_logconfig_t *logconfig; isc_task_t *task; isc_result_t result; int type; RUNCHECK(isc_app_start()); if (argc < 2) { fprintf(stderr, "I:no DH key provided\n"); exit(-1); } ourkeyname = argv[1]; if (argc >= 3) ownername_str = argv[2]; dns_result_register(); mctx = NULL; RUNCHECK(isc_mem_create(0, 0, &mctx)); ectx = NULL; RUNCHECK(isc_entropy_create(mctx, &ectx)); RUNCHECK(isc_entropy_createfilesource(ectx, "random.data")); RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); log = NULL; logconfig = NULL; RUNCHECK(isc_log_create(mctx, &log, &logconfig)); RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); taskmgr = NULL; RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); task = NULL; RUNCHECK(isc_task_create(taskmgr, 0, &task)); timermgr = NULL; RUNCHECK(isc_timermgr_create(mctx, &timermgr)); socketmgr = NULL; RUNCHECK(isc_socketmgr_create(mctx, &socketmgr)); dispatchmgr = NULL; RUNCHECK(dns_dispatchmgr_create(mctx, NULL, &dispatchmgr)); isc_sockaddr_any(&bind_any); attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY | DNS_DISPATCHATTR_IPV4; attrmask = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; dispatchv4 = NULL; RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &bind_any, 4096, 4, 2, 3, 5, attrs, attrmask, &dispatchv4)); requestmgr = NULL; RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, dispatchmgr, dispatchv4, NULL, &requestmgr)); ring = NULL; RUNCHECK(dns_tsigkeyring_create(mctx, &ring)); tctx = NULL; RUNCHECK(dns_tkeyctx_create(mctx, ectx, &tctx)); view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); dns_view_setkeyring(view, ring); dns_tsigkeyring_detach(&ring); sock = NULL; RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &sock)); RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL)); ourkey = NULL; type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY; result = dst_key_fromnamedfile(ourkeyname, NULL, type, mctx, &ourkey); CHECK("dst_key_fromnamedfile", result); isc_buffer_init(&nonce, noncedata, sizeof(noncedata)); result = isc_entropy_getdata(ectx, noncedata, sizeof(noncedata), NULL, ISC_ENTROPY_BLOCKING); CHECK("isc_entropy_getdata", result); isc_buffer_add(&nonce, sizeof(noncedata)); (void)isc_app_run(); dns_requestmgr_shutdown(requestmgr); dns_requestmgr_detach(&requestmgr); dns_dispatch_detach(&dispatchv4); dns_dispatchmgr_destroy(&dispatchmgr); isc_task_shutdown(task); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socket_detach(&sock); isc_socketmgr_destroy(&socketmgr); isc_timermgr_destroy(&timermgr); dst_key_free(&ourkey); dns_tsigkey_detach(&initialkey); dns_tsigkey_detach(&tsigkey); dns_tkeyctx_destroy(&tctx); dns_view_detach(&view); isc_log_destroy(&log); dst_lib_destroy(); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); isc_app_finish(); return (0); }
int main(int argc, char **argv) { isc_result_t result; #ifdef USE_PKCS11 const char *engine = "pkcs11"; #else const char *engine = NULL; #endif char *filename = NULL, *dir = NULL; char newname[1024], oldname[1024]; char keystr[DST_KEY_FORMATSIZE]; char *endp; int ch; isc_entropy_t *ectx = NULL; dst_key_t *key = NULL; isc_uint32_t flags; isc_buffer_t buf; isc_boolean_t force = ISC_FALSE; isc_boolean_t remove = ISC_FALSE; isc_boolean_t id = ISC_FALSE; if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("Out of memory"); dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "E:fK:rRhv:V")) != -1) { switch (ch) { case 'E': engine = isc_commandline_argument; break; case 'f': force = ISC_TRUE; break; case 'K': /* * We don't have to copy it here, but do it to * simplify cleanup later */ dir = isc_mem_strdup(mctx, isc_commandline_argument); if (dir == NULL) { fatal("Failed to allocate memory for " "directory"); } break; case 'r': remove = ISC_TRUE; break; case 'R': id = ISC_TRUE; 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); /* Falls into */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (argc < isc_commandline_index + 1 || argv[isc_commandline_index] == NULL) fatal("The key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("Extraneous arguments"); if (dir != NULL) { filename = argv[isc_commandline_index]; } else { result = isc_file_splitpath(mctx, argv[isc_commandline_index], &dir, &filename); if (result != ISC_R_SUCCESS) fatal("cannot process filename %s: %s", argv[isc_commandline_index], isc_result_totext(result)); if (strcmp(dir, ".") == 0) { isc_mem_free(mctx, dir); dir = NULL; } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); result = dst_key_fromnamedfile(filename, dir, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, mctx, &key); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile name %s: %s", filename, isc_result_totext(result)); if (id) { fprintf(stdout, "%u\n", dst_key_rid(key)); goto cleanup; } dst_key_format(key, keystr, sizeof(keystr)); if (verbose > 2) fprintf(stderr, "%s: %s\n", program, keystr); if (force) set_keyversion(key); else check_keyversion(key, keystr); flags = dst_key_flags(key); if ((flags & DNS_KEYFLAG_REVOKE) == 0) { isc_stdtime_t now; if ((flags & DNS_KEYFLAG_KSK) == 0) fprintf(stderr, "%s: warning: Key is not flagged " "as a KSK. Revoking a ZSK is " "legal, but undefined.\n", program); isc_stdtime_get(&now); dst_key_settime(key, DST_TIME_REVOKE, now); dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE); isc_buffer_init(&buf, newname, sizeof(newname)); dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); if (access(newname, F_OK) == 0 && !force) { fatal("Key file %s already exists; " "use -f to force overwrite", newname); } result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, dir); if (result != ISC_R_SUCCESS) { dst_key_format(key, keystr, sizeof(keystr)); fatal("Failed to write key %s: %s", keystr, isc_result_totext(result)); } isc_buffer_clear(&buf); dst_key_buildfilename(key, 0, dir, &buf); printf("%s\n", newname); /* * Remove old key file, if told to (and if * it isn't the same as the new file) */ if (remove && dst_key_alg(key) != DST_ALG_RSAMD5) { isc_buffer_init(&buf, oldname, sizeof(oldname)); dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE); dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); if (strcmp(oldname, newname) == 0) goto cleanup; (void)unlink(oldname); isc_buffer_clear(&buf); dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); (void)unlink(oldname); } } else { dst_key_format(key, keystr, sizeof(keystr)); fatal("Key %s is already revoked", keystr); } cleanup: dst_key_free(&key); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); if (dir != NULL) isc_mem_free(mctx, dir); isc_mem_destroy(&mctx); return (0); }
int main(int argc, char **argv) { isc_result_t result; #ifdef USE_PKCS11 const char *engine = "pkcs11"; #else const char *engine = NULL; #endif char *filename = NULL, *directory = NULL; char newname[1024]; char keystr[DST_KEY_FORMATSIZE]; char *endp, *p; int ch; isc_entropy_t *ectx = NULL; const char *predecessor = NULL; dst_key_t *prevkey = NULL; dst_key_t *key = NULL; isc_buffer_t buf; dns_name_t *name = NULL; dns_secalg_t alg = 0; unsigned int size = 0; isc_uint16_t flags = 0; int prepub = -1; dns_ttl_t ttl = 0; isc_stdtime_t now; isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE; isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE; isc_boolean_t printinact = ISC_FALSE, printdel = ISC_FALSE; isc_boolean_t force = ISC_FALSE; isc_boolean_t epoch = ISC_FALSE; isc_boolean_t changed = ISC_FALSE; isc_log_t *log = NULL; isc__mem_register(); if (argc == 1) usage(); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("Out of memory"); setup_logging(verbose, mctx, &log); dns_result_register(); isc_commandline_errprint = ISC_FALSE; isc_stdtime_get(&now); #define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'E': engine = isc_commandline_argument; break; case 'f': force = ISC_TRUE; break; case 'p': p = isc_commandline_argument; if (!strcasecmp(p, "all")) { printcreate = ISC_TRUE; printpub = ISC_TRUE; printact = ISC_TRUE; printrev = ISC_TRUE; printinact = ISC_TRUE; printdel = ISC_TRUE; break; } do { switch (*p++) { case 'C': printcreate = ISC_TRUE; break; case 'P': printpub = ISC_TRUE; break; case 'A': printact = ISC_TRUE; break; case 'R': printrev = ISC_TRUE; break; case 'I': printinact = ISC_TRUE; break; case 'D': printdel = ISC_TRUE; break; case ' ': break; default: usage(); break; } } while (*p != '\0'); break; case 'u': epoch = ISC_TRUE; break; case 'K': /* * We don't have to copy it here, but do it to * simplify cleanup later */ directory = isc_mem_strdup(mctx, isc_commandline_argument); if (directory == NULL) { fatal("Failed to allocate memory for " "directory"); } break; case 'L': if (strcmp(isc_commandline_argument, "none") == 0) ttl = 0; else ttl = strtottl(isc_commandline_argument); setttl = ISC_TRUE; break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("-v must be followed by a number"); break; case 'P': if (setpub || unsetpub) fatal("-P specified more than once"); changed = ISC_TRUE; if (!strcasecmp(isc_commandline_argument, "none")) { unsetpub = ISC_TRUE; } else { setpub = ISC_TRUE; pub = strtotime(isc_commandline_argument, now, now); } break; case 'A': if (setact || unsetact) fatal("-A specified more than once"); changed = ISC_TRUE; if (!strcasecmp(isc_commandline_argument, "none")) { unsetact = ISC_TRUE; } else { setact = ISC_TRUE; act = strtotime(isc_commandline_argument, now, now); } break; case 'R': if (setrev || unsetrev) fatal("-R specified more than once"); changed = ISC_TRUE; if (!strcasecmp(isc_commandline_argument, "none")) { unsetrev = ISC_TRUE; } else { setrev = ISC_TRUE; rev = strtotime(isc_commandline_argument, now, now); } break; case 'I': if (setinact || unsetinact) fatal("-I specified more than once"); changed = ISC_TRUE; if (!strcasecmp(isc_commandline_argument, "none")) { unsetinact = ISC_TRUE; } else { setinact = ISC_TRUE; inact = strtotime(isc_commandline_argument, now, now); } break; case 'D': if (setdel || unsetdel) fatal("-D specified more than once"); changed = ISC_TRUE; if (!strcasecmp(isc_commandline_argument, "none")) { unsetdel = ISC_TRUE; } else { setdel = ISC_TRUE; del = strtotime(isc_commandline_argument, now, now); } break; case 'S': predecessor = isc_commandline_argument; break; case 'i': prepub = strtottl(isc_commandline_argument); break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* Falls into */ case 'h': usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (argc < isc_commandline_index + 1 || argv[isc_commandline_index] == NULL) fatal("The key file name was not specified"); if (argc > isc_commandline_index + 1) fatal("Extraneous arguments"); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("Could not initialize hash"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY); if (result != ISC_R_SUCCESS) fatal("Could not initialize dst: %s", isc_result_totext(result)); isc_entropy_stopcallbacksources(ectx); if (predecessor != NULL) { char keystr[DST_KEY_FORMATSIZE]; isc_stdtime_t when; int major, minor; if (prepub == -1) prepub = (30 * 86400); if (setpub || unsetpub) fatal("-S and -P cannot be used together"); if (setact || unsetact) fatal("-S and -A cannot be used together"); result = dst_key_fromnamedfile(predecessor, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &prevkey); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", filename, isc_result_totext(result)); if (!dst_key_isprivate(prevkey)) fatal("%s is not a private key", filename); name = dst_key_name(prevkey); alg = dst_key_alg(prevkey); size = dst_key_size(prevkey); flags = dst_key_flags(prevkey); dst_key_format(prevkey, keystr, sizeof(keystr)); dst_key_getprivateformat(prevkey, &major, &minor); if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) fatal("Predecessor has incompatible format " "version %d.%d\n\t", major, minor); result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when); if (result != ISC_R_SUCCESS) fatal("Predecessor has no activation date. " "You must set one before\n\t" "generating a successor."); result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &act); if (result != ISC_R_SUCCESS) fatal("Predecessor has no inactivation date. " "You must set one before\n\t" "generating a successor."); pub = act - prepub; if (pub < now && prepub != 0) fatal("Predecessor will become inactive before the\n\t" "prepublication period ends. Either change " "its inactivation date,\n\t" "or use the -i option to set a shorter " "prepublication interval."); result = dst_key_gettime(prevkey, DST_TIME_DELETE, &when); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s: WARNING: Predecessor has no " "removal date;\n\t" "it will remain in the zone " "indefinitely after rollover.\n", program); changed = setpub = setact = ISC_TRUE; dst_key_free(&prevkey); } else { if (prepub < 0) prepub = 0; if (prepub > 0) { if (setpub && setact && (act - prepub) < pub) fatal("Activation and publication dates " "are closer together than the\n\t" "prepublication interval."); if (setpub && !setact) { setact = ISC_TRUE; act = pub + prepub; } else if (setact && !setpub) { setpub = ISC_TRUE; pub = act - prepub; } if ((act - prepub) < now) fatal("Time until activation is shorter " "than the\n\tprepublication interval."); } } if (directory != NULL) { filename = argv[isc_commandline_index]; } else { result = isc_file_splitpath(mctx, argv[isc_commandline_index], &directory, &filename); if (result != ISC_R_SUCCESS) fatal("cannot process filename %s: %s", argv[isc_commandline_index], isc_result_totext(result)); } result = dst_key_fromnamedfile(filename, directory, DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &key); if (result != ISC_R_SUCCESS) fatal("Invalid keyfile %s: %s", filename, isc_result_totext(result)); if (!dst_key_isprivate(key)) fatal("%s is not a private key", filename); dst_key_format(key, keystr, sizeof(keystr)); if (predecessor != NULL) { if (!dns_name_equal(name, dst_key_name(key))) fatal("Key name mismatch"); if (alg != dst_key_alg(key)) fatal("Key algorithm mismatch"); if (size != dst_key_size(key)) fatal("Key size mismatch"); if (flags != dst_key_flags(key)) fatal("Key flags mismatch"); } if (force) set_keyversion(key); else check_keyversion(key, keystr); if (verbose > 2) fprintf(stderr, "%s: %s\n", program, keystr); /* * Set time values. */ if (setpub) dst_key_settime(key, DST_TIME_PUBLISH, pub); else if (unsetpub) dst_key_unsettime(key, DST_TIME_PUBLISH); if (setact) dst_key_settime(key, DST_TIME_ACTIVATE, act); else if (unsetact) dst_key_unsettime(key, DST_TIME_ACTIVATE); if (setrev) { if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) fprintf(stderr, "%s: warning: Key %s is already " "revoked; changing the revocation date " "will not affect this.\n", program, keystr); if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0) fprintf(stderr, "%s: warning: Key %s is not flagged as " "a KSK, but -R was used. Revoking a " "ZSK is legal, but undefined.\n", program, keystr); dst_key_settime(key, DST_TIME_REVOKE, rev); } else if (unsetrev) { if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0) fprintf(stderr, "%s: warning: Key %s is already " "revoked; removing the revocation date " "will not affect this.\n", program, keystr); dst_key_unsettime(key, DST_TIME_REVOKE); } if (setinact) dst_key_settime(key, DST_TIME_INACTIVE, inact); else if (unsetinact) dst_key_unsettime(key, DST_TIME_INACTIVE); if (setdel) dst_key_settime(key, DST_TIME_DELETE, del); else if (unsetdel) dst_key_unsettime(key, DST_TIME_DELETE); if (setttl) dst_key_setttl(key, ttl); /* * No metadata changes were made but we're forcing an upgrade * to the new format anyway: use "-P now -A now" as the default */ if (force && !changed) { dst_key_settime(key, DST_TIME_PUBLISH, now); dst_key_settime(key, DST_TIME_ACTIVATE, now); changed = ISC_TRUE; } if (!changed && setttl) changed = ISC_TRUE; /* * Print out time values, if -p was used. */ if (printcreate) printtime(key, DST_TIME_CREATED, "Created", epoch, stdout); if (printpub) printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout); if (printact) printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout); if (printrev) printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout); if (printinact) printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout); if (printdel) printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout); if (changed) { isc_buffer_init(&buf, newname, sizeof(newname)); result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build public key filename: %s", isc_result_totext(result)); } result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, directory); if (result != ISC_R_SUCCESS) { dst_key_format(key, keystr, sizeof(keystr)); fatal("Failed to write key %s: %s", keystr, isc_result_totext(result)); } printf("%s\n", newname); isc_buffer_clear(&buf); result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &buf); if (result != ISC_R_SUCCESS) { fatal("Failed to build private key filename: %s", isc_result_totext(result)); } printf("%s\n", newname); } dst_key_free(&key); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); if (verbose > 10) isc_mem_stats(mctx, stdout); cleanup_logging(&log); isc_mem_free(mctx, directory); isc_mem_destroy(&mctx); return (0); }
int main(int argc, char *argv[]) { int i, ch; char *startstr = NULL, *endstr = NULL; dns_fixedname_t fdomain; dns_name_t *domain = NULL; char *output = NULL; char *endp; unsigned char data[65536]; dns_db_t *db; dns_dbversion_t *version; dns_diff_t diff; dns_difftuple_t *tuple; dns_fixedname_t tname; dst_key_t *key = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_rdataclass_t rdclass; isc_result_t result; isc_buffer_t b; isc_region_t r; isc_log_t *log = NULL; keynode_t *keynode; unsigned int eflags; isc_boolean_t pseudorandom = ISC_FALSE; isc_boolean_t tryverify = ISC_FALSE; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("failed to create memory context: %s", isc_result_totext(result)); dns_result_register(); while ((ch = isc_commandline_parse(argc, argv, "as:e:t:r:v:ph")) != -1) { switch (ch) { case 'a': tryverify = ISC_TRUE; break; case 's': startstr = isc_commandline_argument; break; case 'e': endstr = isc_commandline_argument; break; case 't': endp = NULL; ttl = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("TTL must be numeric"); 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("verbose level must be numeric"); break; case 'p': pseudorandom = ISC_TRUE; break; case 'h': default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); eflags = ISC_ENTROPY_BLOCKING; if (!pseudorandom) eflags |= ISC_ENTROPY_GOODONLY; result = dst_lib_init(mctx, ectx, eflags); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); if (startstr != NULL) starttime = strtotime(startstr, now, now); else starttime = now; if (endstr != NULL) endtime = strtotime(endstr, now, starttime); else endtime = starttime + (30 * 24 * 60 * 60); if (ttl == -1) { ttl = 3600; fprintf(stderr, "%s: TTL not specified, assuming 3600\n", program); } setup_logging(verbose, mctx, &log); dns_diff_init(mctx, &diff); rdclass = 0; ISC_LIST_INIT(keylist); for (i = 0; i < argc; i++) { char namestr[DNS_NAME_FORMATSIZE]; isc_buffer_t namebuf; key = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("error loading key from %s: %s", argv[i], isc_result_totext(result)); if (rdclass == 0) rdclass = dst_key_class(key); isc_buffer_init(&namebuf, namestr, sizeof(namestr)); result = dns_name_tofilenametext(dst_key_name(key), ISC_FALSE, &namebuf); check_result(result, "dns_name_tofilenametext"); isc_buffer_putuint8(&namebuf, 0); if (domain == NULL) { dns_fixedname_init(&fdomain); domain = dns_fixedname_name(&fdomain); dns_name_copy(dst_key_name(key), domain, NULL); } else if (!dns_name_equal(domain, dst_key_name(key))) { char str[DNS_NAME_FORMATSIZE]; dns_name_format(domain, str, sizeof(str)); fatal("all keys must have the same owner - %s " "and %s do not match", str, namestr); } if (output == NULL) { output = isc_mem_allocate(mctx, strlen("keyset-") + strlen(namestr) + 1); if (output == NULL) fatal("out of memory"); sprintf(output, "keyset-%s", namestr); } if (dst_key_iszonekey(key)) { dst_key_t *zonekey = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &zonekey); if (result != ISC_R_SUCCESS) fatal("failed to read private key %s: %s", argv[i], isc_result_totext(result)); if (!zonekey_on_list(zonekey)) { keynode = isc_mem_get(mctx, sizeof(keynode_t)); if (keynode == NULL) fatal("out of memory"); keynode->key = zonekey; ISC_LIST_INITANDAPPEND(keylist, keynode, link); } else dst_key_free(&zonekey); } dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dst_key_todns(key, &b); dst_key_free(&key); if (result != ISC_R_SUCCESS) fatal("failed to convert key %s to a DNS KEY: %s", argv[i], isc_result_totext(result)); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, rdclass, dns_rdatatype_dnskey, &r); tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } db = NULL; result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("failed to create a database"); version = NULL; dns_db_newversion(db, &version); result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_fixedname_init(&tname); dns_rdataset_init(&rdataset); result = dns_db_find(db, domain, version, dns_rdatatype_dnskey, 0, 0, NULL, dns_fixedname_name(&tname), &rdataset, NULL); check_result(result, "dns_db_find"); if (ISC_LIST_EMPTY(keylist)) fprintf(stderr, "%s: no private zone key found; not self-signing\n", program); for (keynode = ISC_LIST_HEAD(keylist); keynode != NULL; keynode = ISC_LIST_NEXT(keynode, link)) { dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dns_dnssec_sign(domain, &rdataset, keynode->key, &starttime, &endtime, mctx, &b, &rdata); isc_entropy_stopcallbacksources(ectx); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("failed to sign keyset with key %s: %s", keystr, isc_result_totext(result)); } if (tryverify) { result = dns_dnssec_verify(domain, &rdataset, keynode->key, ISC_TRUE, mctx, &rdata); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("signature from key '%s' failed to " "verify: %s", keystr, isc_result_totext(result)); } } tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &version, ISC_TRUE); result = dns_db_dump(db, version, output); if (result != ISC_R_SUCCESS) { char domainstr[DNS_NAME_FORMATSIZE]; dns_name_format(domain, domainstr, sizeof(domainstr)); fatal("failed to write database for %s to %s", domainstr, output); } printf("%s\n", output); dns_db_detach(&db); while (!ISC_LIST_EMPTY(keylist)) { keynode = ISC_LIST_HEAD(keylist); ISC_LIST_UNLINK(keylist, keynode, link); dst_key_free(&keynode->key); isc_mem_put(mctx, keynode, sizeof(keynode_t)); } cleanup_logging(&log); cleanup_entropy(&ectx); isc_mem_free(mctx, output); dst_lib_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }