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

📄 certext.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*																			*
*					Certificate Attribute Management Routines				*
*						Copyright Peter Gutmann 1996-2003					*
*																			*
****************************************************************************/

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#if defined( INC_ALL ) ||  defined( INC_CHILD )
  #include "cert.h"
  #include "certattr.h"
  #include "../misc/asn1_rw.h"
#else
  #include "cert/cert.h"
  #include "cert/certattr.h"
  #include "misc/asn1_rw.h"
#endif /* Compiler-specific includes */

/* Prototypes for functions in certdn.c */

int convertEmail( CERT_INFO *certInfoPtr, void **dnListHead,
				  const CRYPT_ATTRIBUTE_TYPE altNameType );

/* Prototypes for functions in cryptcrt.c */

int textToOID( const char *oid, const int oidLength, BYTE *binaryOID );

/****************************************************************************
*																			*
*								Attribute Type Mapping						*
*																			*
****************************************************************************/

/* Get the attribute information for a given OID */

const ATTRIBUTE_INFO *oidToAttribute( const ATTRIBUTE_TYPE attributeType,
									  const BYTE *oid )
	{
	const ATTRIBUTE_INFO *attributeInfoPtr = \
							selectAttributeInfo( attributeType );
	const int length = sizeofOID( oid );

	assert( isReadPtr( attributeInfoPtr, ATTRIBUTE_INFO ) );

	while( attributeInfoPtr->fieldID != CRYPT_ERROR )
		{
		if( attributeInfoPtr->oid != NULL && \
			sizeofOID( attributeInfoPtr->oid ) == length && \
			!memcmp( attributeInfoPtr->oid, oid, length ) )
			return( attributeInfoPtr );
		attributeInfoPtr++;
		}

	/* It's an unknown attribute */
	return( NULL );
	}

/* Get the attribute and attributeID for a field ID */

static const ATTRIBUTE_INFO *fieldIDToAttribute( const ATTRIBUTE_TYPE attributeType,
		const CRYPT_ATTRIBUTE_TYPE fieldID, const CRYPT_ATTRIBUTE_TYPE subFieldID,
		CRYPT_ATTRIBUTE_TYPE *attributeID )
	{
	const ATTRIBUTE_INFO *attributeInfoPtr = \
							selectAttributeInfo( attributeType );
	int i;

	assert( isReadPtr( attributeInfoPtr, ATTRIBUTE_INFO ) );

	/* Clear the return value */
	if( attributeID != NULL )
		*attributeID = CRYPT_ERROR;

	/* Find the information on this attribute field */
	for( i = 0; attributeInfoPtr[ i ].fieldID != CRYPT_ERROR; i++ )
		{
		/* If the previous entry doesn't have more data following it, the
		   current entry is the start of a complete attribute and therefore
		   contains the attribute ID */
		if( attributeID != NULL && \
			( !i || !( attributeInfoPtr[ i - 1 ].flags & FL_MORE ) ) )
			{
			int j;

			/* Usually the attribute ID is the fieldID for the first entry,
			   however in some cases the attributeID is the same as the
			   fieldID and isn't specified until later on (denoted by the
			   fieldID being FIELDID_FOLLOWS), so we have to look ahead to
			   find it */
			*attributeID = attributeInfoPtr[ i ].fieldID;
			for( j = i + 1; *attributeID == FIELDID_FOLLOWS; j++ )
				*attributeID = attributeInfoPtr[ j ].fieldID;
			}

		/* Check whether the field ID for this entry matches the one we want */
		if( attributeInfoPtr[ i ].fieldID == fieldID )
			{
			ATTRIBUTE_INFO *altEncodingTable = \
						( ATTRIBUTE_INFO * ) attributeInfoPtr[ i ].extraData;

			/* If we're after a subfield match as well, try and match the
			   subfield */
			if( subFieldID != CRYPT_ATTRIBUTE_NONE && altEncodingTable != NULL )
				{
				for( i = 0; altEncodingTable[ i ].fieldID != CRYPT_ERROR; i++ )
					if( altEncodingTable[ i ].fieldID == subFieldID )
						return( &altEncodingTable[ i ] );

				return( NULL );
				}

			return( &attributeInfoPtr[ i ] );
			}
		}

	return( NULL );
	}

/****************************************************************************
*																			*
*					Attribute Location/Cursor Movement Routines				*
*																			*
****************************************************************************/

/* Find the start and end of an attribute from a field within the
   attribute */

static ATTRIBUTE_LIST *findAttributeStart( const ATTRIBUTE_LIST *attributeListPtr )
	{
	CRYPT_ATTRIBUTE_TYPE attributeID;

	if( attributeListPtr == NULL )
		return( NULL );
	attributeID = attributeListPtr->attributeID;

	/* Move backwards until we find the start of the attribute */
	while( attributeListPtr->prev != NULL && \
		   attributeListPtr->prev->attributeID == attributeID )
		attributeListPtr = attributeListPtr->prev;

	return( ( ATTRIBUTE_LIST * ) attributeListPtr );
	}

