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

📄 pkcs11_init.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
	   to be v1 even though it might work in practice */
	pC_GetFunctionList = ( CK_C_GetFunctionList ) \
				DynamicBind( pkcs11Info->hPKCS11, "C_GetFunctionList" );
	if( pC_GetFunctionList == NULL )
		status = CKR_GENERAL_ERROR;
	else
		status = pC_GetFunctionList( &pkcs11Info->functionListPtr ) & 0xFFFF;
	if( status != CKR_OK )
		{
		/* Free the library reference and clear the info */
		DynamicUnload( pkcs11Info->hPKCS11 );
		memset( pkcs11Info, 0, sizeof( PKCS11_DRIVER_INFO ) );
		return( CRYPT_ERROR );
		}
	status = C_Initialize( NULL_PTR ) & 0xFFFF;
	if( status == CKR_OK || status == CKR_CRYPTOKI_ALREADY_INITIALIZED )
		{
		isInitialised = TRUE;
		status = C_GetInfo( &info ) & 0xFFFF;
		if( status == CKR_OK && info.cryptokiVersion.major <= 1 )
			{
			/* It's v1, we can't work with it */
			status = CKR_FUNCTION_NOT_SUPPORTED;
			}
		}
	if( status != CKR_OK )
		{
		if( isInitialised )
			C_Finalize( NULL_PTR );
		DynamicUnload( pkcs11Info->hPKCS11 );
		memset( pkcs11Info, 0, sizeof( PKCS11_DRIVER_INFO ) );
		return( CRYPT_ERROR );
		}
#endif /* USE_EXPLICIT_LINKING */

	/* Copy out the device driver's name so that the user can access it by 
	   name.  Some vendors erroneously null-terminate the string so we check 
	   for nulls as well */
	memcpy( pkcs11Info->name, info.libraryDescription, 32 );
	while( i > 0 && ( pkcs11Info->name[ i - 1 ] == ' ' || \
					  !pkcs11Info->name[ i - 1 ] ) )
		i--;
	pkcs11Info->name[ i ] = '\0';

	return( CRYPT_OK );
	}

void deviceEndPKCS11( void )
	{
	int i;

	if( pkcs11Initialised )
		for( i = 0; i < MAX_PKCS11_DRIVERS; i++ )
			{
			if( pkcs11InfoTbl[ i ].hPKCS11 != NULL_INSTANCE )
				{
#ifdef USE_EXPLICIT_LINKING
				pkcs11InfoTbl[ i ].pC_Finalize( NULL_PTR );
#else
				PKCS11_DRIVER_INFO *pkcs11Info = &pkcs11InfoTbl[ i ];

				C_Finalize( NULL_PTR );
#endif /* USE_EXPLICIT_LINKING */
				DynamicUnload( pkcs11InfoTbl[ i ].hPKCS11 );
				}
			pkcs11InfoTbl[ i ].hPKCS11 = NULL_INSTANCE;
			}
	pkcs11Initialised = FALSE;
	}

int deviceInitPKCS11( void )
	{
	int tblIndex = 0, optionIndex;

	/* If we've previously tried to init the drivers, don't try it again */
	if( pkcs11Initialised )
		return( CRYPT_OK );
	memset( pkcs11InfoTbl, 0, sizeof( pkcs11InfoTbl ) );

	/* Try and link in each driver specified in the config options.  Since
	   this is a general systemwide config option, we always query the built-
	   in default user object */
	for( optionIndex = 0; optionIndex < MAX_PKCS11_DRIVERS; optionIndex++ )
		{
		MESSAGE_DATA msgData;
		char deviceDriverName[ MAX_PATH_LENGTH + 1 + 8 ];
		int status;

		setMessageData( &msgData, deviceDriverName, MAX_PATH_LENGTH );
		status = krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE, 
						IMESSAGE_GETATTRIBUTE_S, &msgData, 
						optionIndex + CRYPT_OPTION_DEVICE_PKCS11_DVR01 );
		if( cryptStatusError( status ) )
			continue;
		deviceDriverName[ msgData.length ] = '\0';
		status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ], 
								   deviceDriverName );
		if( cryptStatusOK( status ) )
			{
			tblIndex++;
			pkcs11Initialised = TRUE;
			}
		}

	/* If it's a Unix system and there were no drivers explicitly specified,
	   try with the default driver name "libpkcs11.so".  Unlike Windows,
	   where there are large numbers of PKCS #11 vendors and we have to use
	   vendor-specific names, under Unix there are very few vendors and 
	   there's usually only one device/driver in use which inevitably 
	   co-opts /usr/lib for its own use, so we can always try for a standard
	   name and location.

	   As a backup measure, we try for the nCipher PKCS #11 driver, which is
	   by far the most commonly used one on Unix systems (this may sometimes 
	   be found as /usr/lib/libcknfast.so) */
