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

📄 cryptusr.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
		if( status == CRYPT_ERROR_NOTFOUND && idType == USERID_NAME && \
			idLength == primarySOInfo.userNameLength && \
			!memcmp( id, primarySOInfo.userName, 
					 primarySOInfo.userNameLength ) )
			status = OK_SPECIAL;

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

	/* Check whether this user is present in the index */
	status = findUser( bufPtr, length, idType, id, idLength );
	if( bufPtr != buffer )
		clFree( "findUserFileRef", bufPtr );

	return( status );
	}

/* Insert a new entry into the index */

static int insertIndexEntry( const USER_INFO *userInfoPtr, 
							 BYTE *userIndexData, int *userIndexDataLength )
	{
	STREAM stream;
	BYTE userInfoBuffer[ MAX_USERINDEX_SIZE ];
	int userInfoLength, newReference = 0, lastPos = 0;

	/* If there's already index data present, find the appropriate place to
	   insert the new entry and the file reference to use */
	if( *userIndexDataLength )
		{
		sMemConnect( &stream, userIndexData, *userIndexDataLength );
		while( stell( &stream ) < *userIndexDataLength )
			{
			long fileReference;
			int status;

			/* Read an index entry and check whether the file reference
			   matches the expected file reference */
			readSequence( &stream, NULL );
			readUniversal( &stream );
			readUniversal( &stream );
			status = readShortInteger( &stream, &fileReference );
			if( cryptStatusError( status ) )
				{
				sMemDisconnect( &stream );
				return( status );
				}
			if( fileReference != newReference )
				break;
			lastPos = stell( &stream );
			newReference++;
			}
		sMemDisconnect( &stream );
		}

	/* We've found an unused reference, insert the user data at this point */
	sMemOpen( &stream, userInfoBuffer, MAX_USERINDEX_SIZE );
	writeSequence( &stream, 2 * sizeofObject( KEYID_SIZE ) + \
				   sizeofObject( userInfoPtr->userNameLength ) + \
				   sizeofShortInteger( newReference ) );
	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 );
	writeShortInteger( &stream, newReference, DEFAULT_TAG );
	userInfoLength = stell( &stream );
	sMemDisconnect( &stream );
	if( lastPos < *userIndexDataLength )
		memmove( userIndexData + lastPos + userInfoLength,
				 userIndexData + lastPos, *userIndexDataLength - lastPos );
	memcpy( userIndexData + lastPos, userInfoBuffer, userInfoLength );
	*userIndexDataLength += userInfoLength;

	return( newReference );
	}

/* Read a user's info from a user keyset and verify it using the creating
   SO's key */

static int getCheckUserInfo( USER_FILE_INFO *userFileInfo, const int fileRef )
	{
	CRYPT_ALGO_TYPE hashAlgo;
	CRYPT_KEYSET iUserKeyset;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	MESSAGE_KEYMGMT_INFO getkeyInfo;
	STREAM stream;
	BYTE buffer[ KEYSET_BUFFERSIZE ];
	void *bufPtr = buffer, *hashDataPtr, *signaturePtr;
	char userFileName[ 16 ];
	int soFileRef, hashDataLength, signatureLength, length, enumValue, status;

	/* Clear return values */
	memset( userFileInfo, 0, sizeof( USER_FILE_INFO ) );

	/* Open the index keyset and read the user info from it */
	sPrintf( userFileName, "u%06x", fileRef );
	status = openUserKeyset( &iUserKeyset, userFileName, 
							 CRYPT_KEYOPT_READONLY );
	if( cryptStatusError( status ) )
		return( status );
	status = readUserData( iUserKeyset, CRYPT_IATTRIBUTE_USERINFO,
						   &bufPtr, &length, CRYPT_ERROR );
	krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		return( status );

	/* Burrow into the user info to get the information we need.  We do it
	   this way rather than using envelopes because we don't need the full 
	   generality of the enveloping process (we know exactly what data to 
	   expect) and to avoid the overhead of de-enveloping data every time a 
	   user logs in */
	sMemConnect( &stream, buffer, length );
	readSequence( &stream, NULL );			/* Outer wrapper */
	readUniversal( &stream );				/* ContentType OID */
	readConstructed( &stream, NULL, 0 );	/* Content */
	readSequence( &stream, NULL );
	readUniversal( &stream );				/* Version */
	readSet( &stream, NULL );				/* DigestAlgorithms */
	readAlgoID( &stream, &hashAlgo );
	readSequence( &stream, NULL );			/* EncapContentInfo */
	readUniversal( &stream );				/* ContentType OID */
	readConstructed( &stream, NULL, 0 );	/* Content type wrapper */
	status = readGenericHole( &stream, &hashDataLength, DEFAULT_TAG );
	if( cryptStatusError( status ) )
		{
		sMemDisconnect( &stream );
		return( status );
		}
	hashDataPtr = sMemBufPtr( &stream );

	/* Read the user info */
	readSequence( &stream, NULL );
	readEnumerated( &stream, &enumValue );
	userFileInfo->type = enumValue;
	readOctetString( &stream, userFileInfo->userID, &length, KEYID_SIZE );
	readOctetString( &stream, userFileInfo->creatorID, &length, KEYID_SIZE );
	status = readCharacterString( &stream, userFileInfo->userName, 
								  &userFileInfo->userNameLength, 
								  CRYPT_MAX_TEXTSIZE, BER_STRING_UTF8 );
	if( cryptStatusError( status ) )
		{
		sMemDisconnect( &stream );
		return( status );
		}

	/* Read the signature */
	status = readSet( &stream, &signatureLength );
	signaturePtr = sMemBufPtr( &stream );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		return( status );

	/* Open the SO keyset and read the SO public key from it */
	status = soFileRef = \
		findUserFileRef( USERID_USERID, userFileInfo->creatorID, KEYID_SIZE );
	if( cryptStatusOK( status ) )
		{
		sPrintf( userFileName, "u%06x", soFileRef );
		status = openUserKeyset( &iUserKeyset, userFileName, 
								 CRYPT_KEYOPT_READONLY );
		}
	if( cryptStatusError( status ) )
		return( status );
	setMessageKeymgmtInfo( &getkeyInfo, CRYPT_IKEYID_KEYID, 
						   userFileInfo->creatorID, KEYID_SIZE, NULL, 0, 
						   KEYMGMT_FLAG_NONE );
	status = krnlSendMessage( iUserKeyset, IMESSAGE_KEY_GETKEY, 
							  &getkeyInfo, KEYMGMT_ITEM_PUBLICKEY );
	krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		return( status );

	/* Hash the signed data and verify the signature using the SO key */
	setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_SHA );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT, &createInfo, 
							  OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		{
		krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CTX_HASH, 
						 hashDataPtr, hashDataLength );
		status = krnlSendMessage( createInfo.cryptHandle, 
								  IMESSAGE_CTX_HASH, hashDataPtr, 0 );
		if( cryptStatusOK( status ) )
			status = iCryptCheckSignatureEx( signaturePtr, signatureLength,
											 CRYPT_FORMAT_CRYPTLIB,
											 getkeyInfo.cryptHandle, 
											 createInfo.cryptHandle, NULL );
		krnlSendNotifier( createInfo.cryptHandle, 
						  IMESSAGE_DECREFCOUNT );
		}
	krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		return( status );

	/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
	/* MAC (???) using password - needs PKCS #15 changes */
	/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/

	if( cryptStatusError( status ) )
		return( status );

	return( status );
	}

