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

📄 cryptusr.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
		}

	return( CRYPT_OK );
	}
#endif /* 0 */

/* Sign the user info and write it to the user keyset */

static int writeUserInfo( const CRYPT_KEYSET iUserKeyset, 
						  const USER_INFO *userInfoPtr, 
						  const CRYPT_CONTEXT iSignContext )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	STREAM stream;
	BYTE userInfoBuffer[ 1024 ];
	static const int minBufferSize = MIN_BUFFER_SIZE;
	int userInfoLength, status;

	/* Write the user information to a memory buffer */
	sMemOpen( &stream, userInfoBuffer, MAX_USERINFO_SIZE );
	writeSequence( &stream, sizeofShortInteger( userInfoPtr->type ) + \
				   2 * sizeofObject( KEYID_SIZE ) + \
				   sizeofObject( userInfoPtr->userNameLength ) );
	writeEnumerated( &stream, userInfoPtr->type, DEFAULT_TAG );
	writeOctetString( &stream, userInfoPtr->userID, KEYID_SIZE, DEFAULT_TAG );
	writeOctetString( &stream, userInfoPtr->creatorID, KEYID_SIZE, DEFAULT_TAG );
	writeCharacterString( &stream, userInfoPtr->userName, 
						  userInfoPtr->userNameLength, BER_STRING_UTF8 );
	userInfoLength = stell( &stream );
	sMemDisconnect( &stream );

	/* Create a cryptlib envelope to sign the data.  This is kind of
	   heavyweight, but it's OK because we rarely create new users and it
	   saves having to hand-assemble the data like the PKCS #15 code does */
	setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_CRYPTLIB );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		return( status );
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE, 
					 ( int * ) &minBufferSize, CRYPT_ATTRIBUTE_BUFFERSIZE );
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE, 
					 &userInfoLength, CRYPT_ENVINFO_DATASIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  IMESSAGE_SETATTRIBUTE, 
							  ( void * ) &iSignContext, 
							  CRYPT_ENVINFO_SIGNATURE );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Push in the data and pop the signed result */
	setMessageData( &msgData, userInfoBuffer, userInfoLength );
	status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_ENV_PUSHDATA, 
							  &msgData, 0 );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( createInfo.cryptHandle, 
								  IMESSAGE_ENV_PUSHDATA, &msgData, 0 );
		}
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, userInfoBuffer, 1024 );
		status = krnlSendMessage( createInfo.cryptHandle, 
								  IMESSAGE_ENV_POPDATA, &msgData, 0 );
		}
	krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		return( status );

	/* Add the user ID and SO-signed user info to the keyset */
	status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_USERINFO );
	zeroise( userInfoBuffer, 1024 );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, ( void * ) userInfoPtr->userID, 
						KEYID_SIZE );
		status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S, 
								  &msgData, CRYPT_IATTRIBUTE_USERID );
		}
	return( status );
	}

/****************************************************************************
*																			*
*							User Management Functions						*
*																			*
****************************************************************************/

/* Perform a zeroise */

