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

📄 certechk.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* If we've reached the end of the list of recognised attributes, 
		   use a non-ID which doesn't match any table entry */
		fieldID = CRYPT_UNUSED;
	else
		/* If we're encoding a subtyped field, the fieldID is the field ID
		   within the parent field, or the subFieldID */
		if( attributeCheckInfo->subtypeParent == attributeListPtr->fieldID )
			fieldID = attributeListPtr->subFieldID;
		else
			/* It's a standard attribute field */
			fieldID = attributeListPtr->fieldID;

	/* If the field in the attribute list matches the one in the table,
	   process it and move on to the next one */
	if( attributeListPtr != NULL && attributeInfoPtr->fieldID == fieldID )
		{
		/* If it's a subtyped or CHOICE field, check the components using
		   their own encoding table */
		if( attributeInfoPtr->fieldType == FIELDTYPE_SUBTYPED || \
			attributeInfoPtr->fieldType == FIELDTYPE_CHOICE )
			{
			int status;

			/* Switch to the new encoding table and record the fact that
			   we've done this, and set the new stack top to the level at
			   which we start encoding the subtype */
			if( attributeInfoPtr->fieldType == FIELDTYPE_CHOICE )
				{
				/* Stack the value start position in the attribute list and
				   record the fact that we're processing a CHOICE */
				stack[ attributeCheckInfo->stackPos ].size = 0;
				stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
				stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr;
				attributeCheckInfo->choiceState = CHOICE_START;
				}
			attributeCheckInfo->attributeInfoPtr = \
							( ATTRIBUTE_INFO * ) attributeInfoPtr->extraData;
			attributeCheckInfo->subtypeParent = attributeListPtr->fieldID;
			attributeCheckInfo->stackTop = attributeCheckInfo->stackPos;
			status = checkAttribute( attributeCheckInfo );
			attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
			attributeCheckInfo->subtypeParent = CRYPT_ATTRIBUTE_NONE;
			attributeCheckInfo->stackTop = 0;
			return( status );
			}

		/* If there's an extended validation function attached to this field,
		   call it */
		if( attributeInfoPtr->extraData != NULL )
			{
			VALIDATION_FUNCTION validationFunction = \
						( VALIDATION_FUNCTION ) attributeInfoPtr->extraData;

			attributeCheckInfo->errorType = validationFunction( attributeListPtr );
			if( attributeCheckInfo->errorType != CRYPT_OK )
				return( CRYPT_ERROR_INVALID );
			}

		/* If this is an optional field and the value is the same as the
		   default value, remember that it doesn't get encoded */
		if( ( attributeInfoPtr->flags & FL_DEFAULT ) && \
			( attributeInfoPtr->defaultValue == attributeListPtr->value ) )
			{
			attributeListPtr->flags |= ATTR_FLAG_DEFAULTVALUE;
			attributeCheckInfo->attributeListPtr = attributeListPtr->next;
			return( CRYPT_OK );
			}

		/* Remember the encoded size of this field */
		attributeListPtr->attributeInfoPtr = attributeInfoPtr;
		attributeListPtr->encodedSize = writeAttributeField( NULL, attributeListPtr );
		if( attributeCheckInfo->stackPos )
			stack[ attributeCheckInfo->stackPos - 1 ].size += attributeListPtr->encodedSize;

		/* If this is a CHOICE field, update the choice state */
		if( attributeCheckInfo->choiceState != CHOICE_NONE )
			{
			if( attributeCheckInfo->choiceState == CHOICE_DONE )
				{
				/* If we've already processed one of the CHOICE options, there
				   can't be another one present */
				attributeCheckInfo->errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
				return( CRYPT_ERROR_INVALID );
				}
			if( attributeCheckInfo->choiceState == CHOICE_START )
				/* Remember that we've seen a CHOICE option */
				attributeCheckInfo->choiceState = CHOICE_DONE;
			}

		/* Move on to the next attribute field */
		attributeCheckInfo->attributeListPtr = attributeListPtr->next;
		return( CRYPT_OK );
		}

	/* If it's an attributeTypeAndValue sequence, check whether it contains
	   the field we want */
	if( attributeInfoPtr->flags & FL_IDENTIFIER )
		{
		BOOLEAN endOfAttributeField = FALSE;

		if( !checkComponentPresent( fieldID, &attributeInfoPtr ) )
			{
			/* Since we've jumped over several items we may be pointing at an
			   end-of-sequence flag for which no sequence start was stacked,
			   so we skip the stack update step */
			attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
			return( OK_SPECIAL );
			}

		/* Stack the position of the sequence start and the following OID */
		stack[ attributeCheckInfo->stackPos ].size = 0;
		stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
		stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr++;
		stack[ attributeCheckInfo->stackPos ].size = 0;
		stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
		stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr;

		/* If the OID entry is marked as the end-of-sequence, there are no
		   parameters attached so we move on to the next entry */
		if( attributeInfoPtr->flags & FL_SEQEND_MASK )
			endOfAttributeField = TRUE;

		/* Sometimes the OID is followed by a fixed-value blob field which
		   constitutes parameters for the OID, if this is present we stack it
		   as well */
		if( attributeInfoPtr[ 1 ].flags & FL_NONENCODING )
			{
			attributeInfoPtr++;
			stack[ attributeCheckInfo->stackPos ].size = 0;
			stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
			stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr;

			/* 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 */
			attributeCheckInfo->attributeListPtr = attributeListPtr->next;
		return( CRYPT_OK );
		}

	/* If it's a sequence/set or a non-encoding value then it's a nop 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 */
		stack[ attributeCheckInfo->stackPos ].size = 0;
		stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
		stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr;
		return( CRYPT_OK );
		}

	/* 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 */

