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

📄 certext.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
		const ATTRIBUTE_INFO *attributeInfoPtr = \
				( srcListPtr->attributeInfoPtr != NULL ) ? \
				srcListPtr->attributeInfoPtr : \
				fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
										ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
									attributeID, CRYPT_ATTRIBUTE_NONE, NULL );
		int status;

		assert( isReadPtr( attributeInfoPtr, ATTRIBUTE_INFO ) );

		/* Copy the complete attribute across unless it's one that we 
		   explicitly don't propagate from source to destination */
		if( !( attributeInfoPtr->flags & FL_NOCOPY ) )
			{
			status = copyAttribute( destListHeadPtr, srcListPtr, FALSE );
			if( cryptStatusError( status ) )
				return( status );
			}

		/* Move on to the next attribute */
		while( srcListPtr != NULL && srcListPtr->attributeID == attributeID )
			srcListPtr = srcListPtr->next;
		}

	/* If there are blob-type attributes left at the end of the list, copy
	   them across last */
	if( srcListPtr != NULL )
		{
		ATTRIBUTE_LIST *insertPoint;

		/* Find the end of the destination list */
		for( insertPoint = *destListHeadPtr;
			 insertPoint != NULL && insertPoint->next != NULL;
			 insertPoint = insertPoint->next );

		/* Copy all remaining attributes across */
		while( srcListPtr != NULL )
			{
			ATTRIBUTE_LIST *newAttribute;
			int status;

			status = copyAttributeField( &newAttribute, srcListPtr );
			if( cryptStatusError( status ) )
				return( status );
			insertDoubleListElement( destListHeadPtr, insertPoint, 
									 newAttribute );
			srcListPtr = srcListPtr->next;
			}
		}

	return( CRYPT_OK );
	}

/* Copy attributes that are propagated down cert chains from an issuer to a
   subject cert, changing the field types from subject to issuer at the same
   time if required */

int copyIssuerAttributes( ATTRIBUTE_LIST **destListHeadPtr,
						  const ATTRIBUTE_LIST *srcListPtr,
						  CRYPT_ATTRIBUTE_TYPE *errorLocus, 
						  CRYPT_ERRTYPE_TYPE *errorType,
						  const CRYPT_CERTTYPE_TYPE type )
	{
	ATTRIBUTE_LIST *attributeListPtr;
	int status = CRYPT_OK;

	assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
	assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );

	/* If the destination is a CA cert and the source has name constraints,
	   copy them over to the destination */
	attributeListPtr = findAttributeField( *destListHeadPtr, 
										   CRYPT_CERTINFO_CA, 
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL && attributeListPtr->intValue )
		{
		ATTRIBUTE_LIST *srcPermittedSubtrees, *srcExcludedSubtrees;

		srcPermittedSubtrees = findAttributeField( srcListPtr,
												   CRYPT_CERTINFO_PERMITTEDSUBTREES,
												   CRYPT_ATTRIBUTE_NONE );
		srcExcludedSubtrees = findAttributeField( srcListPtr,
												  CRYPT_CERTINFO_EXCLUDEDSUBTREES,
												  CRYPT_ATTRIBUTE_NONE );

		/* If we're copying permitted or excluded subtrees, they can't 
		   already be present. We check the two separately rather than just 
		   checking for the overall presence of name constraints since in 
		   theory it's possible to merge permitted and excluded constraints,
		   so that permitted constraints in the destination don't clash with
		   excluded constraints in the source (yet another one of X.509's 
		   semantic holes) */
		if( srcPermittedSubtrees != NULL && \
			findAttributeField( *destListHeadPtr, \
								CRYPT_CERTINFO_PERMITTEDSUBTREES,
								CRYPT_ATTRIBUTE_NONE ) != NULL )
			{
			*errorLocus = CRYPT_CERTINFO_PERMITTEDSUBTREES;
			*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
			return( CRYPT_ERROR_DUPLICATE );
			}
		if( srcExcludedSubtrees != NULL && \
			findAttributeField( *destListHeadPtr, \
								CRYPT_CERTINFO_EXCLUDEDSUBTREES,
								CRYPT_ATTRIBUTE_NONE ) != NULL )
			{
			*errorLocus = CRYPT_CERTINFO_EXCLUDEDSUBTREES;
			*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
			return( CRYPT_ERROR_DUPLICATE );
			}

		/* Copy the fields across */
		if( srcPermittedSubtrees != NULL )
			status = copyAttribute( destListHeadPtr, srcPermittedSubtrees, FALSE );
		if( cryptStatusOK( status ) && srcExcludedSubtrees != NULL )
			status = copyAttribute( destListHeadPtr, srcExcludedSubtrees, FALSE );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* If it's an attribute certificate, that's all we can copy */
	if( type == CRYPT_CERTTYPE_ATTRIBUTE_CERT )
		return( CRYPT_OK );

	/* Copy the altName and keyIdentifier if these are present.  We don't
	   have to check for their presence in the destination cert since they're
	   read-only fields and can't be added by the user */
	attributeListPtr = findAttribute( srcListPtr,
									  CRYPT_CERTINFO_SUBJECTALTNAME, FALSE );
	if( attributeListPtr != NULL )
		{
		status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		}
	attributeListPtr = findAttribute( srcListPtr,
									  CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER, FALSE );
	if( attributeListPtr != NULL )
		{
		status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Copy the authorityInfoAccess if it's present.  This one is a bit 
	   tricky both because it's a multi-valued attribute and some values 
	   may already be present in the destination cert and because it's not 
	   certain that the issuer cert's AIA should be the same as the subject 
	   cert's AIA.  At the moment with monolithic CAs (i.e.ones that control 
	   all the certs down to the EE) this is always the case, and if it isn't
	   it's assumed that the CA will set the EE's AIA to the appropriate 
	   value before trying to sign the cert.  Because of this we copy the 
	   issuer AIA if there's no subject AIA present, otherwise we assume that 
	   the CA has set the subject AIA to its own choice of value and don't 
	   try and copy anything */
	attributeListPtr = findAttribute( srcListPtr,
									  CRYPT_CERTINFO_AUTHORITYINFOACCESS, FALSE );
	if( attributeListPtr != NULL && \
		findAttribute( *destListHeadPtr, 
					   CRYPT_CERTINFO_AUTHORITYINFOACCESS, FALSE ) == NULL )
		{
		status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		}

	return( CRYPT_OK );
	}