static ATTRIBUTE_LIST *findAttributeEnd( const ATTRIBUTE_LIST *attributeListPtr )
	{
	CRYPT_ATTRIBUTE_TYPE attributeID;

	if( attributeListPtr == NULL )
		return( NULL );
	attributeID = attributeListPtr->attributeID;

	/* Move forwards until we're just before the start of the next 
	   attribute */
	while( attributeListPtr->next != NULL && \
		   attributeListPtr->next->attributeID > 0 && \
		   attributeListPtr->next->attributeID == attributeID )
		attributeListPtr = attributeListPtr->next;

	return( ( ATTRIBUTE_LIST * ) attributeListPtr );
	}

/* Find an attribute in a list of certificate attributes by object identifier
   (for blob-type attributes) or by field and subfield ID (for known
   attributes), with extended handling for fields with default values */

ATTRIBUTE_LIST *findAttributeByOID( const ATTRIBUTE_LIST *attributeListPtr,
									const BYTE *oid )
	{
	/* Find the position of this component in the list */
	while( attributeListPtr != NULL && \
		   ( !isBlobAttribute( attributeListPtr ) || \
			 sizeofOID( attributeListPtr->oid ) != sizeofOID( oid ) || \
			 memcmp( attributeListPtr->oid, oid, sizeofOID( oid ) ) ) )
		 attributeListPtr = attributeListPtr->next;

	return( ( ATTRIBUTE_LIST * ) attributeListPtr );
	}

ATTRIBUTE_LIST *findAttributeField( const ATTRIBUTE_LIST *attributeListPtr,
									const CRYPT_ATTRIBUTE_TYPE fieldID,
									const CRYPT_ATTRIBUTE_TYPE subFieldID )
	{
	assert( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
			fieldID <= CRYPT_CERTINFO_LAST );

	/* Find the position of this component in the list */
	while( attributeListPtr != NULL && \
		   attributeListPtr->attributeID > 0 && \
		   attributeListPtr->fieldID != fieldID )
		attributeListPtr = attributeListPtr->next;
	if( subFieldID == CRYPT_ATTRIBUTE_NONE )
		return( ( attributeListPtr != NULL && \
				  attributeListPtr->attributeID > 0 ) ? \
				( ATTRIBUTE_LIST * ) attributeListPtr : NULL );

	/* Find the subfield in the field */
	while( attributeListPtr != NULL && \
		   attributeListPtr->attributeID > 0 && \
		   attributeListPtr->fieldID == fieldID )
		{
		if( attributeListPtr->subFieldID == subFieldID )
			return( ( ATTRIBUTE_LIST * ) attributeListPtr );
		attributeListPtr = attributeListPtr->next;
		}

	return( NULL );
	}

