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

📄 comp_get.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
	const CRYPT_ATTRIBUTE_TYPE fieldID = certInfoPtr->attributeCursor->fieldID;
	ATTRIBUTE_LIST *attributeListPtr;
	int iterationCount;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	/* We're inside a GeneralName, clear any possible saved selection */
	certInfoPtr->currentSelection.generalName = CRYPT_ATTRIBUTE_NONE;

	REQUIRES( selectionInfoConsistent( certInfoPtr ) );

	/* Search for a DN in the current GeneralName */
	for( attributeListPtr = certInfoPtr->attributeCursor, 
			iterationCount = 0; 
		 attributeListPtr != NULL && \
			attributeListPtr->attributeID == attributeID && \
			attributeListPtr->fieldID == fieldID && \
			iterationCount < FAILSAFE_ITERATIONS_MAX;
		 attributeListPtr = attributeListPtr->next, iterationCount++ )
		{
		if( attributeListPtr->fieldType == FIELDTYPE_DN )
			{
			/* We found a DN, select it */
			certInfoPtr->currentSelection.dnPtr = &attributeListPtr->value;
			if( updateCursor )
				certInfoPtr->attributeCursor = attributeListPtr;
			certInfoPtr->currentSelection.dnInExtension = TRUE;
			ENSURES( selectionInfoConsistent( certInfoPtr ) );

			return( CRYPT_OK );
			}
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );

	return( CRYPT_ERROR_NOTFOUND );
	}

/* Find a GeneralName field in a GeneralName */

#if 0

/* Currently handled with:

	attributeListPtr = findAttributeField( certInfoPtr->attributeCursor,
										   certInfoPtr->attributeCursor->fieldID,
										   certInfoType ); */

static const ATTRIBUTE_LIST *findGeneralNameField( const ATTRIBUTE_LIST *attributeListPtr,
												   const CRYPT_ATTRIBUTE_TYPE certInfoType )
	{
	const CRYPT_ATTRIBUTE_TYPE attributeID = attributeListPtr->attributeID;
	const CRYPT_ATTRIBUTE_TYPE fieldID = attributeListPtr->fieldID;
	int iterationCount;

	REQUIRES( isGeneralNameSelectionComponent( attributeListPtr->fieldID ) );

	/* Search for the GeneralName component in the current GeneralName */
	for( iterationCount = 0;
		 attributeListPtr != NULL && \
			attributeListPtr->attributeID == attributeID && \
			attributeListPtr->fieldID == fieldID && \
			iterationCount < FAILSAFE_ITERATIONS_LARGE;
		 attributeListPtr = attributeListPtr->next, iterationCount++ )
		{
		if( attributeListPtr->subFieldID == certInfoType )
			return( attributeListPtr );
		}
	ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_LARGE );

	return( NULL );
	}
#endif /* 0 */

