Exemple #1
0
static void create_dnskeys(dnssec_keystore_t *keystore,
			   dnssec_key_algorithm_t algorithm, const char *id,
			   dnssec_key_t **p11_key_ptr, dnssec_key_t **soft_key_ptr)
{
	int r;

	// construct PKCS #11 privkey-pubkey key pair

	dnssec_key_t *p11_key = NULL;
	r = dnssec_key_new(&p11_key);
	ok(r == DNSSEC_EOK && p11_key != NULL, MSG_PKCS11 " dnssec_key_new()");

	r = dnssec_key_set_algorithm(p11_key, algorithm);
	ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_set_key_algorithm()");

	r = dnssec_key_import_keystore(p11_key, keystore, id);
	ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_key_import_keystore()");

	// construct software public key

	dnssec_key_t *soft_key = NULL;
	r = dnssec_key_new(&soft_key);
	ok(r == DNSSEC_EOK && soft_key != NULL, MSG_SOFTWARE " dnssec_key_new()");

	dnssec_binary_t rdata = { 0 };
	dnssec_key_get_rdata(p11_key, &rdata);
	r = dnssec_key_set_rdata(soft_key, &rdata);
	ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_key_set_rdata()");

	*p11_key_ptr = p11_key;
	*soft_key_ptr = soft_key;
}
Exemple #2
0
/*!
 * Generate new key with parameters from KASP policy and add it into zone.
 */
int generate_key(dnssec_event_ctx_t *ctx, bool ksk, dnssec_kasp_key_t **key_ptr)
{
	assert(ctx);
	assert(ctx->zone);
	assert(ctx->keystore);
	assert(ctx->policy);

	dnssec_key_algorithm_t algorithm = ctx->policy->algorithm;
	unsigned size = ksk ? ctx->policy->ksk_size : ctx->policy->zsk_size;

	// generate key in the keystore

	_cleanup_free_ char *id = NULL;
	int r = dnssec_keystore_generate_key(ctx->keystore, algorithm, size, &id);
	if (r != DNSSEC_EOK) {
		return r;
	}

	// create KASP key

	dnssec_key_t *dnskey = NULL;
	r = dnssec_key_new(&dnskey);
	if (r != DNSSEC_EOK) {
		return r;
	}

	r = dnssec_key_set_dname(dnskey, ctx->zone->dname);
	if (r != DNSSEC_EOK) {
		dnssec_key_free(dnskey);
		return r;
	}

	dnssec_key_set_flags(dnskey, dnskey_flags(ksk));

	r = dnssec_key_import_keystore(dnskey, ctx->keystore, id, algorithm);
	if (r != DNSSEC_EOK) {
		dnssec_key_free(dnskey);
		return r;
	}

	dnssec_kasp_key_t *key = calloc(1, sizeof(*key));
	if (!key) {
		dnssec_key_free(dnskey);
		return DNSSEC_ENOMEM;
	}

	key->key = dnskey;
	key->timing.created = ctx->now;

	// add into KASP zone

	dnssec_list_t *keys = dnssec_kasp_zone_get_keys(ctx->zone);
	dnssec_list_append(keys, key);

	if (key_ptr) {
		*key_ptr = key;
	}

	return DNSSEC_EOK;
}
Exemple #3
0
/*!
 * Create DNSKEY from parameters.
 */
static int create_dnskey(const uint8_t *dname, key_params_t *params,
			 dnssec_key_t **key_ptr)
{
	assert(dname);
	assert(params);
	assert(key_ptr);

	int result = key_params_check(params);
	if (result != DNSSEC_EOK) {
		return result;
	}

	// create key

	dnssec_key_t *key = NULL;
	result = dnssec_key_new(&key);
	if (result != DNSSEC_EOK) {
		return result;
	}

	// set key parameters

	result = dnssec_key_set_dname(key, dname);
	if (result != DNSSEC_EOK) {
		dnssec_key_free(key);
		return result;
	}

	dnssec_key_set_algorithm(key, params->algorithm);

	uint16_t flags = dnskey_flags(params->is_ksk);
	dnssec_key_set_flags(key, flags);

	result = dnssec_key_set_pubkey(key, &params->public_key);
	if (result != DNSSEC_EOK) {
		dnssec_key_free(key);
		return result;
	}

	// validate key ID

	const char *key_id = dnssec_key_get_id(key);
	if (!key_id) {
		dnssec_key_free(key);
		return DNSSEC_INVALID_PUBLIC_KEY;
	}

	if (!dnssec_keyid_equal(params->id, key_id)) {
		dnssec_key_free(key);
		return DNSSEC_INVALID_KEY_ID;
	}

	*key_ptr = key;

	return DNSSEC_EOK;
}
Exemple #4
0
/*!
 * Parse DNSKEY record.
 *
 * \todo Currently, the function waits for the first DNSKEY record, and skips
 * the others. We should be more strict and report other records as errors.
 * However, there is currently no API to stop the scanner.
 */
