Example #1
0
/*%
 * Writes a public key to disk in DNS format.
 */
static isc_result_t
write_public_key(const dst_key_t *key, int type, const char *directory) {
	FILE *fp;
	isc_buffer_t keyb, textb, fileb, classb;
	isc_region_t r;
	char filename[ISC_DIR_NAMEMAX];
	unsigned char key_array[DST_KEY_MAXSIZE];
	char text_array[DST_KEY_MAXTEXTSIZE];
	char class_array[10];
	isc_result_t ret;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_fsaccess_t access;

	REQUIRE(VALID_KEY(key));

	isc_buffer_init(&keyb, key_array, sizeof(key_array));
	isc_buffer_init(&textb, text_array, sizeof(text_array));
	isc_buffer_init(&classb, class_array, sizeof(class_array));

	ret = dst_key_todns(key, &keyb);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	isc_buffer_usedregion(&keyb, &r);
	dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r);

	ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb);
	if (ret != ISC_R_SUCCESS)
		return (DST_R_INVALIDPUBLICKEY);

	ret = dns_rdataclass_totext(key->key_class, &classb);
	if (ret != ISC_R_SUCCESS)
		return (DST_R_INVALIDPUBLICKEY);

	/*
	 * Make the filename.
	 */
	isc_buffer_init(&fileb, filename, sizeof(filename));
	ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	/*
	 * Create public key file.
	 */
	if ((fp = fopen(filename, "w")) == NULL)
		return (DST_R_WRITEERROR);

	if (issymmetric(key)) {
		access = 0;
		isc_fsaccess_add(ISC_FSACCESS_OWNER,
				 ISC_FSACCESS_READ | ISC_FSACCESS_WRITE,
				 &access);
		(void)isc_fsaccess_set(filename, access);
	}

	/* Write key information in comments */
	if ((type & DST_TYPE_KEY) == 0) {
		fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ",
			(key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ?
				"revoked " :
				"",
			(key->key_flags & DNS_KEYFLAG_KSK) != 0 ?
				"key" :
				"zone",
			key->key_id);
		ret = dns_name_print(key->key_name, fp);
		if (ret != ISC_R_SUCCESS) {
			fclose(fp);
			return (ret);
		}
		fputc('\n', fp);

		printtime(key, DST_TIME_CREATED, "; Created", fp);
		printtime(key, DST_TIME_PUBLISH, "; Publish", fp);
		printtime(key, DST_TIME_ACTIVATE, "; Activate", fp);
		printtime(key, DST_TIME_REVOKE, "; Revoke", fp);
		printtime(key, DST_TIME_INACTIVE, "; Inactive", fp);
		printtime(key, DST_TIME_DELETE, "; Delete", fp);
	}

	/* Now print the actual key */
	ret = dns_name_print(key->key_name, fp);
	fprintf(fp, " ");

	if (key->key_ttl != 0)
		fprintf(fp, "%d ", key->key_ttl);

	isc_buffer_usedregion(&classb, &r);
	if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length)
	       ret = DST_R_WRITEERROR;

	if ((type & DST_TYPE_KEY) != 0)
		fprintf(fp, " KEY ");
	else
		fprintf(fp, " DNSKEY ");

	isc_buffer_usedregion(&textb, &r);
	if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length)
	       ret = DST_R_WRITEERROR;

	fputc('\n', fp);
	fflush(fp);
	if (ferror(fp))
		ret = DST_R_WRITEERROR;
	fclose(fp);

	return (ret);
}
Example #2
0
/*%
 * Writes a public key to disk in DNS format.
 */
static isc_result_t
write_public_key(const dst_key_t *key, int type, const char *directory) {
	FILE *fp;
	isc_buffer_t keyb, textb, fileb, classb;
	isc_region_t r;
	char filename[ISC_DIR_NAMEMAX];
	unsigned char key_array[DST_KEY_MAXSIZE];
	char text_array[DST_KEY_MAXTEXTSIZE];
	char class_array[10];
	isc_result_t ret;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_fsaccess_t access;

	REQUIRE(VALID_KEY(key));

	isc_buffer_init(&keyb, key_array, sizeof(key_array));
	isc_buffer_init(&textb, text_array, sizeof(text_array));
	isc_buffer_init(&classb, class_array, sizeof(class_array));

	ret = dst_key_todns(key, &keyb);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	isc_buffer_usedregion(&keyb, &r);
	dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r);

	ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb);
	if (ret != ISC_R_SUCCESS)
		return (DST_R_INVALIDPUBLICKEY);

	ret = dns_rdataclass_totext(key->key_class, &classb);
	if (ret != ISC_R_SUCCESS)
		return (DST_R_INVALIDPUBLICKEY);

	/*
	 * Make the filename.
	 */
	isc_buffer_init(&fileb, filename, sizeof(filename));
	ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	/*
	 * Create public key file.
	 */
	if ((fp = fopen(filename, "w")) == NULL)
		return (DST_R_WRITEERROR);

	if (issymmetric(key)) {
		access = 0;
		isc_fsaccess_add(ISC_FSACCESS_OWNER,
				 ISC_FSACCESS_READ | ISC_FSACCESS_WRITE,
				 &access);
		(void)isc_fsaccess_set(filename, access);
	}

	ret = dns_name_print(key->key_name, fp);
	if (ret != ISC_R_SUCCESS) {
		fclose(fp);
		return (ret);
	}

	fprintf(fp, " ");

	isc_buffer_usedregion(&classb, &r);
	fwrite(r.base, 1, r.length, fp);

	if ((type & DST_TYPE_KEY) != 0)
		fprintf(fp, " KEY ");
	else
		fprintf(fp, " DNSKEY ");

	isc_buffer_usedregion(&textb, &r);
	fwrite(r.base, 1, r.length, fp);

	fputc('\n', fp);
	fclose(fp);

	return (ISC_R_SUCCESS);
}