/* Move the extension cursor to the given extension field */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int moveCursorToField( INOUT CERT_INFO *certInfoPtr,
					   const CRYPT_ATTRIBUTE_TYPE certInfoType )
	{
	const ATTRIBUTE_LIST *attributeListPtr;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( selectionInfoConsistent( certInfoPtr ) );
	REQUIRES( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
			  certInfoType <= CRYPT_CERTINFO_LAST );

	/* Try and locate the given field in the extension */
	attributeListPtr = findAttributeField( certInfoPtr->attributes,
										   certInfoType,
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* We found the given field, update the cursor and select the DN within
	   it if it's present */
	certInfoPtr->currentSelection.updateCursor = FALSE;
	certInfoPtr->attributeCursor = ( ATTRIBUTE_LIST * ) attributeListPtr;
	if( isGeneralNameSelectionComponent( certInfoType ) )
		{
		/* If this is a GeneralName, select the DN within it if there's one
		   present.  Since this is peripheral to the main operation of 
		   moving the cursor, we ignore the return status */
		( void ) findDnInExtension( certInfoPtr, FALSE );
		}
	ENSURES( selectionInfoConsistent( certInfoPtr ) );

	return( CRYPT_OK );
	}

/* Synchronise DN/GeneralName selection information after moving the
   extension cursor */

STDC_NONNULL_ARG( ( 1 ) ) \
void syncSelection( INOUT CERT_INFO *certInfoPtr )
	{
	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	/* We've moved the cursor, clear any saved GeneralName selection */
	certInfoPtr->currentSelection.generalName = CRYPT_ATTRIBUTE_NONE;

	/* I've we've moved the cursor off the GeneralName or there's no DN in
	   the GeneralName, deselect the DN */
	if( !isGeneralNameSelected( certInfoPtr ) || \
		cryptStatusError( findDnInExtension( certInfoPtr, FALSE ) ) )
		{
		certInfoPtr->currentSelection.dnPtr = NULL;
		certInfoPtr->currentSelection.dnInExtension = FALSE;
		}
	}

/* Handle selection of a GeneralName in a certificate extension */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int selectGeneralName( INOUT CERT_INFO *certInfoPtr,
					   IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
					   IN_ENUM( SELECTION_OPTION ) const SELECTION_OPTION option )
	{
	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

#ifndef __WINCE__	/* String too long for compiler */
	REQUIRES( ( option == MAY_BE_ABSENT && \
				isGeneralNameSelectionComponent( certInfoType ) ) || \
			  ( ( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT ) && \
				certInfoType == CRYPT_ATTRIBUTE_NONE ) );
#endif /* !__WINCE__ */
	REQUIRES( selectionInfoConsistent( certInfoPtr ) );

	certInfoPtr->currentSelection.updateCursor = FALSE;

	if( option == MAY_BE_ABSENT )
		{
		/* If the selection is present, update the extension cursor and
		   exit */
		if( cryptStatusOK( moveCursorToField( certInfoPtr, certInfoType ) ) )
			return( CRYPT_OK );

		/* If the certificate is in the high state then the MAY is treated 
		   as a MUST since we can't be selecting something in order to 
		   create it later as we can for a certificate in the low state */
		if( certInfoPtr->certificate != NULL )
			return( CRYPT_ERROR_NOTFOUND );

		/* The selection isn't present, remember it for later without
		   changing any other selection info */
		certInfoPtr->currentSelection.generalName = certInfoType;
		certInfoPtr->attributeCursor = NULL;

		ENSURES( selectionInfoConsistent( certInfoPtr ) );

		return( CRYPT_OK );
		}

	ENSURES( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT );

	/* If there's no saved GeneralName selection present, the extension
	   cursor must be pointing to a GeneralName */
	if( certInfoPtr->currentSelection.generalName == CRYPT_ATTRIBUTE_NONE )
		{
		return( isGeneralNameSelected( certInfoPtr ) ? \
				CRYPT_OK : CRYPT_ERROR_NOTFOUND );
		}

	/* Try and move the cursor to the saved GeneralName selection */
	if( cryptStatusOK( \
			moveCursorToField( certInfoPtr,
							   certInfoPtr->currentSelection.generalName ) ) )
		return( CRYPT_OK );
	if( option == MUST_BE_PRESENT )
		return( CRYPT_ERROR_NOTFOUND );

	/* We're creating the GeneralName extension, deselect the current DN and
	   remember that we have to update the extension cursor when we've done
	   it */
	certInfoPtr->currentSelection.dnPtr = NULL;
	certInfoPtr->currentSelection.dnInExtension = FALSE;
	certInfoPtr->currentSelection.updateCursor = TRUE;

	ENSURES( selectionInfoConsistent( certInfoPtr ) );

	return( CRYPT_OK );
	}

/* Handle selection of DNs */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int selectDN( INOUT CERT_INFO *certInfoPtr, 
			  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
			  IN_ENUM( SELECTION_OPTION ) const SELECTION_OPTION option )
	{
	CRYPT_ATTRIBUTE_TYPE generalName = \
							certInfoPtr->currentSelection.generalName;
	static const int value = CRYPT_UNUSED;
	int status;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( ( option == MAY_BE_ABSENT && \
				isDNSelectionComponent( certInfoType ) ) || \
			  ( ( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT ) && \
				certInfoType == CRYPT_ATTRIBUTE_NONE ) );
	REQUIRES( selectionInfoConsistent( certInfoPtr ) );

	if( option == MAY_BE_ABSENT )
		{
		/* Try and select a DN based on the supplied attribute ID */
		switch( certInfoType )
			{
			case CRYPT_CERTINFO_SUBJECTNAME:
				certInfoPtr->currentSelection.dnPtr = &certInfoPtr->subjectName;
				break;

			case CRYPT_CERTINFO_ISSUERNAME:
				certInfoPtr->currentSelection.dnPtr = &certInfoPtr->issuerName;

				/* If it's a self-signed certificate and the issuer name 
				   isn't explicitly present then it must be implicitly 
				   present as the subject name */
				if( certInfoPtr->issuerName == NULL && \
					( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) )
					certInfoPtr->currentSelection.dnPtr = &certInfoPtr->subjectName;
				break;

			default:
				retIntError();
			}

		/* We've selected a built-in DN, remember that this isn't one in an
		   (optional) extension */
		certInfoPtr->currentSelection.dnInExtension = FALSE;

		ENSURES( selectionInfoConsistent( certInfoPtr ) );

		return( CRYPT_OK );
		}

	/* If there's a DN already selected, we're done */
	if( certInfoPtr->currentSelection.dnPtr != NULL )
		return( CRYPT_OK );

	ENSURES( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT );

	/* To select a DN in a GeneralName we first need to have a GeneralName
	   selected */
	status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE, option );
	if( cryptStatusError( status ) )
		return( status );

	/* If we've now got a GeneralName selected, try and find a DN in it */
	if( isGeneralNameSelected( certInfoPtr ) )
		{
		/* If there's a DN currently selected, we're done */
		if( certInfoPtr->attributeCursor->fieldType == FIELDTYPE_DN )
			{
			certInfoPtr->currentSelection.dnPtr = \
							&certInfoPtr->attributeCursor->value;
			certInfoPtr->currentSelection.dnInExtension = TRUE;

			ENSURES( selectionInfoConsistent( certInfoPtr ) );

			return( CRYPT_OK );
			}

		/* There's no DN selected, see if there's one present somewhere in
		   the extension */
		if( cryptStatusOK( findDnInExtension( certInfoPtr, TRUE ) ) )
			return( CRYPT_OK );

		/* If there's no DN present and we're not about to create one,
		   exit */
		if( option == MUST_BE_PRESENT )
			return( CRYPT_ERROR_NOTFOUND );

		/* Create the DN in the currently selected GeneralName */
		generalName = certInfoPtr->attributeCursor->fieldID;
		}

	/* We're being asked to instantiate the DN, create the attribute field
	   that contains it */
	status = addAttributeField( &certInfoPtr->attributes, generalName,
						CRYPT_CERTINFO_DIRECTORYNAME, &value, CRYPT_UNUSED,
						ATTR_FLAG_NONE, &certInfoPtr->errorLocus,
						&certInfoPtr->errorType );
	if( cryptStatusError( status ) )
		return( status );

	/* Find the field that we just created.  This is a newly-created
	   attribute so it's the only one present (i.e we don't have to worry
	   about finding one added at the end of the sequence of identical
	   attributes) and we also know that it must be present since we've
	   just created it */
	return( selectGeneralName( certInfoPtr, generalName, MAY_BE_ABSENT ) );
	}

