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

📄 crypt.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
			return( status );

		case CRYPT_IATTRIBUTE_SSH2_PUBLICKEY:
			assert( contextType == CONTEXT_PKC );

			/* Write the SSHv2-format key data from the context */
			sMemOpen( &stream, msgData->data, msgData->length );
			status = writeSsh2PublicKey( &stream, cryptInfoPtr );
			if( cryptStatusOK( status ) )
				msgData->length = stell( &stream );
			sMemDisconnect( &stream );
			return( status );
		}

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

static int processSetAttribute( CRYPT_INFO *cryptInfoPtr,
								void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = cryptInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = cryptInfoPtr->type;
	const int *valuePtr = ( int * ) messageDataPtr;
	int ( *cryptFunction )( CRYPT_INFO *cryptInfoPtr, void *buffer,
							int length ) = NULL;
	int status;

	switch( messageValue )
		{
		case CRYPT_CTXINFO_MODE:
			assert( contextType == CONTEXT_CONV );
			switch( *valuePtr )
				{
				case CRYPT_MODE_ECB:
					cryptFunction = capabilityInfoPtr->encryptFunction;
					break;
				case CRYPT_MODE_CBC:
					cryptFunction = capabilityInfoPtr->encryptCBCFunction;
					break;
				case CRYPT_MODE_CFB:
					cryptFunction = capabilityInfoPtr->encryptCFBFunction;
					break;
				case CRYPT_MODE_OFB:
					cryptFunction = capabilityInfoPtr->encryptOFBFunction;
					break;
				default:
					assert( NOTREACHED );
				}
			if( cryptFunction == NULL )
				return( CRYPT_ERROR_NOTAVAIL );
			cryptInfoPtr->ctxConv.mode = *valuePtr;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYSIZE:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_PKC || \
					contextType == CONTEXT_MAC );

			/* Trim the user-supplied value to the correct shape, taking 
			   into account various issues such as limitations with the
			   underlying crypto code/hardware and the (in)ability to export 
			   overly long keys with short public keys */
			status = getOptimalKeysize( cryptInfoPtr, *valuePtr );
			if( cryptStatusError( status ) )
				return( status );
			if( contextType == CONTEXT_CONV )
				cryptInfoPtr->ctxConv.userKeyLength = status;
			else
				if( contextType == CONTEXT_MAC )
					cryptInfoPtr->ctxMAC.userKeyLength = status;
				else
					cryptInfoPtr->ctxPKC.keySizeBits = bytesToBits( status );
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ALGO:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				cryptInfoPtr->ctxConv.keySetupAlgorithm = *valuePtr;
			else
				cryptInfoPtr->ctxMAC.keySetupAlgorithm = *valuePtr;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ITERATIONS:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				cryptInfoPtr->ctxConv.keySetupIterations = *valuePtr;
			else
				cryptInfoPtr->ctxMAC.keySetupIterations = *valuePtr;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_INITIALISED:
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_KEYSIZE:
			if( contextType == CONTEXT_CONV )
				{
				cryptInfoPtr->ctxConv.keySet = TRUE;
				cryptInfoPtr->ctxConv.keyLength = *valuePtr;
				return( CRYPT_OK );
				}
			if( contextType == CONTEXT_PKC )
				{
				if( !cryptInfoPtr->labelSize )
					/* PKC context must have a key label set */
					return( exitNotInited( cryptInfoPtr,
							CRYPT_CTXINFO_LABEL ) );
				cryptInfoPtr->ctxPKC.keySet = TRUE;
				cryptInfoPtr->ctxPKC.keySizeBits = bytesToBits( *valuePtr );
				return( CRYPT_OK );
				}
			if( contextType == CONTEXT_MAC )
				{
				cryptInfoPtr->ctxMAC.keySet = TRUE;
				cryptInfoPtr->ctxMAC.userKeyLength = *valuePtr;
				return( CRYPT_OK );
				}
			assert( NOTREACHED );

		case CRYPT_IATTRIBUTE_DEVICEOBJECT:
			cryptInfoPtr->deviceObject = *valuePtr;
			return( CRYPT_OK );
		}

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

