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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}