/* Copy attributes that are propagated from an OCSP request to a response */

int copyRequestAttributes( ATTRIBUTE_LIST **destListHeadPtr,
						   const ATTRIBUTE_LIST *srcListPtr,
						   CRYPT_ATTRIBUTE_TYPE *errorLocus, 
						   CRYPT_ERRTYPE_TYPE *errorType )
	{
	ATTRIBUTE_LIST *attributeListPtr;
	int status = CRYPT_OK;

	assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
	assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );

	/* If the nonce attribute is already present in the destination, delete
	   it */
	attributeListPtr = findAttributeField( *destListHeadPtr,
							CRYPT_CERTINFO_OCSP_NONCE, CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL )
		deleteAttributeField( destListHeadPtr, NULL, attributeListPtr, NULL );

	/* Copy the nonce attribute from the source to the destination.  We don't
	   copy anything else (i.e. we default to deny-all) to prevent the 
	   requester from being able to insert arbitrary attributes into the 
	   response */
	attributeListPtr = findAttributeField( srcListPtr,
							CRYPT_CERTINFO_OCSP_NONCE, CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL )
		status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );

	return( status );
	}

/* Copy attributes that are propagated from a revocation request to a CRL */

int copyRevocationAttributes( ATTRIBUTE_LIST **destListHeadPtr,
							  const ATTRIBUTE_LIST *srcListPtr,
							  CRYPT_ATTRIBUTE_TYPE *errorLocus, 
							  CRYPT_ERRTYPE_TYPE *errorType )
	{
	ATTRIBUTE_LIST *attributeListPtr;
	int status = CRYPT_OK;

	assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
	assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );

	/* Copy the CRL reason and invalidity date attributes from the source to 
	   the destination.  We don't copy anything else (i.e.default to deny-all)
	   to prevent the requester from being able to insert arbitrary 
	   attributes into the CRL */
	attributeListPtr = findAttribute( srcListPtr,
									  CRYPT_CERTINFO_CRLREASON, FALSE );
	if( attributeListPtr != NULL )
		{
		status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
		if( cryptStatusError( status ) )
			return( status );
		}
	attributeListPtr = findAttribute( srcListPtr,
									  CRYPT_CERTINFO_INVALIDITYDATE, FALSE );
	if( attributeListPtr != NULL )
		status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );

	return( status );
	}

/* Delete an attribute/attribute field from a list of attributes, updating
   the list cursor at the same time.  This is a somewhat ugly kludge, it's
   not really possible to do this cleanly since deleting attributes affects
   the attribute cursor */

