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

📄 certstr.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	insertPoint->next = newElement;
	newElement->prev = insertPoint;
	}

static int insertDNstring( void **dnListHead, const CRYPT_ATTRIBUTE_TYPE type,
						   const void *value, const int valueLength,
						   const ASN1_STRINGTYPE stringType, const int flags,
						   CRYPT_ERRTYPE_TYPE *errorType )
	{
	const DN_COMPONENT_INFO *dnComponentInfo;
	DN_COMPONENT *listHeadPtr = *dnListHead;
	DN_COMPONENT *newElement, *insertPoint;
	ASN1_STRINGTYPE dnStringType = stringType;
	BYTE dnString[ ( CRYPT_MAX_TEXTSIZE + 1 ) * 2 ];
	const void *dnStringPtr = value;
	int dnStringLength = valueLength;

	/* If the DN is locked against modification we can't make any further
	   updates */
	if( listHeadPtr != NULL && listHeadPtr->flags & DN_FLAG_LOCKED )
		return( CRYPT_ERROR_INITED );

	/* If we've been fed the string from an external source, copy the string
	   to the internal format */
	if( !( flags & DN_FLAG_NOCHECK ) )
		{
		dnStringType = copyConvertString( value, valueLength, dnString,
								&dnStringLength, CRYPT_MAX_TEXTSIZE,
								FALSE, FALSE );
		if( dnStringType == STRINGTYPE_NONE )
			{
			/* The copy can only fail if the data is too large */
			*errorType = CRYPT_ERRTYPE_ATTR_SIZE;
			return( CRYPT_ARGERROR_NUM1 );
			}
		dnStringPtr = dnString;
		}

	/* Find the type information for this component if it's a recognised
	   type */
	if( type > CRYPT_CERTINFO_FIRST && type < CRYPT_CERTINFO_LAST )
		{
		int i;

		/* It's a handled component, get the pointer to the OID */
		for( i = 0; certInfoOIDs[ i ].type != CRYPT_ATTRIBUTE_NONE; i++ )
			if( certInfoOIDs[ i ].type == type )
				{
				dnComponentInfo = &certInfoOIDs[ i ];
				break;
				}
		assert( certInfoOIDs[ i ].type != CRYPT_ATTRIBUTE_NONE );
		}
	else
		/* It's a non-handled component, the type is an index into the
		   component table.  At this point we run into a GCC 2.7.x compiler
		   bug (detect with '#if defined( __GNUC__ ) && ( __GNUC__ == 2 )').
		   If we use the expression '&certInfoOIDs[ type - DN_OID_OFFSET ]'
		   what we should get is:
				leal -1000(%ebp,%ebp,2),%eax
				movl certInfoOIDs(,%eax,4),%eax
		   but what we actually get is:
				leal -3000(%ebp,%ebp,2),%eax
				movl certInfoOIDs(,%eax,4),%eax
		   To fix this we need to insert some form of dummy evaluation in a
		   form which ensures that it can't be optimised away (which is
		   actually quite difficult with gcc because it optimises any simple
		   code way).  To work around this we insert a dummy expression to
		   keep the value live */
		{
#if defined( __GNUC__ ) && ( __GNUC__ == 2 )
		int i = type - DN_OID_OFFSET;
		dnComponentInfo = &certInfoOIDs[ i ];
		if( dnComponentInfo < 0 )	/* Dummy code to keep i live */
			newElement = ( i + type ) ? NULL : ( void * ) dnStringPtr;
#else
		dnComponentInfo = &certInfoOIDs[ type - DN_OID_OFFSET ];
#endif /* gcc 2.7.x bug workaround */
		assert( type - DN_OID_OFFSET < \
				sizeof( certInfoOIDs ) / sizeof( DN_COMPONENT_INFO ) );
		}

	/* Make sure the length is valid.  If it's being read from an encoded
	   form we allow abnormally-long lengths (although we still keep them
	   within a sensible limit) since this is better than failing to read a
	   cert because it contains a broken DN */
	if( dnStringLength > ( ( flags & DN_FLAG_NOCHECK ) ? MAX_ATTRIBUTE_SIZE : \
						   ( dnStringType == STRINGTYPE_UNICODE ) ? \
							 dnComponentInfo->maxLength * 2 : \
							 dnComponentInfo->maxLength ) )
		{
		if( errorType != NULL )
			*errorType = CRYPT_ERRTYPE_ATTR_SIZE;
		return( CRYPT_ARGERROR_NUM1 );
		}

	/* Find the correct place in the list to insert the new element */
	if( listHeadPtr != NULL )
		{
		DN_COMPONENT *prevElement = NULL;

		/* If it's being read from an external cert item, just append it to
		   the end of the list */
		if( flags & DN_FLAG_NOCHECK )
			for( insertPoint = listHeadPtr; insertPoint->next != NULL;
				 insertPoint = insertPoint->next );
		else
			{
			for( insertPoint = listHeadPtr; insertPoint != NULL && \
				 dnSortOrder( type ) >= dnSortOrder( insertPoint->type );
				 insertPoint = insertPoint->next )
				{
				/* Make sure this component isn't already present.  For now
				   we only allow a single DN component of any type to keep
				   things simple for the user, if it's necessary to allow
				   multiple components of the same type we need to check the
				   value and valueLength as well */
				if( insertPoint->type == type )
					{
					if( errorType != NULL )
						*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
					return( CRYPT_ERROR_INITED );
					}

				prevElement = insertPoint;
				}
			insertPoint = prevElement;
			}
		}

	/* Allocate memory for the new element and copy over the information */
	if( ( newElement  = ( DN_COMPONENT * ) malloc( sizeof( DN_COMPONENT ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( newElement, 0, sizeof( DN_COMPONENT ) );
	newElement->type = type;
	newElement->stringType = dnStringType;
	newElement->typeInfo = dnComponentInfo;
	if( dnStringLength > CRYPT_MAX_TEXTSIZE )
		{
		if( ( newElement->value = malloc( dnStringLength ) ) == NULL )
			{
			free( newElement );
			return( CRYPT_ERROR_MEMORY );
			}
		}
	else
		newElement->value = newElement->smallValue;
	memcpy( newElement->value, dnStringPtr, dnStringLength );
	newElement->valueLength = dnStringLength;
	newElement->flags = flags;

	/* If it's a country code supplied by the user, force it to uppercase as
	   per ISO 3166 */
	if( type == CRYPT_CERTINFO_COUNTRYNAME )
		{
		newElement->smallValue[ 0 ] = toupper( newElement->smallValue[ 0 ] );
		newElement->smallValue[ 1 ] = toupper( newElement->smallValue[ 1 ] );
		if( !checkCountryCode( ( char * ) newElement->smallValue ) )
			{
			free( newElement );
			if( errorType != NULL )
				*errorType = CRYPT_ERRTYPE_ATTR_VALUE;
			return( CRYPT_ERROR_INVALID );
			}
		}

	/* If we're reading an encoded T61String, try and guess whether it's
	   using floating diacritics and convert them to the correct latin-1
	   representation.  This is mostly guesswork since some implementations
	   use floating diacritics and some don't, the only known user is
	   Deutsche Telekom who use them for a/o/u-umlauts so we only interpret
	   the character if the result would be one of these values */
	if( ( flags & DN_FLAG_NOCHECK ) && dnStringType == STRINGTYPE_T61 )
		{
		BYTE *valuePtr = newElement->value;
		int i;

		for( i = 0; i < newElement->valueLength - 1; i++ )
			if( valuePtr[ i ] == 0xC8 )
				{
				int ch = valuePtr[ i + 1 ];

				/* If it's an umlautable character, convert the following
				   ASCII value to the equivalent latin-1 form and move the
				   rest of the string down */
				if( ch == 'a' || ch == 'A' || ch == 'o' || ch == 'O' || \
					ch == 'u' || ch == 'U' )
					{
					valuePtr[ i ] = valuePtr[ i + 1 ] + \
									( ( ch == 'a' || ch == 'A' ) ? 131 : 135 );
					if( ch >= 'a' )
						valuePtr[ i ] += 32;
					if( newElement->valueLength - i > 2 )
						memmove( valuePtr + i + 1, valuePtr + i + 2,
								 newElement->valueLength - ( i + 2 ) );
					newElement->valueLength--;
					}
				}
		valuePtr[ newElement->valueLength ] = '\0';
		}

	/* Link it into the list */
	insertListElement( dnListHead, insertPoint, newElement );

	return( CRYPT_OK );
	}

int insertDNComponent( void **dnListHead,
					   const CRYPT_ATTRIBUTE_TYPE type,
					   const void *value, const int valueLength,
					   CRYPT_ERRTYPE_TYPE *errorType )
	{
	return( insertDNstring( dnListHead, type, value, valueLength, 0, 0,
							errorType ) );
	}

/* Delete a DN component from a list */

static int deleteComponent( void **dnListHead, DN_COMPONENT *theElement )
	{
	DN_COMPONENT *listPrevPtr, *listNextPtr;

	if( theElement == NULL )
		return( CRYPT_ERROR_NOTFOUND );
	listPrevPtr = theElement->prev;
	listNextPtr = theElement->next;

	/* Remove the item from the list */
	if( theElement == *dnListHead )
		*dnListHead = listNextPtr;			/* Delete from start */
	else
		listPrevPtr->next = listNextPtr;	/* Delete from middle or end */
	if( listNextPtr != NULL )
		listNextPtr->prev = listPrevPtr;

	/* Clear all data in the list item and free the memory */
	if( theElement->value != theElement->smallValue )
		{
		zeroise( theElement->value, theElement->valueLength );
		free( theElement->value );
		}
	zeroise( theElement, sizeof( DN_COMPONENT ) );
	free( theElement );

	return( CRYPT_OK );
	}

int deleteDNComponent( void **dnListHead,
					   const CRYPT_ATTRIBUTE_TYPE type, const void *value,
					   const int valueLength )
	{
	DN_COMPONENT *listHeadPtr = *dnListHead;

	/* If the DN is locked against modification we can't make any further
	   updates */
	if( listHeadPtr != NULL && listHeadPtr->flags & DN_FLAG_LOCKED )
		return( CRYPT_ERROR_PERMISSION );

	/* Find the component in the list and delete it */
	return( deleteComponent( dnListHead, findDNComponent( listHeadPtr, type,
													value, valueLength ) ) );
	}

/* Get the value of a DN component */

int getDNComponentValue( const void *dnListHead,
						 const CRYPT_ATTRIBUTE_TYPE type,
						 void *value, int *length, const int maxLength )
	{
	const DN_COMPONENT *dnComponent = findDNComponent( dnListHead, type,
													   NULL, 0 );

	if( dnComponent == NULL )
		return( CRYPT_ERROR_NOTFOUND );
	*length = dnComponent->valueLength;
	if( value == NULL )
		return( CRYPT_OK );
	if( dnComponent->valueLength > maxLength )
		return( CRYPT_ERROR_OVERFLOW );
	if( checkBadPtrWrite( value, dnComponent->valueLength ) )
		return( CRYPT_ARGERROR_STR1 );
	memcpy( value, dnComponent->value, dnComponent->valueLength );
	return( CRYPT_OK );
	}

/* Delete a DN component list */

void deleteDN( void **dnListHead )
	{
	DN_COMPONENT *listPtr = *dnListHead;

	/* Mark the list as being empty */
	*dnListHead = NULL;

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

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

		listPtr = listPtr->next;
		if( itemToFree->value != itemToFree->smallValue )
			{
			zeroise( itemToFree->value, itemToFree->valueLength );
			free( itemToFree->value );
			}
		zeroise( itemToFree, sizeof( DN_COMPONENT ) );
		free( itemToFree );
		}
	}

/* Compare two DN's.  Since this is used for constraint comparisons as well
   as just strict equality checks, we provide a flag which, if set, returns
   a match if the first DN is a proper substring of the second DN */

BOOLEAN compareDN( const void *dnComponentListHead1,
				   const void *dnComponentListHead2,
				   const BOOLEAN dn1substring )
	{
	DN_COMPONENT *dn1ptr = ( DN_COMPONENT * ) dnComponentListHead1;
	DN_COMPONENT *dn2ptr = ( DN_COMPONENT * ) dnComponentListHead2;

	/* Check each DN component for equality */
	while( dn1ptr != NULL && dn2ptr != NULL )
		{
		/* If the RDN types differ, the DN's don't match */
		if( dn1ptr->type != dn2ptr->type )
			return( FALSE );

		/* Compare the current RDN's */
		if( !compareASN1string( dn1ptr->value, dn1ptr->valueLength,
								dn2ptr->value, dn2ptr->valueLength ) )
			return( FALSE );

		/* Move on to the next component */
		dn1ptr = dn1ptr->next;
		dn2ptr = dn2ptr->next;
		}

	/* If we've reached the end of both DN's or we're looking for a substring
	   match, the two match */
	return( ( ( dn1ptr == NULL && dn2ptr == NULL ) || dn1substring ) ? \
			TRUE : FALSE );
	}

/* Copy a DN */

int copyDN( void **dnDest, const void *dnSrc )
	{
	const DN_COMPONENT *srcPtr = dnSrc;
	DN_COMPONENT *destPtr = NULL;

	for( *dnDest = NULL; srcPtr != NULL; srcPtr = srcPtr->next )
		{
		DN_COMPONENT *newElement;
		void *valuePtr;

		/* Allocate memory for the new element and copy over the information */
		if( ( ( newElement = \

⌨️ 快捷键说明

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