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

📄 cryptcfg.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*						 cryptlib Configuration Routines					*
*						Copyright Peter Gutmann 1994-2002					*
*																			*
****************************************************************************/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crypt.h"
#ifdef INC_ALL
  #include "asn1.h"
#else
  #include "keymgmt/asn1.h"
#endif /* Compiler-specific includes */

/* Prototypes for functions in certrust.c */

int setTrustedCert( void *certObject, const int certObjectLength );
CRYPT_CERTIFICATE getFirstTrustedCert( void **statePtr, int *stateIndex );
CRYPT_CERTIFICATE getNextTrustedCert( void **statePtr, int *stateIndex );

/****************************************************************************
*																			*
*							Configuration Options							*
*																			*
****************************************************************************/

/* Configuration option types */

typedef enum {
	OPTION_NONE,					/* Non-option */
	OPTION_STRING,					/* Literal string */
	OPTION_NUMERIC,					/* Numeric value */
	OPTION_BOOLEAN					/* Boolean flag */
	} OPTION_TYPE;

/* The configuration options.  These are broken up into two parts, the fixed
   default values which are shared across all cryptlib operations and the
   variable values which are variable for each user object.

   Alongside the CRYPT_ATTRIBUTE_TYPE we store a persistant index value for
   the option which always stays the same even if the attribute type changes,
   this avoids the need to change the config file every time an attribute is
   added or deleted */

typedef struct {
	const CRYPT_ATTRIBUTE_TYPE option;/* Magic number for this option */
	const OPTION_TYPE type;			/* Option type */
	const int index;				/* Index value for this option */
	const char FAR_BSS *strDefault;	/* Default if it's a string option */
	const int intDefault;			/* Default if it's a numeric/boolean */
	} FIXED_OPTION_INFO;

typedef struct {
	char *strValue;					/* Value if it's a string option */
	int intValue;					/* Value if it's a numeric/boolean */
	BOOLEAN dirty;					/* Whether option has been changed */
	} OPTION_INFO;

