33#include "cmdhandler.h"
39#include "clientpipe.h"
49static const char *module_str =
"keystate_export_cmd";
58get_dnskey(
const char *
id,
const char *zone,
const char *keytype,
int alg, uint32_t ttl)
61 hsm_sign_params_t *sign_params;
64 hsm_ctx_t *hsm_ctx = hsm_create_context();
66 ods_log_error(
"[%s] Could not connect to HSM", module_str);
69 if (!(key = hsm_find_key_by_id(hsm_ctx,
id))) {
70 hsm_destroy_context(hsm_ctx);
76 sign_params = hsm_sign_params_new();
77 sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone);
78 sign_params->algorithm = (ldns_algorithm) alg;
79 sign_params->flags = LDNS_KEY_ZONE_KEY;
81 if (keytype && (!strcasecmp(keytype,
"KSK") || !strcasecmp(keytype,
"CSK")))
82 sign_params->flags = sign_params->flags | LDNS_KEY_SEP_KEY;
85 dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params);
88 hsm_sign_params_free(sign_params);
89 hsm_destroy_context(hsm_ctx);
93 ldns_rr_set_ttl(dnskey_rr, ttl);
109print_ds_from_id(
int sockfd,
key_data_t *key,
const char *zone,
110 const char* state,
int bind_style,
int print_sha1)
138 ds_sha_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1);
139 rrstr = ldns_rr2str(ds_sha_rr);
140 ldns_rr_free(ds_sha_rr);
142 (void)client_printf(sockfd,
";%s %s DS record (SHA1):\n%s", state,
key_data_role_text(key), rrstr);
145 ds_sha_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256);
146 rrstr = ldns_rr2str(ds_sha_rr);
147 ldns_rr_free(ds_sha_rr);
149 (void)client_printf(sockfd,
";%s %s DS record (SHA256):\n%s", state,
key_data_role_text(key), rrstr);
153 rrstr = ldns_rr2str_fmt(ldns_output_format_nocomments, dnskey_rr);
155 (void)client_printf(sockfd,
"%s", rrstr);
159 ldns_rr_free(dnskey_rr);
165 const char *zonename,
const char *keytype,
const char *keystate,
166 const hsm_key_t *hsmkey,
int all,
int bind_style,
int print_sha1)
172 const char *azonename = NULL;
186 ods_log_error(
"[%s] Error fetching from database", module_str);
199 ods_log_error(
"[%s] Error fetching from database", module_str);
211 if (keystate && strcasecmp(
map_keystate(key), keystate)) {
215 if (!keytype && !keystate && !hsmkey &&
226 ods_log_error(
"[%s] Error fetching from database", module_str);
227 client_printf_err(sockfd,
"Error fetching from database \n");
232 if (print_ds_from_id(sockfd, key, (
const char*)azonename?azonename:zonename, (
const char*)
map_keystate(key), bind_style, print_sha1)) {
233 ods_log_error(
"[%s] Error in print_ds_from_id", module_str);
234 client_printf_err(sockfd,
"Error in print_ds_from_id \n");
237 ods_log_error(
"[%s] Error fetching from database", module_str);
238 client_printf_err(sockfd,
"Error fetching from database \n");
252 client_printf(sockfd,
254 " --zone <zone> | --all aka -z | -a \n"
255 " --keystate <state> aka -e\n"
256 " --keytype <type> aka -t \n"
257 " --cka_id <CKA_ID> aka -k \n"
258 " [--ds [--sha1]] aka -d [-s]\n"
265 client_printf(sockfd,
266 "Export DNSKEY(s) for a given zone or all of them from the database.\n"
267 "If keytype and keystate are not specified, KSKs which are waiting for command ds-submit, ds-seen, ds-retract and ds-gone are shown. Otherwise both keystate and keytype must be given.\n"
268 "If cka_id is specified then that key is output for the specified zones.\n"
271 "zone|all specify a zone or all of them\n"
272 "keystate limit the output to a given state\n"
273 "keytype limit the output to a given type, can be ZSK, KSK, or CSK\n"
274 "cka_id limit the output to the given key locator\n"
275 "ds export DS in BIND format which can be used for upload to a registry\n"
276 "sha1 When outputting DS print sha1 instead of sha256\n");
280run(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
283 char buf[ODS_SE_MAXLINE];
284 const char *argv[
NARGV];
286 const char *zonename = NULL;
287 const char* keytype = NULL;
288 const char* keystate = NULL;
289 const char* cka_id = NULL;
295 int long_index = 0, opt = 0;
298 static struct option long_options[] = {
299 {
"zone", required_argument, 0,
'z'},
300 {
"keytype", required_argument, 0,
't'},
301 {
"keystate", required_argument, 0,
'e'},
302 {
"cka_id", required_argument, 0,
'k'},
303 {
"all", no_argument, 0,
'a'},
304 {
"ds", no_argument, 0,
'd'},
305 {
"sha1", no_argument, 0,
's'},
312 strncpy(buf, cmd,
sizeof(buf));
313 buf[
sizeof(buf)-1] =
'\0';
316 argc = ods_str_explode(buf,
NARGV, argv);
318 client_printf_err(sockfd,
"too many arguments\n");
319 ods_log_error(
"[%s] too many arguments for %s command",
325 while ((opt = getopt_long(argc, (
char*
const*)argv,
"z:t:e:k:ads", long_options, &long_index)) != -1) {
349 client_printf_err(sockfd,
"unknown arguments\n");
350 ods_log_error(
"[%s] unknown arguments for %s command",
357 if (strcasecmp(keytype,
"KSK") && strcasecmp(keytype,
"ZSK") && strcasecmp(keytype,
"CSK")) {
358 ods_log_error(
"[%s] unknown keytype, should be one of KSK, ZSK, or CSK", module_str);
359 client_printf_err(sockfd,
"unknown keytype, should be one of KSK, ZSK, or CSK\n");
365 if (strcasecmp(keystate,
"generate") && strcasecmp(keystate,
"publish") && strcasecmp(keystate,
"ready") && strcasecmp(keystate,
"active") && strcasecmp(keystate,
"retire") && strcasecmp(keystate,
"unknown") && strcasecmp(keystate,
"mixed")) {
366 ods_log_error(
"[%s] unknown keystate", module_str);
367 client_printf_err(sockfd,
"unknown keystate\n");
373 if ((!zonename && !all) || (zonename && all)) {
374 ods_log_error(
"[%s] expected either --zone or --all for %s command", module_str,
key_export_funcblock.cmdname);
375 client_printf_err(sockfd,
"expected either --zone or --all \n");
379 ods_log_error(
"[%s] Unknown zone: %s", module_str, zonename);
380 client_printf_err(sockfd,
"Unknown zone: %s\n", zonename);
390 if ((keytype && !keystate) || (!keytype && keystate)) {
391 ods_log_error(
"[%s] expected both --keystate and --keytype together or none of them", module_str);
392 client_printf_err(sockfd,
"expected both --keystate and --keytype together or none of them\n");
397 client_printf_err(sockfd,
"CKA_ID %s can not be found!\n", cka_id);
402 return perform_keystate_export(sockfd, dbconn, zonename, (
const char*) keytype, (
const char*) keystate, hsmkey, all, ds, bsha1);
406 "key export", &usage, &help, NULL, &run
db_clause_list_t * db_clause_list_new(void)
void db_clause_list_free(db_clause_list_t *clause_list)
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
const char * hsm_key_locator(const hsm_key_t *hsm_key)
hsm_key_t * hsm_key_new_get_by_locator(const db_connection_t *connection, const char *locator)
const db_value_t * hsm_key_id(const hsm_key_t *hsm_key)
void key_data_free(key_data_t *key_data)
const hsm_key_t * key_data_hsm_key(const key_data_t *key_data)
db_clause_t * key_data_hsm_key_id_clause(db_clause_list_t *clause_list, const db_value_t *hsm_key_id)
key_data_list_t * key_data_list_new_get(const db_connection_t *connection)
int key_data_list_get_by_clauses(key_data_list_t *key_data_list, const db_clause_list_t *clause_list)
const char * key_data_role_text(const key_data_t *key_data)
void key_data_list_free(key_data_list_t *key_data_list)
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
int key_data_cache_hsm_key(key_data_t *key_data)
key_data_list_t * key_data_list_new(const db_connection_t *connection)
unsigned int key_data_algorithm(const key_data_t *key_data)
db_clause_t * key_data_zone_id_clause(db_clause_list_t *clause_list, const db_value_t *zone_id)
const db_value_t * key_data_zone_id(const key_data_t *key_data)
@ KEY_DATA_DS_AT_PARENT_SUBMITTED
@ KEY_DATA_DS_AT_PARENT_RETRACT
@ KEY_DATA_DS_AT_PARENT_SUBMIT
@ KEY_DATA_DS_AT_PARENT_RETRACTED
int key_data_cache_key_states(key_data_t *key_data)
const key_state_t * key_data_cached_dnskey(key_data_t *key_data)
const key_state_t * key_data_cached_ds(key_data_t *key_data)
unsigned int key_state_ttl(const key_state_t *key_state)
struct cmd_func_block key_export_funcblock
const char * map_keystate(key_data_t *key)
void zone_db_free(zone_db_t *zone)
const char * zone_db_name(const zone_db_t *zone)
int zone_db_get_by_id(zone_db_t *zone, const db_value_t *id)
zone_db_t * zone_db_new(const db_connection_t *connection)
const db_value_t * zone_db_id(const zone_db_t *zone)
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)