Пример #1
0
isc_result_t
dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
		   unsigned char *secret, int length, isc_boolean_t generated,
		   dns_name_t *creator, isc_stdtime_t inception,
		   isc_stdtime_t expire, isc_mem_t *mctx,
		   dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
{
	dst_key_t *dstkey = NULL;
	isc_result_t result;

	REQUIRE(length >= 0);
	if (length > 0)
		REQUIRE(secret != NULL);

	if (!dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME) && length > 0)
		return (DNS_R_BADALG);

	if (secret != NULL) {
		isc_buffer_t b;

		isc_buffer_init(&b, secret, length);
		isc_buffer_add(&b, length);
		result = dst_key_frombuffer(name, DST_ALG_HMACMD5,
					    DNS_KEYOWNER_ENTITY,
					    DNS_KEYPROTO_DNSSEC,
					    dns_rdataclass_in,
					    &b, mctx, &dstkey);
		if (result != ISC_R_SUCCESS)
			return (result);
	}
	result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
					   generated, creator,
					   inception, expire, mctx, ring, key);
	if (result != ISC_R_SUCCESS && dstkey != NULL)
		dst_key_free(&dstkey);
	return (result);
}
Пример #2
0
static isc_result_t
restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
	dst_key_t *dstkey = NULL;
	char namestr[1024];
	char creatorstr[1024];
	char algorithmstr[1024];
	char keystr[4096];
	unsigned int inception, expire;
	int n;
	isc_buffer_t b;
	dns_name_t *name, *creator, *algorithm;
	dns_fixedname_t fname, fcreator, falgorithm;
	isc_result_t result;
	unsigned int dstalg;

	n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr,
		   creatorstr, &inception, &expire, algorithmstr, keystr);
	if (n == EOF)
		return (ISC_R_NOMORE);
	if (n != 6)
		return (ISC_R_FAILURE);

	if (isc_serial_lt(expire, now))
		return (DNS_R_EXPIRED);

	dns_fixedname_init(&fname);
	name = dns_fixedname_name(&fname);
	isc_buffer_init(&b, namestr, strlen(namestr));
	isc_buffer_add(&b, strlen(namestr));
	result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_fixedname_init(&fcreator);
	creator = dns_fixedname_name(&fcreator);
	isc_buffer_init(&b, creatorstr, strlen(creatorstr));
	isc_buffer_add(&b, strlen(creatorstr));
	result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_fixedname_init(&falgorithm);
	algorithm = dns_fixedname_name(&falgorithm);
	isc_buffer_init(&b, algorithmstr, strlen(algorithmstr));
	isc_buffer_add(&b, strlen(algorithmstr));
	result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dstalg = dst_alg_fromname(algorithm);
	if (dstalg == 0)
		return (DNS_R_BADALG);

	result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY,
				 DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
				 ring->mctx, keystr, &dstkey);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
					   ISC_TRUE, creator, inception,
					   expire, ring->mctx, ring, NULL);
	if (dstkey != NULL)
		dst_key_free(&dstkey);
	return (result);
}
Пример #3
0
isc_result_t
dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
		dns_tsec_t **tsecp)
{
	isc_result_t result;
	dns_tsec_t *tsec;
	dns_tsigkey_t *tsigkey = NULL;
	dns_name_t *algname;

	REQUIRE(mctx != NULL);
	REQUIRE(tsecp != NULL && *tsecp == NULL);

	tsec = isc_mem_get(mctx, sizeof(*tsec));
	if (tsec == NULL)
		return (ISC_R_NOMEMORY);

	tsec->type = type;
	tsec->mctx = mctx;

	switch (type) {
	case dns_tsectype_tsig:
		switch (dst_key_alg(key)) {
		case DST_ALG_HMACMD5:
			algname = dns_tsig_hmacmd5_name;
			break;
		case DST_ALG_HMACSHA1:
			algname = dns_tsig_hmacsha1_name;
			break;
		case DST_ALG_HMACSHA224:
			algname = dns_tsig_hmacsha224_name;
			break;
		case DST_ALG_HMACSHA256:
			algname = dns_tsig_hmacsha256_name;
			break;
		case DST_ALG_HMACSHA384:
			algname = dns_tsig_hmacsha384_name;
			break;
		case DST_ALG_HMACSHA512:
			algname = dns_tsig_hmacsha512_name;
			break;
		default:
			isc_mem_put(mctx, tsec, sizeof(*tsec));
			return (DNS_R_BADALG);
		}
		result = dns_tsigkey_createfromkey(dst_key_name(key),
						   algname, key, ISC_FALSE,
						   NULL, 0, 0, mctx, NULL,
						   &tsigkey);
		if (result != ISC_R_SUCCESS) {
			isc_mem_put(mctx, tsec, sizeof(*tsec));
			return (result);
		}
		tsec->ukey.tsigkey = tsigkey;
		break;
	case dns_tsectype_sig0:
		tsec->ukey.key = key;
		break;
	default:
		INSIST(0);
	}

	tsec->magic = DNS_TSEC_MAGIC;

	*tsecp = tsec;
	return (ISC_R_SUCCESS);
}
Пример #4
0
static isc_result_t
process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
		dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout,
		dns_tsig_keyring_t *ring)
{
	isc_result_t result = ISC_R_SUCCESS;
	dst_key_t *dstkey = NULL;
	dns_tsigkey_t *tsigkey = NULL;
	dns_fixedname_t principal;
	isc_stdtime_t now;
	isc_region_t intoken;
	isc_buffer_t *outtoken = NULL;
	gss_ctx_id_t gss_ctx = NULL;

	/*
	 * You have to define either a gss credential (principal) to
	 * accept with tkey-gssapi-credential, or you have to
	 * configure a specific keytab (with tkey-gssapi-keytab) in
	 * order to use gsstkey
	 */
	if (tctx->gsscred == NULL && tctx->gssapi_keytab == NULL) {
		tkey_log("process_gsstkey(): no tkey-gssapi-credential "
			 "or tkey-gssapi-keytab configured");
		return (ISC_R_NOPERM);
	}

	if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
	    !dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
		tkeyout->error = dns_tsigerror_badalg;
		tkey_log("process_gsstkey(): dns_tsigerror_badalg");	/* XXXSRA */
		return (ISC_R_SUCCESS);
	}

	/*
	 * XXXDCL need to check for key expiry per 4.1.1
	 * XXXDCL need a way to check fully established, perhaps w/key_flags
	 */

	intoken.base = tkeyin->key;
	intoken.length = tkeyin->keylen;

	result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
	if (result == ISC_R_SUCCESS)
		gss_ctx = dst_key_getgssctx(tsigkey->key);

	dns_fixedname_init(&principal);

	/*
	 * Note that tctx->gsscred may be NULL if tctx->gssapi_keytab is set
	 */
	result = dst_gssapi_acceptctx(tctx->gsscred, tctx->gssapi_keytab,
				      &intoken,
				      &outtoken, &gss_ctx,
				      dns_fixedname_name(&principal),
				      tctx->mctx);
	if (result == DNS_R_INVALIDTKEY) {
		if (tsigkey != NULL)
			dns_tsigkey_detach(&tsigkey);
		tkeyout->error = dns_tsigerror_badkey;
		tkey_log("process_gsstkey(): dns_tsigerror_badkey");    /* XXXSRA */
		return (ISC_R_SUCCESS);
	}
	if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
		goto failure;
	/*
	 * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times.
	 */

	isc_stdtime_get(&now);

	if (tsigkey == NULL) {
#ifdef GSSAPI
		OM_uint32 gret, minor, lifetime;
#endif
		isc_uint32_t expire;

		RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx,
					  &dstkey, &intoken));
		/*
		 * Limit keys to 1 hour or the context's lifetime whichever
		 * is smaller.
		 */
		expire = now + 3600;
