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

📄 ext_chk.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
				return( status );

			/* If the fields are fixed-value we always move on to the next
			   entry since there are no user-supplied parameters present */
			endOfAttributeField = TRUE;
			}

		attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
		if( endOfAttributeField )
			{
			/* If this is all that needs to be encoded move on to the next
			   attribute field */
			if( attributeListPtr == NULL )
				attributeCheckInfo->attributeListPtr = NULL;
			else
				attributeCheckInfo->attributeListPtr = attributeListPtr->next;
			}
		return( CRYPT_OK );
		}

	/* If it's a SEQUENCE/SET or a non-encoding value then it's a no-op entry
	   used only for encoding purposes and can be skipped, however we need to
	   remember it for later encoding */
	if( attributeInfoPtr->fieldType == BER_SEQUENCE || \
		attributeInfoPtr->fieldType == BER_SET || \
		attributeInfoPtr->flags & FL_NONENCODING )
		{
		/* Stack the sequence or value start position in the attribute list */
		return( stackInfo( attributeCheckInfo, attributeListPtr, 
						   attributeInfoPtr ) );
		}

	/* If it's a non-optional field and the attribute field doesn't match,
	   it's an error - attribute attributeID is missing field
	   attributeInfoPtr->fieldID (optional subfield
	   attributeInfoPtr->subFieldID) (set by the error handler in the calling
	   code) */
	if( !( attributeInfoPtr->flags & FL_OPTIONAL ) )
		{
		attributeCheckInfo->errorType = CRYPT_ERRTYPE_ATTR_ABSENT;
		return( CRYPT_ERROR_NOTINITED );
		}

	return( CRYPT_OK );
	}

/* Check an individual attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int checkAttribute( INOUT_ARRAY( ATTRIBUTE_CHECK_INFO ) \
								ATTRIBUTE_CHECK_INFO *attributeCheckInfo )
	{
	ATTRIBUTE_LIST *restartEntry = NULL;
	ATTRIBUTE_INFO *restartPoint = NULL;
	int restartStackPos = 0, iterationCount = 0;
	BOOLEAN attributeContinues;

	assert( isWritePtr( attributeCheckInfo, \
						sizeof( ATTRIBUTE_CHECK_INFO ) ) );

	/* Step through the attribute comparing the fields that are present in
	   the attribute list with the fields that should be present according
	   to the table and set encoding synchronisation points as required */
	do
		{
		int status;

		/* Sanity check to make sure that we don't fall off the end of the 
		   encoding table */
		ENSURES( attributeCheckInfo->attributeInfoPtr->fieldID != CRYPT_ERROR );

		/* Check whether this is a repeated instance of the same attribute
		   and if it is remember the encoding restart point.  We have to do
		   this before we check the attribute info because it usually
		   updates the info after the check */
		if( restartEntry == NULL && \
			attributeCheckInfo->attributeListPtr != NULL && \
			attributeCheckInfo->attributeListPtr->next != NULL && \
			( attributeCheckInfo->attributeListPtr->fieldID == \
			  attributeCheckInfo->attributeListPtr->next->fieldID ) && \
			( attributeCheckInfo->attributeListPtr->subFieldID == \
			  attributeCheckInfo->attributeListPtr->next->subFieldID ) )
			{
			restartEntry = attributeCheckInfo->attributeListPtr;
			restartPoint = attributeCheckInfo->attributeInfoPtr + 1;
			restartStackPos = attributeCheckInfo->stackPos + 1;
			}

		/* Check the current encoding table entry */
		status = checkAttributeEntry( attributeCheckInfo );
		if( status != OK_SPECIAL )
			{
			if( cryptStatusError( status ) )
				{
				attributeCheckInfo->errorLocus = \
							attributeCheckInfo->attributeInfoPtr->fieldID;
				return( status );
				}

			/* If this is the end of a constructed item unstack it and
			   update the attribute list entry with the length information.
			   If it's a sequence with all fields optional (so that nothing
			   gets encoded) we don't do anything */
			status = updateStackedInfo( attributeCheckInfo->stack,
										attributeCheckInfo->stackPos,
										&attributeCheckInfo->stackPos,
				decodeNestingLevel( attributeCheckInfo->attributeInfoPtr->flags ),
										TRUE );
			if( cryptStatusError( status ) )
				return( status );
			}

		/* If there's another instance of the same item, don't move on to
		   the next table entry */
		if( restartEntry != NULL && \
			restartEntry != attributeCheckInfo->attributeListPtr )
			{
#if 0
			/* Currently we don't allow the creation of multivalued
			   instances of fields although we can read certificates that 
			   contain them */
			retIntError();
#endif /* 0 */

			/* Restart at the table entry for the previous instance of the 
			   item and adjust the stack to match */
			attributeCheckInfo->attributeInfoPtr = restartPoint;
			attributeContinues = TRUE;
			if( attributeCheckInfo->stackPos > restartStackPos )
				{
				status = updateStackedInfo( attributeCheckInfo->stack,
											attributeCheckInfo->stackPos,
											&attributeCheckInfo->stackPos,
											attributeCheckInfo->stackPos - \
												restartStackPos, TRUE );
				if( cryptStatusError( status ) )
					return( status );
				}
			restartEntry = NULL;
			restartPoint = NULL;
			restartStackPos = 0;

			continue;
			}

		/* Move on to the next table entry.  We have to check the
		   continuation flag before we move to the next table entry in order
		   to include processing of the last field in an attribute */
		attributeContinues = \
				( attributeCheckInfo->attributeInfoPtr->flags & FL_MORE ) ? \
				TRUE : FALSE;
		attributeCheckInfo->attributeInfoPtr++;
		}
	while( attributeContinues && \
		   iterationCount++ < FAILSAFE_ITERATIONS_LARGE );
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
	attributeCheckInfo->choiceState = CHOICE_NONE;
	
	/* We've reached the end of the attribute, if there are still constructed
	   objects stacked, unstack them and update their length information.  If
	   it's a sequence with all fields optional (so that nothing gets
	   encoded) we don't do anything */
	return( updateStackedInfo( attributeCheckInfo->stack, 
							   attributeCheckInfo->stackPos,
							   &attributeCheckInfo->stackPos,
							   attributeCheckInfo->stackPos - \
									attributeCheckInfo->stackTop, FALSE ) );
	}