int deleteAttributeField( ATTRIBUTE_LIST **attributeListPtr,
						  ATTRIBUTE_LIST **listCursorPtr,
						  ATTRIBUTE_LIST *listItem,
						  const void *dnDataPtr )
	{
	ATTRIBUTE_LIST *listPrevPtr = listItem->prev;
	ATTRIBUTE_LIST *listNextPtr = listItem->next;
	BOOLEAN deletedDN = FALSE;

	assert( isWritePtr( attributeListPtr, ATTRIBUTE_LIST * ) );
	assert( isWritePtr( *attributeListPtr, ATTRIBUTE_LIST ) );
	assert( isWritePtr( listItem, ATTRIBUTE_LIST ) );

	/* If we're about to delete the field that's pointed to by the attribute 
	   cursor, advance the cursor to the next field.  If there's no next 
	   field, move it to the previous field.  This behaviour is the most
	   logically consistent, it means we can do things like deleting an
	   entire attribute list by repeatedly deleting a field */
	if( listCursorPtr != NULL && *listCursorPtr == listItem )
		*listCursorPtr = ( listNextPtr != NULL ) ? listNextPtr : listPrevPtr;

	/* Remove the item from the list */
	if( listItem == *attributeListPtr )
		{
		/* Special case for first item */
		*attributeListPtr = listNextPtr;
		if( listNextPtr != NULL )
			listNextPtr->prev = NULL;
		}
	else
		{
		/* Delete from the middle or the end of the chain */
		listPrevPtr->next = listNextPtr;
		if( listNextPtr != NULL )
			listNextPtr->prev = listPrevPtr;
		}

	/* Clear all data in the item and free the memory */
	if( listItem->fieldType == FIELDTYPE_DN )
		{
		if( dnDataPtr != NULL && dnDataPtr == &listItem->value )
			deletedDN = TRUE;
		deleteDN( ( void ** ) &listItem->value );
		}
	endVarStruct( listItem, ATTRIBUTE_LIST );
	clFree( "deleteAttributeField", listItem );

	return( deletedDN ? OK_SPECIAL : CRYPT_OK );
	}

int deleteAttribute( ATTRIBUTE_LIST **attributeListPtr,
					 ATTRIBUTE_LIST **listCursorPtr,
					 ATTRIBUTE_LIST *listItem,
					 const void *dnDataPtr )
	{
	CRYPT_ATTRIBUTE_TYPE attributeID;
	ATTRIBUTE_LIST *attributeListCursor;
	int status = CRYPT_OK;

	assert( isWritePtr( attributeListPtr, ATTRIBUTE_LIST * ) );
	assert( isWritePtr( *attributeListPtr, ATTRIBUTE_LIST ) );
	assert( isWritePtr( listItem, ATTRIBUTE_LIST ) );

	/* If it's a blob-type attribute, everything is contained in this one
	   list item so we only need to destroy that */
	if( isBlobAttribute( listItem ) )
		return( deleteAttributeField( attributeListPtr, listCursorPtr, 
									  listItem, NULL ) );

	/* If it's a field that denotes an entire (constructed) attribute, it
	   won't have an entry in the list, so we find the first field of the
	   constructed attribute that's present in the list and start deleting
	   from that point */
	if( isCompleteAttribute( listItem ) )
		{
		for( attributeListCursor = *attributeListPtr; 
			 attributeListCursor != NULL && \
				attributeListCursor->attributeID != listItem->intValue;
			 attributeListCursor = attributeListCursor->next );
		}
	else
		/* The list item is a field in the attribute, find the start of the
		   fields in this attribute */
		attributeListCursor = findAttributeStart( listItem );
	assert( isWritePtr( attributeListCursor, ATTRIBUTE_LIST ) );
	attributeID = attributeListCursor->attributeID;

	/* It's an item with multiple fields, destroy each field separately */
	while( attributeListCursor != NULL && \
		   attributeListCursor->attributeID == attributeID )
		{
		ATTRIBUTE_LIST *itemToFree = attributeListCursor;
		int localStatus;

		attributeListCursor = attributeListCursor->next;
		localStatus = deleteAttributeField( attributeListPtr, listCursorPtr, 
											itemToFree, dnDataPtr );
		if( cryptStatusError( localStatus ) )
			status = localStatus;
		}

	return( status );
	}

/* Delete a complete set of attributes */

void deleteAttributes( ATTRIBUTE_LIST **attributeListPtr )
	{
	ATTRIBUTE_LIST *attributeListCursor = *attributeListPtr;

	/* If the list was empty, return now */
	if( attributeListCursor == NULL )
		return;

	/* Destroy any remaining list items */
	while( attributeListCursor != NULL )
		{
		ATTRIBUTE_LIST *itemToFree = attributeListCursor;

		attributeListCursor = attributeListCursor->next;
		deleteAttributeField( attributeListPtr, NULL, itemToFree, NULL );
		}
	}

⌨️ 快捷键说明

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