#ifdef GSSAPI
		gret = gss_context_time(&minor, gss_ctx, &lifetime);
		if (gret == GSS_S_COMPLETE && now + lifetime < expire)
			expire = now + lifetime;
#endif
		RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
						 dstkey, ISC_TRUE,
						 dns_fixedname_name(&principal),
						 now, expire, ring->mctx, ring,
						 NULL));
		dst_key_free(&dstkey);
		tkeyout->inception = now;
		tkeyout->expire = expire;
	} else {
		tkeyout->inception = tsigkey->inception;
		tkeyout->expire = tsigkey->expire;
		dns_tsigkey_detach(&tsigkey);
	}

	if (outtoken) {
		tkeyout->key = isc_mem_get(tkeyout->mctx,
					   isc_buffer_usedlength(outtoken));
		if (tkeyout->key == NULL) {
			result = ISC_R_NOMEMORY;
			goto failure;
		}
		tkeyout->keylen = isc_buffer_usedlength(outtoken);
		memmove(tkeyout->key, isc_buffer_base(outtoken),
		       isc_buffer_usedlength(outtoken));
		isc_buffer_free(&outtoken);
	} else {
		tkeyout->key = isc_mem_get(tkeyout->mctx, tkeyin->keylen);
		if (tkeyout->key == NULL) {
			result = ISC_R_NOMEMORY;
			goto failure;
		}
		tkeyout->keylen = tkeyin->keylen;
		memmove(tkeyout->key, tkeyin->key, tkeyin->keylen);
	}

	tkeyout->error = dns_rcode_noerror;

	tkey_log("process_gsstkey(): dns_tsigerror_noerror");   /* XXXSRA */

	return (ISC_R_SUCCESS);

