예제 #1
0
void InfoTests::testGetInfo()
{
	CK_RV rv;
	CK_INFO ckInfo;

	// Just make sure that we finalize any previous failed tests
	C_Finalize(NULL_PTR);

	rv = C_GetInfo(&ckInfo);
	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);

	rv = C_Initialize(NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_OK);

	rv = C_GetInfo(NULL_PTR);
	CPPUNIT_ASSERT(rv == CKR_ARGUMENTS_BAD);

	rv = C_GetInfo(&ckInfo);
	CPPUNIT_ASSERT(rv == CKR_OK);

	C_Finalize(NULL_PTR);
}
예제 #2
0
static int loadPKCS11driver( PKCS11_DRIVER_INFO *pkcs11Info,
							 const char *driverName )
	{
	CK_C_GetFunctionList pC_GetFunctionList;
	CK_INFO info DUMMY_INIT_STRUCT;
	CK_RV status;
#ifdef __WIN16__
	UINT errorMode;
#endif /* __WIN16__ */
	BOOLEAN isInitialised = FALSE;
	int i = 32;

	assert( isWritePtr( pkcs11Info, sizeof( PKCS11_DRIVER_INFO ) ) );
	assert( isReadPtr( driverName, 4 ) );

	/* Obtain a handle to the device driver module */
#ifdef __WIN16__
	errorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX );
	pkcs11Info->hPKCS11 = LoadLibrary( driverName );
	SetErrorMode( errorMode );
	if( pkcs11Info->hPKCS11 < HINSTANCE_ERROR )
		{
		pkcs11Info->hPKCS11 = NULL_HINSTANCE;
		return( CRYPT_ERROR );
		}
#else
	if( ( pkcs11Info->hPKCS11 = DynamicLoad( driverName ) ) == NULL_INSTANCE )
		return( CRYPT_ERROR );
#endif /* OS-specific dynamic load */

	/* Get the access information for the PKCS #11 library, initialise it, 
	   and get information on the device.  There are four types of PKCS #11 
	   driver around: v1, v1-like claiming to be v2, v2-like claiming to be 
	   v1, and v2.  cryptlib can in theory handle all of these, however 
	   there are some problem areas with v1 (for example v1 uses 16-bit 
	   values while v2 uses 32-bit ones, this is usually OK because data is 
	   passed around as 32-bit values with the high bits zeroed but some 
	   implementations may leave garbage in the high 16 bits that leads to 
	   all sorts of confusion).  Because of this we explicitly fail if 
	   something claims 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
		{
		CK_FUNCTION_LIST_PTR functionListPtr;

		/* The following two-step initialisation is needed because PKCS #11 
		   uses a 1-byte alignment on structs, which means that if we pass
		   in the pkcs11Info member address directly we run into alignment
		   problems with 64-bit architectures */
		status = pC_GetFunctionList( &functionListPtr ) & 0xFFFF;
		if( status == CKR_OK )
			pkcs11Info->functionListPtr = functionListPtr;
		}
	if( status != CKR_OK )
		{
		/* Free the library reference and clear the information */
		DynamicUnload( pkcs11Info->hPKCS11 );
		memset( pkcs11Info, 0, sizeof( PKCS11_DRIVER_INFO ) );
		return( CRYPT_ERROR );
		}
	status = C_Initialize( NULL_PTR ) & 0xFFFF;
	if( status == CKR_ARGUMENTS_BAD && \
		strFindStr( driverName, strlen( driverName ), "softokn3.", 9 ) >= 0 )
		{
		typedef struct CK_C_INITIALIZE_ARGS {
			CK_CREATEMUTEX CreateMutex;
			CK_DESTROYMUTEX DestroyMutex;
			CK_LOCKMUTEX LockMutex;
			CK_UNLOCKMUTEX UnlockMutex;
			CK_FLAGS flags;
			CK_VOID_PTR LibraryParameters;
			CK_VOID_PTR pReserved;
			} Netscape_CK_C_INITIALIZE_ARGS;
		Netscape_CK_C_INITIALIZE_ARGS initArgs;

		/* Netscape invented their own extension to CK_C_INITIALIZE_ARGS, 
		   adding a 'LibraryParameters' string to allow the specification of 
		   free-form parameters.  If the Netscape library's C_Initialize()
		   is called then it'll return CKR_ARGUMENTS_BAD (rather than 
		   assuming sensible default values), so that we have to call it 
		   again with explicitly-specified parameters.

		   Even this doesn't work properly though, according to the Netscape 
		   docs we can set LibraryParameters to NULL, but this still results 
		   in C_Initialize() returning CKR_ARGUMENTS_BAD.  Later in the docs
		   is a requirement that the softokn3 library be passed a 
		   "parameters=" string, but it's unclear what parameters need to be 
		   set, to what values, and what effect these values may have on the
		   behaviour of existing configs for applications like Firefox.  The
		   following config lets the C_Initialize() call succeed but causes
		   odd failures later in other PKCS #11 functions */
		DEBUG_DIAG(( "Driver is the buggy Netscape/NSS one that requires "
					 "nonstandard initialisation, see the code comment for "
					 "details" ));
		assert( DEBUG_WARN );
		memset( &initArgs, 0, sizeof( Netscape_CK_C_INITIALIZE_ARGS ) );
		initArgs.LibraryParameters = \
			"configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db' "
			"flags=noModDB,noCertDB,noKeyDB,optimizeSpace,readOnly";
		status = C_Initialize( &initArgs );
		}
	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 );
		}

	/* 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 );
	}