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

📄 cryptusr.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 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, RESOURCE_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 );
	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 = readOctetStringTag( &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_ID, 
						   userFileInfo->creatorID, KEYID_SIZE, NULL, 0, 
						   KEYMGMT_FLAG_NONE );
	status = krnlSendMessage( iUserKeyset, RESOURCE_IMESSAGE_KEY_GETKEY, 
							  &getkeyInfo, KEYMGMT_ITEM_PUBLICKEY );
	krnlSendNotifier( iUserKeyset, RESOURCE_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,
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		{
		krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_CTX_HASH, 
						 hashDataPtr, hashDataLength );
		status = krnlSendMessage( createInfo.cryptHandle, 
								  RESOURCE_IMESSAGE_CTX_HASH, hashDataPtr, 0 );
		if( cryptStatusOK( status ) )
			status = iCryptCheckSignatureEx( signaturePtr, signatureLength,
											 getkeyInfo.cryptHandle, 
											 createInfo.cryptHandle, NULL );
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		}
	krnlSendNotifier( getkeyInfo.cryptHandle, RESOURCE_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( RESOURCE_MESSAGE_CTX_SIGN, 
											ACTION_PERM_NONE_EXTERNAL ) | \
							MK_ACTION_PERM( RESOURCE_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, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );
	setResourceData( &msgData, userInfoPtr->userName, 
					 userInfoPtr->userNameLength );
	krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_SETATTRIBUTE_S, 
					 &msgData, CRYPT_CTXINFO_LABEL );
	krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_SETATTRIBUTE,
					 ( int * ) &keyLength, CRYPT_CTXINFO_KEYSIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_CTX_GENKEY, NULL, FALSE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( createInfo.cryptHandle, 
								  RESOURCE_IMESSAGE_SETATTRIBUTE, 
								  ( int * ) &actionPerms, 
								  CRYPT_IATTRIBUTE_ACTIONPERMS );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Add the newly-created private key to the keyset */
	setResourceData( &msgData, ( void * ) userInfoPtr->userID, 
					 KEYID_SIZE );
	status = krnlSendMessage( iUserKeyset, RESOURCE_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, RESOURCE_IMESSAGE_KEY_SETKEY, 
								  &setkeyInfo, KEYMGMT_ITEM_PRIVATEKEY );
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

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

/* 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( RESOURCE_MESSAGE_CTX_ENCRYPT, 
											ACTION_PERM_NONE_EXTERNAL ) | \
							MK_ACTION_PERM( RESOURCE_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, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );
	setResourceData( &msgData, userInfoPtr->userID, KEYID_SIZE );
	krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_SETATTRIBUTE_S, 
					 &msgData, CRYPT_CTXINFO_LABEL );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_CTX_GENKEY, NULL, FALSE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( createInfo.cryptHandle, 
								  RESOURCE_IMESSAGE_SETATTRIBUTE, 
								  ( int * ) &actionPerms, 
								  CRYPT_IATTRIBUTE_ACTIONPERMS );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Add the newly-created secret key to the keyset */
	setResourceData( &msgData, ( void * ) userInfoPtr->userID, 
					 KEYID_SIZE );
	status = krnlSendMessage( iUserKeyset, RESOURCE_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, RESOURCE_IMESSAGE_KEY_SETKEY, 
								  &setkeyInfo, KEYMGMT_ITEM_SECRETKEY );
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

	return( CRYPT_OK );
	}

/* 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 ];
	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, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		return( status );
	krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_SETATTRIBUTE, 
					 ( int * ) &minBufferSize, CRYPT_ATTRIBUTE_BUFFERSIZE );
	krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_SETATTRIBUTE, 
					 &userInfoLength, CRYPT_ENVINFO_DATASIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_SETATTRIBUTE, 
							  ( void * ) &iSignContext, 
							  CRYPT_ENVINFO_SIGNATURE );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

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

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

⌨️ 快捷键说明

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