static const FIXED_OPTION_INFO FAR_BSS fixedOptionInfo[] = {
	/* Dummy entry for CRYPT_ATTRIBUTE_NONE */
	{ CRYPT_ATTRIBUTE_NONE, 0 },

	/* cryptlib information (read-only) */
	{ CRYPT_OPTION_INFO_DESCRIPTION, OPTION_STRING, CRYPT_UNUSED, "cryptlib encryption library" },
	{ CRYPT_OPTION_INFO_COPYRIGHT, OPTION_STRING, CRYPT_UNUSED, "Copyright Peter Gutmann, Eric Young, 1994-2001" },
	{ CRYPT_OPTION_INFO_MAJORVERSION, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 3 },
	{ CRYPT_OPTION_INFO_MINORVERSION, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 0 },
	{ CRYPT_OPTION_INFO_STEPPING, OPTION_NUMERIC, CRYPT_UNUSED, NULL, 6 },

	/* Context options, base = 0 */
	/* Algorithm = Conventional encryption/hash/MAC options */
	{ CRYPT_OPTION_ENCR_ALGO, OPTION_NUMERIC, 0, NULL, CRYPT_ALGO_3DES },
	{ CRYPT_OPTION_ENCR_HASH, OPTION_NUMERIC, 1, NULL, CRYPT_ALGO_SHA },
	{ CRYPT_OPTION_ENCR_MAC, OPTION_NUMERIC, 2, NULL, CRYPT_ALGO_HMAC_SHA },

	/* Algorithm = PKC options */
	{ CRYPT_OPTION_PKC_ALGO, OPTION_NUMERIC, 3, NULL, CRYPT_ALGO_RSA },
	{ CRYPT_OPTION_PKC_KEYSIZE, OPTION_NUMERIC, 4, NULL, bitsToBytes( 1024 ) },

	/* Algorithm = Signature options */
	{ CRYPT_OPTION_SIG_ALGO, OPTION_NUMERIC, 5, NULL, CRYPT_ALGO_RSA },
	{ CRYPT_OPTION_SIG_KEYSIZE, OPTION_NUMERIC, 6, NULL, bitsToBytes( 1024 ) },

	/* Algorithm = Key derivation options */
	{ CRYPT_OPTION_KEYING_ALGO, OPTION_NUMERIC, 7, NULL, CRYPT_ALGO_SHA },
	{ CRYPT_OPTION_KEYING_ITERATIONS, OPTION_NUMERIC, 8, NULL, 500 },

	/* Certificate options, base = 100 */
	{ CRYPT_OPTION_CERT_CREATEV3CERT, OPTION_BOOLEAN, 100, NULL, TRUE },
	{ CRYPT_OPTION_CERT_PKCS10ALT, OPTION_BOOLEAN, 101, NULL, FALSE },
	{ CRYPT_OPTION_CERT_FIXEMAILADDRESS, OPTION_BOOLEAN, 102, NULL, TRUE },
	{ CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, OPTION_BOOLEAN, 103, NULL, FALSE },
	{ CRYPT_OPTION_CERT_TRUSTCHAINROOT, OPTION_BOOLEAN, 104, NULL, FALSE },
	{ CRYPT_OPTION_CERT_VALIDITY, OPTION_NUMERIC, 105, NULL, 365 },
	{ CRYPT_OPTION_CERT_UPDATEINTERVAL, OPTION_NUMERIC, 106, NULL, 90 },
	{ CRYPT_OPTION_CERT_ENCODE_VALIDITYNESTING, OPTION_BOOLEAN, 107, NULL, TRUE },
	{ CRYPT_OPTION_CERT_DECODE_VALIDITYNESTING, OPTION_BOOLEAN, 108, NULL, FALSE },
	{ CRYPT_OPTION_CERT_ENCODE_CRITICAL, OPTION_BOOLEAN, 109, NULL, TRUE },
	{ CRYPT_OPTION_CERT_DECODE_CRITICAL, OPTION_BOOLEAN, 110, NULL, TRUE },

	/* CMS options */
	{ CRYPT_OPTION_CMS_DEFAULTATTRIBUTES, OPTION_BOOLEAN, 130, NULL, TRUE },

	/* Keyset options, base = 200 */
	/* Keyset = LDAP options */
	{ CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS, OPTION_STRING, 200, "inetOrgPerson" },
	{ CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE, OPTION_NUMERIC, 210, NULL, CRYPT_CERTTYPE_NONE },
	{ CRYPT_OPTION_KEYS_LDAP_FILTER, OPTION_STRING, 211, "(objectclass=*)" },
	{ CRYPT_OPTION_KEYS_LDAP_CACERTNAME, OPTION_STRING, 212, "cACertificate;binary" },
	{ CRYPT_OPTION_KEYS_LDAP_CERTNAME, OPTION_STRING, 213, "userCertificate;binary" },
	{ CRYPT_OPTION_KEYS_LDAP_CRLNAME, OPTION_STRING, 214, "certificateRevocationList;binary" },
	{ CRYPT_OPTION_KEYS_LDAP_EMAILNAME, OPTION_STRING, 215, "mail" },

	/* Device options, base = 300 */
	/* Device = PKCS #11 token options */
	{ CRYPT_OPTION_DEVICE_PKCS11_DVR01, OPTION_STRING, 300, NULL },
	{ CRYPT_OPTION_DEVICE_PKCS11_DVR02, OPTION_STRING, 301, NULL },
	{ CRYPT_OPTION_DEVICE_PKCS11_DVR03, OPTION_STRING, 302, NULL },
	{ CRYPT_OPTION_DEVICE_PKCS11_DVR04, OPTION_STRING, 303, NULL },
	{ CRYPT_OPTION_DEVICE_PKCS11_DVR05, OPTION_STRING, 304, NULL },
	{ CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY, OPTION_BOOLEAN, 305, NULL, FALSE },

	/* Device = Hardware RNG options */
	{ CRYPT_OPTION_DEVICE_SERIALRNG, OPTION_STRING, 310, NULL },
	{ CRYPT_OPTION_DEVICE_SERIALRNG_PARAMS, OPTION_STRING, 311, NULL },

	/* Session options, base = 400 */

	/* Miscellaneous options, base = 500 */
	{ CRYPT_OPTION_NET_SOCKS_SERVER, OPTION_STRING, 500, NULL },
	{ CRYPT_OPTION_NET_SOCKS_USERNAME, OPTION_STRING, 501, NULL },
	{ CRYPT_OPTION_NET_HTTP_PROXY, OPTION_STRING, 502, NULL },
	{ CRYPT_OPTION_NET_CONNECTTIMEOUT, OPTION_NUMERIC, 503, NULL, 30 },
	{ CRYPT_OPTION_NET_TIMEOUT, OPTION_NUMERIC, 504, NULL, 0 },
	{ CRYPT_OPTION_MISC_ASYNCINIT, OPTION_BOOLEAN, 504, NULL, TRUE },

	/* cryptlib state information.  These are special-case options which
	   record state information rather than a static config value.  The
	   config-option-changed status value is updated dynamically, being set 
	   to TRUE if any config option is changed.  Writing it to FALSE commits 
	   the changes to disk.  The self-test status value is initially set to
	   FALSE, writing it to TRUE triggers a self-test which remains at TRUE
	   if the test succeeds */
	{ CRYPT_OPTION_CONFIGCHANGED, OPTION_BOOLEAN, CRYPT_UNUSED, NULL, FALSE },
	{ CRYPT_OPTION_SELFTESTOK, OPTION_BOOLEAN, CRYPT_UNUSED, NULL, FALSE },

	{ CRYPT_ATTRIBUTE_NONE, OPTION_NONE, CRYPT_UNUSED, NULL, 0 }
	};

