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

📄 pkcs15.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
			return( CRYPT_ERROR_BADDATA );
		if( peekTag( stream ) == MAKE_CTAG( 0 ) )
			readUniversal( stream );
		status = readLongSequence( stream, NULL );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Allocate the PKCS #15 object info */
	if( ( pkcs15info = clAlloc( "initFunction", \
								sizeof( PKCS15_INFO ) * \
								MAX_PKCS15_OBJECTS ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS );
	keysetInfo->keyData = pkcs15info;
	keysetInfo->keyDataSize = sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS;

	/* If this is a newly-created keyset, there's nothing left to do */
	if( options == CRYPT_KEYOPT_CREATE )
		return( CRYPT_OK );

	/* Read all of the keys in the keyset */
	status = readKeyset( &keysetInfo->keysetFile->stream, pkcs15info, 
						 endPos );
	if( cryptStatusError( status ) )
		{
		pkcs15Free( pkcs15info );
		clFree( "initFunction", keysetInfo->keyData );
		keysetInfo->keyData = NULL;
		keysetInfo->keyDataSize = 0;
		}

	return( status );
	}

/****************************************************************************
*																			*
*						PKCS #15 Shutdown Functions							*
*																			*
****************************************************************************/

/* Write the wrapping needed for individual objects */

static void writeObjectWrapper( STREAM *stream, const int length,
								const int tag )
	{
	writeConstructed( stream, ( int ) sizeofObject( length ), tag );
	writeConstructed( stream, length, CTAG_OV_DIRECT );
	assert( sStatusOK( stream ) );
	}

/* Write a data item */

static int sizeofDataItem( const PKCS15_INFO *pkcs15infoPtr )
	{
	const int dataSize = \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
				pkcs15infoPtr->dataDataSize : \
				( int ) sizeofObject( pkcs15infoPtr->dataDataSize );
	const int labelSize = \
			( pkcs15infoPtr->labelLength ) ? \
				( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;

	return( ( int ) \
		sizeofObject( \
			sizeofObject( labelSize ) + \
			sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
			sizeofObject( \
				sizeofObject( \
					sizeofOID( OID_CRYPTLIB_CONFIGDATA ) + dataSize ) ) ) );
	}

static void writeDataItem( STREAM *stream, const PKCS15_INFO *pkcs15infoPtr )
	{
	const BYTE *oid = \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA ) ? \
				OID_CRYPTLIB_CONFIGDATA : \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX ) ? \
				OID_CRYPTLIB_USERINDEX : OID_CRYPTLIB_USERINFO;
	const int labelSize = \
			( pkcs15infoPtr->labelLength ) ? \
				( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
	const int contentSize = sizeofOID( oid ) + \
			( ( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
				pkcs15infoPtr->dataDataSize : \
				( int ) sizeofObject( pkcs15infoPtr->dataDataSize ) );

	assert( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
			pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX || \
			pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO );

	writeConstructed( stream, \
			( int ) sizeofObject( labelSize ) + \
			( int ) sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
			( int ) sizeofObject( sizeofObject( contentSize ) ),
			CTAG_DO_OIDDO );
	writeSequence( stream, labelSize );
	if( labelSize )
		writeCharacterString( stream, ( BYTE * ) pkcs15infoPtr->label,
							  pkcs15infoPtr->labelLength, BER_STRING_UTF8 );
	writeSequence( stream, sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) );
	writeOID( stream, OID_CRYPTLIB_CONTENTTYPE );
	writeConstructed( stream, ( int ) sizeofObject( contentSize ),
					  CTAG_OB_TYPEATTR );
	writeSequence( stream, contentSize );
	writeOID( stream, oid );
	if( pkcs15infoPtr->dataType != CRYPT_IATTRIBUTE_USERINFO )
		/* UserInfo is a straight object, the others are SEQUENCEs of
		   objects */
		writeSequence( stream, pkcs15infoPtr->dataDataSize );
	swrite( stream, pkcs15infoPtr->dataData, pkcs15infoPtr->dataDataSize );
	assert( sStatusOK( stream ) );
	}

/* Flush a PKCS #15 collection to a stream */

static int pkcs15Flush( STREAM *stream, const PKCS15_INFO *pkcs15info )
	{
	int pubKeySize = 0, privKeySize = 0, certSize = 0, dataSize = 0;
	int objectsSize = 0, i;

	/* Determine the overall size of the objects */
	for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
		switch( pkcs15info[ i ].type )
			{
			case PKCS15_SUBTYPE_NONE:
				break;

			case PKCS15_SUBTYPE_NORMAL:
				pubKeySize += pkcs15info[ i ].pubKeyDataSize;
				privKeySize += pkcs15info[ i ].privKeyDataSize;
				/* Drop through */

			case PKCS15_SUBTYPE_CERT:
				certSize += pkcs15info[ i ].certDataSize;
				break;

			case PKCS15_SUBTYPE_SECRETKEY:
				assert( NOTREACHED );
				break;

			case PKCS15_SUBTYPE_DATA:
				dataSize += sizeofDataItem( &pkcs15info[ i ] );
				break;

			default:
				assert( NOTREACHED );
			}

	/* Determine how much data there is to write.  If there's no data
	   present, let the caller know that the keyset is empty */
	objectsSize = \
		( pubKeySize > 0 ? \
			( int ) sizeofObject( sizeofObject( pubKeySize ) ) : 0 ) +
		( privKeySize > 0 ? \
			( int ) sizeofObject( sizeofObject( privKeySize ) ) : 0 ) +
		( certSize > 0 ? \
			( int ) sizeofObject( sizeofObject( certSize ) ) : 0 ) +
		( dataSize > 0 ? \
			( int ) sizeofObject( sizeofObject( dataSize ) ) : 0 );
	if( objectsSize <= 0 )
		return( OK_SPECIAL );

	/* Write the header information and each public key, private key, and
	   cert */
	writeCMSheader( stream, OID_PKCS15_CONTENTTYPE,
					sizeofShortInteger( 0 ) + sizeofObject( objectsSize ),
					FALSE );
	writeShortInteger( stream, 0, DEFAULT_TAG );
	writeSequence( stream, objectsSize );
	if( privKeySize > 0 )
		{
		writeObjectWrapper( stream, privKeySize, PKCS15_OBJECT_PRIVKEY );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].privKeyDataSize > 0 )
				swrite( stream, pkcs15info[ i ].privKeyData,
						pkcs15info[ i ].privKeyDataSize );
		}
	if( pubKeySize > 0 )
		{
		writeObjectWrapper( stream, pubKeySize, PKCS15_OBJECT_PUBKEY );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].pubKeyDataSize > 0 )
				swrite( stream, pkcs15info[ i ].pubKeyData,
						pkcs15info[ i ].pubKeyDataSize );
		}
	if( certSize > 0 )
		{
		writeObjectWrapper( stream, certSize, PKCS15_OBJECT_CERT );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( ( pkcs15info[ i ].type == PKCS15_SUBTYPE_NORMAL && \
				  pkcs15info[ i ].certDataSize > 0 ) || \
				( pkcs15info[ i ].type == PKCS15_SUBTYPE_CERT ) )
				swrite( stream, pkcs15info[ i ].certData,
						pkcs15info[ i ].certDataSize );
		}
	if( dataSize > 0 )
		{
		writeObjectWrapper( stream, dataSize, PKCS15_OBJECT_DATA );

		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].dataDataSize > 0 )
				writeDataItem( stream, &pkcs15info[ i ] );
		}
	assert( sStatusOK( stream ) );

	return( sflush( stream ) );
	}