static int checkAttribute( ATTRIBUTE_CHECK_INFO *attributeCheckInfo )
	{
	BOOLEAN attributeContinues;

	assert( isWritePtr( attributeCheckInfo, ATTRIBUTE_CHECK_INFO ) );

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

		/* 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 */
			updateStackedInfo( attributeCheckInfo->stack,
				&attributeCheckInfo->stackPos,
				decodeNestingLevel( attributeCheckInfo->attributeInfoPtr->flags ),
				TRUE );
			}

		/* If it's another instance of the same item, don't move on to the
		   next table entry */
		if( attributeCheckInfo->attributeListPtr != NULL && \
			attributeCheckInfo->attributeListPtr->next != NULL && \
			( attributeCheckInfo->attributeListPtr->fieldID == \
			  attributeCheckInfo->attributeListPtr->next->fieldID ) && \
			( attributeCheckInfo->attributeListPtr->subFieldID == \
			  attributeCheckInfo->attributeListPtr->next->subFieldID ) )
			{
			/* Currently we don't allow the creation of multivalued 
			   instances of fields, although we can read certs which contain
			   them */
			assert( NOTREACHED );
			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 );
	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 */
	updateStackedInfo( attributeCheckInfo->stack, &attributeCheckInfo->stackPos,
					   attributeCheckInfo->stackPos - attributeCheckInfo->stackTop,
					   FALSE );

	return( CRYPT_OK );
	}

/* Check the entire list of attributes */

int checkAttributes( const ATTRIBUTE_TYPE attributeType,
					 const ATTRIBUTE_LIST *listHeadPtr,
					 CRYPT_ATTRIBUTE_TYPE *errorLocus, 
					 CRYPT_ERRTYPE_TYPE *errorType )
	{
	ATTRIBUTE_CHECK_INFO attributeCheckInfo;
	const ATTRIBUTE_INFO *attributeInfoStartPtr = \
							selectAttributeInfo( attributeType );
	ATTRIBUTE_LIST *attributeListPtr;

	/* If we've already done a validation pass, some of the fields will
	   contain values which were previously set, so before we begin we walk
	   down the list resetting the fields which are updated by this
	   function */
	for( attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr;
		 attributeListPtr != NULL && attributeListPtr->fieldID != CRYPT_ATTRIBUTE_NONE;
		 attributeListPtr = attributeListPtr->next )
		{
		attributeListPtr->attributeInfoPtr = NULL;
		attributeListPtr->encodedSize = attributeListPtr->fifoPos = \
			attributeListPtr->fifoEnd = 0;
		attributeListPtr->flags &= ~ATTR_FLAG_DEFAULTVALUE;
		}

	/* 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 */
	while( attributeCheckInfo.attributeListPtr != NULL && \
		   attributeCheckInfo.attributeListPtr->fieldID != CRYPT_ATTRIBUTE_NONE )
		{
		int status;

		/* Find the start of this attribute in the attribute info table and
		   remember it as an encoding sync 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 */
		while( attributeCheckInfo.attributeInfoPtr->fieldID != \
			   attributeCheckInfo.attributeListPtr->attributeID )
			attributeCheckInfo.attributeInfoPtr++;
		while( attributeCheckInfo.attributeInfoPtr != attributeInfoStartPtr && \
			   attributeCheckInfo.attributeInfoPtr[ -1 ].fieldID == FIELDID_FOLLOWS )
			attributeCheckInfo.attributeInfoPtr--;

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

	return( CRYPT_OK );
	}

⌨️ 快捷键说明

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