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

📄 cryptctx.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
			return( status );

#ifndef USE_FIPS140
		case CRYPT_CTXINFO_KEY_COMPONENTS:
			assert( contextType == CONTEXT_PKC );
			assert( needsKey( contextInfoPtr ) );

			assert( msgData->length == sizeof( CRYPT_PKCINFO_RSA ) || \
					msgData->length == sizeof( CRYPT_PKCINFO_DLP ) );

			/* We need to have a key label set before we can continue */
			if( !contextInfoPtr->labelSize )
				return( exitErrorNotInited( contextInfoPtr,
											CRYPT_CTXINFO_LABEL ) );

			/* Load the key into the context */
			status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
										msgData->data, msgData->length );
			if( cryptStatusOK( status ) )
				contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL | \
										 CONTEXT_PBO;
			return( status );
#endif /* USE_FIPS140 */

		case CRYPT_CTXINFO_IV:
			assert( contextType == CONTEXT_CONV );

			/* If it's a mode that doesn't use an IV, the load IV operation
			   is meaningless */
			if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
				isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
				return( CRYPT_ERROR_NOTAVAIL );

			/* Make sure that the data size is valid */
			if( msgData->length != capabilityInfoPtr->blockSize )
				return( CRYPT_ARGERROR_NUM1 );

			/* Load the IV */
			assert( capabilityInfoPtr->initKeyParamsFunction != NULL );
			return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
								msgData->data, msgData->length, CRYPT_UNUSED ) );

		case CRYPT_CTXINFO_LABEL:
			if( contextInfoPtr->labelSize )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_LABEL ) );

			/* Check any device object the context is associated with to
			   make sure that nothing with that label already exists in the
			   device.  The semantics for keysets are somewhat different,
			   the check for duplicates is performed when the context is
			   explicitly added to the keyset but with devices the context
			   is implicitly created within the device at some future point
			   that depends on the device (at context creation, on key load/
			   generation, or at some other point).  Because of this we
			   perform a pre-emptive check for duplicates to avoid a
			   potentially confusing error condition at some point in the
			   future.  In addition, we can't send the message to the context
			   because the kernel won't forward this message type (sending a
			   get-key message to a context doesn't make sense) so we have to
			   explicitly get the dependent device and send the get-key
			   directly to it */
			if( contextType == CONTEXT_PKC )
				{
				CRYPT_HANDLE cryptHandle;

				status = krnlSendMessage( contextInfoPtr->objectHandle,
										  IMESSAGE_GETDEPENDENT,
										  &cryptHandle, OBJECT_TYPE_DEVICE );
				if( cryptStatusOK( status ) )
					{
					MESSAGE_KEYMGMT_INFO getkeyInfo;

					setMessageKeymgmtInfo( &getkeyInfo,
										CRYPT_KEYID_NAME, msgData->data,
										msgData->length, NULL, 0,
										KEYMGMT_FLAG_CHECK_ONLY );
					status = krnlSendMessage( contextInfoPtr->objectHandle,
										MESSAGE_KEY_GETKEY, &getkeyInfo,
										KEYMGMT_ITEM_PUBLICKEY );
					if( cryptStatusError( status ) )
						{
						setMessageKeymgmtInfo( &getkeyInfo,
										CRYPT_KEYID_NAME, msgData->data,
										msgData->length, NULL, 0,
										KEYMGMT_FLAG_CHECK_ONLY );
						status = krnlSendMessage( contextInfoPtr->objectHandle,
										MESSAGE_KEY_GETKEY, &getkeyInfo,
										KEYMGMT_ITEM_PRIVATEKEY );
						}
					if( cryptStatusOK( status ) )
						/* We found something with this label already 
						   present, we can't use it again */
						return( CRYPT_ERROR_DUPLICATE );
					}
				}

			/* Set the label */
			memcpy( contextInfoPtr->label, msgData->data, msgData->length );
			contextInfoPtr->labelSize = msgData->length;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
			assert( contextType == CONTEXT_PKC );
			assert( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
					contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
					contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );
			assert( msgData->length == PGP_KEYID_SIZE );
			memcpy( contextInfoPtr->ctxPKC->openPgpKeyID, msgData->data,
					msgData->length );
			contextInfoPtr->ctxPKC->openPgpKeyIDSet = TRUE;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_KEY_SPKI:
			assert( contextType == CONTEXT_PKC );

			/* If the keys are held externally (e.g. in a crypto device),
			   copy the data in and set up any other information that we may 
			   need from it.  This information is used when loading a 
			   context from a key contained in a device, where the actual 
			   key components aren't directly available in the context but 
			   may be needed in the future for things like cert requests */
			if( contextInfoPtr->flags & CONTEXT_DUMMY )
				{
				if( ( contextInfoPtr->ctxPKC->publicKeyInfo = \
									clAlloc( "processSetAttributeS", \
											 msgData->length ) ) == NULL )
					return( CRYPT_ERROR_MEMORY );
				memcpy( contextInfoPtr->ctxPKC->publicKeyInfo, msgData->data,
						msgData->length );
				contextInfoPtr->ctxPKC->publicKeyInfoSize = msgData->length;
				return( calculateKeyID( contextInfoPtr ) );
				}

			/* Drop through */

		case CRYPT_IATTRIBUTE_KEY_SSH1:
		case CRYPT_IATTRIBUTE_KEY_SSH2:
		case CRYPT_IATTRIBUTE_KEY_PGP:
		case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
		case CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL:
			{
			static const int actionFlags = \
				MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_NONE_EXTERNAL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_NONE_EXTERNAL );
			static const int actionFlagsDH = ACTION_PERM_NONE_EXTERNAL_ALL;
			static const int actionFlagsPGP = \
				MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
				MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL );
			STREAM stream;

			assert( contextType == CONTEXT_PKC );

			/* Read the appropriately-formatted key data into the context,
			   applying a lowest-common-denominator set of usage flags to
			   the loaded key (more specific usage restrictions will be set
			   by higher-level code) */
			sMemConnect( &stream, msgData->data, msgData->length );
			status = contextInfoPtr->ctxPKC->readPublicKeyFunction( &stream,
						contextInfoPtr,
						( messageValue == CRYPT_IATTRIBUTE_KEY_SPKI || \
						  messageValue == CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL ) ? \
							KEYFORMAT_CERT : \
						( messageValue == CRYPT_IATTRIBUTE_KEY_SSH1 ) ? \
							KEYFORMAT_SSH1 : \
						( messageValue == CRYPT_IATTRIBUTE_KEY_SSH2 ) ? \
							KEYFORMAT_SSH2 : KEYFORMAT_PGP );
			sMemDisconnect( &stream );
			if( cryptStatusError( status ) )
				return( status );

			/* If it's a partial load of the public portions of a private 
			   key with further key component operations to follow, there's 
			   nothing more to do at this point and we're done */
			if( messageValue == CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL || \
				messageValue == CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL )
				return( calculateKeyID( contextInfoPtr ) );

			/* Perform an internal load that uses the key component values 
			   that we've just read into the context */
			contextInfoPtr->flags |= CONTEXT_ISPUBLICKEY;
			status = contextInfoPtr->loadKeyFunction( contextInfoPtr, NULL, 0 );
			if( cryptStatusError( status ) )
				/* Map the status to a more appropriate code if necessary */
				return( cryptArgError( status ) ? \
						CRYPT_ERROR_BADDATA : status );
			contextInfoPtr->flags |= CONTEXT_KEY_SET;

			/* Restrict the key usage to public-key-only actions if 
			   necessary.  For PGP key loads (which, apart from the 
			   restrictions specified with the stored key data aren't 
			   constrained by the presence of ACLs in the form of certs) we 
			   allow external usage, for DH (whose keys can be both public 
			   and private keys even though technically it's a public key)
			   we allow both encryption and decryption usage, and for public 
			   keys read from certs we  allow internal usage only */
			status = krnlSendMessage( contextInfoPtr->objectHandle,
							IMESSAGE_SETATTRIBUTE, 
							( messageValue == CRYPT_IATTRIBUTE_KEY_PGP ) ? \
								( void * ) &actionFlagsPGP : \
							( capabilityInfoPtr->cryptAlgo == CRYPT_ALGO_DH ) ? \
								( void * ) &actionFlagsDH : \
								( void * ) &actionFlags,
							CRYPT_IATTRIBUTE_ACTIONPERMS );
			if( cryptStatusError( status ) )
				return( status );
			contextInfoPtr->flags |= CONTEXT_KEY_SET;
			return( calculateKeyID( contextInfoPtr ) );
			}

		case CRYPT_IATTRIBUTE_PGPVALIDITY:
			assert( contextType == CONTEXT_PKC );
			contextInfoPtr->ctxPKC->pgpCreationTime = \
									*( ( time_t * ) msgData->data );
			return( CRYPT_OK );
		}

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