static void parse_record(zs_scanner_t *scanner)
{
	assert(scanner);
	assert(scanner->data);

	dnssec_key_t *key = scanner->data;

	if (dnssec_key_get_dname(key) != NULL) {
		// skip till the the parser finishes
		return;
	}

	if (scanner->r_type != RTYPE_DNSKEY) {
		// should report error
		return;
	}

	dnssec_binary_t rdata = {
		.data = scanner->r_data,
		.size = scanner->r_data_length
	};
	dnssec_key_set_dname(key, scanner->dname);
	dnssec_key_set_rdata(key, &rdata);
}

int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr)
{
	assert(filename);
	assert(key_ptr);

	dnssec_key_t *key = NULL;
	int result = dnssec_key_new(&key);
	if (result != DNSSEC_EOK) {
		return result;
	}

	uint16_t cls = CLASS_IN;
	uint32_t ttl = 0;
	zs_scanner_t *scanner = zs_scanner_create(".", cls, ttl,
						  parse_record, NULL, key);
	if (!scanner) {
		dnssec_key_free(key);
		return DNSSEC_NOT_FOUND;
	}

	result = zs_scanner_parse_file(scanner, filename);
	zs_scanner_free(scanner);
	if (result != 0 || dnssec_key_get_dname(key) == NULL) {
		dnssec_key_free(key);
		return DNSSEC_INVALID_PUBLIC_KEY;
	}

	*key_ptr = key;
	return DNSSEC_EOK;
}
Exemple #5
0
int kr_dnssec_key_from_rdata(struct dseckey **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen)
{
	if (!key || !rdata || rdlen == 0) {
		return kr_error(EINVAL);
	}

	dnssec_key_t *new_key = NULL;
	const dnssec_binary_t binary_key = {
		.size = rdlen,
		.data = (uint8_t *)rdata
	};

	int ret = dnssec_key_new(&new_key);
	if (ret != DNSSEC_EOK) {
		return kr_error(ENOMEM);
	}
	ret = dnssec_key_set_rdata(new_key, &binary_key);
	if (ret != DNSSEC_EOK) {
		dnssec_key_free(new_key);
		return kr_error(ENOMEM);
	}
	if (kown) {
		ret = dnssec_key_set_dname(new_key, kown);
		if (ret != DNSSEC_EOK) {
			dnssec_key_free(new_key);
			return kr_error(ENOMEM);
		}
	}

	*key = (struct dseckey *) new_key;
	return kr_ok();
}

void kr_dnssec_key_free(struct dseckey **key)
{
	assert(key);

	dnssec_key_free((dnssec_key_t *) *key);
	*key = NULL;
}
Exemple #6
0
/*!
 * Parse DNSKEY record.
 *
 * \todo Currently, the function waits for the first DNSKEY record, and skips
 * the others. We should be more strict and report other records as errors.
 */
static void parse_record(zs_scanner_t *scanner)
{
	assert(scanner);
	assert(scanner->process.data);

	dnssec_key_t *key = scanner->process.data;

	if (dnssec_key_get_dname(key) != NULL) {
		// should report error
		scanner->state = ZS_STATE_STOP;
		return;
	}

	if (scanner->r_type != RTYPE_DNSKEY) {
		// should report error
		scanner->state = ZS_STATE_STOP;
		return;
	}

	dnssec_binary_t rdata = {
		.data = scanner->r_data,
		.size = scanner->r_data_length
	};
	dnssec_key_set_dname(key, scanner->dname);
	dnssec_key_set_rdata(key, &rdata);
}

int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr)
{
	assert(filename);
	assert(key_ptr);

	dnssec_key_t *key = NULL;
	int result = dnssec_key_new(&key);
	if (result != DNSSEC_EOK) {
		return result;
	}

	uint16_t cls = CLASS_IN;
	uint32_t ttl = 0;
	zs_scanner_t *scanner = malloc(sizeof(zs_scanner_t));
	if (scanner == NULL) {
		dnssec_key_free(key);
		return DNSSEC_ENOMEM;
	}

	if (zs_init(scanner, ".", cls, ttl) != 0 ||
	    zs_set_input_file(scanner, filename) != 0 ||
	    zs_set_processing(scanner, parse_record, NULL, key) != 0 ||
	    zs_parse_all(scanner) != 0) {
		zs_deinit(scanner);
		free(scanner);
		dnssec_key_free(key);
		return DNSSEC_NOT_FOUND;
	}
	zs_deinit(scanner);
	free(scanner);

	if (dnssec_key_get_dname(key) == NULL) {
		dnssec_key_free(key);
		return DNSSEC_INVALID_PUBLIC_KEY;
	}

	*key_ptr = key;
	return DNSSEC_EOK;
}