ATTRIBUTE_LIST *findAttributeFieldEx( const ATTRIBUTE_LIST *attributeListPtr,
									  const CRYPT_ATTRIBUTE_TYPE fieldID )
	{
	static const ATTRIBUTE_LIST defaultField = DEFAULTFIELD_VALUE;
	static const ATTRIBUTE_LIST completeAttribute = COMPLETEATTRIBUTE_VALUE;
	const ATTRIBUTE_LIST *attributeListCursor = attributeListPtr;
	const ATTRIBUTE_INFO *attributeInfoPtr;
	const ATTRIBUTE_TYPE attributeType = \
							( fieldID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
							ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE;
	CRYPT_ATTRIBUTE_TYPE attributeID;

	assert( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
			fieldID <= CRYPT_CERTINFO_LAST );

	/* Find the position of this component in the list */
	while( attributeListCursor != NULL && \
		   attributeListCursor->attributeID > 0 && \
		   attributeListCursor->fieldID != fieldID )
		attributeListCursor = attributeListCursor->next;
	if( attributeListCursor != NULL )
		return( attributeListCursor->attributeID > 0 ? \
				( ATTRIBUTE_LIST * ) attributeListCursor : NULL );

	/* The field isn't present in the list of attributes, check whether
	   the attribute itself is present and whether this field has a default
	   value */
	attributeInfoPtr = fieldIDToAttribute( attributeType, fieldID, 
										   CRYPT_ATTRIBUTE_NONE, &attributeID );
	if( attributeInfoPtr == NULL )
		/* There's no attribute containing this field, exit */
		return( NULL );

	/* Check whether any part of the attribute that contains the given 
	   field is present in the list of attribute fields */
	for( attributeListCursor = ( ATTRIBUTE_LIST * ) attributeListPtr;
		 attributeListCursor != NULL && \
			attributeListCursor->attributeID > 0 && \
			attributeListCursor->attributeID != attributeID;
		 attributeListCursor = attributeListCursor->next );
	if( attributeListCursor == NULL )
		return( NULL );

	/* Some other part of the attribute containing the given field is present 
	   in the list.  If this field wasn't found that could either be a 
	   default value (in which case we return an entry that denotes that 
	   this field is absent but has a default setting) or a field that 
	   denotes an entire constructed attribute (in which case we return an 
	   entry that denotes this) */
	if( attributeInfoPtr->flags & FL_DEFAULT )
		return( ( ATTRIBUTE_LIST * ) &defaultField );
	if( attributeInfoPtr->fieldType == BER_SEQUENCE )
		return( ( ATTRIBUTE_LIST * ) &completeAttribute );

	return( NULL );
	}

/* Find an overall attribute in a list of attributes.  This is almost always
   used as a check for the presence of an overall attribute, so we provide
   a separate function to make this explicit */

ATTRIBUTE_LIST *findAttribute( const ATTRIBUTE_LIST *attributeListPtr,
							   const CRYPT_ATTRIBUTE_TYPE attributeID,
							   const BOOLEAN isFieldID )
	{
	const ATTRIBUTE_LIST *attributeListCursor = attributeListPtr;
	CRYPT_ATTRIBUTE_TYPE localAttributeID = attributeID;

	assert( attributeID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
			attributeID <= CRYPT_CERTINFO_LAST );
	
	/* If this is a (potential) fieldID rather than an attributeID, find the
	   attributeID for the attribute containing this field */
	if( isFieldID )
		{
		if( fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
									ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, 
								attributeID, CRYPT_ATTRIBUTE_NONE, 
								&localAttributeID ) == NULL )
			/* There's no attribute containing this field, exit */
			return( NULL );
		}
	else
		/* Make sure that we're searching on an attribute ID rather than a 
		   field ID */
		assert( \
			fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
									ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, 
								attributeID, CRYPT_ATTRIBUTE_NONE, 
								&localAttributeID ) != NULL && \
			attributeID == localAttributeID );

	/* Check whether this attribute is present in the list of attribute 
	   fields */
	while( attributeListCursor != NULL && \
		   attributeListCursor->attributeID > 0 )
		{
		if( attributeListCursor->attributeID == localAttributeID )
			return( ( ATTRIBUTE_LIST * ) attributeListCursor );
		attributeListCursor = attributeListCursor->next;
		}
	return( NULL );
	}


BOOLEAN checkAttributePresent( const ATTRIBUTE_LIST *attributeListPtr,
							   const CRYPT_ATTRIBUTE_TYPE fieldID )
	{
	return( findAttribute( attributeListPtr, fieldID, FALSE ) != NULL ? \
			TRUE : FALSE );
	}

/* Get the default value for an optional field of an attribute */

int getDefaultFieldValue( const CRYPT_ATTRIBUTE_TYPE fieldID )
	{
	const ATTRIBUTE_INFO *attributeInfoPtr = \
			fieldIDToAttribute( ( fieldID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
									ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
								fieldID, CRYPT_ATTRIBUTE_NONE, NULL );

	assert( isReadPtr( attributeInfoPtr, ATTRIBUTE_INFO ) );

	return( ( int ) attributeInfoPtr->defaultValue );
	}

/* Move the attribute cursor relative to the current cursor position.  This
   moves as far as possible in the direction given and then returns an
   appropriate return code, either CRYPT_OK or CRYPT_ERROR_NOTFOUND if no
   movement is possible */

int moveAttributeCursor( ATTRIBUTE_LIST **currentCursor,
						 const CRYPT_ATTRIBUTE_TYPE certInfoType, 
						 const int position )
	{
	const ATTRIBUTE_LIST *newCursor = *currentCursor, *lastCursor = NULL;
	const BOOLEAN absMove = ( position == CRYPT_CURSOR_FIRST || \
							  position == CRYPT_CURSOR_LAST ) ? TRUE : FALSE;
	int count;

	assert( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION || \
			certInfoType == CRYPT_CERTINFO_CURRENT_FIELD || \
			certInfoType == CRYPT_CERTINFO_CURRENT_COMPONENT );
	assert( position <= CRYPT_CURSOR_FIRST && \
			position >= CRYPT_CURSOR_LAST );

	/* Positioning in null attribute lists is always unsuccessful */
	if( currentCursor == NULL || *currentCursor == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* Set the amount we want to move by based on the position code.  This
	   means we can handle the movement in a simple while loop instead of
	   having to special-case it for moves by one item */
	count = absMove ? INT_MAX : 1;

⌨️ 快捷键说明

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