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

📄 cryptenv.c

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

	/* If we're querying something which resides in the content list, make
	   sure there's a content list present.  If it's present but nothing is
	   selected, select the first entry */
	if( messageValue == CRYPT_ENVINFO_PRIVATEKEY_LABEL && \
		envelopeInfoPtr->contentListCurrent == NULL )
		{
		if( envelopeInfoPtr->contentList == NULL )
			return( CRYPT_ERROR_NOTFOUND );
		envelopeInfoPtr->contentListCurrent = envelopeInfoPtr->contentList;
		}

	/* Generic attributes are valid for all envelope types */
	if( messageValue == CRYPT_ENVINFO_PRIVATEKEY_LABEL )
		{
		MESSAGE_KEYMGMT_INFO getkeyInfo;
		char label[ CRYPT_MAX_TEXTSIZE ];

		/* Make sure that the current required resource is a private key and
		   that there's a keyset available to pull the key from */
		contentListItem = envelopeInfoPtr->contentListCurrent;
		if( contentListItem->envInfo != CRYPT_ENVINFO_PRIVATEKEY )
			return( CRYPT_ERROR_NOTFOUND );
		if( envelopeInfoPtr->iDecryptionKeyset == CRYPT_ERROR )
			{
			setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_KEYSET_DECRYPT,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			return( CRYPT_ERROR_NOTINITED );
			}

		/* Try and get the key label information.  Since we're accessing the 
		   key by (unique) key ID, there's no real need to specify a 
		   preference for encryption keys */
		if( contentListItem->issuerAndSerialNumber == NULL )
			{
			setMessageKeymgmtInfo( &getkeyInfo, 
								   ( contentListItem->formatType == CRYPT_FORMAT_PGP ) ? \
								   CRYPT_IKEYID_PGPKEYID : CRYPT_IKEYID_KEYID, 
								   contentListItem->keyID,
								   contentListItem->keyIDsize,
								   label, CRYPT_MAX_TEXTSIZE,
								   KEYMGMT_FLAG_LABEL_ONLY );
			}
		else
			{
			setMessageKeymgmtInfo( &getkeyInfo, 
								   CRYPT_IKEYID_ISSUERANDSERIALNUMBER,
								   contentListItem->issuerAndSerialNumber,
								   contentListItem->issuerAndSerialNumberSize,
								   label, CRYPT_MAX_TEXTSIZE,
								   KEYMGMT_FLAG_LABEL_ONLY );
			}
		status = krnlSendMessage( envelopeInfoPtr->iDecryptionKeyset,
								  RESOURCE_IMESSAGE_KEY_GETKEY, &getkeyInfo, 
								  KEYMGMT_ITEM_PRIVATEKEY );
		if( cryptStatusOK( status ) )
			return( attributeCopy( messageDataPtr, getkeyInfo.auxInfo,
								   getkeyInfo.auxInfoLength ) );
		return( status );
		}

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

