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 cmd_dnskey (int argc, char *argv[]) { char *id; char *name; int type; int algo; hsm_key_t *key = NULL; ldns_rr *dnskey_rr; hsm_sign_params_t *sign_params; if (argc != 4) { usage(); return -1; } id = strdup(argv[0]); name = strdup(argv[1]); type = atoi(argv[2]); algo = atoi(argv[3]); key = hsm_find_key_by_id(NULL, id); if (!key) { printf("Key not found: %s\n", id); free(name); free(id); return -1; } if (type != LDNS_KEY_ZONE_KEY && type != LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY) { printf("Invalid key type: %i\n", type); printf("Please use: %i or %i\n", LDNS_KEY_ZONE_KEY, LDNS_KEY_ZONE_KEY + LDNS_KEY_SEP_KEY); free(name); free(id); return -1; } hsm_key_info_t *key_info = hsm_get_key_info(NULL, key); switch (algo) { case LDNS_SIGN_RSAMD5: case LDNS_SIGN_RSASHA1: case LDNS_SIGN_RSASHA1_NSEC3: case LDNS_SIGN_RSASHA256: case LDNS_SIGN_RSASHA512: if (strcmp(key_info->algorithm_name, "RSA") != 0) { printf("Not an RSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_DSA: case LDNS_SIGN_DSA_NSEC3: if (strcmp(key_info->algorithm_name, "DSA") != 0) { printf("Not a DSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_ECC_GOST: if (strcmp(key_info->algorithm_name, "GOST") != 0) { printf("Not a GOST key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; /* TODO: We can remove the directive if we require LDNS >= 1.6.13 */ #if !defined LDNS_BUILD_CONFIG_USE_ECDSA || LDNS_BUILD_CONFIG_USE_ECDSA case LDNS_SIGN_ECDSAP256SHA256: if (strcmp(key_info->algorithm_name, "ECDSA") != 0) { printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } if (key_info->keysize != 256) { printf("The key is a ECDSA/%lu, expecting ECDSA/256 for this algorithm.\n", key_info->keysize); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; case LDNS_SIGN_ECDSAP384SHA384: if (strcmp(key_info->algorithm_name, "ECDSA") != 0) { printf("Not an ECDSA key, the key is of algorithm %s.\n", key_info->algorithm_name); hsm_key_info_free(key_info); free(name); free(id); return -1; } if (key_info->keysize != 384) { printf("The key is a ECDSA/%lu, expecting ECDSA/384 for this algorithm.\n", key_info->keysize); hsm_key_info_free(key_info); free(name); free(id); return -1; } break; #endif default: printf("Invalid algorithm: %i\n", algo); hsm_key_info_free(key_info); free(name); free(id); return -1; } hsm_key_info_free(key_info); sign_params = hsm_sign_params_new(); sign_params->algorithm = algo; sign_params->flags = type; sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name); dnskey_rr = hsm_get_dnskey(NULL, key, sign_params); sign_params->keytag = ldns_calc_keytag(dnskey_rr); ldns_rr_print(stdout, dnskey_rr); hsm_sign_params_free(sign_params); ldns_rr_free(dnskey_rr); hsm_key_free(key); free(name); free(id); return 0; }
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, NULL); 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; }
int cmd_generate (int argc, char *argv[]) { char *repository = NULL; char *algorithm = NULL; unsigned int keysize = 1024; hsm_key_t *key = NULL; hsm_ctx_t *ctx = NULL; if (argc < 2 || argc > 3) { usage(); return -1; } repository = strdup(argv[0]); /* Check for repository before starting using it */ if (hsm_token_attached(ctx, repository) == 0) { hsm_print_error(ctx); return 1; } algorithm = strdup(argv[1]); if (argc == 3) { keysize = atoi(argv[2]); } if (!strcasecmp(algorithm, "rsa")) { printf("Generating %d bit RSA key in repository: %s\n", keysize, repository); key = hsm_generate_rsa_key(NULL, repository, keysize); } else if (!strcasecmp(algorithm, "dsa")) { printf("Generating %d bit DSA key in repository: %s\n", keysize, repository); key = hsm_generate_dsa_key(NULL, repository, keysize); } else if (!strcasecmp(algorithm, "gost")) { printf("Generating 512 bit GOST key in repository: %s\n", repository); key = hsm_generate_gost_key(NULL, repository); } else if (!strcasecmp(algorithm, "ecdsa")) { if (keysize == 256) { printf("Generating a P-256 ECDSA key in repository: %s\n", repository); key = hsm_generate_ecdsa_key(NULL, repository, "P-256"); } else if (keysize == 384) { printf("Generating a P-384 ECDSA key in repository: %s\n", repository); key = hsm_generate_ecdsa_key(NULL, repository, "P-384"); } else { printf("Invalid ECDSA key size: %d\n", keysize); printf("Expecting 256 or 384.\n"); return -1; } } else { printf("Unknown algorithm: %s\n", algorithm); return -1; } if (key) { hsm_key_info_t *key_info; key_info = hsm_get_key_info(NULL, key); printf("Key generation successful: %s\n", key_info ? key_info->id : "NULL"); hsm_key_info_free(key_info); if (verbose) hsm_print_key(key); hsm_key_free(key); } else { printf("Key generation failed.\n"); return -1; } return 0; }
static int perform_keystate_list(int sockfd, db_connection_t *dbconn, const char* filterZone, char** filterKeytype, char** filterKeystate, void (printheader)(int sockfd), void (printkey)(int sockfd, zone_t* zone, key_data_t* key, char*tchange, hsm_key_t* hsmKey)) { key_data_list_t* key_list; key_data_t* key; zone_t *zone = NULL; char* tchange; hsm_key_t *hsmkey; int cmp; int i, skipPrintKey; if (!(key_list = key_data_list_new_get(dbconn))) { client_printf_err(sockfd, "Unable to get list of keys, memory " "allocation or database error!\n"); return 1; } if (printheader) { (*printheader)(sockfd); } while ((key = key_data_list_get_next(key_list))) { /* only refetches zone if different from previous */ if (zone && (db_value_cmp(zone_id(zone), key_data_zone_id(key), &cmp) || cmp)) { zone_free(zone); zone = NULL; } if (!zone) { zone = key_data_get_zone(key); } hsmkey = key_data_get_hsm_key(key); key_data_cache_key_states(key); tchange = map_keytime(zone, key); /* allocs */ skipPrintKey = 0; if(printkey == NULL) skipPrintKey = 1; if(filterZone != NULL && strcmp(zone_name(zone), filterZone)) skipPrintKey = 1; for(i=0; filterKeytype && filterKeytype[i]; i++) if(!strcasecmp(filterKeytype[i],key_data_role_text(key))) break; if(filterKeytype && filterKeytype[i] == NULL) skipPrintKey = 1; for(i=0; filterKeystate && filterKeystate[i]; i++) if(!strcasecmp(filterKeystate[i],map_keystate(key))) break; if(filterKeystate && filterKeystate[i] == NULL) skipPrintKey = 1; if (!skipPrintKey) { (*printkey)(sockfd, zone, key, tchange, hsmkey); } free(tchange); hsm_key_free(hsmkey); key_data_free(key); } zone_free(zone); key_data_list_free(key_list); return 0; }