/* Check the entire list of attributes */

CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3, 4 ) ) \
int checkAttributes( IN_ENUM( ATTRIBUTE ) const ATTRIBUTE_TYPE attributeType,
					 const ATTRIBUTE_LIST *listHeadPtr,
					 OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
						CRYPT_ATTRIBUTE_TYPE *errorLocus,
					 OUT_ENUM_OPT( CRYPT_ERRTYPE ) \
						CRYPT_ERRTYPE_TYPE *errorType )
	{
	ATTRIBUTE_CHECK_INFO attributeCheckInfo;
	const ATTRIBUTE_INFO *attributeInfoStartPtr = \
							selectAttributeInfo( attributeType );
	ATTRIBUTE_LIST *attributeListPtr;
	int iterationCount;

	assert( isReadPtr( listHeadPtr, sizeof( ATTRIBUTE_LIST ) ) );
	assert( isWritePtr( errorLocus, sizeof( CRYPT_ATTRIBUTE_TYPE ) ) );
	assert( isWritePtr( errorType, sizeof( CRYPT_ERRTYPE_TYPE ) ) );

	REQUIRES( attributeType == ATTRIBUTE_CERTIFICATE || \
			  attributeType == ATTRIBUTE_CMS );
	REQUIRES( attributeInfoStartPtr != NULL );

	/* If we've already done a validation pass some of the fields will
	   contain values that were previously set so before we begin we walk
	   down the list resetting the fields that are updated by this
	   function */
	for( attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr, \
			iterationCount = 0;
		 attributeListPtr != NULL && \
			isValidAttributeField( attributeListPtr ) && \
			iterationCount < FAILSAFE_ITERATIONS_MAX; 
		 attributeListPtr = attributeListPtr->next, iterationCount++ )
		{
		if( attributeListPtr->next != NULL && \
			isValidAttributeField( attributeListPtr->next ) && \
			attributeListPtr->attributeID > \
						attributeListPtr->next->attributeID )
			{
			/* Safety check in case of an invalid attribute list */
			retIntError();
			}
		attributeListPtr->attributeInfoPtr = NULL;
		attributeListPtr->encodedSize = attributeListPtr->fifoPos = \
			attributeListPtr->fifoEnd = 0;
		attributeListPtr->flags &= ~ATTR_FLAG_DEFAULTVALUE;
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );

	/* Set up the attribute-checking state information */
	memset( &attributeCheckInfo, 0, sizeof( ATTRIBUTE_CHECK_INFO ) );
	attributeCheckInfo.attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr;
	attributeCheckInfo.attributeInfoPtr = ( ATTRIBUTE_INFO * ) attributeInfoStartPtr;

	/* Walk down the list of known attributes checking each one for
	   consistency */
	for( iterationCount = 0;
		 attributeCheckInfo.attributeListPtr != NULL && \
			attributeCheckInfo.attributeListPtr->fieldID != CRYPT_ATTRIBUTE_NONE && \
			iterationCount < FAILSAFE_ITERATIONS_MAX;
		 iterationCount++ )
		{
		int innerIterationCount, status;

		/* Find the start of this attribute in the attribute info table and
		   remember it as an encoding synchronisation point.  Comparing the 
		   field ID with the attribute ID is usually valid because the 
		   attribute info table always begins the series of entries for an 
		   attribute with the attribute ID.  The one exception is where the 
		   attribute ID is the same as the field ID but they're separate 
		   entries in the table, in which case the first entries will 
		   contain a FIELDID_FOLLOWS code to indicate that a following field 
		   contains the attribute/fieldID */
		for( innerIterationCount = 0;
			 ( attributeCheckInfo.attributeInfoPtr->fieldID != \
					attributeCheckInfo.attributeListPtr->attributeID ) && \
				attributeCheckInfo.attributeInfoPtr->fieldID != CRYPT_ERROR && \
				innerIterationCount < FAILSAFE_ITERATIONS_LARGE;
			 attributeCheckInfo.attributeInfoPtr++, innerIterationCount++ );
		ENSURES( innerIterationCount < FAILSAFE_ITERATIONS_LARGE );
		ENSURES( attributeCheckInfo.attributeInfoPtr->fieldID != CRYPT_ERROR );

		for( innerIterationCount = 0;
			 attributeCheckInfo.attributeInfoPtr != attributeInfoStartPtr && \
				attributeCheckInfo.attributeInfoPtr[ -1 ].fieldID == FIELDID_FOLLOWS && \
				innerIterationCount < FAILSAFE_ITERATIONS_LARGE;
			 attributeCheckInfo.attributeInfoPtr--, innerIterationCount++ );
		ENSURES( innerIterationCount < FAILSAFE_ITERATIONS_LARGE );

		/* Check this attribute */
		status = checkAttribute( &attributeCheckInfo );
		if( cryptStatusError( status ) )
			{
			*errorLocus = attributeCheckInfo.errorLocus;
			*errorType = attributeCheckInfo.errorType;
			return( status );
			}
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );

	return( CRYPT_OK );
	}

⌨️ 快捷键说明

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