#ifdef UNIX
	if( !pkcs11Initialised )
		{
		status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ], 
								   "libpkcs11.so" );
		if( cryptStatusOK( status ) )
			pkcs11Initialised = TRUE;
		}
	if( !pkcs11Initialised )
		{
		status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ], 
								   "/opt/nfast/toolkits/pkcs11/libcknfast.so" );
		if( cryptStatusOK( status ) )
			pkcs11Initialised = TRUE;
		}
#endif /* UNIX */
	
	return( pkcs11Initialised ? CRYPT_OK : CRYPT_ERROR );
	}

#else

int deviceInitPKCS11( void )
	{
	int status;

	/* If we've previously tried to init the drivers, don't try it again */
	if( pkcs11Initialised )
		return( CRYPT_OK );

	status = C_Initialize( NULL_PTR );
	if( status != CKR_OK && status != CKR_CRYPTOKI_ALREADY_INITIALIZED )
		return( CRYPT_ERROR );
	pkcs11Initialised = TRUE;
	return( CRYPT_OK );
	}

void deviceEndPKCS11( void )
	{
	if( pkcs11Initialised )
		C_Finalize( NULL_PTR );
	pkcs11Initialised = FALSE;
	}
#endif /* DYNAMIC_LOAD */

/****************************************************************************
*																			*
*						 	Device Capability Routines						*
*																			*
****************************************************************************/

/* The reported key size for PKCS #11 implementations is rather inconsistent,
   most are reported in bits, a number don't return a useful value, and a few
   are reported in bytes.  The following macros sort out which algorithms
   have valid key size info and which report the length in bytes */

#define keysizeValid( algo ) \
	( ( algo ) == CRYPT_ALGO_DH || ( algo ) == CRYPT_ALGO_RSA || \
	  ( algo ) == CRYPT_ALGO_DSA || ( algo ) == CRYPT_ALGO_RC2 || \
	  ( algo ) == CRYPT_ALGO_RC4 || ( algo ) == CRYPT_ALGO_RC5 || \
	  ( algo ) == CRYPT_ALGO_CAST )
#define keysizeInBytes( algo ) \
	( ( algo ) == CRYPT_ALGO_RC5 || ( algo ) == CRYPT_ALGO_CAST )

/* Templates for the various capabilities.  These contain only basic 
   information, the remaining fields are filled in when the capability is 
   set up */

static CAPABILITY_INFO FAR_BSS capabilityTemplates[] = {
	/* Encryption capabilities */
	{ CRYPT_ALGO_DES, bitsToBytes( 64 ), "DES", 3,
		MIN_KEYSIZE, bitsToBytes( 64 ), bitsToBytes( 64 ) },
	{ CRYPT_ALGO_3DES, bitsToBytes( 64 ), "3DES", 4,
		bitsToBytes( 64 + 8 ), bitsToBytes( 128 ), bitsToBytes( 192 ) },
#ifdef USE_IDEA
	{ CRYPT_ALGO_IDEA, bitsToBytes( 64 ), "IDEA", 4,
		MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 128 ) },
#endif /* USE_IDEA */
#ifdef USE_CAST
	{ CRYPT_ALGO_CAST, bitsToBytes( 64 ), "CAST-128", 8,
		MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 128 ) },
#endif /* USE_CAST */
#ifdef USE_RC2
	{ CRYPT_ALGO_RC2, bitsToBytes( 64 ), "RC2", 3,
		MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 1024 ) },
#endif /* USE_RC2 */
#ifdef USE_RC4
	{ CRYPT_ALGO_RC4, bitsToBytes( 8 ), "RC4", 3,
		MIN_KEYSIZE, bitsToBytes( 128 ), 256 },
#endif /* USE_RC4 */
#ifdef USE_RC5
	{ CRYPT_ALGO_RC5, bitsToBytes( 64 ), "RC5", 3,
		MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 832 ) },
#endif /* USE_RC5 */
	{ CRYPT_ALGO_AES, bitsToBytes( 128 ), "AES", 3,
		bitsToBytes( 128 ), bitsToBytes( 128 ), bitsToBytes( 256 ) },
#ifdef USE_BLOWFISH
	{ CRYPT_ALGO_BLOWFISH, bitsToBytes( 64 ), "Blowfish", 8,
		MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 448 ) },
#endif /* USE_BLOWFISH */
#ifdef USE_SKIPJACK
	{ CRYPT_ALGO_SKIPJACK, bitsToBytes( 64 ), "Skipjack", 8,
		bitsToBytes( 80 ), bitsToBytes( 80 ), bitsToBytes( 80 ) },
#endif /* USE_SKIPJACK */

	/* Hash capabilities */