/* Create an SO private key and write it to the user keyset */

static int createSOKey( const CRYPT_KEYSET iUserKeyset, 
						USER_INFO *userInfoPtr, const char *password,
						const int passwordLength )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int keyLength = /*128*/64;
	const int actionPerms = MK_ACTION_PERM( MESSAGE_CTX_SIGN, 
											ACTION_PERM_NONE_EXTERNAL ) | \
							MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, 
											ACTION_PERM_NONE_EXTERNAL );
	int status;

#ifndef NDEBUG
/* Warn that we're using a debug mode for now.  The user management code
   isn't complete yet so this isn't a problem */
puts( "Kludging SO key size to 512 bits." );
#endif /* NDEBUG */

	/* Create the SO private key, making it internal and signature-only */
	setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_RSA );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );
	setMessageData( &msgData, userInfoPtr->userName, 
					userInfoPtr->userNameLength );
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S, 
					 &msgData, CRYPT_CTXINFO_LABEL );
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE,
					 ( int * ) &keyLength, CRYPT_CTXINFO_KEYSIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  IMESSAGE_CTX_GENKEY, NULL, FALSE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( createInfo.cryptHandle, 
								  IMESSAGE_SETATTRIBUTE, 
								  ( int * ) &actionPerms, 
								  CRYPT_IATTRIBUTE_ACTIONPERMS );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Add the newly-created private key to the keyset */
	setMessageData( &msgData, ( void * ) userInfoPtr->userID, KEYID_SIZE );
	status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_USERID );
	if( cryptStatusOK( status ) )
		{
		MESSAGE_KEYMGMT_INFO setkeyInfo;

		setMessageKeymgmtInfo( &setkeyInfo, CRYPT_KEYID_NONE, NULL, 0, 
							   ( void * ) password, passwordLength, 
							   KEYMGMT_FLAG_NONE );
		setkeyInfo.cryptHandle = createInfo.cryptHandle;
		status = krnlSendMessage( iUserKeyset, IMESSAGE_KEY_SETKEY, 
								  &setkeyInfo, KEYMGMT_ITEM_PRIVATEKEY );
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	userInfoPtr->iCryptContext = createInfo.cryptHandle;
	return( CRYPT_OK );
	}

#if 0	/* Currently unused, for future use for CA users */

/* Create a CA secret key and write it to the user keyset */

static int createCAKey( const CRYPT_KEYSET iUserKeyset, 
						USER_INFO *userInfoPtr, const char *password,
						const int passwordLength )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int actionPerms = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, 
											ACTION_PERM_NONE_EXTERNAL ) | \
							MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, 
											ACTION_PERM_NONE_EXTERNAL );
	int status;

	/* Create the CA secret key, making it internal-only */
	setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_3DES );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );
	setMessageData( &msgData, userInfoPtr->userID, KEYID_SIZE );
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S, 
					 &msgData, CRYPT_CTXINFO_LABEL );
	status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CTX_GENKEY, 
							  NULL, FALSE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( createInfo.cryptHandle, 
								  IMESSAGE_SETATTRIBUTE, 
								  ( int * ) &actionPerms, 
								  CRYPT_IATTRIBUTE_ACTIONPERMS );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Add the newly-created secret key to the keyset */
	setMessageData( &msgData, ( void * ) userInfoPtr->userID, KEYID_SIZE );
	status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_USERID );
	if( cryptStatusOK( status ) )
		{
		MESSAGE_KEYMGMT_INFO setkeyInfo;

		setMessageKeymgmtInfo( &setkeyInfo, CRYPT_KEYID_NONE, NULL, 0, 
							   ( void * ) password, passwordLength, 
							   KEYMGMT_FLAG_NONE );
		setkeyInfo.cryptHandle = createInfo.cryptHandle;
		status = krnlSendMessage( iUserKeyset, IMESSAGE_KEY_SETKEY, 
								  &setkeyInfo, KEYMGMT_ITEM_SECRETKEY );
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );

⌨️ 快捷键说明

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