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

📄 dst_api.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef LINTstatic const char rcsid[] = "$Header: /proj/cvs/prod/bind9/lib/bind/dst/dst_api.c,v 1.4.2.6 2002/07/12 00:17:19 marka Exp $";#endif/* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL * TRUSTED INFORMATION SYSTEMS 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 THE SOFTWARE. *//* * This file contains the interface between the DST API and the crypto API. * This is the only file that needs to be changed if the crypto system is * changed.  Exported functions are: * void dst_init()	 Initialize the toolkit * int  dst_check_algorithm()   Function to determines if alg is suppored. * int  dst_compare_keys()      Function to compare two keys for equality. * int  dst_sign_data()         Incremental signing routine. * int  dst_verify_data()       Incremental verify routine. * int  dst_generate_key()      Function to generate new KEY * DST_KEY *dst_read_key()      Function to retrieve private/public KEY. * void dst_write_key()         Function to write out a key. * DST_KEY *dst_dnskey_to_key() Function to convert DNS KEY RR to a DST *				KEY structure. * int dst_key_to_dnskey() 	Function to return a public key in DNS  *				format binary * DST_KEY *dst_buffer_to_key() Converst a data in buffer to KEY * int *dst_key_to_buffer()	Writes out DST_KEY key matterial in buffer * void dst_free_key()       	Releases all memory referenced by key structure */#include "port_before.h"#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <memory.h>#include <ctype.h>#include <time.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include "dst_internal.h"#include "port_after.h"/* static variables */static int done_init = 0;dst_func *dst_t_func[DST_MAX_ALGS];const char *key_file_fmt_str = "Private-key-format: v%s\nAlgorithm: %d (%s)\n";const char *dst_path = "";/* internal I/O functions */static DST_KEY *dst_s_read_public_key(const char *in_name, 				      const u_int16_t in_id, int in_alg);static int dst_s_read_private_key_file(char *name, DST_KEY *pk_key,				       u_int16_t in_id, int in_alg);static int dst_s_write_public_key(const DST_KEY *key);static int dst_s_write_private_key(const DST_KEY *key);/* internal function to set up data structure */static DST_KEY *dst_s_get_key_struct(const char *name, const int alg,				     const int flags, const int protocol,				     const int bits);/* *  dst_init *	This function initializes the Digital Signature Toolkit. *	Right now, it just checks the DSTKEYPATH environment variable. *  Parameters *	none *  Returns *	none */voiddst_init(){	char *s;	int len;	if (done_init != 0)		return;	done_init = 1;	s = getenv("DSTKEYPATH");	len = 0;	if (s) {		struct stat statbuf;		len = strlen(s);		if (len > PATH_MAX) {			EREPORT(("%s is longer than %d characters, ignoring\n",				 s, PATH_MAX));		} else if (stat(s, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) {			EREPORT(("%s is not a valid directory\n", s));		} else {			char *tmp;			tmp = (char *) malloc(len + 2);			memcpy(tmp, s, len + 1);			if (tmp[strlen(tmp) - 1] != '/') {				tmp[strlen(tmp) + 1] = 0;				tmp[strlen(tmp)] = '/';			}			dst_path = tmp;		}	}	memset(dst_t_func, 0, sizeof(dst_t_func));	/* first one is selected */	dst_hmac_md5_init();}/* *  dst_check_algorithm *	This function determines if the crypto system for the specified *	algorithm is present. *  Parameters *	alg     1       KEY_RSA *		3       KEY_DSA *	      157     KEY_HMAC_MD5 *		      future algorithms TBD and registered with IANA. *  Returns *	1 - The algorithm is available. *	0 - The algorithm is not available. */intdst_check_algorithm(const int alg){	return (dst_t_func[alg] != NULL);}/*  * dst_s_get_key_struct  *	This function allocates key structure and fills in some of the  *	fields of the structure.  * Parameters:  *	name:     the name of the key  *	alg:      the algorithm number  *	flags:    the dns flags of the key *	protocol: the dns protocol of the key *	bits:     the size of the key * Returns: *       NULL if error *       valid pointer otherwise */static DST_KEY *dst_s_get_key_struct(const char *name, const int alg, const int flags,		     const int protocol, const int bits){	DST_KEY *new_key = NULL; 	if (dst_check_algorithm(alg)) /* make sure alg is available */		new_key = (DST_KEY *) malloc(sizeof(*new_key));	if (new_key == NULL)		return (NULL);	memset(new_key, 0, sizeof(*new_key));	new_key->dk_key_name = strdup(name);	new_key->dk_alg = alg;	new_key->dk_flags = flags;	new_key->dk_proto = protocol;	new_key->dk_KEY_struct = NULL;	new_key->dk_key_size = bits;	new_key->dk_func = dst_t_func[alg];	return (new_key);}/* *  dst_compare_keys *	Compares two keys for equality. *  Parameters *	key1, key2      Two keys to be compared. *  Returns *	0	       The keys are equal. *	non-zero	The keys are not equal. */intdst_compare_keys(const DST_KEY *key1, const DST_KEY *key2){	if (key1 == key2)		return (0);	if (key1 == NULL || key2 == NULL)		return (4);	if (key1->dk_alg != key2->dk_alg)		return (1);	if (key1->dk_key_size != key2->dk_key_size)		return (2);	if (key1->dk_id != key2->dk_id)		return (3);	return (key1->dk_func->compare(key1, key2));}/* * dst_sign_data *	An incremental signing function.  Data is signed in steps. *	First the context must be initialized (SIG_MODE_INIT). *	Then data is hashed (SIG_MODE_UPDATE).  Finally the signature *	itself is created (SIG_MODE_FINAL).  This function can be called *	once with INIT, UPDATE and FINAL modes all set, or it can be *	called separately with a different mode set for each step.  The *	UPDATE step can be repeated. * Parameters *	mode    A bit mask used to specify operation(s) to be performed. *		  SIG_MODE_INIT	   1   Initialize digest *		  SIG_MODE_UPDATE	 2   Add data to digest *		  SIG_MODE_FINAL	  4   Generate signature *					      from signature *		  SIG_MODE_ALL (SIG_MODE_INIT,SIG_MODE_UPDATE,SIG_MODE_FINAL *	data    Data to be signed. *	len     The length in bytes of data to be signed. *	in_key  Contains a private key to sign with. *		  KEY structures should be handled (created, converted, *		  compared, stored, freed) by the DST. *	signature *	      The location to which the signature will be written. *	sig_len Length of the signature field in bytes. * Return *	 0      Successfull INIT or Update operation *	>0      success FINAL (sign) operation *	<0      failure */intdst_sign_data(const int mode, DST_KEY *in_key, void **context, 	      const u_char *data, const int len,	      u_char *signature, const int sig_len){	DUMP(data, mode, len, "dst_sign_data()");	if (mode & SIG_MODE_FINAL &&	    (in_key->dk_KEY_struct == NULL || signature == NULL))		return (MISSING_KEY_OR_SIGNATURE);	if (in_key->dk_func && in_key->dk_func->sign)		return (in_key->dk_func->sign(mode, in_key, context, data, len,					      signature, sig_len));	return (UNKNOWN_KEYALG);}/* *  dst_verify_data *	An incremental verify function.  Data is verified in steps. *	First the context must be initialized (SIG_MODE_INIT). *	Then data is hashed (SIG_MODE_UPDATE).  Finally the signature *	is verified (SIG_MODE_FINAL).  This function can be called *	once with INIT, UPDATE and FINAL modes all set, or it can be *	called separately with a different mode set for each step.  The *	UPDATE step can be repeated. *  Parameters *	mode	Operations to perform this time. *		      SIG_MODE_INIT       1   Initialize digest *		      SIG_MODE_UPDATE     2   add data to digest *		      SIG_MODE_FINAL      4   verify signature *		      SIG_MODE_ALL *			  (SIG_MODE_INIT,SIG_MODE_UPDATE,SIG_MODE_FINAL) *	data	Data to pass through the hash function. *	len	 Length of the data in bytes. *	in_key      Key for verification. *	signature   Location of signature. *	sig_len     Length of the signature in bytes. *  Returns *	0	   Verify success *	Non-Zero    Verify Failure */intdst_verify_data(const int mode, DST_KEY *in_key, void **context, 		const u_char *data, const int len,		const u_char *signature, const int sig_len){	DUMP(data, mode, len, "dst_verify_data()");	if (mode & SIG_MODE_FINAL &&	    (in_key->dk_KEY_struct == NULL || signature == NULL))		return (MISSING_KEY_OR_SIGNATURE);	if (in_key->dk_func == NULL || in_key->dk_func->verify == NULL)		return (UNSUPPORTED_KEYALG);	return (in_key->dk_func->verify(mode, in_key, context, data, len,					signature, sig_len));}/* *  dst_read_private_key *	Access a private key.  First the list of private keys that have *	already been read in is searched, then the key accessed on disk. *	If the private key can be found, it is returned.  If the key cannot *	be found, a null pointer is returned.  The options specify required *	key characteristics.  If the private key requested does not have *	these characteristics, it will not be read. *  Parameters *	in_keyname  The private key name. *	in_id	    The id of the private key. *	options     DST_FORCE_READ  Read from disk - don't use a previously *				      read key. *		  DST_CAN_SIGN    The key must be useable for signing. *		  DST_NO_AUTHEN   The key must be useable for authentication. *		  DST_STANDARD    Return any key  *  Returns *	NULL	If there is no key found in the current directory or *		      this key has not been loaded before. *	!NULL       Success - KEY structure returned. */DST_KEY *dst_read_key(const char *in_keyname, const u_int16_t in_id, 	     const int in_alg, const int type){	char keyname[PATH_MAX];	DST_KEY *dg_key = NULL, *pubkey = NULL;	if (!dst_check_algorithm(in_alg)) { /* make sure alg is available */		EREPORT(("dst_read_private_key(): Algorithm %d not suppored\n",			 in_alg));		return (NULL);	}	if ((type & (DST_PUBLIC | DST_PRIVATE)) == 0) 		return (NULL);	if (in_keyname == NULL) {		EREPORT(("dst_read_private_key(): Null key name passed in\n"));		return (NULL);	} else		strcpy(keyname, in_keyname);	/* before I read in the public key, check if it is allowed to sign */	if ((pubkey = dst_s_read_public_key(keyname, in_id, in_alg)) == NULL)		return (NULL);	if (type == DST_PUBLIC) 		return pubkey; 	if (!(dg_key = dst_s_get_key_struct(keyname, pubkey->dk_alg,					 pubkey->dk_flags, pubkey->dk_proto,					    0)))		return (dg_key);	/* Fill in private key and some fields in the general key structure */	if (dst_s_read_private_key_file(keyname, dg_key, pubkey->dk_id,					pubkey->dk_alg) == 0)		dg_key = dst_free_key(dg_key);	pubkey = dst_free_key(pubkey);	return (dg_key);}int dst_write_key(const DST_KEY *key, const int type){	int pub = 0, priv = 0;	if (key == NULL) 		return (0);	if (!dst_check_algorithm(key->dk_alg)) { /* make sure alg is available */		EREPORT(("dst_write_key(): Algorithm %d not suppored\n", 			 key->dk_alg));		return (UNSUPPORTED_KEYALG);	}	if ((type & (DST_PRIVATE|DST_PUBLIC)) == 0)		return (0);	if (type & DST_PUBLIC) 		if ((pub = dst_s_write_public_key(key)) < 0)			return (pub);	if (type & DST_PRIVATE)		if ((priv = dst_s_write_private_key(key)) < 0)			return (priv);	return (priv+pub);}/* *  dst_write_private_key *	Write a private key to disk.  The filename will be of the form: *	K<key->dk_name>+<key->dk_alg>+<key->dk_id>.<private key suffix>. *	If there is already a file with this name, an error is returned. * *  Parameters *	key     A DST managed key structure that contains *	      all information needed about a key. *  Return *	>= 0    Correct behavior.  Returns length of encoded key value *		  written to disk. *	<  0    error. */static intdst_s_write_private_key(const DST_KEY *key){	u_char encoded_block[RAW_KEY_SIZE];	char file[PATH_MAX];	int len;	FILE *fp;	/* First encode the key into the portable key format */	if (key == NULL)		return (-1);	if (key->dk_KEY_struct == NULL)		return (0);	/* null key has no private key */	if (key->dk_func == NULL || key->dk_func->to_file_fmt == NULL) {		EREPORT(("dst_write_private_key(): Unsupported operation %d\n",			 key->dk_alg));		return (-5);	} else if ((len = key->dk_func->to_file_fmt(key, (char *)encoded_block,					     sizeof(encoded_block))) <= 0) {		EREPORT(("dst_write_private_key(): Failed encoding private RSA bsafe key %d\n", len));		return (-8);	}	/* Now I can create the file I want to use */	dst_s_build_filename(file, key->dk_key_name, key->dk_id, key->dk_alg,			     PRIVATE_KEY, PATH_MAX);	/* Do not overwrite an existing file */	if ((fp = dst_s_fopen(file, "w", 0600)) != NULL) {		int nn;		if ((nn = fwrite(encoded_block, 1, len, fp)) != len) {			EREPORT(("dst_write_private_key(): Write failure on %s %d != %d errno=%d\n",				 file, len, nn, errno));			return (-5);		}		fclose(fp);	} else {		EREPORT(("dst_write_private_key(): Can not create file %s\n"			 ,file));		return (-6);	}	memset(encoded_block, 0, len);	return (len);}/** *  dst_read_public_key *	Read a public key from disk and store in a DST key structure. *  Parameters *	in_name	 K<in_name><in_id>.<public key suffix> is the *		      filename of the key file to be read. *  Returns *	NULL	    If the key does not exist or no name is supplied. *	NON-NULL	Initialized key structure if the key exists. */static DST_KEY *dst_s_read_public_key(const char *in_name, const u_int16_t in_id, int in_alg){	int flags, proto, alg, len, dlen;	int c;	char name[PATH_MAX], enckey[RAW_KEY_SIZE], *notspace;	u_char deckey[RAW_KEY_SIZE];	FILE *fp;	if (in_name == NULL) {		EREPORT(("dst_read_public_key(): No key name given\n"));		return (NULL);	}	if (dst_s_build_filename(name, in_name, in_id, in_alg, PUBLIC_KEY,				 PATH_MAX) == -1) {		EREPORT(("dst_read_public_key(): Cannot make filename from %s, %d, and %s\n",			 in_name, in_id, PUBLIC_KEY));		return (NULL);	}	/*	 * Open the file and read it's formatted contents up to key	 * File format:	 *    domain.name [ttl] [IN] KEY  <flags> <protocol> <algorithm> <key>	 * flags, proto, alg stored as decimal (or hex numbers FIXME).	 * (FIXME: handle parentheses for line continuation.)	 */	if ((fp = dst_s_fopen(name, "r", 0)) == NULL) {		EREPORT(("dst_read_public_key(): Public Key not found %s\n",			 name));		return (NULL);	}	/* Skip domain name, which ends at first blank */	while ((c = getc(fp)) != EOF)		if (isspace(c))			break;	/* Skip blank to get to next field */	while ((c = getc(fp)) != EOF)		if (!isspace(c))			break;	/* Skip optional TTL -- if initial digit, skip whole word. */	if (isdigit(c)) {		while ((c = getc(fp)) != EOF)			if (isspace(c))				break;		while ((c = getc(fp)) != EOF)			if (!isspace(c))				break;	}	/* Skip optional "IN" */	if (c == 'I' || c == 'i') {		while ((c = getc(fp)) != EOF)			if (isspace(c))				break;		while ((c = getc(fp)) != EOF)			if (!isspace(c))				break;	}	/* Locate and skip "KEY" */	if (c != 'K' && c != 'k') {		EREPORT(("\"KEY\" doesn't appear in file: %s", name));		return NULL;	}	while ((c = getc(fp)) != EOF)		if (isspace(c))			break;	while ((c = getc(fp)) != EOF)		if (!isspace(c))

⌨️ 快捷键说明

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