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

📄 user.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
				break;
			}
		if( i >= MAX_USER_OBJECTS )
			break;
		}
	ENSURES_N( newFileRef < MAX_USER_OBJECTS );
	*fileRef = newFileRef;

	return( userIndexPtr );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
static int createUserEntry( OUT_PTR USER_FILE_INFO **userIndexPtrPtr,
							IN_ARRAY( noUserIndexEntries ) \
								USER_FILE_INFO *userIndex, 
							IN_RANGE( 1, MAX_USER_OBJECTS ) \
								const int noUserIndexEntries,
							INOUT USER_FILE_INFO *userFileInfo )
	{
	USER_FILE_INFO *userIndexPtr;
	int fileRef, iterationCount, status = CRYPT_OK;

	assert( isWritePtr( userIndexPtrPtr, sizeof( USER_FILE_INFO * ) ) );
	assert( isWritePtr( userIndex, \
						sizeof( USER_FILE_INFO ) * noUserIndexEntries ) );
	assert( isWritePtr( userFileInfo, sizeof( USER_FILE_INFO ) ) );

	REQUIRES( noUserIndexEntries > 0 && \
			  noUserIndexEntries <= MAX_USER_OBJECTS );

	/* Clear return value */
	*userIndexPtrPtr = NULL;

	/* Check whether this user is already present in the index */
	if( findUser( userIndex, noUserIndexEntries, USERID_NAME, 
				  userFileInfo->userName, userFileInfo->userNameLength ) != NULL )
		return( CRYPT_ERROR_DUPLICATE );

	/* Make sure that the userID that we're using is unique.  This is a 
	   pretty straightforward operation, we just keep generating new random 
	   IDs until we get one that's not already present */
	for( iterationCount = 0; 
		 !cryptStatusError( status ) && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE;
		 iterationCount++ )
		{
		if( findUser( userIndex, noUserIndexEntries, USERID_USERID, 
					  userFileInfo->userID, KEYID_SIZE ) != NULL )
			{
			MESSAGE_DATA msgData;

			setMessageData( &msgData, ( void * ) userFileInfo->userID, 
							KEYID_SIZE );
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  IMESSAGE_GETATTRIBUTE_S, &msgData,
									  CRYPT_IATTRIBUTE_RANDOM_NONCE );
			}
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );

	/* Locate a new unused entry that we can use */
	userIndexPtr = findFreeEntry( userIndex, MAX_USER_OBJECTS, &fileRef );
	if( userIndexPtr == NULL )
		return( CRYPT_ERROR_OVERFLOW );
	userFileInfo->fileRef = fileRef;

	return( CRYPT_OK );
	}