static int processSetAttributeS( CRYPT_INFO *cryptInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = cryptInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = cryptInfoPtr->type;
	const RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	MECHANISM_DERIVE_INFO mechanismInfo;
	STREAM stream;
	int status;

	switch( messageValue )
		{
		case CRYPT_CTXINFO_KEYING_SALT:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			if( contextType == CONTEXT_CONV )
				{
				if( cryptInfoPtr->ctxConv.saltLength )
					{
					setErrorInfo( cryptInfoPtr, CRYPT_CTXINFO_KEYING_SALT,
								  CRYPT_ERRTYPE_ATTR_PRESENT );
					return( CRYPT_ERROR_INITED );
					}
				memcpy( cryptInfoPtr->ctxConv.salt, msgData->data,
						msgData->length );
				cryptInfoPtr->ctxConv.saltLength = msgData->length;
				return( CRYPT_OK );
				}
			if( cryptInfoPtr->ctxMAC.saltLength )
				{
				setErrorInfo( cryptInfoPtr, CRYPT_CTXINFO_KEYING_SALT,
							  CRYPT_ERRTYPE_ATTR_PRESENT );
				return( CRYPT_ERROR_INITED );
				}
			memcpy( cryptInfoPtr->ctxMAC.salt, msgData->data,
					msgData->length );
			cryptInfoPtr->ctxMAC.saltLength = msgData->length;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_VALUE:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			assert( needsKey( cryptInfoPtr ) );

			/* Set up various parameters if they're not already set */
			if( contextType == CONTEXT_CONV )
				{
				if( !cryptInfoPtr->ctxConv.saltLength )
					{
					getNonce( cryptInfoPtr->ctxConv.salt, PKCS5_SALT_SIZE );
					cryptInfoPtr->ctxConv.saltLength = PKCS5_SALT_SIZE;
					}
				setMechanismDeriveInfo( &mechanismInfo,
					cryptInfoPtr->ctxConv.userKey,
						getOptimalKeysize( cryptInfoPtr, 0 ),
					msgData->data, msgData->length, CRYPT_ALGO_SHA,
					cryptInfoPtr->ctxConv.salt, cryptInfoPtr->ctxConv.saltLength,
					cryptInfoPtr->ctxConv.keySetupIterations );
				cryptInfoPtr->ctxConv.keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
				}
			else
				{
				if( !cryptInfoPtr->ctxMAC.saltLength )
					{
					getNonce( cryptInfoPtr->ctxMAC.salt, PKCS5_SALT_SIZE );
					cryptInfoPtr->ctxMAC.saltLength = PKCS5_SALT_SIZE;
					}
				setMechanismDeriveInfo( &mechanismInfo,
					cryptInfoPtr->ctxMAC.userKey,
						getOptimalKeysize( cryptInfoPtr, 0 ),
					msgData->data, msgData->length, CRYPT_ALGO_SHA,
					cryptInfoPtr->ctxMAC.salt, cryptInfoPtr->ctxMAC.saltLength,
					cryptInfoPtr->ctxMAC.keySetupIterations );
				cryptInfoPtr->ctxMAC.keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
				}
			if( !mechanismInfo.iterations )
				{
				krnlSendMessage( cryptInfoPtr->ownerHandle,
					RESOURCE_IMESSAGE_GETATTRIBUTE, &mechanismInfo.iterations,
					CRYPT_OPTION_KEYING_ITERATIONS );
				if( contextType == CONTEXT_CONV )
					cryptInfoPtr->ctxConv.keySetupIterations = \
												mechanismInfo.iterations;
				else
					cryptInfoPtr->ctxMAC.keySetupIterations = \
												mechanismInfo.iterations;
				}

			/* Turn the user key into an encryption context key */
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  RESOURCE_IMESSAGE_DEV_DERIVE,
									  &mechanismInfo, MECHANISM_PKCS5 );
			if( cryptStatusError( status ) )
				return( status );

			/* Load the key into the context */
			return( loadKey( cryptInfoPtr, mechanismInfo.dataOut,
							 mechanismInfo.dataOutLength ) );

		case CRYPT_CTXINFO_KEY:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			assert( needsKey( cryptInfoPtr ) );

			/* The kernel performs a general check on the size of this
			   attribute but doesn't know about context-subtype-specific
			   limits so we perform a context-specific check here */
			if( msgData->length < capabilityInfoPtr->minKeySize || \
				msgData->length > capabilityInfoPtr->maxKeySize )
				return( CRYPT_ARGERROR_NUM1 );

			/* Load the key into the context */
			return( loadKey( cryptInfoPtr, msgData->data, msgData->length ) );

		case CRYPT_CTXINFO_KEY_COMPONENTS:
			assert( contextType == CONTEXT_PKC );
			assert( needsKey( cryptInfoPtr ) );

			/* Make sure the supplied key data is valid */
			if( msgData->length != sizeof( CRYPT_PKCINFO_RSA ) && \
				msgData->length != sizeof( CRYPT_PKCINFO_DLP ) && \
				msgData->length != sizeof( PKCINFO_LOADINTERNAL ) )
				return( CRYPT_ARGERROR_NUM1 );

			/* We need to have a key label set before we can continue, 
			   however if we're creating a public-key context through an 
			   internal read (for example as part of importing a cert) there 
			   won't be one available so we don't require a label for 
			   internal loads of public keys */
			if( !cryptInfoPtr->labelSize && \
				msgData->length != sizeof( PKCINFO_LOADINTERNAL ) )
				return( exitNotInited( cryptInfoPtr, CRYPT_CTXINFO_LABEL ) );

			/* Load the key into the context */
			return( loadKey( cryptInfoPtr, msgData->data, msgData->length ) );

		case CRYPT_CTXINFO_IV:
			assert( contextType == CONTEXT_CONV );

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

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

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

		case CRYPT_CTXINFO_LABEL:
			if( cryptInfoPtr->labelSize )
				{
				setErrorInfo( cryptInfoPtr, CRYPT_CTXINFO_LABEL,
							  CRYPT_ERRTYPE_ATTR_PRESENT );
				return( CRYPT_ERROR_INITED );
				}

			/* Check any device object the context is associated with to 
			   make sure 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 which depends 
			   on the device (at context creation, on key load/generation, or 
			   at some other point).  Because of this we perform a preemptive 
			   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( cryptInfoPtr->objectHandle,
										  RESOURCE_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( cryptInfoPtr->objectHandle,
									RESOURCE_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( cryptInfoPtr->objectHandle,
									RESOURCE_MESSAGE_KEY_GETKEY, &getkeyInfo, 
									KEYMGMT_ITEM_PRIVATEKEY );
						}
					if( cryptStatusOK( status ) )
						/* We found something with this label, we can't use 
						   it again */
						return( CRYPT_ERROR_DUPLICATE );
					}
				}

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

		case CRYPT_IATTRIBUTE_OPENPGP_KEYID:
			assert( contextType == CONTEXT_PKC );
			assert( cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
					cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
					cryptInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );

⌨️ 快捷键说明

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