static int processSetAttribute( ENVELOPE_INFO *envelopeInfoPtr,
								void *messageDataPtr, const int messageValue )
	{
	RESOURCE_MESSAGE_CHECK_TYPE checkType = RESOURCE_MESSAGE_CHECK_NONE;
	OBJECT_TYPE objectType = OBJECT_TYPE_CONTEXT;
	ACTION_TYPE usage = ACTION_NONE;
	const int value = *( int * ) messageDataPtr;
	int status;

	/* If it's an initialisation message, there's nothing to do */
	if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
		return( CRYPT_OK );

	/* Generic attributes are valid for all envelope types */
	if( messageValue == CRYPT_ATTRIBUTE_BUFFERSIZE )
		{
		envelopeInfoPtr->bufSize = value;
		return( CRYPT_OK );
		}

	/* In general we can't add new enveloping information once we've started
	   processing data */
	if( messageValue != CRYPT_ENVINFO_CURRENT_COMPONENT && \
		envelopeInfoPtr->state != STATE_PREDATA )
		{
		/* We can't add new information once we've started enveloping */
		if( !( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) )
			return( CRYPT_ERROR_INITED );

		/* We can only add signature check information once we've started
		   de-enveloping */
		if( messageValue != CRYPT_ENVINFO_SIGNATURE )
			return( CRYPT_ERROR_INITED );
		}

	/* If we're de-enveloping PGP data, make sure the attribute is valid for
	   PGP envelopes.  We can't perform this check via the ACLs because the
	   data type isn't known at envelope creation time, so there's a single
	   generic de-envelope type for which the ACLs allow the union of all
	   de-enveloping attribute types.  The following check weeds out the ones
	   which don't work for PGP */
	if( ( envelopeInfoPtr->type == CRYPT_FORMAT_PGP ) && \
		( messageValue == CRYPT_ENVINFO_MAC || \
		  messageValue == CRYPT_ENVINFO_KEY || \
		  messageValue == CRYPT_ENVINFO_SESSIONKEY || \
		  messageValue == CRYPT_ENVINFO_HASH ) )
		return( CRYPT_ARGERROR_VALUE );

	/* Since the information may not be used for quite some time after it's
	   added, we do some preliminary checking here to allow us to return an
	   error code immediately rather than from some deeply-buried function an
	   indeterminate time in the future */
	switch( messageValue )
		{
		case CRYPT_ENVINFO_DATASIZE:
			if( envelopeInfoPtr->payloadSize != CRYPT_UNUSED )
				return( CRYPT_ERROR_INITED );
			break;

#ifndef NO_COMPRESSION
		case CRYPT_ENVINFO_COMPRESSION:
			if( envelopeInfoPtr->usage != ACTION_NONE )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_COMPRESS;
			break;
#endif /* NO_COMPRESSION */

		case CRYPT_ENVINFO_CONTENTTYPE:
			if( envelopeInfoPtr->type == CRYPT_FORMAT_SMIME )
				return( CRYPT_ARGERROR_VALUE );

			/* Exactly what is supposed to happen when PGP is asked to sign 
			   non-plain-data is ill-defined.  No command-line PGP option 
			   will generate this type of message, and the RFCs don't specify
			   the behaviour (in fact RFC 1991's description of PGP signing 
			   is completely wrong).  In practice PGP hashes and signs the 
			   payload contents of a PGP literal data packet, however if 
			   there are extra layers of processing between the signing and 
			   literal packets (eg compression or encryption), what gets 
			   hashed isn't specified.  If it's always the payload of the 
			   final (literal) data packet, we'd have to be able to burrow 
			   down through arbitrary amounts of further data and processing 
			   in order to get to the payload data to hash (this also makes
			   things like mail gateways which only allow signed messages
			   through infeasible unless the gateway holds everyone's private
			   key in able to get at the plaintext to hash).  Because of this 
			   problem, we disallow any attempts to set a content-type other 
			   than plain data if we're signing a PGP-format message */
			if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP && \
				envelopeInfoPtr->usage == ACTION_SIGN && \
				value != CRYPT_CONTENT_DATA )
				return( CRYPT_ARGERROR_VALUE );

			/* For user-friendliness we allow overwriting a given content
			   type with the same type, which is useful for cases when
			   cryptlib automatically presets the type based on other
			   information */
			if( envelopeInfoPtr->contentType && \
				envelopeInfoPtr->contentType != value )
				return( CRYPT_ERROR_INITED );
			break;

		case CRYPT_ENVINFO_DETACHEDSIGNATURE:
		case CRYPT_IATTRIBUTE_INCLUDESIGCERT:
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_SIGN )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_SIGN;
			break;

		case CRYPT_ENVINFO_MAC:
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_MAC )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_MAC;
			break;

		case CRYPT_ENVINFO_CURRENT_COMPONENT:
			break;

		case CRYPT_ENVINFO_KEY:
			checkType = RESOURCE_MESSAGE_CHECK_CRYPT;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_CRYPT )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_CRYPT;
			break;

		case CRYPT_ENVINFO_SESSIONKEY:
			checkType = RESOURCE_MESSAGE_CHECK_CRYPT;
			if( !( envelopeInfoPtr->usage == ACTION_NONE || \
				   ( ( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) && \
					 envelopeInfoPtr->usage == ACTION_CRYPT ) ) )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_CRYPT;
			break;

		case CRYPT_ENVINFO_SIGNATURE:
			checkType = \
					( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) ? \
						RESOURCE_MESSAGE_CHECK_PKC_SIGCHECK : \
						RESOURCE_MESSAGE_CHECK_PKC_SIGN;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_SIGN )
				return( CRYPT_ERROR_INITED );
			if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP && \
				envelopeInfoPtr->contentType == CRYPT_CONTENT_DATA )
				/* See the long comment for CRYPT_ENVINFO_CONTENTTYPE */
				return( CRYPT_ARGERROR_VALUE );
			usage = ACTION_SIGN;
			break;

		case CRYPT_ENVINFO_SIGNATURE_EXTRADATA:
			if( envelopeInfoPtr->type != CRYPT_FORMAT_CMS && \
				envelopeInfoPtr->type != CRYPT_FORMAT_SMIME )
				return( CRYPT_ARGERROR_VALUE );
			else
				if( envelopeInfoPtr->usage != ACTION_SIGN )
					return( CRYPT_ERROR_NOTINITED );
			break;

		case CRYPT_ENVINFO_PUBLICKEY:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_ENCRYPT;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_CRYPT )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_CRYPT;
			break;

		case CRYPT_ENVINFO_PRIVATEKEY:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_DECRYPT;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_CRYPT )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_CRYPT;
			break;

		case CRYPT_ENVINFO_ORIGINATOR:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_KA_EXPORT;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_CRYPT )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_CRYPT;
			if( envelopeInfoPtr->iOriginatorChain != CRYPT_ERROR )
				return( CRYPT_ERROR_INITED );
			break;

		case CRYPT_ENVINFO_HASH:
			checkType = RESOURCE_MESSAGE_CHECK_HASH;
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_SIGN )
				return( CRYPT_ERROR_INITED );
			usage = ACTION_SIGN;
			break;

		case CRYPT_ENVINFO_KEYSET_ENCRYPT:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_ENCRYPT;
			objectType = OBJECT_TYPE_KEYSET;
			if( envelopeInfoPtr->iEncryptionKeyset != CRYPT_ERROR )
				return( CRYPT_ERROR_INITED );
			break;

		case CRYPT_ENVINFO_KEYSET_DECRYPT:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_DECRYPT;
			objectType = OBJECT_TYPE_KEYSET;
			if( envelopeInfoPtr->iDecryptionKeyset != CRYPT_ERROR )
				return( CRYPT_ERROR_INITED );
			break;

		case CRYPT_ENVINFO_KEYSET_SIGCHECK:
			checkType = RESOURCE_MESSAGE_CHECK_PKC_SIGCHECK;
			objectType = OBJECT_TYPE_KEYSET;
			if( envelopeInfoPtr->iSigCheckKeyset != CRYPT_ERROR )
				return( CRYPT_ERROR_INITED );
			break;

		default:
			assert( NOTREACHED );
		}
	if( checkType != RESOURCE_MESSAGE_CHECK_NONE )
		{
		int type, status;

		/* Check the object as appropriate.  A key agreement key can also act
		   as a public key because of the way KEA works, so if a check for a
		   straight public key fails we try again to see if it's a key
		   agreement key with import capabilities */
		status = krnlSendMessage( value, RESOURCE_IMESSAGE_CHECK, NULL,
								  checkType );
		if( status == CRYPT_ARGERROR_OBJECT && \
			messageValue == CRYPT_ENVINFO_PUBLICKEY )
			status = krnlSendMessage( value, RESOURCE_IMESSAGE_CHECK, NULL,
									  RESOURCE_MESSAGE_CHECK_PKC_KA_IMPORT );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_NUM1 );

		/* Make sure the object corresponds to a representable algorithm
		   type */
		if( checkType == RESOURCE_MESSAGE_CHECK_CRYPT ||
			checkType == RESOURCE_MESSAGE_CHECK_HASH )
			{
			CRYPT_ALGO algorithm;

			krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE, &algorithm,
							 CRYPT_CTXINFO_ALGO );
			if( checkType == RESOURCE_MESSAGE_CHECK_CRYPT )
				{
				CRYPT_MODE mode;

				krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE, &mode,
								 CRYPT_CTXINFO_MODE );
				status = envelopeInfoPtr->checkCryptAlgo( algorithm, mode );
				}
			else
				status = envelopeInfoPtr->checkHashAlgo( algorithm );
			if( cryptStatusError( status ) )
				return( CRYPT_ERROR_NOTAVAIL );
			}

		/* Make sure the object is of the correct type */
		status = krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE,
								  &type, CRYPT_IATTRIBUTE_TYPE );
		if( cryptStatusError( status ) )
			return( status );
		if( messageValue == CRYPT_ENVINFO_SIGNATURE || \
			messageValue == CRYPT_ENVINFO_PUBLICKEY || \
			messageValue == CRYPT_ENVINFO_PRIVATEKEY || \
			messageValue == CRYPT_ENVINFO_ORIGINATOR )
			{
			/* Public-key objects can be encryption contexts or certificates */
			if( type != objectType && type != OBJECT_TYPE_CERTIFICATE )
				return( CRYPT_ARGERROR_NUM1 );

			/* If we're using CMS enveloping, the object must have an 
			   initialised cert of the correct type associated with it */
			if( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
				envelopeInfoPtr->type == CRYPT_FORMAT_SMIME )
				{
				int inited, certType;

				status = krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE, 
										  &inited, CRYPT_CERTINFO_IMMUTABLE );
				if( cryptStatusError( status ) || !inited )
					return( CRYPT_ARGERROR_NUM1 );
				status = krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE,
										  &certType, CRYPT_CERTINFO_CERTTYPE );
				if( cryptStatusError( status ) ||
					( certType != CRYPT_CERTTYPE_CERTIFICATE && \
					  certType != CRYPT_CERTTYPE_CERTCHAIN ) )
					return( CRYPT_ARGERROR_NUM1 );
				}
			}
		else
			if( type != objectType && \
				( objectType == OBJECT_TYPE_KEYSET && \
				  type != OBJECT_TYPE_DEVICE ) )
				return( CRYPT_ARGERROR_NUM1 );
		}
	else
		/* If it's additional signature information, make sure the object is
		   CMS attributes */
		if( messageValue == CRYPT_ENVINFO_SIGNATURE_EXTRADATA )
			{
			int certType, status;

			status = krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE,
									  &certType, CRYPT_CERTINFO_CERTTYPE );
			if( cryptStatusError( status ) ||
				certType != CRYPT_CERTTYPE_CMS_ATTRIBUTES )
				return( CRYPT_ARGERROR_NUM1 );
			}

	/* If it's meta-information, process it now */
	if( messageValue == CRYPT_ENVINFO_CURRENT_COMPONENT )
		return( moveCursor( envelopeInfoPtr, value ) );

	/* Add it to the envelope */
	status = envelopeInfoPtr->addInfo( envelopeInfoPtr, messageValue,
									   &value, 0 );
	if( cryptStatusOK( status ) && usage != ACTION_NONE )
		/* The action was successfully added, update the usage if 
		   necessary */
		envelopeInfoPtr->usage = usage;
	return( status );
	}

static int processSetAttributeS( ENVELOPE_INFO *envelopeInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	MESSAGE_KEYMGMT_INFO getkeyInfo;
	ACTION_TYPE usage = ACTION_NONE;
	int status;

	/* Handle the various information types */
	switch( messageValue )
		{
		case CRYPT_ENVINFO_PASSWORD:
			/* Set the envelope usage type based on the fact that we've been
			   fed a password */
			if( envelopeInfoPtr->usage == ACTION_NONE )
				usage = ACTION_CRYPT;
			else		
				if( envelopeInfoPtr->usage != ACTION_CRYPT && \
					envelopeInfoPtr->usage != ACTION_MAC )
					return( CRYPT_ERROR_INITED );

⌨️ 快捷键说明

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