/****************************************************************************
*																			*
*							Get Certificate Info							*
*																			*
****************************************************************************/

/* Copy integer-value data from a certificate */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int copyCertInfoValue( OUT TYPECAST( int * ) void *certInfo, 
							  const int value )
	{
	assert( isWritePtr( certInfo, sizeof( int ) ) );

	if( certInfo != NULL )
		*( ( int * ) certInfo ) = value;
	return( CRYPT_OK );
	}

/* Get a certificate component */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getCertAttributeComponentData( const ATTRIBUTE_LIST *attributeListPtr,
				OUT_BUFFER_OPT( certInfoMaxLength, certInfoLength ) void *certInfo, 
				IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
				OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
				certInfoMaxLength < MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* If the data type is an OID we have to convert it to a human-readable
	   form before we return it */
	if( attributeListPtr->fieldType == BER_OBJECT_IDENTIFIER )
		{
		char textOID[ ( CRYPT_MAX_TEXTSIZE * 2 ) + 8 ];
		int textOidLength, status;

		ENSURES( certInfoLength != NULL );

		status = oidToText( attributeListPtr->value, 
							attributeListPtr->valueLength, 
							textOID, CRYPT_MAX_TEXTSIZE * 2, 
							&textOidLength );
		if( cryptStatusError( status ) )

⌨️ 快捷键说明

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