#ifdef USE_MD2
	{ CRYPT_ALGO_MD2, bitsToBytes( 128 ), "MD2", 3,
		bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_MD2 */
#ifdef USE_MD5
	{ CRYPT_ALGO_MD5, bitsToBytes( 128 ), "MD5", 3,
		bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_MD2 */
	{ CRYPT_ALGO_SHA1, bitsToBytes( 160 ), "SHA1", 3,
		bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#ifdef USE_SHA2
	{ CRYPT_ALGO_SHA2, bitsToBytes( 256 ), "SHA2", 4,
		bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_SHA2 */

	/* MAC capabilities */
#ifdef USE_HMAC_MD5
	{ CRYPT_ALGO_HMAC_MD5, bitsToBytes( 128 ), "HMAC-MD5", 8,
	  bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#endif /* USE_HMAC_MD5 */
	{ CRYPT_ALGO_HMAC_SHA, bitsToBytes( 160 ), "HMAC-SHA", 8,
	  bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#ifdef USE_HMAC_RIPEMD160
	{ CRYPT_ALGO_HMAC_RIPEMD160, bitsToBytes( 160 ), "HMAC-RIPEMD160", 14,
	  bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#endif /* USE_HMAC_RIPEMD160 */

	/* Public-key capabilities */
#ifdef USE_DH
	{ CRYPT_ALGO_DH, bitsToBytes( 0 ), "Diffie-Hellman", 14,
		MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#endif /* USE_DH */
	{ CRYPT_ALGO_RSA, bitsToBytes( 0 ), "RSA", 3,
		MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#ifdef USE_DSA
	{ CRYPT_ALGO_DSA, bitsToBytes( 0 ), "DSA", 3,
		MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#endif /* USE_DSA */

	/* Hier ist der Mast zu ende */
	{ CRYPT_ERROR }, { CRYPT_ERROR }
	};

/* Query a given capability for a device and fill out a capability info
   record for it if present */

static CAPABILITY_INFO *getCapability( const DEVICE_INFO *deviceInfo,
									   const PKCS11_MECHANISM_INFO *mechanismInfoPtr,
									   const int maxMechanisms )
	{
	VARIABLE_CAPABILITY_INFO *capabilityInfo;
	CK_MECHANISM_INFO pMechanism;
	CK_RV status;
	const CRYPT_ALGO_TYPE cryptAlgo = mechanismInfoPtr->cryptAlgo;
	const BOOLEAN isPKC = ( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
							cryptAlgo <= CRYPT_ALGO_LAST_PKC ) ? TRUE : FALSE;
	const CK_FLAGS keyGenFlag = isPKC ? CKF_GENERATE_KEY_PAIR : CKF_GENERATE;
	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
	int hardwareOnly, i, iterationCount;

	assert( isReadPtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
	assert( isReadPtr( mechanismInfoPtr, \
					   maxMechanisms * sizeof( PKCS11_MECHANISM_INFO ) ) );

	/* Get the information for this mechanism.  Since many PKCS #11 drivers
	   implement some of their capabilities using God knows what sort of 
	   software implementation, we provide the option to skip emulated 
	   mechanisms if required */
	status = C_GetMechanismInfo( pkcs11Info->slotID, 
								 mechanismInfoPtr->mechanism,
								 &pMechanism );
	if( status != CKR_OK )
		return( NULL );
	krnlSendMessage( deviceInfo->ownerHandle, IMESSAGE_GETATTRIBUTE, 
					 &hardwareOnly, CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY );
	if( hardwareOnly && !( pMechanism.flags & CKF_HW ) )
		return( NULL );

	/* Copy across the template for this capability */
	if( ( capabilityInfo = clAlloc( "getCapability", \
									sizeof( CAPABILITY_INFO ) ) ) == NULL )
		return( NULL );
	for( i = 0; capabilityTemplates[ i ].cryptAlgo != cryptAlgo && \
				capabilityTemplates[ i ].cryptAlgo != CRYPT_ERROR && \
				i < FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO ); 
		 i++ );
	if( i >= FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO ) || \
		capabilityTemplates[ i ].cryptAlgo == CRYPT_ERROR )
		retIntError_Null();
	memcpy( capabilityInfo, &capabilityTemplates[ i ],
			sizeof( CAPABILITY_INFO ) );

	/* Set up the keysize information if there's anything useful available */
	if( keysizeValid( cryptAlgo ) )
		{
		int minKeySize = ( int ) pMechanism.ulMinKeySize;
		int maxKeySize = ( int ) pMechanism.ulMaxKeySize;

		/* Adjust the key size to bytes and make sure that all values are 
		   consistent.  Some implementations report silly lower bounds (e.g. 
		   1-bit RSA, "You naughty minKey") so we adjust them to a sane value 
		   if necessary.  We also limit the maximum key size to match the
		   cryptlib native max.key size, both for consistency and because
		   cryptlib performs buffer allocation based on the maximum native
		   buffer size */
		if( !keysizeInBytes( cryptAlgo ) )
			{
			minKeySize = bitsToBytes( minKeySize );
			maxKeySize = bitsToBytes( maxKeySize );
			}
		if( minKeySize > capabilityInfo->minKeySize )
			capabilityInfo->minKeySize = minKeySize;

⌨️ 快捷键说明

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