failure:
	if (tsigkey != NULL)
		dns_tsigkey_detach(&tsigkey);

	if (dstkey != NULL)
		dst_key_free(&dstkey);

	if (outtoken != NULL)
		isc_buffer_free(&outtoken);

	tkey_log("process_gsstkey(): %s",
		isc_result_totext(result));	/* XXXSRA */

	return (result);
}
Пример #5
0
int
main(int argc, char **argv) {
	char *keyname;
	isc_taskmgr_t *taskmgr;
	isc_timermgr_t *timermgr;
	isc_socketmgr_t *socketmgr;
	isc_socket_t *sock;
	unsigned int attrs, attrmask;
	isc_sockaddr_t bind_any;
	dns_dispatchmgr_t *dispatchmgr;
	dns_dispatch_t *dispatchv4;
	dns_view_t *view;
	isc_entropy_t *ectx;
	dns_tkeyctx_t *tctx;
	dst_key_t *dstkey;
	isc_log_t *log;
	isc_logconfig_t *logconfig;
	isc_task_t *task;
	isc_result_t result;
	int type;

	RUNCHECK(isc_app_start());

	if (argc < 2) {
		fprintf(stderr, "I:no key to delete\n");
		exit(-1);
	}
	keyname = argv[1];

	dns_result_register();

	mctx = NULL;
	RUNCHECK(isc_mem_create(0, 0, &mctx));

	ectx = NULL;
	RUNCHECK(isc_entropy_create(mctx, &ectx));
	RUNCHECK(isc_entropy_createfilesource(ectx, "random.data"));
	RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE));

	log = NULL;
	logconfig = NULL;
	RUNCHECK(isc_log_create(mctx, &log, &logconfig));

	RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY));

	taskmgr = NULL;
	RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
	task = NULL;
	RUNCHECK(isc_task_create(taskmgr, 0, &task));
	timermgr = NULL;
	RUNCHECK(isc_timermgr_create(mctx, &timermgr));
	socketmgr = NULL;
	RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
	dispatchmgr = NULL;
	RUNCHECK(dns_dispatchmgr_create(mctx, NULL, &dispatchmgr));
	isc_sockaddr_any(&bind_any);
	attrs = DNS_DISPATCHATTR_UDP |
		DNS_DISPATCHATTR_MAKEQUERY |
		DNS_DISPATCHATTR_IPV4;
	attrmask = DNS_DISPATCHATTR_UDP |
		   DNS_DISPATCHATTR_TCP |
		   DNS_DISPATCHATTR_IPV4 |
		   DNS_DISPATCHATTR_IPV6;
	dispatchv4 = NULL;
	RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
					  &bind_any, 4096, 4, 2, 3, 5,
					  attrs, attrmask, &dispatchv4));
	requestmgr = NULL;
	RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
					    dispatchmgr, dispatchv4, NULL,
					    &requestmgr));

	ring = NULL;
	RUNCHECK(dns_tsigkeyring_create(mctx, &ring));
	tctx = NULL;
	RUNCHECK(dns_tkeyctx_create(mctx, ectx, &tctx));

	view = NULL;
	RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
	dns_view_setkeyring(view, ring);

	sock = NULL;
	RUNCHECK(isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp,
				   &sock));

	RUNCHECK(isc_app_onrun(mctx, task, sendquery, NULL));

	dstkey = NULL;
	type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_KEY;
	result = dst_key_fromnamedfile(keyname, NULL, type, mctx, &dstkey);
	CHECK("dst_key_fromnamedfile", result);
	result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
					   DNS_TSIG_HMACMD5_NAME,
					   dstkey, ISC_TRUE, NULL, 0, 0,
					   mctx, ring, &tsigkey);
	dst_key_free(&dstkey);
	CHECK("dns_tsigkey_createfromkey", result);

	(void)isc_app_run();

	dns_requestmgr_shutdown(requestmgr);
	dns_requestmgr_detach(&requestmgr);
	dns_dispatch_detach(&dispatchv4);
	dns_dispatchmgr_destroy(&dispatchmgr);
	isc_task_shutdown(task);
	isc_task_detach(&task);
	isc_taskmgr_destroy(&taskmgr);
	isc_socket_detach(&sock);
	isc_socketmgr_destroy(&socketmgr);
	isc_timermgr_destroy(&timermgr);

	dns_tsigkeyring_detach(&ring);

	dns_tsigkey_detach(&tsigkey);

	dns_tkeyctx_destroy(&tctx);

	dns_view_detach(&view);

	isc_log_destroy(&log);

	dst_lib_destroy();
	isc_hash_destroy();
	isc_entropy_detach(&ectx);

	isc_mem_destroy(&mctx);

	isc_app_finish();

	return (0);
}
Пример #6
0
static isc_result_t
process_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
		dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx,
		dns_rdata_tkey_t *tkeyout,
		dns_tsig_keyring_t *ring, dns_namelist_t *namelist)
{
	isc_result_t result = ISC_R_SUCCESS;
	dst_key_t *dstkey = NULL;
	void *gssctx = NULL;
	isc_stdtime_t now;
	isc_region_t intoken;
	unsigned char array[1024];
	isc_buffer_t outtoken;

	UNUSED(namelist);

	if (tctx->gsscred == NULL)
		return (ISC_R_NOPERM);

	if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
	    !dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
		tkeyout->error = dns_tsigerror_badalg;
		return (ISC_R_SUCCESS);
	}

	intoken.base = tkeyin->key;
	intoken.length = tkeyin->keylen;

	isc_buffer_init(&outtoken, array, sizeof(array));
	RETERR(dst_gssapi_acceptctx(name, tctx->gsscred, &intoken,
				    &outtoken, &gssctx));

	dstkey = NULL;
	RETERR(dst_key_fromgssapi(name, gssctx, msg->mctx, &dstkey));

	result = dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
					   dstkey, ISC_TRUE, signer,
					   tkeyin->inception, tkeyin->expire,
					   msg->mctx, ring, NULL);
#if 1
	if (result != ISC_R_SUCCESS)
		goto failure;
#else
	if (result == ISC_R_NOTFOUND) {
		tkeyout->error = dns_tsigerror_badalg;
		return (ISC_R_SUCCESS);
	}
	if (result != ISC_R_SUCCESS)
		goto failure;
#endif

	/* This key is good for a long time */
	isc_stdtime_get(&now);
	tkeyout->inception = tkeyin->inception;
	tkeyout->expire = tkeyin->expire;

	tkeyout->key = isc_mem_get(msg->mctx,
				   isc_buffer_usedlength(&outtoken));
	if (tkeyout->key == NULL) {
		result = ISC_R_NOMEMORY;
		goto failure;
	}
	tkeyout->keylen = isc_buffer_usedlength(&outtoken);
	memcpy(tkeyout->key, isc_buffer_base(&outtoken), tkeyout->keylen);

	return (ISC_R_SUCCESS);

 failure:
	if (dstkey != NULL)
		dst_key_free(&dstkey);

	return (result);
}