/** * Drudge. * */ static void worker_drudge(worker_type* worker) { engine_type* engine = NULL; zone_type* zone = NULL; task_type* task = NULL; rrset_type* rrset = NULL; ods_status status = ODS_STATUS_OK; worker_type* superior = NULL; hsm_ctx_t* ctx = NULL; ods_log_assert(worker); ods_log_assert(worker->engine); ods_log_assert(worker->type == WORKER_DRUDGER); engine = (engine_type*) worker->engine; while (worker->need_to_exit == 0) { ods_log_deeebug("[%s[%i]] report for duty", worker2str(worker->type), worker->thread_num); /* initialize */ superior = NULL; zone = NULL; task = NULL; /* get item */ lock_basic_lock(&engine->signq->q_lock); rrset = (rrset_type*) fifoq_pop(engine->signq, &superior); if (!rrset) { ods_log_deeebug("[%s[%i]] nothing to do, wait", worker2str(worker->type), worker->thread_num); /** * Apparently the queue is empty. Wait until new work is queued. * The drudger will release the signq lock while sleeping and * will automatically grab the lock when the threshold is reached. * Threshold is at 1 and MAX (after a number of tries). */ lock_basic_sleep(&engine->signq->q_threshold, &engine->signq->q_lock, 0); rrset = (rrset_type*) fifoq_pop(engine->signq, &superior); } lock_basic_unlock(&engine->signq->q_lock); /* do some work */ if (rrset) { ods_log_assert(superior); if (!ctx) { ods_log_debug("[%s[%i]] create hsm context", worker2str(worker->type), worker->thread_num); ctx = hsm_create_context(); } if (!ctx) { ods_log_crit("[%s[%i]] error creating libhsm context", worker2str(worker->type), worker->thread_num); engine->need_to_reload = 1; lock_basic_lock(&superior->worker_lock); superior->jobs_failed++; lock_basic_unlock(&superior->worker_lock); } else { ods_log_assert(ctx); lock_basic_lock(&superior->worker_lock); task = superior->task; ods_log_assert(task); zone = task->zone; lock_basic_unlock(&superior->worker_lock); ods_log_assert(zone); ods_log_assert(zone->apex); ods_log_assert(zone->signconf); worker->clock_in = time(NULL); status = rrset_sign(ctx, rrset, superior->clock_in); lock_basic_lock(&superior->worker_lock); if (status == ODS_STATUS_OK) { superior->jobs_completed++; } else { superior->jobs_failed++; } lock_basic_unlock(&superior->worker_lock); } if (worker_fulfilled(superior) && superior->sleeping) { ods_log_deeebug("[%s[%i]] wake up superior[%u], work is " "done", worker2str(worker->type), worker->thread_num, superior->thread_num); worker_wakeup(superior); } superior = NULL; rrset = NULL; } /* done work */ } /* wake up superior */ if (superior && superior->sleeping) { ods_log_deeebug("[%s[%i]] wake up superior[%u], i am exiting", worker2str(worker->type), worker->thread_num, superior->thread_num); worker_wakeup(superior); } /* cleanup open HSM sessions */ if (ctx) { hsm_destroy_context(ctx); } return; }
int main (int argc, char *argv[]) { int result; hsm_ctx_t *ctx; hsm_key_t **keys; hsm_key_t *key = NULL; char *id; size_t key_count = 0; size_t i; ldns_rr_list *rrset; ldns_rr *rr, *sig, *dnskey_rr; ldns_status status; hsm_sign_params_t *sign_params; int do_generate = 0; int do_sign = 0; int do_delete = 0; int do_random = 0; int res; uint32_t r32; uint64_t r64; char *config = NULL; const char *repository = "default"; int ch; progname = argv[0]; while ((ch = getopt(argc, argv, "hgsdrc:")) != -1) { switch (ch) { case 'c': config = strdup(optarg); break; case 'g': do_generate = 1; break; case 'h': usage(); exit(0); break; case 's': do_sign = 1; break; case 'd': do_delete = 1; break; case 'r': do_random = 1; break; default: usage(); exit(1); } } if (!config) { usage(); exit(1); } /* * Open HSM library */ fprintf(stdout, "Starting HSM lib test\n"); result = hsm_open(config, hsm_prompt_pin); fprintf(stdout, "hsm_open result: %d\n", result); /* * Create HSM context */ ctx = hsm_create_context(); printf("global: "); hsm_print_ctx(NULL); printf("my: "); hsm_print_ctx(ctx); /* * Generate a new key OR find any key with an ID */ if (do_generate) { key = hsm_generate_rsa_key(ctx, repository, 1024); if (key) { printf("\nCreated key!\n"); hsm_print_key(key); printf("\n"); } else { printf("Error creating key, bad token name?\n"); hsm_print_error(ctx); exit(1); } } else if (do_sign || do_delete) { keys = hsm_list_keys(ctx, &key_count); printf("I have found %u keys\n", (unsigned int) key_count); /* let's just use the very first key we find and throw away the rest */ for (i = 0; i < key_count && !key; i++) { printf("\nFound key!\n"); hsm_print_key(keys[i]); id = hsm_get_key_id(ctx, keys[i]); if (id) { printf("Using key ID: %s\n", id); if (key) hsm_key_free(key); key = hsm_find_key_by_id(ctx, id); printf("ptr: 0x%p\n", (void *) key); free(id); } else { printf("Got no key ID (broken key?), skipped...\n"); } hsm_key_free(keys[i]); } free(keys); if (!key) { printf("Failed to find useful key\n"); exit(1); } } /* * Do some signing */ if (do_sign) { printf("\nSigning with:\n"); hsm_print_key(key); printf("\n"); rrset = ldns_rr_list_new(); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL); if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr); sign_params = hsm_sign_params_new(); sign_params->algorithm = LDNS_RSASHA1; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se."); dnskey_rr = hsm_get_dnskey(ctx, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); sig = hsm_sign_rrset(ctx, rrset, key, sign_params); if (sig) { ldns_rr_list_print(stdout, rrset); ldns_rr_print(stdout, sig); ldns_rr_print(stdout, dnskey_rr); ldns_rr_free(sig); } else { hsm_print_error(ctx); exit(-1); } /* cleanup */ ldns_rr_list_deep_free(rrset); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); } /* * Delete key */ if (do_delete) { printf("\nDelete key:\n"); hsm_print_key(key); /* res = hsm_remove_key(ctx, key); */ res = hsm_remove_key(ctx, key); printf("Deleted key. Result: %d\n", res); printf("\n"); } if (key) hsm_key_free(key); /* * Test random{32,64} functions */ if (do_random) { r32 = hsm_random32(ctx); printf("random 32: %u\n", r32); r64 = hsm_random64(ctx); printf("random 64: %llu\n", (long long unsigned int)r64); } /* * Destroy HSM context */ if (ctx) { hsm_destroy_context(ctx); } /* * Close HSM library */ result = hsm_close(); fprintf(stdout, "all done! hsm_close result: %d\n", result); if (config) free(config); return 0; }
static uint16_t dnskey_from_id(std::string &dnskey, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm, int bDS, uint32_t ttl) { hsm_key_t *key; hsm_sign_params_t *sign_params; ldns_rr *dnskey_rr; ldns_algorithm algo = (ldns_algorithm)algorithm; /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error("[%s] Could not connect to HSM", module_str); return false; } key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { // printf("Key %s in DB but not repository\n", id); hsm_destroy_context(hsm_ctx); return 0; } /* * Sign params only need to be kept around * for the hsm_get_dnskey() call. */ sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = algo; sign_params->flags = LDNS_KEY_ZONE_KEY; if (role == ::ods::keystate::KSK) sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ /* Get the DNSKEY record */ dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); hsm_sign_params_free(sign_params); /* Calculate the keytag for this key, we return it. */ uint16_t keytag = ldns_calc_keytag(dnskey_rr); /* Override the TTL in the dnskey rr */ if (ttl) ldns_rr_set_ttl(dnskey_rr, ttl); char *rrstr; if (!bDS) { #if 0 ldns_rr_print(stdout, dnskey_rr); #endif rrstr = ldns_rr2str(dnskey_rr); dnskey = rrstr; LDNS_FREE(rrstr); } else { switch (algo) { case LDNS_RSASHA1: // 5 { /* DS record (SHA1) */ ldns_rr *ds_sha1_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA1); #if 0 ldns_rr_print(stdout, ds_sha1_rr); #endif rrstr = ldns_rr2str(ds_sha1_rr); dnskey = rrstr; LDNS_FREE(rrstr); ldns_rr_free(ds_sha1_rr); break; } case LDNS_RSASHA256: // 8 - RFC 5702 { /* DS record (SHA256) */ ldns_rr *ds_sha256_rr = ldns_key_rr2ds(dnskey_rr, LDNS_SHA256); #if 0 ldns_rr_print(stdout, ds_sha256_rr); #endif rrstr = ldns_rr2str(ds_sha256_rr); dnskey = rrstr; LDNS_FREE(rrstr); ldns_rr_free(ds_sha256_rr); break; } default: keytag = 0; } } ldns_rr_free(dnskey_rr); hsm_key_free(key); hsm_destroy_context(hsm_ctx); return keytag; }
static void import_all_keys_from_all_hsms(int sockfd, OrmConn conn) { hsm_ctx_t * hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error_and_printf(sockfd, module_str, "could not connect to HSM"); return; } size_t nkeys; hsm_key_t **kl = hsm_list_keys(hsm_ctx, &nkeys); if (!kl) { ods_log_error_and_printf(sockfd, module_str, "could not list hsm keys"); return; } ods_printf(sockfd, "HSM keys:\n" " " "Algorithm: " "Bits: " "Id: " "\n" ); OrmTransactionRW transaction(conn); if (!transaction.started()) { ods_log_error_and_printf(sockfd, module_str, "could not start database transaction"); hsm_key_list_free(kl,nkeys); hsm_destroy_context(hsm_ctx); return; } for (int i=0; i<nkeys; ++i) { hsm_key_t *k = kl[i]; hsm_key_info_t *kinf = hsm_get_key_info(hsm_ctx,k); OrmResultRef result; if (!OrmMessageEnumWhere(conn, ::ods::hsmkey::HsmKey::descriptor(), result, "locator='%s'",kinf->id)) { // free allocated resources hsm_key_info_free(kinf); ods_log_error_and_printf(sockfd, module_str, "database query failed"); break; } if (OrmFirst(result)) { // Key already exists ::ods::hsmkey::HsmKey key; OrmContextRef context; if (!OrmGetMessage(result,key,true,context)) { // free allocated resources hsm_key_info_free(kinf); // release query result, we don't need it anymore. result.release(); // This is an unexpected error ! ods_log_error_and_printf(sockfd, module_str, "database record retrieval failed"); break; } else { // release query result, we don't need it anymore. result.release(); // retrieved the key from the database // Change key settings based on information from HSM key info if (key.key_type() == std::string(kinf->algorithm_name) || key.repository() == std::string(k->module->name)) { // key in the table does NOT need updating. } else { // key in the table needs updating. key.set_key_type( kinf->algorithm_name ); key.set_repository( k->module->name ); if (!OrmMessageUpdate(context)) { // This is an unexpected error ! ods_log_error_and_printf(sockfd, module_str, "database record retrieval failed"); } else { ods_printf(sockfd, "%-7s %-10s %-7ld %-40s\n", "update", kinf->algorithm_name, kinf->keysize, kinf->id ); } } // release the context, we don't need it anymore. context.release(); } } else { // release query result, we don't need it anymore. result.release(); // key does not exist ::ods::hsmkey::HsmKey key; key.set_locator(kinf->id); key.set_bits(kinf->keysize); key.set_key_type( kinf->algorithm_name ); key.set_repository( k->module->name ); // verify that according to the proto file definition the key is // fully initialized. if(!key.IsInitialized()) { // free allocated resources hsm_key_info_free(kinf); ods_log_error_and_printf(sockfd, module_str, "new HsmKey missing required fields"); break; } pb::uint64 keyid; if (!OrmMessageInsert(conn, key, keyid)) { // free allocated resources hsm_key_info_free(kinf); // This is an unexpected error ! ods_log_error_and_printf(sockfd, module_str, "database record insertion failed"); break; } else { // Key was inserted successfully ods_printf(sockfd, "%-7s %-10s %-7ld %-40s\n", "import", kinf->algorithm_name, kinf->keysize, kinf->id ); } } hsm_key_info_free(kinf); } hsm_key_list_free(kl,nkeys); hsm_destroy_context(hsm_ctx); }
static bool retract_dnskey_by_id(int sockfd, const char *ds_retract_command, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm) { /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error_and_printf(sockfd, module_str, "could not connect to HSM"); return false; } hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { ods_log_error_and_printf(sockfd, module_str, "key %s not found in any HSM", id); hsm_destroy_context(hsm_ctx); return false; } bool bOK = false; char *dnskey_rr_str; hsm_sign_params_t *sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = (ldns_algorithm)algorithm; sign_params->flags = LDNS_KEY_ZONE_KEY; sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); #if 0 ldns_rr_print(stdout, dnskey_rr); #endif dnskey_rr_str = ldns_rr2str(dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); /* Replace tab with white-space */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == '\t') { dnskey_rr_str[i] = ' '; } } /* We need to strip off trailing comments before we send to any clients that might be listening */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == ';') { dnskey_rr_str[i] = '\n'; dnskey_rr_str[i+1] = '\0'; break; } } // pass the dnskey rr string to a configured // delegation signer retract program. if (ds_retract_command && ds_retract_command[0] != '\0') { /* send records to the configured command */ FILE *fp = popen(ds_retract_command, "w"); if (fp == NULL) { ods_log_error_and_printf(sockfd, module_str, "failed to run command: %s: %s", ds_retract_command, strerror(errno)); } else { int bytes_written = fprintf(fp, "%s", dnskey_rr_str); if (bytes_written < 0) { ods_log_error_and_printf(sockfd, module_str, "[%s] Failed to write to %s: %s", ds_retract_command, strerror(errno)); } else { if (pclose(fp) == -1) { ods_log_error_and_printf(sockfd, module_str, "failed to close %s: %s", ds_retract_command, strerror(errno)); } else { bOK = true; ods_printf(sockfd, "key %s retracted by %s\n", id, ds_retract_command); } } } } else { ods_log_error_and_printf(sockfd, module_str, "no \"DelegationSignerRetractCommand\" binary " "configured in conf.xml."); } LDNS_FREE(dnskey_rr_str); hsm_destroy_context(hsm_ctx); return bOK; }
static bool retract_dnskey_by_id(int sockfd, const char *ds_retract_command, const char *id, ::ods::keystate::keyrole role, const char *zone, int algorithm, bool force) { struct stat stat_ret; /* Code to output the DNSKEY record (stolen from hsmutil) */ hsm_ctx_t *hsm_ctx = hsm_create_context(); if (!hsm_ctx) { ods_log_error_and_printf(sockfd, module_str, "could not connect to HSM"); return false; } hsm_key_t *key = hsm_find_key_by_id(hsm_ctx, id); if (!key) { ods_log_error_and_printf(sockfd, module_str, "key %s not found in any HSM", id); hsm_destroy_context(hsm_ctx); return false; } bool bOK = false; char *dnskey_rr_str; hsm_sign_params_t *sign_params = hsm_sign_params_new(); sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, zone); sign_params->algorithm = (ldns_algorithm)algorithm; sign_params->flags = LDNS_KEY_ZONE_KEY; sign_params->flags += LDNS_KEY_SEP_KEY; /*KSK=>SEP*/ ldns_rr *dnskey_rr = hsm_get_dnskey(hsm_ctx, key, sign_params); #if 0 ldns_rr_print(stdout, dnskey_rr); #endif dnskey_rr_str = ldns_rr2str(dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); /* Replace tab with white-space */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == '\t') { dnskey_rr_str[i] = ' '; } } /* We need to strip off trailing comments before we send to any clients that might be listening */ for (int i = 0; dnskey_rr_str[i]; ++i) { if (dnskey_rr_str[i] == ';') { dnskey_rr_str[i] = '\n'; dnskey_rr_str[i+1] = '\0'; break; } } // pass the dnskey rr string to a configured // delegation signer retract program. if (!ds_retract_command || ds_retract_command[0] == '\0') { if (!force) { ods_log_error_and_printf(sockfd, module_str, "No \"DelegationSignerRetractCommand\" " "configured. No state changes made. " "Use --force to override."); bOK = false; } /* else: Do nothing, return keytag. */ } else if (stat(ds_retract_command, &stat_ret) != 0) { /* First check that the command exists */ ods_log_error_and_printf(sockfd, module_str, "Cannot stat file %s: %s", ds_retract_command, strerror(errno)); } else if (S_ISREG(stat_ret.st_mode) && !(stat_ret.st_mode & S_IXUSR || stat_ret.st_mode & S_IXGRP || stat_ret.st_mode & S_IXOTH)) { /* Then see if it is a regular file, then if usr, grp or * all have execute set */ ods_log_error_and_printf(sockfd, module_str, "File %s is not executable", ds_retract_command); } else { /* send records to the configured command */ FILE *fp = popen(ds_retract_command, "w"); if (fp == NULL) { ods_log_error_and_printf(sockfd, module_str, "failed to run command: %s: %s", ds_retract_command, strerror(errno)); } else { int bytes_written = fprintf(fp, "%s", dnskey_rr_str); if (bytes_written < 0) { ods_log_error_and_printf(sockfd, module_str, "[%s] Failed to write to %s: %s", ds_retract_command, strerror(errno)); } else if (pclose(fp) == -1) { ods_log_error_and_printf(sockfd, module_str, "failed to close %s: %s", ds_retract_command, strerror(errno)); } else { bOK = true; ods_printf(sockfd, "key %s retracted by %s\n", id, ds_retract_command); } } } LDNS_FREE(dnskey_rr_str); hsm_destroy_context(hsm_ctx); return bOK; }
int main (int argc, char *argv[]) { int result; hsm_ctx_t *ctx = NULL; hsm_key_t *key = NULL; unsigned int keysize = 1024; unsigned int iterations = 1; unsigned int threads = 1; static struct timeval start,end; char *config = NULL; const char *repository = NULL; sign_arg_t sign_arg_array[PTHREAD_THREADS_MAX]; pthread_t thread_array[PTHREAD_THREADS_MAX]; pthread_attr_t thread_attr; void *thread_status; int ch; unsigned int n; double elapsed, speed; progname = argv[0]; while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) { switch (ch) { case 'c': config = strdup(optarg); break; case 'i': iterations = atoi(optarg); break; case 'r': repository = strdup(optarg); break; case 's': keysize = atoi(optarg); break; case 't': threads = atoi(optarg); break; default: usage(); exit(1); } } if (!repository) { usage(); exit(1); } #if 0 if (!config) { usage(); exit(1); } #endif /* Open HSM library */ fprintf(stderr, "Opening HSM Library...\n"); result = hsm_open(config, hsm_prompt_pin, NULL); if (result) { fprintf(stderr, "hsm_open() returned %d\n", result); exit(-1); } /* Create HSM context */ ctx = hsm_create_context(); if (! ctx) { fprintf(stderr, "hsm_create_context() returned error\n"); exit(-1); } /* Generate a temporary key */ fprintf(stderr, "Generating temporary key...\n"); key = hsm_generate_rsa_key(ctx, repository, keysize); if (key) { char *id = hsm_get_key_id(ctx, key); fprintf(stderr, "Temporary key created: %s\n", id); free(id); } else { fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository); exit(-1); } /* Prepare threads */ pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); for (n=0; n<threads; n++) { sign_arg_array[n].id = n; sign_arg_array[n].ctx = hsm_create_context(); if (! sign_arg_array[n].ctx) { fprintf(stderr, "hsm_create_context() returned error\n"); exit(-1); } sign_arg_array[n].key = key; sign_arg_array[n].iterations = iterations; } fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n", iterations, algoname, threads, (threads > 1 ? "threads" : "thread")); gettimeofday(&start, NULL); /* Create threads for signing */ for (n=0; n<threads; n++) { result = pthread_create(&thread_array[n], &thread_attr, sign, (void *) &sign_arg_array[n]); if (result) { fprintf(stderr, "pthread_create() returned %d\n", result); exit(EXIT_FAILURE); } } /* Wait for threads to finish */ for (n=0; n<threads; n++) { result = pthread_join(thread_array[n], &thread_status); if (result) { fprintf(stderr, "pthread_join() returned %d\n", result); exit(EXIT_FAILURE); } } gettimeofday(&end, NULL); fprintf(stderr, "Signing done.\n"); /* Report results */ end.tv_sec -= start.tv_sec; end.tv_usec-= start.tv_usec; elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001; speed = iterations / elapsed * threads; printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n", threads, (threads > 1 ? "threads" : "thread"), iterations, speed, keysize); /* Delete temporary key */ fprintf(stderr, "Deleting temporary key...\n"); result = hsm_remove_key(ctx, key); if (result) { fprintf(stderr, "hsm_remove_key() returned %d\n", result); exit(-1); } /* Clean up */ hsm_destroy_context(ctx); (void) hsm_close(); if (config) free(config); return 0; }
/** * Publish the keys as indicated by the signer configuration. * */ ods_status zone_publish_dnskeys(zone_type* zone) { hsm_ctx_t* ctx = NULL; uint32_t ttl = 0; uint16_t i = 0; ods_status status = ODS_STATUS_OK; rrset_type* rrset = NULL; rr_type* dnskey = NULL; if (!zone || !zone->db || !zone->signconf || !zone->signconf->keys) { return ODS_STATUS_ASSERT_ERR; } ods_log_assert(zone->name); /* hsm access */ ctx = hsm_create_context(); if (ctx == NULL) { ods_log_error("[%s] unable to publish keys for zone %s: " "error creating libhsm context", zone_str, zone->name); return ODS_STATUS_HSM_ERR; } /* dnskey ttl */ ttl = zone->default_ttl; if (zone->signconf->dnskey_ttl) { ttl = (uint32_t) duration2time(zone->signconf->dnskey_ttl); } /* publish keys */ for (i=0; i < zone->signconf->keys->count; i++) { if (!zone->signconf->keys->keys[i].publish) { continue; } if (!zone->signconf->keys->keys[i].dnskey) { /* get dnskey */ status = lhsm_get_key(ctx, zone->apex, &zone->signconf->keys->keys[i]); if (status != ODS_STATUS_OK) { ods_log_error("[%s] unable to publish dnskeys for zone %s: " "error creating dnskey", zone_str, zone->name); break; } } ods_log_assert(zone->signconf->keys->keys[i].dnskey); ldns_rr_set_ttl(zone->signconf->keys->keys[i].dnskey, ttl); ldns_rr_set_class(zone->signconf->keys->keys[i].dnskey, zone->klass); status = zone_add_rr(zone, zone->signconf->keys->keys[i].dnskey, 0); if (status == ODS_STATUS_UNCHANGED) { /* rr already exists, adjust pointer */ rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_DNSKEY); ods_log_assert(rrset); dnskey = rrset_lookup_rr(rrset, zone->signconf->keys->keys[i].dnskey); ods_log_assert(dnskey); if (dnskey->rr != zone->signconf->keys->keys[i].dnskey) { ldns_rr_free(zone->signconf->keys->keys[i].dnskey); } zone->signconf->keys->keys[i].dnskey = dnskey->rr; status = ODS_STATUS_OK; } else if (status != ODS_STATUS_OK) { ods_log_error("[%s] unable to publish dnskeys for zone %s: " "error adding dnskey", zone_str, zone->name); break; } } /* done */ hsm_destroy_context(ctx); return status; }