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

📄 cryptctx.c

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

		case CRYPT_IATTRIBUTE_KEYID:
			assert( contextType == CONTEXT_PKC );
			return( attributeCopy( msgData, contextInfoPtr->ctxPKC->keyID,
								   KEYID_SIZE ) );

		case CRYPT_IATTRIBUTE_KEYID_PGP:
			assert( contextType == CONTEXT_PKC );
			if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
				return( CRYPT_ERROR_NOTFOUND );
			return( attributeCopy( msgData, contextInfoPtr->ctxPKC->pgpKeyID,
								   PGP_KEYID_SIZE ) );

		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 );
			return( attributeCopy( msgData, contextInfoPtr->ctxPKC->openPgpKeyID,
								   PGP_KEYID_SIZE ) );

#ifdef USE_KEA
		case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
			assert( contextType == CONTEXT_PKC );
			return( attributeCopy( msgData, contextInfoPtr->ctxPKC->domainParamPtr,
								   contextInfoPtr->ctxPKC->domainParamSize ) );

		case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
			assert( contextType == CONTEXT_PKC );
			return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicValuePtr,
								   contextInfoPtr->ctxPKC->publicValueSize ) );
#else
		case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
		case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
			return( CRYPT_ERROR_NOTFOUND );
#endif /* USE_KEA */

		case CRYPT_IATTRIBUTE_KEY_SPKI:
			assert( contextType == CONTEXT_PKC );
			assert( contextInfoPtr->flags & CONTEXT_KEY_SET );
			if( contextInfoPtr->ctxPKC->publicKeyInfo != NULL )
				/* If the data is available in pre-encoded form, copy it
				   out */
				return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicKeyInfo,
									   contextInfoPtr->ctxPKC->publicKeyInfoSize ) );
			/* Drop through */

		case CRYPT_IATTRIBUTE_KEY_SSH1:
		case CRYPT_IATTRIBUTE_KEY_SSH2:
			assert( contextType == CONTEXT_PKC );
			assert( contextInfoPtr->flags & CONTEXT_KEY_SET );

			/* Write the appropriately-formatted key data from the context */
			sMemOpen( &stream, msgData->data, msgData->length );
			status = contextInfoPtr->ctxPKC->writePublicKeyFunction( &stream,
						contextInfoPtr,
							( messageValue == CRYPT_IATTRIBUTE_KEY_SPKI ) ? \
								KEYFORMAT_CERT : \
							( messageValue == CRYPT_IATTRIBUTE_KEY_SSH1 ) ? \
								KEYFORMAT_SSH1 : KEYFORMAT_SSH2, "public" );
			if( cryptStatusOK( status ) )
				msgData->length = stell( &stream );
			sMemDisconnect( &stream );
			return( status );

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

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

static int processSetAttribute( CONTEXT_INFO *contextInfoPtr,
								void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	const int value = *( ( int * ) messageDataPtr );
	CRYPT_ALGO_TYPE *algoValuePtr;
	int *valuePtr;
	int status;

	switch( messageValue )
		{
		case CRYPT_CTXINFO_MODE:
			assert( contextType == CONTEXT_CONV );

			/* If the mode isn't set to the initial default, it's already
			   been explicitly set and we can't change it again */
			if( contextInfoPtr->ctxConv->mode != \
						( isStreamCipher( capabilityInfoPtr->cryptAlgo ) ? \
						CRYPT_MODE_OFB : CRYPT_MODE_CBC ) )
				return( exitErrorInited( contextInfoPtr, CRYPT_CTXINFO_MODE ) );

			/* Set the en/decryption mode */
			assert( capabilityInfoPtr->initKeyParamsFunction != NULL );
			return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
													NULL, 0, value ) );

		case CRYPT_CTXINFO_KEYSIZE:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_PKC || \
					contextType == CONTEXT_MAC );
			assert( capabilityInfoPtr->getInfoFunction != NULL );
			if( contextType == CONTEXT_CONV )
				valuePtr = &contextInfoPtr->ctxConv->userKeyLength;
			else
				if( contextType == CONTEXT_MAC )
					valuePtr = &contextInfoPtr->ctxMAC->userKeyLength;
				else
					valuePtr = &contextInfoPtr->ctxPKC->keySizeBits;
			if( *valuePtr )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_KEYSIZE ) );

			/* 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 using short public keys */
			status = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE,
														 contextInfoPtr, value );
			if( cryptStatusError( status ) )
				return( status );
			*valuePtr = ( contextType == CONTEXT_PKC ) ? \
						bytesToBits( status ) : status;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ALGO:
		case CRYPT_OPTION_KEYING_ALGO:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			algoValuePtr = ( contextType == CONTEXT_CONV ) ? \
						   &contextInfoPtr->ctxConv->keySetupAlgorithm : \
						   &contextInfoPtr->ctxMAC->keySetupAlgorithm;
			if( *algoValuePtr != CRYPT_ALGO_NONE )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_KEYING_ALGO ) );
			*algoValuePtr = value;
			return( CRYPT_OK );

		case CRYPT_CTXINFO_KEYING_ITERATIONS:
		case CRYPT_OPTION_KEYING_ITERATIONS:
			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			valuePtr = ( contextType == CONTEXT_CONV ) ? \
					   &contextInfoPtr->ctxConv->keySetupIterations : \
					   &contextInfoPtr->ctxMAC->keySetupIterations;
			if( *valuePtr )
				return( exitErrorInited( contextInfoPtr,
										 CRYPT_CTXINFO_KEYING_ITERATIONS ) );
			*valuePtr = value;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_INITIALISED:
			return( CRYPT_OK );

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

			/* If the key is held outside the context (e.g. in a device), we
			   need to manually supply key-related information needed by the
			   context, which in this case is the key size.  Once this is
			   set, there is (effectively) a key loaded, although the actual
			   keying values are held anderswhere */
			switch( contextType )
				{
				case CONTEXT_CONV:
					contextInfoPtr->ctxConv->userKeyLength = value;
					break;

				case CONTEXT_PKC:
					if( !contextInfoPtr->labelSize )
						/* PKC context must have a key label set */
						return( exitErrorNotInited( contextInfoPtr,
													CRYPT_CTXINFO_LABEL ) );
					contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( value );
					break;

				case CONTEXT_MAC:
					contextInfoPtr->ctxMAC->userKeyLength = value;
					break;

				default:
					assert( NOTREACHED );
				}
			contextInfoPtr->flags |= CONTEXT_KEY_SET;
			return( CRYPT_OK );

		case CRYPT_IATTRIBUTE_DEVICEOBJECT:
