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

📄 cryptkey.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
		case CRYPT_ATTRIBUTE_INT_ERRORCODE:	
			switch( keysetInfoPtr->type )
				{
				case KEYSET_HTTP:
					*valuePtr = keysetInfoPtr->keysetHTTP->errorCode;
					break;

				case KEYSET_LDAP:
					*valuePtr = keysetInfoPtr->keysetLDAP->errorCode;
					break;

				case KEYSET_DBMS:
					*valuePtr = keysetInfoPtr->keysetDBMS->errorCode;
					break;

				default:
					*valuePtr = CRYPT_OK;
				}
			return( CRYPT_OK );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

static int processGetAttributeS( KEYSET_INFO *keysetInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;

	switch( messageValue )
		{
		case CRYPT_ATTRIBUTE_INT_ERRORMESSAGE:
			{
			const char *errorMessagePtr;

			switch( keysetInfoPtr->type )
				{
				case KEYSET_HTTP:
					errorMessagePtr = keysetInfoPtr->keysetHTTP->errorMessage;
					break;

				case KEYSET_LDAP:
					errorMessagePtr = keysetInfoPtr->keysetLDAP->errorMessage;
					break;

				case KEYSET_DBMS:
					errorMessagePtr = keysetInfoPtr->keysetDBMS->errorMessage;
					break;

				default:
					errorMessagePtr = "";
				}
			if( !*errorMessagePtr )
				return( exitErrorNotFound( keysetInfoPtr,
										   CRYPT_ATTRIBUTE_INT_ERRORMESSAGE ) );
			return( attributeCopy( msgData, errorMessagePtr,
								   strlen( errorMessagePtr ) ) );
			}

		case CRYPT_IATTRIBUTE_CONFIGDATA:
		case CRYPT_IATTRIBUTE_USERINDEX:
		case CRYPT_IATTRIBUTE_USERINFO:
		case CRYPT_IATTRIBUTE_TRUSTEDCERT:
		case CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT:
			/* It's encoded cryptlib-specific data, fetch it from to the
			   keyset */
			assert( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
			return( keysetInfoPtr->getItemFunction( keysetInfoPtr, NULL,
									KEYMGMT_ITEM_DATA, CRYPT_KEYID_NONE,
									NULL, 0, msgData->data, &msgData->length,
									messageValue ) );

		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

static int processSetAttribute( KEYSET_INFO *keysetInfoPtr,
								void *messageDataPtr, const int messageValue )
	{
	switch( messageValue )
		{
		case MESSAGE_SETATTRIBUTE:
			/* It's an initialisation message, there's nothing to do */
			assert( *( int * ) messageDataPtr == CRYPT_IATTRIBUTE_INITIALISED );
			return( CRYPT_OK );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

static int processSetAttributeS( KEYSET_INFO *keysetInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	int status;

	switch( messageValue )
		{
		case CRYPT_KEYINFO_QUERY:
		case CRYPT_KEYINFO_QUERY_REQUESTS:
			assert( keysetInfoPtr->getFirstItemFunction != NULL );
			assert( keysetInfoPtr->isBusyFunction != NULL );

			/* If we're in the middle of an existing query the user needs to
			   cancel it before starting another one */
			if( keysetInfoPtr->isBusyFunction( keysetInfoPtr ) && \
				( msgData->length != 6 || \
				  strCompare( msgData->data, "cancel", msgData->length ) ) )
				return( exitErrorIncomplete( keysetInfoPtr, messageValue ) );

			/* Send the query to the data source */
			return( keysetInfoPtr->getFirstItemFunction( keysetInfoPtr, NULL,
						NULL, CRYPT_KEYID_NAME, msgData->data, msgData->length,
						( messageValue == CRYPT_KEYINFO_QUERY_REQUESTS ) ? \
							KEYMGMT_ITEM_REQUEST : KEYMGMT_ITEM_PUBLICKEY,
						KEYMGMT_FLAG_NONE ) );

		case CRYPT_IATTRIBUTE_CONFIGDATA:
		case CRYPT_IATTRIBUTE_USERINDEX:
		case CRYPT_IATTRIBUTE_USERID:
		case CRYPT_IATTRIBUTE_USERINFO:
			/* It's encoded cryptlib-specific data, pass it through to the
			   keyset */
			assert( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
			assert( keysetInfoPtr->setItemFunction != NULL );
			status = keysetInfoPtr->setItemFunction( keysetInfoPtr,
							CRYPT_UNUSED, KEYMGMT_ITEM_DATA,
							msgData->data, msgData->length, messageValue );
			if( cryptStatusOK( status ) && \
				messageValue != CRYPT_IATTRIBUTE_USERID )
				{
				/* The update succeeded, remember that the data in the keyset
				   has changed, unless it's a userID that just modifies
				   existing data */
				keysetInfoPtr->flags |= KEYSET_DIRTY;
				keysetInfoPtr->flags &= ~KEYSET_EMPTY;
				}
			return( status );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/****************************************************************************
*																			*
*								Keyset Message Handler						*
*																			*
****************************************************************************/

/* Handle a message sent to a keyset object */

static int keysetMessageFunction( const void *objectInfoPtr,
								  const MESSAGE_TYPE message,
								  void *messageDataPtr,
								  const int messageValue )
	{
	KEYSET_INFO *keysetInfoPtr = ( KEYSET_INFO * ) objectInfoPtr;

	/* Process the destroy object message */
	if( message == MESSAGE_DESTROY )
		{
		/* If the keyset is active, perform any required cleanup functions */
		if( keysetInfoPtr->flags & KEYSET_OPEN )
			{
			/* Shut down the keyset if required */
			if( keysetInfoPtr->shutdownFunction != NULL )
				keysetInfoPtr->shutdownFunction( keysetInfoPtr );

			/* If the keyset is implemented as a file, close it (the keyset-
			   specific handler sees only an I/O stream and doesn't perform
			   any file-level functions).  Because we cache all information
			   in a PKCS #12/#15 keyset and close the stream immediately
			   afterwards if we've opened it in read-only mode, we only
			   close the underlying stream for a PKCS #12/#15 keyset if it's 
			   still active.  Note the distinction between the keyset being 
			   active and the stream being active, for PKCS #12/#15 the 
			   keyset can be active without being associated with an open 
			   stream */
			if( keysetInfoPtr->flags & KEYSET_STREAM_OPEN )
				{
				/* Since the update may have changed the overall size, we
				   need to clear any leftover data from the previous
				   version of the keyset before we close the file */
				if( keysetInfoPtr->flags & KEYSET_DIRTY )
					fileClearToEOF( &keysetInfoPtr->keysetFile->stream );
				sFileClose( &keysetInfoPtr->keysetFile->stream );

				/* If it's a newly-created empty keyset file or one in which 
				   all the keys have been deleted, remove it.  This situation
				   can occur if there's some sort of error on writing and no 
				   keys are ever written to the keyset */
				if( keysetInfoPtr->flags & KEYSET_EMPTY )
					fileErase( keysetInfoPtr->keysetFile->fileName );
				}
			}

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		assert( message == MESSAGE_GETATTRIBUTE || \
				message == MESSAGE_GETATTRIBUTE_S || \
				message == MESSAGE_SETATTRIBUTE || \
				message == MESSAGE_SETATTRIBUTE_S );


		/* If it's a keyset-specific attribute, forward it directly to
		   the low-level code */
		if( messageValue >= CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS && \
			messageValue <= CRYPT_OPTION_KEYS_LDAP_EMAILNAME )
			{
			int status;

			if( message == MESSAGE_SETATTRIBUTE || \
				message == MESSAGE_SETATTRIBUTE_S )
				{
				assert( keysetInfoPtr->setAttributeFunction != NULL );

				status = keysetInfoPtr->setAttributeFunction( keysetInfoPtr,
											messageDataPtr, messageValue );
				if( status == CRYPT_ERROR_INITED )
					return( exitError( keysetInfoPtr, messageValue,
									   CRYPT_ERRTYPE_ATTR_PRESENT,
									   CRYPT_ERROR_INITED ) );
				}
			else
				{
				assert( message == MESSAGE_GETATTRIBUTE || \
						message == MESSAGE_GETATTRIBUTE_S );
				assert( keysetInfoPtr->getAttributeFunction != NULL );

				status = keysetInfoPtr->getAttributeFunction( keysetInfoPtr,
											messageDataPtr, messageValue );
				if( status == CRYPT_ERROR_NOTFOUND )
					return( exitErrorNotFound( keysetInfoPtr, 
											   messageValue ) );
				}
			return( status );
			}

		if( message == MESSAGE_GETATTRIBUTE )
			return( processGetAttribute( keysetInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_GETATTRIBUTE_S )
			return( processGetAttributeS( keysetInfoPtr, messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE )
			return( processSetAttribute( keysetInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE_S )
			return( processSetAttributeS( keysetInfoPtr, messageDataPtr,
										  messageValue ) );

		assert( NOTREACHED );
		return( CRYPT_ERROR );	/* Get rid of compiler warning */
		}

	/* Process messages that check a keyset */
	if( message == MESSAGE_CHECK )
		{
		/* The check for whether this keyset type can contain an object that 
		   can perform the requested operation has already been performed by 
		   the kernel, so there's nothing further to do here */
		assert( ( messageValue != MESSAGE_CHECK_PKC_PRIVATE && \
				  messageValue != MESSAGE_CHECK_PKC_DECRYPT && \
				  messageValue != MESSAGE_CHECK_PKC_DECRYPT_AVAIL && \
				  messageValue != MESSAGE_CHECK_PKC_SIGN && \
				  messageValue != MESSAGE_CHECK_PKC_SIGN_AVAIL ) || 
				( keysetInfoPtr->type != KEYSET_DBMS && \
				  keysetInfoPtr->type != KEYSET_LDAP && \
				  keysetInfoPtr->type != KEYSET_HTTP ) );

		return( CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == MESSAGE_KEY_GETKEY )
		{
		MESSAGE_KEYMGMT_INFO *getkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
							 getkeyInfo->keyIDtype, getkeyInfo->keyID, \
							 getkeyInfo->keyIDlength );
		BYTE keyIDbuffer[ KEYID_SIZE ];
		int status;

		CONST_SET_STRUCT( keyIDinfo.keyIDtype = getkeyInfo->keyIDtype; \
						  keyIDinfo.keyID = getkeyInfo->keyID; \
						  keyIDinfo.keyIDlength = getkeyInfo->keyIDlength );

		assert( keysetInfoPtr->getItemFunction != NULL );
		assert( keyIDinfo.keyIDtype != CRYPT_KEYID_NONE && \
				keyIDinfo.keyID != NULL && keyIDinfo.keyIDlength > 0 );
		assert( messageValue != KEYMGMT_ITEM_PRIVATEKEY || \
				keysetInfoPtr->type == KEYSET_FILE );
		assert( ( messageValue != KEYMGMT_ITEM_SECRETKEY && \
				  messageValue != KEYMGMT_ITEM_DATA ) || \
				( keysetInfoPtr->type == KEYSET_FILE && \
				  keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 ) );
		assert( ( messageValue != KEYMGMT_ITEM_REQUEST && \
				  messageValue != KEYMGMT_ITEM_REVOCATIONINFO && \
				  messageValue != KEYMGMT_ITEM_PKIUSER ) || \
				keysetInfoPtr->type == KEYSET_DBMS );

		/* Get the key */
		resetErrorInfo( keysetInfoPtr );
		status = initKeysetUpdate( keysetInfoPtr, &keyIDinfo, keyIDbuffer,
								   TRUE );
		if( cryptStatusOK( status ) )
			status = keysetInfoPtr->getItemFunction( keysetInfoPtr,
								&getkeyInfo->cryptHandle, messageValue,
								keyIDinfo.keyIDtype, keyIDinfo.keyID, 
								keyIDinfo.keyIDlength, getkeyInfo->auxInfo, 
								&getkeyInfo->auxInfoLength, 
								getkeyInfo->flags );
		return( status );
		}
	if( message == MESSAGE_KEY_SETKEY )
		{
		MESSAGE_KEYMGMT_INFO *setkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status;

		assert( keysetInfoPtr->setItemFunction != NULL );
		assert( messageValue != KEYMGMT_ITEM_PRIVATEKEY || \
				( keysetInfoPtr->type == KEYSET_FILE && \
				  ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 || \
					keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS12 ) ) );
		assert( ( messageValue != KEYMGMT_ITEM_SECRETKEY && \
				  messageValue != KEYMGMT_ITEM_DATA ) || \
				( keysetInfoPtr->type == KEYSET_FILE && \
				  keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 ) );
		assert( ( messageValue != KEYMGMT_ITEM_REQUEST && \
				  messageValue != KEYMGMT_ITEM_REVOCATIONINFO && \
				  messageValue != KEYMGMT_ITEM_PKIUSER ) || \
				( keysetInfoPtr->type == KEYSET_DBMS ) );

		/* Set the key.  This is currently the only way to associate a cert
		   with a context (that is, it's not possible to add a cert to an
		   existing context directly).  At first glance this should be 
		   possible since the required access checks are performed by the 
		   kernel: The object is of the correct type (a certificate), in the 
		   high state (it's been signed), and the cert owner and context 
		   owner are the same.  However, the process of attaching the cert to
		   the context is quite tricky.  The cert will have a public-key 
		   context already attached to it from when the cert was created or 
		   imported.  In order to attach this to the other context, we need 
		   to first destroy the context associated with the cert and then 
		   replace it with the other context.  This procedure is both messy 
		   and non-atomic.  There are also complications surrounding use 
		   with devices, where contexts are really cryptlib objects but just 
		   dummy values that point back to the object for handling of 
		   operations.  Going via a keyset/device bypasses these issues, but 
		   doing it directly shows up all of these problems */
		resetErrorInfo( keysetInfoPtr );
		status = initKeysetUpdate( keysetInfoPtr, NULL, NULL, FALSE );
		if( cryptStatusOK( status ) )
			status = keysetInfoPtr->setItemFunction( keysetInfoPtr,
							setkeyInfo->cryptHandle, messageValue,
							setkeyInfo->auxInfo, setkeyInfo->auxInfoLength,
							setkeyInfo->flags );
		if( cryptStatusOK( status ) )
			{
			/* The update succeeded, remember that the data in the keyset has
			   changed */
			keysetInfoPtr->flags |= KEYSET_DIRTY;
			keysetInfoPtr->flags &= ~KEYSET_EMPTY;
			}
		return( status );
		}
	if( message == MESSAGE_KEY_DELETEKEY )
		{
		MESSAGE_KEYMGMT_INFO *deletekeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
							 deletekeyInfo->keyIDtype, deletekeyInfo->keyID, \
							 deletekeyInfo->keyIDlength );
		BYTE keyIDbuffer[ KEYID_SIZE ];
		int status;

		CONST_SET_STRUCT( keyIDinfo.keyIDtype = deletekeyInfo->keyIDtype; \
						  keyIDinfo.keyID = deletekeyInfo->keyID; \
						  keyIDinfo.keyIDlength = deletekeyInfo->keyIDlength );

		assert( keysetInfoPtr->deleteItemFunction != NULL );
		assert( keyIDinfo.keyIDtype != CRYPT_KEYID_NONE && \
				keyIDinfo.keyID != NULL && keyIDinfo.keyIDlength > 0 );

		/* Delete the key */
		resetErrorInfo( keysetInfoPtr );
		status = initKeysetUpdate( keysetInfoPtr, &keyIDinfo, keyIDbuffer,
								   FALSE );
		if( cryptStatusOK( status ) )
			status = keysetInfoPtr->deleteItemFunction( keysetInfoPtr,
								messageValue, keyIDinfo.keyIDtype, 
								keyIDinfo.keyID, keyIDinfo.keyIDlength );
		if( cryptStatusOK( status ) )
			/* The update succeeded, remember that the data in the keyset has
			   changed */
			keysetInfoPtr->flags |= KEYSET_DIRTY;
		return( status );
		}
	if( message == MESSAGE_KEY_GETFIRSTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
							 getnextcertInfo->keyIDtype, getnextcertInfo->keyID, \
							 getnextcertInfo->keyIDlength );
		BYTE keyIDbuffer[ KEYID_SIZE ];
		int status;

⌨️ 快捷键说明

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