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

📄 cryptcfg.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 2 页
字号:

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 that's currently set isn't the default
			   setting, clear and free it */
			if( optionInfoPtr->strValue != fixedOptionInfoPtr->strDefault )
				{
				zeroise( optionInfoPtr->strValue,
						 strlen( optionInfoPtr->strValue ) );
				clFree( "endOptions", optionInfoPtr->strValue );
				}
			}
		}

	/* Clear and free the config table */
	memset( optionList, 0, OPTION_INFO_SIZE );
	clFree( "endOptions", optionList );
	}

/****************************************************************************
*																			*
*						Read and Write the Config Options 					*
*																			*
****************************************************************************/

/* Read any user-defined configuration options.  Since the config file is an
   untrusted source, we set the values in it via external messages rather than
   manipulating the config info directly, which means that everything read is
   subject to the usual ACL checks */

static int readTrustedCerts( const CRYPT_KEYSET iCryptKeyset,
							 void *trustInfoPtr )
	{
	RESOURCE_DATA msgData;
	BYTE buffer[ CRYPT_MAX_PKCSIZE + 1536 ];
	int status;

	/* Read each trusted cert from the keyset */
	setMessageData( &msgData, buffer, CRYPT_MAX_PKCSIZE + 1536 );
	status = krnlSendMessage( iCryptKeyset, IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_IATTRIBUTE_TRUSTEDCERT );
	while( cryptStatusOK( status ) )
		{
		/* Add the cert data as a trusted cert item and look for the next
		   one */
		addTrustEntry( trustInfoPtr, CRYPT_UNUSED, msgData.data,
					   msgData.length );
		setMessageData( &msgData, buffer, CRYPT_MAX_PKCSIZE + 1536 );
		status = krnlSendMessage( iCryptKeyset, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT );
		}

	return( ( status == CRYPT_ERROR_NOTFOUND ) ? CRYPT_OK : status );
	}

int readConfig( const CRYPT_USER iCryptUser, const char *fileName,
				void *trustInfoPtr )
	{
	CRYPT_KEYSET iCryptKeyset;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	STREAM stream;
	DYNBUF configDB;
	char configFilePath[ MAX_PATH_LENGTH + 128 ];	/* Protection for Windows */
	int status;

	/* Try and open the config file.  If we can't open it, it means the that
	   file doesn't exist, which isn't an error */
	fileBuildCryptlibPath( configFilePath, fileName, FALSE );
	setMessageCreateObjectInfo( &createInfo, CRYPT_KEYSET_FILE );
	createInfo.arg2 = CRYPT_KEYOPT_READONLY;
	createInfo.strArg1 = configFilePath;
	createInfo.strArgLen1 = strlen( configFilePath );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_KEYSET );
	if( cryptStatusError( status ) )
		return( CRYPT_OK );		/* No config data present */
	iCryptKeyset = createInfo.cryptHandle;

	/* Get the config info from the keyset */
	status = dynCreate( &configDB, iCryptKeyset,
						CRYPT_IATTRIBUTE_CONFIGDATA );
	if( status == CRYPT_ERROR_NOTFOUND )
		{
		/* No config options present, there may still be trusted certs */
		status = readTrustedCerts( iCryptKeyset, trustInfoPtr );
		krnlSendNotifier( iCryptKeyset, IMESSAGE_DECREFCOUNT );
		return( status );
		}
	if( cryptStatusOK( status ) )
		status = readTrustedCerts( iCryptKeyset, trustInfoPtr );
	krnlSendNotifier( iCryptKeyset, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		{
		dynDestroy( &configDB );
		return( status );
		}

	/* Read each config option */
	sMemConnect( &stream, dynData( configDB ), dynLength( configDB ) );
	while( cryptStatusOK( status ) && \
		   stell( &stream ) < dynLength( configDB ) )
		{
		CRYPT_ATTRIBUTE_TYPE attributeType;
		long option;
		int value, tag, i;

		/* Read the wrapper and option index and map it to the actual option.
		   If we find an unknown index or one that shouldn't be writeable to
		   persistent storage, we skip it and continue.  This is done to
		   handle new options that may have been added after this version of
		   cryptlib was built (for unknown indices) and because the stored
		   config options are an untrusted source so we have to check for
		   attempts to feed in bogus values (for non-writeable options) */
		readSequence( &stream, NULL );
		status = readShortInteger( &stream, &option );
		if( cryptStatusError( status ) )
			continue;
		for( i = 1; fixedOptionInfo[ i ].option <= LAST_STORED_OPTION; i++ )
			if( fixedOptionInfo[ i ].index == option )
				break;
		if( fixedOptionInfo[ i ].option > LAST_STORED_OPTION || \
			fixedOptionInfo[ i ].index == CRYPT_UNUSED )
			{
			readUniversal( &stream );
			continue;
			}
		attributeType = fixedOptionInfo[ i ].option;

		/* Read the option value and set the option.  We don't treat a failure
		   to set the option as a problem since the user probably doesn't want
		   the entire system to fail because of a bad config option, and in any
		   case we'll fall back to a safe default value */
		tag = peekTag( &stream );
		if( tag == BER_BOOLEAN || tag == BER_INTEGER )
			{
			/* It's a numeric value, read the appropriate type and try and set
			   the option */
			if( tag == BER_BOOLEAN )
				status = readBoolean( &stream, &value );
			else
				{
				long integer;

				status = readShortInteger( &stream, &integer );
				value = ( int ) integer;
				}
			if( cryptStatusOK( status ) )
				krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE, &value,
								 attributeType );
			}
		else
			{
			int length;

			/* It's a string value, set the option straight from the encoded
			   data */
			status = readGenericHole( &stream, &length, BER_STRING_UTF8 );
			if( cryptStatusError( status ) )
				continue;
			setMessageData( &msgData, sMemBufPtr( &stream ), length );
			krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE_S, &msgData,
							 attributeType );
			status = sSkip( &stream, length );
			}
		}
	sMemDisconnect( &stream );

	/* Clean up */
	dynDestroy( &configDB );
	return( status );
	}