#ifdef USE_DEVICES
			contextInfoPtr->deviceObject = value;
#endif /* USE_DEVICES */
			return( CRYPT_OK );
		}

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

static int processSetAttributeS( CONTEXT_INFO *contextInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
	const CONTEXT_TYPE contextType = contextInfoPtr->type;
	const RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	int status;

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

		case CRYPT_CTXINFO_KEYING_VALUE:
			{
			MECHANISM_DERIVE_INFO mechanismInfo;

			assert( contextType == CONTEXT_CONV || \
					contextType == CONTEXT_MAC );
			assert( needsKey( contextInfoPtr ) );

			/* Set up various parameters if they're not already set.  Since
			   there's only one MUST MAC algorithm for PKCS #5v2, we always
			   force the key derivation algorithm to this value to avoid
			   interop problems */
			if( contextType == CONTEXT_CONV )
				{
				if( !contextInfoPtr->ctxConv->saltLength )
					{
					RESOURCE_DATA nonceMsgData;

					setMessageData( &nonceMsgData, contextInfoPtr->ctxConv->salt,
									PKCS5_SALT_SIZE );
					status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
											  IMESSAGE_GETATTRIBUTE_S,
											  &nonceMsgData,
											  CRYPT_IATTRIBUTE_RANDOM_NONCE );
					if( cryptStatusError( status ) )
						return( status );
					contextInfoPtr->ctxConv->saltLength = PKCS5_SALT_SIZE;
					}
				contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
				setMechanismDeriveInfo( &mechanismInfo,
					contextInfoPtr->ctxConv->userKey,
						capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE, 
										contextInfoPtr,
										contextInfoPtr->ctxConv->userKeyLength ),
					msgData->data, msgData->length,
					contextInfoPtr->ctxConv->keySetupAlgorithm,
					contextInfoPtr->ctxConv->salt, contextInfoPtr->ctxConv->saltLength,
					contextInfoPtr->ctxConv->keySetupIterations );
				}
			else
				{
				if( !contextInfoPtr->ctxMAC->saltLength )
					{
					RESOURCE_DATA nonceMsgData;

					setMessageData( &nonceMsgData, contextInfoPtr->ctxMAC->salt,
									PKCS5_SALT_SIZE );
					status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
											  IMESSAGE_GETATTRIBUTE_S,
											  &nonceMsgData,
											  CRYPT_IATTRIBUTE_RANDOM_NONCE );
					if( cryptStatusError( status ) )
						return( status );
					contextInfoPtr->ctxMAC->saltLength = PKCS5_SALT_SIZE;
					}
				contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_HMAC_SHA;
				setMechanismDeriveInfo( &mechanismInfo,
					contextInfoPtr->ctxMAC->userKey,
						capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_KEYSIZE, 
										contextInfoPtr,
										contextInfoPtr->ctxMAC->userKeyLength ),
					msgData->data, msgData->length,
					contextInfoPtr->ctxConv->keySetupAlgorithm,
					contextInfoPtr->ctxMAC->salt, contextInfoPtr->ctxMAC->saltLength,
					contextInfoPtr->ctxMAC->keySetupIterations );
				}
			if( !mechanismInfo.iterations )
				{
				krnlSendMessage( contextInfoPtr->ownerHandle,
							IMESSAGE_GETATTRIBUTE, &mechanismInfo.iterations,
							CRYPT_OPTION_KEYING_ITERATIONS );
				if( contextType == CONTEXT_CONV )
					contextInfoPtr->ctxConv->keySetupIterations = \
												mechanismInfo.iterations;
				else
					contextInfoPtr->ctxMAC->keySetupIterations = \
												mechanismInfo.iterations;
				}

			/* Turn the user key into an encryption context key and load the
			   key into the context */
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  IMESSAGE_DEV_DERIVE, &mechanismInfo,
									  MECHANISM_PKCS5 );
			if( cryptStatusOK( status ) )
				status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
											mechanismInfo.dataOut,
											mechanismInfo.dataOutLength );
			if( cryptStatusOK( status ) )
				{
				contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL;
				if( contextType == CONTEXT_MAC )
					contextInfoPtr->flags |= CONTEXT_HASH_INITED;
				}
			return( status );
			}

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

			/* 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 */
			status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
										msgData->data, msgData->length );
			if( cryptStatusOK( status ) )
				{
				contextInfoPtr->flags |= CONTEXT_KEY_SET | CONTEXT_EPHEMERAL;
				if( contextType == CONTEXT_MAC )
					contextInfoPtr->flags |= CONTEXT_HASH_INITED;
				}

⌨️ 快捷键说明

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