/* Shut down the PKCS #15 state, flushing information to disk if necessary */

static void shutdownFunction( KEYSET_INFO *keysetInfo )
	{
	/* If the contents have been changed, commit the changes to disk */
	if( keysetInfo->flags & KEYSET_DIRTY )
		{
		BYTE buffer[ STREAM_BUFSIZE ];
		int status;

		sseek( &keysetInfo->keysetFile->stream, 0 );
		sioctl( &keysetInfo->keysetFile->stream, 
				STREAM_IOCTL_IOBUFFER, buffer, STREAM_BUFSIZE );
		status = pkcs15Flush( &keysetInfo->keysetFile->stream,
							  keysetInfo->keyData );
		sioctl( &keysetInfo->keysetFile->stream, 
				STREAM_IOCTL_IOBUFFER, NULL, 0 );
		if( status == OK_SPECIAL )
			keysetInfo->flags |= KEYSET_EMPTY;
		}

	/* Free the PKCS #15 object info */
	if( keysetInfo->keyData != NULL )
		{
		pkcs15Free( keysetInfo->keyData );
		zeroise( keysetInfo->keyData, keysetInfo->keyDataSize );
		clFree( "shutdownFunction", keysetInfo->keyData );
		}
	}

/****************************************************************************
*																			*
*									Delete a Key							*
*																			*
****************************************************************************/

static int deleteItemFunction( KEYSET_INFO *keysetInfo,
							   const KEYMGMT_ITEM_TYPE itemType,
							   const CRYPT_KEYID_TYPE keyIDtype,
							   const void *keyID, const int keyIDlength )
	{
	PKCS15_INFO *pkcs15infoPtr;

	assert( keyIDtype == CRYPT_KEYID_NAME || \
			keyIDtype == CRYPT_KEYID_URI || \
			keyIDtype == CRYPT_IKEYID_KEYID || \
			keyIDtype == CRYPT_IKEYID_ISSUERID );
	assert( keyID != NULL ); assert( keyIDlength >= 1 );

	/* Locate the appropriate object in the PKCS #15 collection */
	pkcs15infoPtr = findEntry( keysetInfo->keyData, keyIDtype, keyID,
							   keyIDlength, KEYMGMT_FLAG_NONE );
	if( pkcs15infoPtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* Clear this entry */
	pkcs15freeEntry( pkcs15infoPtr );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Keyset Access Routines							*
*																			*
****************************************************************************/

int setAccessMethodPKCS15( KEYSET_INFO *keysetInfo )
	{
	/* Set the access method pointers */
	keysetInfo->initFunction = initFunction;
	keysetInfo->shutdownFunction = shutdownFunction;
	keysetInfo->deleteItemFunction = deleteItemFunction;
	initPKCS15read( keysetInfo );
	initPKCS15write( keysetInfo );

	return( CRYPT_OK );
	}
#endif /* USE_PKCS15 */

⌨️ 快捷键说明

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