static int processDeleteAttribute( CONTEXT_INFO *contextInfoPtr,
								   const int messageValue )
	{
	const CONTEXT_TYPE contextType = contextInfoPtr->type;

	switch( messageValue )
		{
		case CRYPT_CTXINFO_KEYING_ALGO:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				{
				if( contextInfoPtr->ctxConv->keySetupAlgorithm == CRYPT_ALGO_NONE )
					return( exitErrorNotFound( contextInfoPtr,
											   CRYPT_CTXINFO_KEYING_ALGO ) );
				contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_NONE;
				return( CRYPT_OK );
				}
			if( !contextInfoPtr->ctxMAC->keySetupAlgorithm )
				return( exitErrorNotFound( contextInfoPtr,
										   CRYPT_CTXINFO_KEYING_ALGO ) );
			contextInfoPtr->ctxMAC->keySetupAlgorithm = CRYPT_ALGO_NONE;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ITERATIONS:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				{
				if( !contextInfoPtr->ctxConv->keySetupIterations )
					return( exitErrorNotFound( contextInfoPtr,
											   CRYPT_CTXINFO_KEYING_ITERATIONS ) );
				contextInfoPtr->ctxConv->keySetupIterations = 0;
				return( CRYPT_OK );
				}
			if( !contextInfoPtr->ctxMAC->keySetupIterations )
				return( exitErrorNotFound( contextInfoPtr,
										   CRYPT_CTXINFO_KEYING_ITERATIONS ) );
			contextInfoPtr->ctxMAC->keySetupIterations = 0;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_SALT:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				{
				if( !contextInfoPtr->ctxConv->saltLength )
					return( exitErrorNotFound( contextInfoPtr,
											   CRYPT_CTXINFO_KEYING_SALT ) );
				zeroise( contextInfoPtr->ctxConv->salt, CRYPT_MAX_HASHSIZE );
				contextInfoPtr->ctxConv->saltLength = 0;
				return( CRYPT_OK );
				}
			if( !contextInfoPtr->ctxMAC->saltLength )
				return( exitErrorNotFound( contextInfoPtr,
										   CRYPT_CTXINFO_KEYING_SALT ) );
			zeroise( contextInfoPtr->ctxMAC->salt, CRYPT_MAX_HASHSIZE );
			contextInfoPtr->ctxMAC->saltLength = 0;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_IV:
			assert( contextType == CONTEXT_CONV );
			if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
				isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
				return( exitErrorNotFound( contextInfoPtr,
										   CRYPT_CTXINFO_IV ) );
			contextInfoPtr->ctxConv->ivLength = \
					contextInfoPtr->ctxConv->ivCount = 0;
			contextInfoPtr->flags &= ~CONTEXT_IV_SET;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_LABEL:
			if( !contextInfoPtr->labelSize )
				return( exitErrorNotFound( contextInfoPtr,
										   CRYPT_CTXINFO_LABEL ) );
			zeroise( contextInfoPtr->label, contextInfoPtr->labelSize );
			contextInfoPtr->labelSize = 0;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_HASHVALUE:
			assert( contextType == CONTEXT_HASH || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_HASH )
				zeroise( contextInfoPtr->ctxHash->hash, CRYPT_MAX_HASHSIZE );
			else
				zeroise( contextInfoPtr->ctxMAC->mac, CRYPT_MAX_HASHSIZE );
			contextInfoPtr->flags &= ~( CONTEXT_HASH_INITED | \
										CONTEXT_HASH_DONE );
			return( CRYPT_OK );
		}

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

/****************************************************************************
*																			*
*								Context Message Handler						*
*																			*
****************************************************************************/

/* Handle a message sent to an encryption context */

static int contextMessageFunction( const void *objectInfoPtr,
								   const MESSAGE_TYPE message,
								   void *messageDataPtr,
								   const int messageValue )
	{
	CONTEXT_INFO *contextInfoPtr = ( CONTEXT_INFO * ) objectInfoPtr;
	const CAPABILITY_INFO *capabilityInfo = contextInfoPtr->capabilityInfo;
	int status;

	/* Process destroy object messages */
	if( message == MESSAGE_DESTROY )
		{
		const CONTEXT_TYPE contextType = contextInfoPtr->type;

#if 0	/* 9/12/02 We can never get here because we can't send a message to a
				   busy object any more */
		/* If the context is busy, abort the async.operation.  We do this by
		   setting the abort flag (which is OK, since the context is about to
		   be destroyed anyway) and then waiting for the busy flag to be
		   cleared */
		contextInfoPtr->flags |= CONTEXT_ASYNC_ABORT;
		krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, &status,
						 CRYPT_IATTRIBUTE_STATUS );
		if( status & OBJECT_FLAG_BUSY )
			{
			/* Unlock the object so the background thread can access it.
			   Nothing else will get in because the object is in the
			   signalled state */
			unlockResource( contextInfoPtr );

			/* Wait awhile and check whether we've left the busy state */

⌨️ 快捷键说明

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