static int zeroiseUsers( void )
	{
	CRYPT_KEYSET iIndexKeyset;
	RESOURCE_DATA msgData;
	STREAM stream;
	static const BYTE zeroUserData[] = { 0x30, 0x00 };
	BYTE buffer[ KEYSET_BUFFERSIZE ];
	void *bufPtr = buffer;
	int length, status;

	/* Open the index file and read the index entries from it.  We open it in
	   exclusive mode and keep it open to ensure that noone else can access 
	   it while the zeroise is occurring */
	status = openUserKeyset( &iIndexKeyset, "index", 
							 CRYPT_IKEYOPT_EXCLUSIVEACCESS );
	if( cryptStatusError( status ) )
		{
		/* If there's no index file present, we're already in the zeroised 
		   state */
		if( status == CRYPT_ERROR_NOTFOUND )
			return( CRYPT_OK );

		/* If there's something there but it's damaged, delete it so we can
		   start again */
		if( status == CRYPT_ERROR_BADDATA )
			{
			char userFilePath[ MAX_PATH_LENGTH + 128 ];	/* Protection for Windows */

			fileBuildCryptlibPath( userFilePath, "index", BUILDPATH_GETPATH );
			fileErase( userFilePath );

			return( CRYPT_OK );
			}

		return( status );
		}
	status = readUserData( iIndexKeyset, CRYPT_IATTRIBUTE_USERINDEX,
						   &bufPtr, &length, 0 );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
		if( bufPtr != buffer )
			clFree( "zeroiseUsers", bufPtr );
		return( status );
		}

	/* Step through each entry clearing the user info for it */
	sMemConnect( &stream, bufPtr, length );
	while( stell( &stream ) < length )
		{
		STREAM fileStream;
		char userFilePath[ MAX_PATH_LENGTH + 128 ];	/* Protection for Windows */
		char userFileName[ 16 ];
		long fileRef;

		/* Get the file reference for this user */
		readSequence( &stream, NULL );
		readUniversal( &stream );
		readUniversal( &stream );
		readUniversal( &stream );
		status = readShortInteger( &stream, &fileRef );
		if( cryptStatusError( status ) )
			continue;

		/* Erase the given user keyset */
		sPrintf( userFileName, "u%06lx",  fileRef );
		fileBuildCryptlibPath( userFilePath, userFileName, 
							   BUILDPATH_GETPATH );
		status = sFileOpen( &fileStream, userFilePath, 
							FILE_READ | FILE_WRITE | FILE_EXCLUSIVE_ACCESS );
		if( cryptStatusError( status ) )
			continue;
		fileClearToEOF( &fileStream );
		sFileClose( &fileStream );
		fileErase( userFilePath );
		}
	sMemDisconnect( &stream );
	if( bufPtr != buffer )
		clFree( "zeroiseUsers", bufPtr );

	/* Erase the index file by setting zero-length user index info, which
	   results in an empty keyset which is erased on close */
	setMessageData( &msgData, ( void * ) zeroUserData, 2 );
	status = krnlSendMessage( iIndexKeyset, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_USERINDEX );
	krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
	
	return( status );
	}

/* Create a user object keyset */