/* Read the user index file:

	UserIndexEntry ::= SEQUENCE {
		iD					OCTET STRING SIZE(16),	-- User ID
		creatorID			OCTET STRING SIZE(16),	-- Creating SO's ID
		name				UTF8String,				-- User name
		fileReference		INTEGER					-- Reference to user file
		} */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readIndexEntry( INOUT STREAM *stream, 
						   INOUT USER_FILE_INFO *userIndexPtr )
	{
	USER_FILE_INFO userIndexEntry;
	long value;
	int length, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( userIndexPtr, sizeof( USER_FILE_INFO ) ) );

	/* Clear return value */
	memset( userIndexPtr, 0, sizeof( USER_FILE_INFO ) );

	/* Read the user index data */
	memset( &userIndexEntry, 0, sizeof( USER_FILE_INFO ) );
	readSequence( stream, NULL );
	readOctetString( stream, userIndexEntry.userID, &length, KEYID_SIZE, 
					 KEYID_SIZE );
	readOctetString( stream, userIndexEntry.creatorID, &length, KEYID_SIZE, 
					 KEYID_SIZE );
	readCharacterString( stream, userIndexEntry.userName, 
						 CRYPT_MAX_TEXTSIZE, &userIndexEntry.userNameLength, 
						 BER_STRING_UTF8 );
	status = readShortInteger( stream, &value );
	if( cryptStatusError( status ) )
		return( status );
	userIndexEntry.fileRef = value;

	/* Return the result to the caller */
	memcpy( userIndexPtr, &userIndexEntry, sizeof( USER_FILE_INFO ) );
	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int readIndex( IN_HANDLE const CRYPT_KEYSET iIndexKeyset, 
					  IN_ARRAY( maxUserObjects ) USER_FILE_INFO *userIndex, 
					  IN_RANGE( 1, MAX_USER_OBJECTS ) const int maxUserObjects )
	{
	STREAM stream;
	DYNBUF userIndexDB;
	int i, iterationCount, status;

	assert( isWritePtr( userIndex, \
						maxUserObjects * sizeof( USER_FILE_INFO ) ) );

	REQUIRES( isHandleRangeValid( iIndexKeyset ) );
	REQUIRES( maxUserObjects > 0 && maxUserObjects <= MAX_USER_OBJECTS );

	/* Read the user index file into memory */
	status = dynCreate( &userIndexDB, iIndexKeyset, 
						CRYPT_IATTRIBUTE_USERINDEX );
	if( cryptStatusError( status ) )
		return( status );
	sMemConnect( &stream, dynData( userIndexDB ), dynLength( userIndexDB ) );
	for( i = 0, iterationCount = 0; 
		 cryptStatusOK( status ) && \
			stell( &stream ) < dynLength( userIndexDB ) && \
			i < maxUserObjects && iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 i++, iterationCount++ )
		{
		status = readIndexEntry( &stream, &userIndex[ i ] );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	sMemDisconnect( &stream );
	dynDestroy( &userIndexDB );
	if( cryptStatusError( status ) )
		return( status );
	if( i > maxUserObjects )
		return( CRYPT_ERROR_OVERFLOW );

	return( i );
	}

/* Write the user index file */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeUserIndexEntry( INOUT STREAM *stream, 
								const USER_FILE_INFO *userIndexPtr )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( userIndexPtr, sizeof( USER_FILE_INFO ) ) );

	writeSequence( stream, 2 * sizeofObject( KEYID_SIZE ) + \
				   sizeofObject( userIndexPtr->userNameLength ) + \
				   sizeofShortInteger( userIndexPtr->fileRef) );
	writeOctetString( stream, userIndexPtr->userID, KEYID_SIZE, DEFAULT_TAG );
	writeOctetString( stream, userIndexPtr->creatorID, KEYID_SIZE, DEFAULT_TAG );
	writeCharacterString( stream, userIndexPtr->userName,
						  userIndexPtr->userNameLength, BER_STRING_UTF8 );
	return( writeShortInteger( stream, userIndexPtr->fileRef, DEFAULT_TAG ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int writeUserIndex( IN_HANDLE const CRYPT_KEYSET iIndexKeyset,
						   IN_ARRAY( noUserIndexEntries ) \
							USER_FILE_INFO *userIndex, 
						   IN_RANGE( 1, MAX_USER_OBJECTS ) \
							const int noUserIndexEntries )
	{
	STREAM stream;
	MESSAGE_DATA msgData;
	BYTE userIndexData[ MAX_USERINDEX_SIZE + 8 ];
	int userIndexDataLength, i, iterationCount, status = CRYPT_OK;

	assert( isWritePtr( userIndex, \
						noUserIndexEntries * sizeof( USER_FILE_INFO ) ) );

	REQUIRES( isHandleRangeValid( iIndexKeyset ) );
	REQUIRES( noUserIndexEntries > 0 && \
			  noUserIndexEntries <= MAX_USER_OBJECTS );

	/* Write the user index data to a buffer so that we can send it to the 
	   index keyset */
	sMemOpen( &stream, userIndexData, MAX_USERINDEX_SIZE );
	for( i = 0, iterationCount = 0; 
		 i < noUserIndexEntries && cryptStatusOK( status ) && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE; 
		 i++, iterationCount++ )
		{
		if( userIndex[ i ].state != USER_STATE_NONE )
			status = writeUserIndexEntry( &stream, &userIndex[ i ] );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	userIndexDataLength = stell( &stream );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the user index data to the keyset */
	setMessageData( &msgData, userIndexData, userIndexDataLength );
	return( krnlSendMessage( iIndexKeyset, IMESSAGE_SETATTRIBUTE_S,
							 &msgData, CRYPT_IATTRIBUTE_USERINDEX ) );
	}

/****************************************************************************
*																			*
*							Read/Write User Data							*
*																			*
****************************************************************************/

/* Read/write user data:

	UserInfo ::= SEQUENCE {
		role				ENUMERATED,				-- SO/user/CA
		iD					OCTET STRING SIZE(16),	-- User ID
		creatorID			OCTET STRING SIZE(16),	-- Creating SO's ID
		name				UTF8String,				-- User name
		} */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readUserData( INOUT USER_FILE_INFO *userFileInfoPtr, 
						 IN_BUFFER( userDataLength ) const void *userData, 
						 IN_LENGTH_SHORT const int userDataLength )
	{
	STREAM stream;
	int enumValue, length, status;

	assert( isWritePtr( userFileInfoPtr, sizeof( USER_FILE_INFO ) ) );
	assert( isReadPtr( userData, userDataLength ) );

	REQUIRES( userDataLength > 0 && userDataLength < MAX_INTLENGTH_SHORT );

	/* Clear return value */
	memset( userFileInfoPtr, 0, sizeof( userFileInfoPtr ) );

	/* Read the user info */
	sMemConnect( &stream, userData, userDataLength );
	readSequence( &stream, NULL );
	readEnumerated( &stream, &enumValue );
	userFileInfoPtr->type = enumValue;
	readOctetString( &stream, userFileInfoPtr->userID, &length, 
					 KEYID_SIZE, KEYID_SIZE );
	readOctetString( &stream, userFileInfoPtr->creatorID, &length, 
					 KEYID_SIZE, KEYID_SIZE );
	status = readCharacterString( &stream, userFileInfoPtr->userName,
								  CRYPT_MAX_TEXTSIZE, 
								  &userFileInfoPtr->userNameLength,
								  BER_STRING_UTF8 );
	sMemDisconnect( &stream );

	return( status );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
static int writeUserData( OUT_BUFFER( userDataMaxLength, \
									  *userDataLength ) void *userData, 
						  IN_LENGTH_SHORT const int userDataMaxLength,
						  OUT_LENGTH_SHORT_Z int *userDataLength, 
						  const USER_INFO *userInfoPtr )
	{
	const USER_FILE_INFO *userFileInfo = &userInfoPtr->userFileInfo;
	STREAM stream;
	int status;

	assert( isWritePtr( userData, userDataMaxLength ) );
	assert( isWritePtr( userDataLength, sizeof( int ) ) );
	assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );

	REQUIRES( userDataMaxLength > 0 && \
			  userDataMaxLength < MAX_INTLENGTH_SHORT );

	/* Clear return values */
	memset( userData, 0, min( 16, userDataMaxLength ) );
	*userDataLength = 0;

	/* Write the user information to a memory buffer */
	sMemOpen( &stream, userData, userDataMaxLength );
	writeSequence( &stream, sizeofShortInteger( userFileInfo->type ) + \
				   2 * sizeofObject( KEYID_SIZE ) + \
				   sizeofObject( userFileInfo->userNameLength ) );
	writeEnumerated( &stream, userFileInfo->type, DEFAULT_TAG );
	writeOctetString( &stream, userFileInfo->userID, KEYID_SIZE, 
					  DEFAULT_TAG );
	writeOctetString( &stream, userFileInfo->creatorID, KEYID_SIZE, 
					  DEFAULT_TAG );
	status = writeCharacterString( &stream, userFileInfo->userName,
								   userFileInfo->userNameLength, 
								   BER_STRING_UTF8 );
	if( cryptStatusOK( status ) )
		*userDataLength = stell( &stream );
	sMemDisconnect( &stream );

	return( status );
	}

/* Send user data to a user keyset */

CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
static int commitUserData( IN_HANDLE const CRYPT_KEYSET iUserKeyset, 
						   const USER_INFO *userInfoPtr, 
						   IN_BUFFER( userDataLength ) const void *userData, 
						   IN_LENGTH_SHORT const int userDataLength )
	{
	MESSAGE_DATA msgData;
	int status;

	assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
	assert( isReadPtr( userData, userDataLength ) );

	REQUIRES( isHandleRangeValid( iUserKeyset ) );
	REQUIRES( userDataLength > 0 && userDataLength < MAX_INTLENGTH_SHORT );

	/* Add the user ID and SO-signed user info to the keyset */
	setMessageData( &msgData, ( void * ) userData, userDataLength );
	status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S,
							  &msgData, CRYPT_IATTRIBUTE_USERINFO );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, ( void * ) userInfoPtr->userFileInfo.userID,
						KEYID_SIZE );
		status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S,

⌨️ 快捷键说明

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