/* Write any user-defined configuration options.  This is performed in two
   phases, a first phase that encodes the config data and a second phase
   that writes the data to disk.  The reason for the split is that the
   second phase doesn't require the use of the user object data any more
   and can be a somewhat lengthy process due to disk accesses and other bits
   and pieces.  Because of this the caller is expected to unlock the user
   object between the two phases to ensure that the second phase doesn't
   stall all other operations that require it */

int encodeConfigData( OPTION_INFO *optionList, const char *fileName,
					  void *trustInfoPtr, void **data, int *length )
	{
	STREAM stream;
	const BOOLEAN trustedCertsPresent = \
					( enumTrustedCerts( trustInfoPtr, CRYPT_UNUSED,
										CRYPT_UNUSED ) != CRYPT_ERROR ) ? \
					TRUE : FALSE;
	int i;

	/* Clear the return values */
	*data = NULL;
	*length = 0;

	/* If neither the config options nor any cert trust settings have
	   changed, there's nothing to do */
	for( i = 1; fixedOptionInfo[ i ].option <= LAST_STORED_OPTION; i++ )
		if( optionList[ i ].dirty )
			break;
	if( fixedOptionInfo[ i ].option >= LAST_STORED_OPTION && \
		!trustedCertsPresent )
		return( CRYPT_OK );

	/* Make a first pass through the config options to determine the total
	   encoded length of the ones that don't match the default setting.  We
	   can't just check the isDirty flag because if a value is reset to its
	   default setting the encoded size will be zero even though the isDirty
	   flag is set */
	for( i = 1; fixedOptionInfo[ i ].option <= LAST_STORED_OPTION; i++ )
		{
		const FIXED_OPTION_INFO *fixedOptionInfoPtr = &fixedOptionInfo[ i ];
		const OPTION_INFO *optionInfoPtr = &optionList[ i ];

		/* If it's an option that can't be written to disk, skip it */
		if( fixedOptionInfoPtr->index == CRYPT_UNUSED )
			continue;

		if( fixedOptionInfoPtr->type == OPTION_STRING )
			{
			/* If the string value is the same as the default, there's
			   nothing to do */
			if( optionInfoPtr->strValue == NULL || \
				optionInfoPtr->strValue == fixedOptionInfoPtr->strDefault )
				continue;
			*length += ( int ) sizeofObject( \
						sizeofShortInteger( fixedOptionInfoPtr->index ) + \
						sizeofObject( strlen( optionInfoPtr->strValue ) ) );
			}
		else
			{
			/* If the integer/boolean value that's currently set isn't the
			   default setting, update it */
			if( optionInfoPtr->intValue == fixedOptionInfoPtr->intDefault )
				continue;
			*length += ( int ) sizeofObject( \
						sizeofShortInteger( fixedOptionInfoPtr->index ) + \
						( fixedOptionInfoPtr->type == OPTION_NUMERIC ? \
						  sizeofShortInteger( optionInfoPtr->intValue ) : \
						  sizeofBoolean() ) );
			}
		}

	/* If we've gone back to all default values from having non-default ones
	   stored, we either have to write only trusted certs or nothing at all */
	if( *length <= 0 )
		{
		char configFilePath[ MAX_PATH_LENGTH + 128 ];	/* Protection for Windows */

		/* There's no data to write, if there are trusted certs present
		   notify the caller */
		if( trustedCertsPresent )
			return( OK_SPECIAL );

		/* There's nothing to write, delete the config file */
		fileBuildCryptlibPath( configFilePath, fileName, FALSE );
		fileErase( configFilePath );
		return( CRYPT_OK );
		}

	assert( *length > 0 );

	/* Allocate a buffer to hold the encoded values */
	if( ( *data = clAlloc( "encodeConfigData", *length ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );

	/* Write the config options */
	sMemOpen( &stream, *data, *length );
	for( i = 1; fixedOptionInfo[ i ].option <= LAST_STORED_OPTION; i++ )
		{
		const FIXED_OPTION_INFO *fixedOptionInfoPtr = &fixedOptionInfo[ i ];
		const OPTION_INFO *optionInfoPtr = &optionList[ i ];

		/* If it's an option that can't be written to disk, skip it */
		if( fixedOptionInfoPtr->index == CRYPT_UNUSED )
			continue;

		if( fixedOptionInfoPtr->type == OPTION_STRING )
			{
			if( optionInfoPtr->strValue == NULL || \
				optionInfoPtr->strValue == fixedOptionInfoPtr->strDefault )
				continue;
			writeSequence( &stream,
						   sizeofShortInteger( fixedOptionInfoPtr->index ) + \
						   sizeofObject( strlen( optionInfoPtr->strValue ) ) );
			writeShortInteger( &stream, fixedOptionInfoPtr->index,
							   DEFAULT_TAG );
			writeCharacterString( &stream, optionInfoPtr->strValue,
								  strlen( optionInfoPtr->strValue ),
								  BER_STRING_UTF8 );
			continue;
			}

		if( optionInfoPtr->intValue == fixedOptionInfoPtr->intDefault )
			continue;
		if( fixedOptionInfoPtr->type == OPTION_NUMERIC )
			{
			writeSequence( &stream,
						   sizeofShortInteger( fixedOptionInfoPtr->index ) + \
						   sizeofShortInteger( optionInfoPtr->intValue ) );
			writeShortInteger( &stream, fixedOptionInfoPtr->index,
							   DEFAULT_TAG );
			writeShortInteger( &stream, optionInfoPtr->intValue,
							   DEFAULT_TAG );
			}
		else
			{
			writeSequence( &stream,
						   sizeofShortInteger( fixedOptionInfoPtr->index ) + \
						   sizeofBoolean() );
			writeShortInteger( &stream, fixedOptionInfoPtr->index,
							   DEFAULT_TAG );
			writeBoolean( &stream, optionInfoPtr->intValue, DEFAULT_TAG );
			}
		}
	assert( sGetStatus( &stream ) == CRYPT_OK );
	sMemDisconnect( &stream );

	/* We've written the config data to the memory buffer, let the caller
	   know that they can unlock it and commit it to permanent storage */
	return( OK_SPECIAL );
	}

int commitConfigData( const CRYPT_USER cryptUser, const char *fileName,
					  const void *data, const int length )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	char configFilePath[ MAX_PATH_LENGTH + 128 ];	/* Protection for Windows */
	int status;

	/* Build the path to the config file and try and create it */
	fileBuildCryptlibPath( configFilePath, fileName, TRUE );
	setMessageCreateObjectInfo( &createInfo, CRYPT_KEYSET_FILE );
	createInfo.arg2 = CRYPT_KEYOPT_CREATE;
	createInfo.strArg1 = configFilePath;
	createInfo.strArgLen1 = strlen( configFilePath );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_KEYSET );
	if( cryptStatusError( status ) )
		/* Map the lower-level keyset-specific error into a more meaningful
		   generic error */
		return( CRYPT_ERROR_OPEN );

	/* Send the config data (if there is any) and any trusted certs to the
	   keyset */
	if( length > 0 )
		{
		setMessageData( &msgData, ( void * ) data, length );
		status = krnlSendMessage( createInfo.cryptHandle,
								  IMESSAGE_SETATTRIBUTE_S, &msgData,
								  CRYPT_IATTRIBUTE_CONFIGDATA );
		}
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( cryptUser, IMESSAGE_SETATTRIBUTE,
								  &createInfo.cryptHandle,
								  CRYPT_IATTRUBUTE_CERTKEYSET );
	krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		{
		fileErase( configFilePath );
		return( CRYPT_ERROR_WRITE );
		}
	return( CRYPT_OK );
	}

⌨️ 快捷键说明

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