/* The last option which is written to disk.  Further options beyond this one
   are ephemeral and are never written to disk */

#define LAST_STORED_OPTION	CRYPT_OPTION_MISC_ASYNCINIT

/* The size of the variable-length config data */

#define OPTION_INFO_SIZE	( sizeof( OPTION_INFO ) * \
							  CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST )

/****************************************************************************
*																			*
*						Set/Query Library-wide Config Options				*
*																			*
****************************************************************************/

/* Set the value of a numeric or string option */

int setOption( OPTION_INFO *optionList, const CRYPT_ATTRIBUTE_TYPE option,
			   const int value )
	{
	const FIXED_OPTION_INFO *fixedOptionInfoPtr;
	OPTION_INFO *optionInfoPtr;

	/* The update of the selt-test status is performed in two phases, when we 
	   begin the self-test it's set to an undefined value, once the self-test
	   completes it's set to the test result.  Since there's no way to 
	   indicate an internal status update from an external attempt to do the
	   same thing, we disallow any attempt to update the value when it's in
	   the undefined state, and use a write of CRYPT_OPTION_LAST to indicate
	   an update of the self-test status */
	if( option == CRYPT_OPTION_LAST )
		{
		assert( optionList[ CRYPT_OPTION_SELFTESTOK - \
							CRYPT_OPTION_FIRST ].intValue == CRYPT_ERROR );
		optionList[ CRYPT_OPTION_SELFTESTOK - \
					CRYPT_OPTION_FIRST ].intValue = value;
		return( CRYPT_OK );
		}

	/* Get a pointer to the option information and make sure everything is
	   OK */
	assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
	optionInfoPtr = &optionList[ option - CRYPT_OPTION_FIRST ];
	fixedOptionInfoPtr = &fixedOptionInfo[ option - CRYPT_OPTION_FIRST ];
	assert( fixedOptionInfoPtr->type == OPTION_NUMERIC || \
			fixedOptionInfoPtr->type == OPTION_BOOLEAN );

	/* If the value is the same as the current one, there's nothing to do */
	if( optionInfoPtr->intValue == value )
		return( CRYPT_OK );

	/* If we're forcing a commit by returning the config.changed flag to its
	   ground state, write any changed options to disk */
	if( option == CRYPT_OPTION_CONFIGCHANGED )
		{
		int i;

		/* Make sure there's something to write.  We do this to avoid problems
		   with programs which always try to update the config (whether it's
		   necessary or not), which can cause problems with media with limited
		   writeability */
		for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
			if( optionList[ i ].dirty )
				break;
		if( fixedOptionInfo[ i ].option == CRYPT_ATTRIBUTE_NONE )
			/* Nothing has been changed, there's nothing to write */
			return( CRYPT_OK );

		/* We don't do anything at this level to write the config data since
		   we currently have the user object locked and don't want to stall
		   all operations which depend on it while we're updating the config
		   data, so we tell the user object to perform the necessary
		   operations */
		return( OK_SPECIAL );
		}

	/* If we're forcing a self-test by changing the value of the self-test
	   status, perform an algorithm self-test */
	if( option == CRYPT_OPTION_SELFTESTOK )
		{
		/* The self-test can take some time to complete, and while it's
		   running we don't want to leave the user object locked since this 
		   will block most other threads which eventually read some sort of 
		   config option.  To get around this problem we set the result 
		   value to an undefined status and unlock the user object around the 
		   call, then re-lock it and set its actual value via an update of 
		   the pseudo-option CRYPT_OPTION_LAST once the self-test is done */
		if( optionInfoPtr->intValue == CRYPT_ERROR )
			return( CRYPT_ERROR_BUSY );
		optionInfoPtr->intValue = CRYPT_ERROR;
		return( OK_SPECIAL );
		}

	if( fixedOptionInfoPtr->type == OPTION_BOOLEAN )
		/* Turn a generic zero/nonzero boolean into TRUE or FALSE */
		optionInfoPtr->intValue = ( value ) ? TRUE : FALSE;
	else
		optionInfoPtr->intValue = value;
	optionInfoPtr->dirty = TRUE;

	/* Remember that the config options have been changed */
	optionInfoPtr = \
			&optionList[ CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST ];
	optionInfoPtr->intValue = TRUE;
	return( CRYPT_OK );
	}

int setOptionString( OPTION_INFO *optionList,
					 const CRYPT_ATTRIBUTE_TYPE option, const char *value,
					 const int valueLength )
	{
	const FIXED_OPTION_INFO *fixedOptionInfoPtr;
	OPTION_INFO *optionInfoPtr;
	char *valuePtr;

	/* Get a pointer to the option information and make sure everything is
	   OK */
	assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
	optionInfoPtr = &optionList[ option - CRYPT_OPTION_FIRST ];
	fixedOptionInfoPtr = &fixedOptionInfo[ option - CRYPT_OPTION_FIRST ];
	assert( fixedOptionInfoPtr->type == OPTION_STRING );

	/* Try and allocate room for the new option */
	if( ( valuePtr = malloc( valueLength + 1 ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memcpy( valuePtr, value, valueLength );
	valuePtr[ valueLength ] = '\0';

	/* If the new value isn't different from the current one, don't do
	   anything */
	if( optionInfoPtr->strValue != NULL && \
		!memcmp( optionInfoPtr->strValue, value, valueLength ) )
		{
		free( valuePtr );
		return( CRYPT_OK );
		}

	/* If the string value which is currently set isn't the default setting,
	   clear and free it */
	if( optionInfoPtr->strValue != fixedOptionInfoPtr->strDefault )
		{
		zeroise( optionInfoPtr->strValue, strlen( optionInfoPtr->strValue ) );
		free( optionInfoPtr->strValue );
		}

	/* Set the value */
	optionInfoPtr->strValue = valuePtr;
	optionInfoPtr->dirty = TRUE;

	/* Remember that the config options have been changed */
	optionInfoPtr = \
			&optionList[ CRYPT_OPTION_CONFIGCHANGED - CRYPT_OPTION_FIRST ];
	optionInfoPtr->intValue = TRUE;
	return( CRYPT_OK );
	}

/* Query the value of a numeric or string option */

int getOption( OPTION_INFO *optionList, const CRYPT_ATTRIBUTE_TYPE option )
	{
	assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
	assert( fixedOptionInfo[ option - \
							 CRYPT_OPTION_FIRST ].type == OPTION_NUMERIC || \
			fixedOptionInfo[ option - \
							 CRYPT_OPTION_FIRST ].type == OPTION_BOOLEAN );

	return( optionList[ option - CRYPT_OPTION_FIRST ].intValue );
	}

char *getOptionString( OPTION_INFO *optionList,
					   const CRYPT_ATTRIBUTE_TYPE option )
	{
	assert( option > CRYPT_OPTION_FIRST && option < CRYPT_OPTION_LAST );
	assert( fixedOptionInfo[ option - \
							 CRYPT_OPTION_FIRST ].type == OPTION_STRING );

	return( optionList[ option - CRYPT_OPTION_FIRST ].strValue );
	}

/* Initialise/clean up the config option handling */

int initOptions( OPTION_INFO **optionListPtr )
	{
	OPTION_INFO *optionList;
	int i;

	/* Perform a consistency check on the options */
	FORALL( i, 1, CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST,
			fixedOptionInfo[ i ].option == i + CRYPT_OPTION_FIRST );

	/* Allocate storage for the variable config data */
	if( ( optionList = malloc( OPTION_INFO_SIZE ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( optionList, 0, OPTION_INFO_SIZE );

	/* Walk through the config table setting up each option to contain
	   its default value */
	for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
		if( fixedOptionInfo[ i ].type == OPTION_STRING )
			optionList[ i ].strValue = \
						( char * ) fixedOptionInfo[ i ].strDefault;
		else
			optionList[ i ].intValue = fixedOptionInfo[ i ].intDefault;
	*optionListPtr = optionList;

	return( CRYPT_OK );
	}

void endOptions( OPTION_INFO *optionList )
	{
	int i;

	/* Walk through the config table clearing and freeing each option */
	for( i = 1; fixedOptionInfo[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
		{
		const FIXED_OPTION_INFO *fixedOptionInfoPtr = &fixedOptionInfo[ i ];
		OPTION_INFO *optionInfoPtr = &optionList[ i ];

		if( fixedOptionInfoPtr->type == OPTION_STRING )
			{
			/* If the string value which is currently set isn't the default

⌨️ 快捷键说明

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