static int createUserKeyset( CRYPT_KEYSET *iCreatedKeyset, 
							 USER_INFO *userInfoPtr )
	{
	CRYPT_KEYSET iIndexKeyset, iUserKeyset;
	BOOLEAN newIndex = FALSE;
	BYTE buffer[ KEYSET_BUFFERSIZE ];
	void *bufPtr = buffer;
	char userFileName[ 16 ];
	int fileRef, length, status;

	/* Clear return value */
	*iCreatedKeyset = CRYPT_ERROR;

	/* Try and open the config file.  If we can't open it and the return 
	   status indicates that the file doesn't exist, try and create it 
	   instead */
	status = openUserKeyset( &iIndexKeyset, "index", 
							 CRYPT_IKEYOPT_EXCLUSIVEACCESS );
	if( status == CRYPT_ERROR_NOTFOUND )
		{
		status = openUserKeyset( &iIndexKeyset, "index", 
								 CRYPT_KEYOPT_CREATE );
		newIndex = TRUE;
		}
	if( cryptStatusError( status ) )
		return( status );	

	/* If there's index data present, read it and make sure that the new 
	   user isn't already present */
	if( !newIndex )
		{
		/* Read the index entries from the keyset */
		status = readUserData( iIndexKeyset, CRYPT_IATTRIBUTE_USERINDEX,
							   &bufPtr, &length, MAX_USERINDEX_SIZE );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
			if( bufPtr != buffer )
				clFree( "createUserKeyset", bufPtr );
			return( status );
			}

		/* Check whether this user is present in the index */
		status = findUser( bufPtr, length, USERID_NAME, userInfoPtr->userName, 
						   userInfoPtr->userNameLength );
		if( !cryptStatusError( status ) )
			{
			krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
			if( bufPtr != buffer )
				clFree( "createUserKeyset", bufPtr );
			return( CRYPT_ERROR_DUPLICATE );
			}

		/* Make sure that the userID is unique */
		do
			{
			status = findUser( bufPtr, length, USERID_USERID, 
							   userInfoPtr->userID, KEYID_SIZE );
			if( !cryptStatusError( status ) )
				{
				RESOURCE_DATA msgData;

				setMessageData( &msgData, userInfoPtr->userID, KEYID_SIZE );
				status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
										  IMESSAGE_GETATTRIBUTE_S, &msgData, 
										  CRYPT_IATTRIBUTE_RANDOM_NONCE );
				}
			}
		while( !cryptStatusError( status ) );

		/* Locate a new unused file reference that we can use */
		fileRef = findUser( bufPtr, length, USERID_NONE, NULL, 0 );
		}
	else
		/* No users present yet, use the first user entry */
		fileRef = length = 0;

	/* Create the user keyset */
	sPrintf( userFileName, "u%06x", fileRef );
	status = openUserKeyset( &iUserKeyset, userFileName, 
							 CRYPT_KEYOPT_CREATE );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
		if( bufPtr != buffer )
			clFree( "createUserKeyset", bufPtr );
		return( status );
		}

	/* Update the index file */
	status = insertIndexEntry( userInfoPtr, bufPtr, &length );
	if( cryptStatusOK( status ) )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, bufPtr, length );
		status = krnlSendMessage( iIndexKeyset, IMESSAGE_SETATTRIBUTE_S, 
								  &msgData, CRYPT_IATTRIBUTE_USERINDEX );
		}
	if( cryptStatusError( status ) )
		/* We couldn't update the index file, delete the newly-created user
		   keyset (since we haven't written anything to it, it's zero-length
		   so it's deleted automatically on close) */
		krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
	else
		{
		userInfoPtr->fileRef = fileRef;
		*iCreatedKeyset = iUserKeyset;
		}
	krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );

	/* Clean up */
	if( bufPtr != buffer )
		clFree( "createUserKeyset", bufPtr );
	return( status );
	}

/* Set/change the password for a user object */

static int setPassword( USER_INFO *userInfoPtr, const char *password, 
						const int passwordLength )
	{
	CRYPT_KEYSET iUserKeyset;
	int status;

	/* No-one can ever directly set the default SO password */
	if( passwordLength == PRIMARYSO_PASSWORD_LENGTH && \
		( !memcmp( password, PRIMARYSO_PASSWORD, 
				   PRIMARYSO_PASSWORD_LENGTH ) || \
		  !memcmp( password, PRIMARYSO_ALTPASSWORD, 
				   PRIMARYSO_PASSWORD_LENGTH ) ) )
		return( CRYPT_ERROR_WRONGKEY );

	/* If we're setting the password for the primary SO in the zeroised
	   state, create a new user keyset and SO authentication key and write
	   the details to the keyset */
	if( userInfoPtr->fileRef == -1 )
		{
		status = createUserKeyset( &iUserKeyset, userInfoPtr );
		assert( ( cryptStatusError( status ) && userInfoPtr->fileRef == -1 ) || \
				( cryptStatusOK( status ) && userInfoPtr->fileRef == 0 ) );
		if( cryptStatusOK( status ) )
			{
			RESOURCE_DATA msgData;

			/* Since this user is created implicitly, there's no userID set 
			   by an explicit create so we set it now.  Since this is 
			   effectively a self-created user we also set the creatorID to 
			   the userID */
			setMessageData( &msgData, userInfoPtr->userID, KEYID_SIZE );
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
									  IMESSAGE_GETATTRIBUTE_S, &msgData, 
									  CRYPT_IATTRIBUTE_RANDOM_NONCE );
			if( cryptStatusOK( status ) )

⌨️ 快捷键说明

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