⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dst_parse.c

📁 bind-3.2.
💻 C
字号:
/* * Portions Copyright (C) 1999-2001  Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM AND * NETWORK ASSOCIATES DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE CONSORTIUM OR NETWORK * ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* * Principal Author: Brian Wellington * $Id: dst_parse.c,v 1.31.2.1 2001/09/15 00:37:18 gson Exp $ */#include <config.h>#include <isc/base64.h>#include <isc/dir.h>#include <isc/fsaccess.h>#include <isc/lex.h>#include <isc/mem.h>#include <isc/string.h>#include <isc/util.h>#include "dst_internal.h"#include "dst_parse.h"#include "dst/result.h"#define PRIVATE_KEY_STR "Private-key-format:"#define ALGORITHM_STR "Algorithm:"#define RSA_STR "RSA"#define DH_STR "DH"#define DSA_STR "DSA"#define HMACMD5_STR "HMAC_MD5"struct parse_map {	const int value;	const char *tag;};static struct parse_map map[] = {	{TAG_RSA_MODULUS, "Modulus:"},	{TAG_RSA_PUBLICEXPONENT, "PublicExponent:"},	{TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"},	{TAG_RSA_PRIME1, "Prime1:"},	{TAG_RSA_PRIME2, "Prime2:"},	{TAG_RSA_EXPONENT1, "Exponent1:"},	{TAG_RSA_EXPONENT2, "Exponent2:"},	{TAG_RSA_COEFFICIENT, "Coefficient:"},	{TAG_DH_PRIME, "Prime(p):"},	{TAG_DH_GENERATOR, "Generator(g):"},	{TAG_DH_PRIVATE, "Private_value(x):"},	{TAG_DH_PUBLIC, "Public_value(y):"},	{TAG_DSA_PRIME, "Prime(p):"},	{TAG_DSA_SUBPRIME, "Subprime(q):"},	{TAG_DSA_BASE, "Base(g):"},	{TAG_DSA_PRIVATE, "Private_value(x):"},	{TAG_DSA_PUBLIC, "Public_value(y):"},	{TAG_HMACMD5_KEY, "Key:"},	{0, NULL}};static intfind_value(const char *s, const unsigned int alg) {	int i;	for (i = 0; ; i++) {		if (map[i].tag == NULL)			return (-1);		else if (strcasecmp(s, map[i].tag) == 0 &&			 TAG_ALG(map[i].value) == alg)			return (map[i].value);	}}static const char *find_tag(const int value) {	int i;	for (i = 0; ; i++) {		if (map[i].tag == NULL)			return (NULL);		else if (value == map[i].value)			return (map[i].tag);	}}static intcheck_rsa(const dst_private_t *priv) {	int i, j;	if (priv->nelements != RSA_NTAGS)		return (-1);	for (i = 0; i < RSA_NTAGS; i++) {		for (j = 0; j < priv->nelements; j++)			if (priv->elements[j].tag == TAG(DST_ALG_RSAMD5, i))				break;		if (j == priv->nelements)			return (-1);	}	return (0);}static intcheck_dh(const dst_private_t *priv) {	int i, j;	if (priv->nelements != DH_NTAGS)		return (-1);	for (i = 0; i < DH_NTAGS; i++) {		for (j = 0; j < priv->nelements; j++)			if (priv->elements[j].tag == TAG(DST_ALG_DH, i))				break;		if (j == priv->nelements)			return (-1);	}	return (0);}static intcheck_dsa(const dst_private_t *priv) {	int i, j;	if (priv->nelements != DSA_NTAGS)		return (-1);	for (i = 0; i < DSA_NTAGS; i++) {		for (j = 0; j < priv->nelements; j++)			if (priv->elements[j].tag == TAG(DST_ALG_DSA, i))				break;		if (j == priv->nelements)			return (-1);	}	return (0);}static intcheck_hmac_md5(const dst_private_t *priv) {	if (priv->nelements != HMACMD5_NTAGS)		return (-1);	if (priv->elements[0].tag != TAG_HMACMD5_KEY)		return (-1);	return (0);}static intcheck_data(const dst_private_t *priv, const unsigned int alg) {	switch (alg) {		case DST_ALG_RSAMD5:			return (check_rsa(priv));		case DST_ALG_DH:			return (check_dh(priv));		case DST_ALG_DSA:			return (check_dsa(priv));		case DST_ALG_HMACMD5:			return (check_hmac_md5(priv));		default:			return (DST_R_UNSUPPORTEDALG);	}}voiddst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) {	int i;	if (priv == NULL)		return;	for (i = 0; i < priv->nelements; i++) {		if (priv->elements[i].data == NULL)			continue;		memset(priv->elements[i].data, 0, MAXFIELDSIZE);		isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE);	}	priv->nelements = 0;}intdst__privstruct_parsefile(dst_key_t *key, const char *filename,			  isc_mem_t *mctx, dst_private_t *priv){	int n = 0, major, minor;	isc_buffer_t b;	isc_lex_t *lex = NULL;	isc_token_t token;	unsigned int opt = ISC_LEXOPT_EOL;	char *newfilename;	int newfilenamelen;	isc_result_t ret;	REQUIRE(priv != NULL);	newfilenamelen = strlen(filename) + 9;	newfilename = isc_mem_get(mctx, newfilenamelen);	if (newfilename == NULL)		return (ISC_R_NOMEMORY);	ret = dst__file_addsuffix(newfilename, newfilenamelen, filename,				  ".private");	INSIST(ret == ISC_R_SUCCESS);	priv->nelements = 0;	ret = isc_lex_create(mctx, 1024, &lex);	if (ret != ISC_R_SUCCESS)		return (ret);	ret = isc_lex_openfile(lex, newfilename);	if (ret != ISC_R_SUCCESS)		goto fail;#define NEXTTOKEN(lex, opt, token) \	{ \		ret = isc_lex_gettoken(lex, opt, token); \		if (ret != ISC_R_SUCCESS) \			goto fail; \	}#define READLINE(lex, opt, token) \	do { \		NEXTTOKEN(lex, opt, token) \	} while ((*token).type != isc_tokentype_eol) \	/*	 * Read the description line.	 */	NEXTTOKEN(lex, opt, &token);	if (token.type != isc_tokentype_string ||	    strcmp(token.value.as_pointer, PRIVATE_KEY_STR) != 0)	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	NEXTTOKEN(lex, opt, &token);	if (token.type != isc_tokentype_string ||	    ((char *)token.value.as_pointer)[0] != 'v')	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	if (sscanf(token.value.as_pointer, "v%d.%d", &major, &minor) != 2)	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	if (major > MAJOR_VERSION ||	    (major == MAJOR_VERSION && minor > MINOR_VERSION))	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	READLINE(lex, opt, &token);	/*	 * Read the algorithm line.	 */	NEXTTOKEN(lex, opt, &token);	if (token.type != isc_tokentype_string ||	    strcmp(token.value.as_pointer, ALGORITHM_STR) != 0)	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token);	if (token.type != isc_tokentype_number ||	    token.value.as_ulong != (unsigned long) dst_key_alg(key))	{		ret = DST_R_INVALIDPRIVATEKEY;		goto fail;	}	READLINE(lex, opt, &token);	/*	 * Read the key data.	 */	for (n = 0; n < MAXFIELDS; n++) {		int tag;		unsigned char *data;		isc_region_t r;		do {			ret = isc_lex_gettoken(lex, opt, &token);			if (ret == ISC_R_EOF)				goto done;			if (ret != ISC_R_SUCCESS)				goto fail;		} while (token.type == isc_tokentype_eol);		if (token.type != isc_tokentype_string) {			ret = DST_R_INVALIDPRIVATEKEY;			goto fail;		}		memset(&priv->elements[n], 0, sizeof(dst_private_element_t));		tag = find_value(token.value.as_pointer, dst_key_alg(key));		if (tag < 0 || TAG_ALG(tag) != dst_key_alg(key)) {			ret = DST_R_INVALIDPRIVATEKEY;			goto fail;		}		priv->elements[n].tag = tag;		data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE);		if (data == NULL)			goto fail;		isc_buffer_init(&b, data, MAXFIELDSIZE);		ret = isc_base64_tobuffer(lex, &b, -1);		if (ret != ISC_R_SUCCESS)			goto fail;		isc_buffer_usedregion(&b, &r);		priv->elements[n].length = r.length;		priv->elements[n].data = r.base;		READLINE(lex, opt, &token);	} done:	priv->nelements = n;	if (check_data(priv, dst_key_alg(key)) < 0)		goto fail;	isc_lex_close(lex);	isc_lex_destroy(&lex);	isc_mem_put(mctx, newfilename, newfilenamelen);	return (ISC_R_SUCCESS);fail:	if (lex != NULL) {		isc_lex_close(lex);		isc_lex_destroy(&lex);	}	isc_mem_put(mctx, newfilename, newfilenamelen);	priv->nelements = n;	dst__privstruct_free(priv, mctx);	return (ret);}intdst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,			  const char *directory){	FILE *fp;	int ret, i;	isc_result_t iret;	char filename[ISC_DIR_NAMEMAX];	char buffer[MAXFIELDSIZE * 2];	isc_buffer_t b;	isc_fsaccess_t access;	REQUIRE(priv != NULL);	if (check_data(priv, dst_key_alg(key)) < 0)		return (DST_R_INVALIDPRIVATEKEY);	isc_buffer_init(&b, filename, sizeof(filename));	ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b);	if (ret != ISC_R_SUCCESS)		return (ret);	if ((fp = fopen(filename, "w")) == NULL)		return (DST_R_WRITEERROR);	access = 0;	isc_fsaccess_add(ISC_FSACCESS_OWNER,			 ISC_FSACCESS_READ | ISC_FSACCESS_WRITE,			 &access);	(void)isc_fsaccess_set(filename, access);	/* XXXDCL return value should be checked for full filesystem */	fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION,		MINOR_VERSION);	fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key));	switch (dst_key_alg(key)) {		case DST_ALG_RSAMD5: fprintf(fp, "(RSA)\n"); break;		case DST_ALG_DH: fprintf(fp, "(DH)\n"); break;		case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break;		case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break;		default : fprintf(fp, "(?)\n"); break;	}	for (i = 0; i < priv->nelements; i++) {		isc_buffer_t b;		isc_region_t r;		const char *s;		s = find_tag(priv->elements[i].tag);		r.base = priv->elements[i].data;		r.length = priv->elements[i].length;		isc_buffer_init(&b, buffer, sizeof(buffer));		iret = isc_base64_totext(&r, sizeof(buffer), "", &b);		if (iret != ISC_R_SUCCESS) {			fclose(fp);			return (DST_R_INVALIDPRIVATEKEY);		}		isc_buffer_usedregion(&b, &r);		fprintf(fp, "%s ", s);		fwrite(r.base, 1, r.length, fp);		fprintf(fp, "\n");	}	fclose(fp);	return (ISC_R_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -