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

📄 trustmgr.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:

		/* Generate the checksum and hash of the cert object's subject name and 
		   key ID */
		status = dynCreate( &subjectDB, iCryptCert, CRYPT_IATTRIBUTE_SUBJECT );
		if( cryptStatusError( status ) )
			return( status );
		status = dynCreate( &subjectKeyDB, iCryptCert, 
							CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
		if( cryptStatusOK( status ) )
			hasSKID = TRUE;
		newElement->sCheck = checksumData( dynData( subjectDB ), 
										   dynLength( subjectDB ) );
		hashData( newElement->sHash, dynData( subjectDB ), 
				  dynLength( subjectDB ) );
		if( hasSKID )
			{
			newElement->kCheck = checksumData( dynData( subjectKeyDB ), 
											   dynLength( subjectKeyDB ) );
			hashData( newElement->kHash, dynData( subjectKeyDB ), 
					  dynLength( subjectKeyDB ) );
			dynDestroy( &subjectKeyDB );
			}
		else
			{
			newElement->kCheck = 0;
			hashData( newElement->kHash, NULL, 0 );
			}
		dynDestroy( &subjectDB );
		}
	if( certObject != NULL || recreateCert )
		{
		DYNBUF certDB;
		int objectLength = certObjectLength, status;

		/* If we're using the data from an existing cert object, all we still
		   need is the encoded data */
		if( recreateCert )
			{
			/* Get the encoded cert */
			status = dynCreate( &certDB, iCryptCert, 
								CRYPT_CERTFORMAT_CERTIFICATE );
			if( cryptStatusError( status ) )
				return( status );
			certObject = dynData( certDB );
			objectLength = dynLength( certDB );
			}
		else
			{
			STREAM stream;
			const BYTE *extensionPtr;
			const void *subjectDNptr, *subjectKeyIDptr;
			int subjectDNsize, subjectKeyIDsize;
			int extensionSize = 0, i;

			/* Parse the certificate to locate the start of the encoded
			   subject DN and cert extensions (if present) */
			sMemConnect( &stream, certObject, certObjectLength );
			readSequence( &stream, NULL );	/* Outer wrapper */
			readSequence( &stream, NULL );	/* Inner wrapper */
			if( peekTag( &stream ) == MAKE_CTAG( 0 ) )
				readUniversal( &stream );	/* Version */
			readUniversal( &stream );		/* Serial number */
			readUniversal( &stream );		/* Sig.algo */
			readUniversal( &stream );		/* Issuer DN */
			readUniversal( &stream );		/* Validity */
			subjectDNptr = sMemBufPtr( &stream );
			readSequence( &stream, &subjectDNsize );
			subjectDNsize = sizeofObject( subjectDNsize );
			readUniversal( &stream );		/* Subject DN */
			status = readUniversal( &stream );/* Public key */
			if( cryptStatusOK( status ) && \
				peekTag( &stream ) == MAKE_CTAG( 3 ) )
				{
				status = readConstructed( &stream, &extensionSize, 3 );
				if( cryptStatusOK( status ) )
					{
					extensionPtr = sMemBufPtr( &stream );
					sSkip( &stream, extensionSize );
					}
				}
			if( cryptStatusOK( status ) )	/* Signature */
				status = readUniversal( &stream );
			sMemDisconnect( &stream );
			if( cryptStatusError( status ) )
				{
				clFree( "addEntry", newElement );
				assert( NOTREACHED );
				return( CRYPT_ERROR_BADDATA );
				}

			/* Now look for the subjectKeyID in the extensions.  It's easier
			   to do a pattern match than to try and parse the extensions */
			subjectKeyIDptr = NULL;
			subjectKeyIDsize = 0;
			for( i = 0; i < extensionSize - 64; i++ )
				{
				/* Look for the OID.  This potentially skips two bytes at a
				   time, but this is safe since the preceding bytes can never
				   contain either of these two values (they're 0x30, len) */
				if( extensionPtr[ i++ ] != BER_OBJECT_IDENTIFIER || \
					extensionPtr[ i++ ] != 3 )
					continue;
				if( memcmp( extensionPtr + i, "\x55\x1D\x0E", 3 ) )
					continue;
				i += 3;

				/* We've found the OID (with 1.1e-12 error probability), skip
				   the critical flag if necessary */
				if( extensionPtr[ i ] == BER_BOOLEAN )
					i += 3;

				/* Check for the OCTET STRING and a reasonable length */
				if( extensionPtr[ i++ ] != BER_OCTETSTRING || \
					extensionPtr[ i ] & 0x80 )
					continue;

				/* Extract the key ID */
				if( i + extensionPtr[ i ] <= extensionSize )
					{
					subjectKeyIDsize = extensionPtr[ i++ ];
					subjectKeyIDptr = extensionPtr + i;
					}
				}

			/* Generate the checksum and hash of the encoded cert's subject 
			   name and key ID */
			newElement->sCheck = checksumData( subjectDNptr, subjectDNsize );
			hashData( newElement->sHash, subjectDNptr, subjectDNsize );
			newElement->kCheck = checksumData( subjectKeyIDptr, subjectKeyIDsize );
			hashData( newElement->kHash, subjectKeyIDptr, subjectKeyIDsize );
			}

		/* Remember the trusted cert data for later use */
		if( ( newElement->certObject = clAlloc( "addEntry", 
												objectLength ) ) == NULL )
			{
			clFree( "addEntry", newElement );
			if( recreateCert )
				dynDestroy( &certDB );
			return( CRYPT_ERROR_MEMORY );
			}
		memcpy( newElement->certObject, certObject, objectLength );
		newElement->certObjectLength = objectLength;
		newElement->iCryptCert = CRYPT_ERROR;

		/* Clean up */
		if( recreateCert )
			dynDestroy( &certDB );
		}
	else
		{
		/* The trusted key exists as a standard cert with a public-key 
		   context attached, remember it for later */
		krnlSendNotifier( iCryptCert, IMESSAGE_INCREFCOUNT );
		newElement->iCryptCert = iCryptCert;
		}

	/* Add it to the list */
	trustInfoEntry = newElement->sCheck & ( TRUSTINFO_SIZE - 1 );
	if( trustInfoIndex[ trustInfoEntry ] == NULL )
		trustInfoIndex[ trustInfoEntry ] = newElement;
	else
		{
		TRUST_INFO *trustInfoCursor;

		/* Add the new element to the end of the list */
		for( trustInfoCursor = trustInfoIndex[ trustInfoEntry ];
			 trustInfoCursor->next != NULL; 
			 trustInfoCursor = trustInfoCursor->next );
		trustInfoCursor->next = newElement;
		}

	return( CRYPT_OK );
	}

int addTrustEntry( void *trustInfoPtr, const CRYPT_CERTIFICATE iCryptCert, 
				   const void *certObject, const int certObjectLength, 
				   const BOOLEAN addSingleCert )
	{
	BOOLEAN seenNonDuplicate = FALSE;
	int status;

	assert( ( isHandleRangeValid( iCryptCert ) && certObject == NULL ) || \
			( iCryptCert == CRYPT_UNUSED && certObject != NULL ) );

	/* If we're adding encoded cert data, we can add it directly */
	if( certObject != NULL )
		return( addEntry( trustInfoPtr, CRYPT_UNUSED, certObject, 
						  certObjectLength ) );

	/* Add the cert/each cert in the trust list */
	status = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusError( status ) )
		return( status );
	if( !addSingleCert )
		/* It's a trust list, move to the start of the list */
		krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
						 MESSAGE_VALUE_CURSORFIRST,
						 CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	do
		{
		/* Add the certificate info if it's not already present */
		if( findTrustEntry( trustInfoPtr, iCryptCert, FALSE ) == NULL )
			{
			seenNonDuplicate = TRUE;
			status = addEntry( trustInfoPtr, iCryptCert, NULL, 0 );
			}
		}
	while( cryptStatusOK( status ) && !addSingleCert && \
		   krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
							MESSAGE_VALUE_CURSORNEXT,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK );
	krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, 
					 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusOK( status ) && !seenNonDuplicate )
		/* There were no new certs to add present, return an inited error */
		status = CRYPT_ERROR_INITED;
	
	return( status );
	}

void deleteTrustEntry( void *trustInfoPtr, void *trustEntry )
	{
	TRUST_INFO **trustInfoIndex = ( TRUST_INFO ** ) trustInfoPtr;
	TRUST_INFO *entryToDelete = ( TRUST_INFO * ) trustEntry, *prevInfoPtr;
	const int trustInfoEntry = entryToDelete->sCheck & ( TRUSTINFO_SIZE - 1 );

	assert( trustInfoIndex[ trustInfoEntry ] != NULL );

	/* Unlink the trust info index */
	prevInfoPtr = trustInfoIndex[ trustInfoEntry ];
	if( prevInfoPtr == entryToDelete )
		/* Unlink from the start of the list */
		trustInfoIndex[ trustInfoEntry ] = entryToDelete->next;
	else
		{
		/* Unlink from the middle/end of the list */
		while( prevInfoPtr->next != entryToDelete )
			prevInfoPtr = prevInfoPtr->next;
		prevInfoPtr->next = entryToDelete->next;
		}

	/* Free the trust info entry */
	if( entryToDelete->iCryptCert != CRYPT_ERROR )
		krnlSendNotifier( entryToDelete->iCryptCert, IMESSAGE_DECREFCOUNT );
	if( entryToDelete->certObject != NULL )
		{
		zeroise( entryToDelete->certObject, entryToDelete->certObjectLength );
		clFree( "deleteTrustEntry", entryToDelete->certObject );
		}
	memset( entryToDelete, 0, sizeof( TRUST_INFO ) );
	clFree( "deleteTrustEntry", entryToDelete );
	}

/****************************************************************************
*																			*
*						Init/Shut down Trusted Cert Info					*
*																			*
****************************************************************************/

/* Initialise and shut down the trust information */

int initTrustInfo( void **trustInfoPtrPtr )
	{
	TRUST_INFO *trustInfoIndex;

	/* Initialise the trust information table */
	if( ( trustInfoIndex = \
			clAlloc( "initTrustInfo", TRUSTINFO_SIZE * \
									  sizeof( TRUST_INFO * ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( trustInfoIndex, 0, TRUSTINFO_SIZE * sizeof( TRUST_INFO * ) );
	*trustInfoPtrPtr = trustInfoIndex;
	return( CRYPT_OK );
	}

void endTrustInfo( void *trustInfoPtr )
	{
	TRUST_INFO **trustInfoIndex = ( TRUST_INFO ** ) trustInfoPtr;
	int i;

	if( trustInfoIndex == NULL )
		return;

	/* Destroy the chain of items at each table position */
	for( i = 0; i < TRUSTINFO_SIZE; i++ )
		{
		TRUST_INFO *trustInfoCursor = trustInfoIndex[ i ];

		/* Destroy any items in the list */
		while( trustInfoCursor != NULL )
			{
			TRUST_INFO *itemToFree = trustInfoCursor;

			trustInfoCursor = trustInfoCursor->next;
			deleteTrustEntry( trustInfoIndex, itemToFree );
			}
		}
	memset( trustInfoIndex, 0, TRUSTINFO_SIZE * sizeof( TRUST_INFO * ) );
	clFree( "endTrustInfo", trustInfoIndex );
	}

⌨️ 快捷键说明

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