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

📄 testdev.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
		puts( "Error: Couldn't locate public key in device." );
		pubKeyContext = CRYPT_UNUSED;
		}
	status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
								 CRYPT_KEYID_NAME, keyLabel, NULL );
	if( cryptStatusOK( status ) )
		{
		puts( "Found a private key in the device, details follow..." );
		printCertChainInfo( privKeyContext );
		if( pubKeyContext == CRYPT_UNUSED )
			{
			/* No explicit public key found, try using the private key for
			   both key types */
			puts( "No public key found, attempting to continue using the "
				  "private key as both a\n  public and a private key." );
			pubKeyContext = privKeyContext;
			}
		}
	else
		{
		puts( "Error: Couldn't locate private key in device." );
		privKeyContext = CRYPT_UNUSED;
		}
	sigKeyContext = privKeyContext;
	if( deviceType == CRYPT_DEVICE_FORTEZZA )
		{
		cryptDestroyContext( pubKeyContext );	/* pubK is sig.only */
		status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
									 CRYPT_KEYID_NAME, "Test KEA key", NULL );
		if( cryptStatusOK( status ) )
			{
			puts( "Found a key agreement key in the device, details follow..." );
			printCertChainInfo( privKeyContext );
			pubKeyContext = privKeyContext;		/* Fortezza allows both uses */
			}
		else
			{
			pubKeyContext = CRYPT_UNUSED;
			privKeyContext = CRYPT_UNUSED;
			}
		}

	/* If we got something, try some simple operations with it */
	if( pubKeyContext != CRYPT_UNUSED )
		{
		if( !testCMSEnvelopePKCCryptEx( pubKeyContext, cryptDevice, password ) )
			return( FALSE );
		}
	else
		puts( "Public-key enveloping tests skipped because no key was "
			  "available.\n" );
	if( sigKeyContext != CRYPT_UNUSED )
		{
		if( !testCMSEnvelopeSignEx( sigKeyContext ) )
			return( FALSE );
		}
	else
		puts( "Signed enveloping tests skipped because no key was "
			  "available." );

	/* Test the key with a server session, meant to imitate use with an HSM.
	   This is disabled by default since it requires the simultaneous use of
	   both a client and server session, which has to be done manually */
#if 0
	testSessionTSPServerEx( sigKeyContext );
#endif /* 0 */

	/* Clean up */
	if( pubKeyContext == CRYPT_UNUSED && sigKeyContext == CRYPT_UNUSED )
		return( FALSE );
	if( privKeyContext != CRYPT_UNUSED )
		cryptDestroyContext( privKeyContext );
	if( sigKeyContext != CRYPT_UNUSED && privKeyContext != sigKeyContext )
		cryptDestroyContext( sigKeyContext );
	if( pubKeyContext != CRYPT_UNUSED && pubKeyContext != privKeyContext )
		cryptDestroyContext( pubKeyContext );
	return( TRUE );
	}

/* General device test routine */

static int testCryptoDevice( const CRYPT_DEVICE_TYPE deviceType,
							 const char *deviceName,
							 const DEVICE_CONFIG_INFO *deviceInfo )
	{
	CRYPT_DEVICE cryptDevice;
	BOOLEAN isWriteProtected = FALSE, isAutoDetect = FALSE;
	BOOLEAN initDevice = FALSE, testResult = FALSE, partialSuccess = FALSE;
	int status;

	/* Open a connection to the device */
	if( deviceType == CRYPT_DEVICE_PKCS11 || \
		deviceType == CRYPT_DEVICE_CRYPTOAPI )
		{
		if( !memcmp( deviceInfo->name, "[A", 2 ) )
			{
			printf( "\nTesting %s with autodetection...\n", deviceName );
			isAutoDetect = TRUE;
			}
		else
			printf( "\nTesting %s %s...\n", deviceInfo->name, deviceName );
		status = cryptDeviceOpen( &cryptDevice, CRYPT_UNUSED, deviceType,
								  deviceInfo->name );
		}
	else
		{
		printf( "\nTesting %s...\n", deviceName );
		status = cryptDeviceOpen( &cryptDevice, CRYPT_UNUSED, deviceType,
								  deviceName );
		}
	if( status == CRYPT_ERROR_PARAM2 )
		{
		puts( "Support for this device type isn't enabled in this build of "
			  "cryptlib." );
		return( CRYPT_ERROR_NOTAVAIL );	/* Device access not available */
		}
	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ERROR_PARAM3 || status == CRYPT_ERROR_NOTFOUND )
			puts( "Crypto device not detected, skipping test." );
		else
			printf( "cryptDeviceOpen() failed with error code %d, line %d.\n",
					status, __LINE__ );
		return( FALSE );
		}

	/* If it's one of the smarter classes of device, authenticate ourselves to
	   the device, which is usually required in order to allow it to be used
	   fully */
	if( deviceType == CRYPT_DEVICE_PKCS11 || deviceType == CRYPT_DEVICE_FORTEZZA )
		{
		deviceInfo = checkLogonDevice( cryptDevice, deviceType, deviceInfo, 
									   isAutoDetect, TEST_INITIALISE_CARD );
		if( deviceInfo == NULL )
			return( FALSE );
		}

	/* Write-protected devices won't allow contexts to be created in them,
	   before we try the general device capabilities test we make sure we
	   can actually perform the operation */
	if( deviceType == CRYPT_DEVICE_PKCS11 )
		{
		CRYPT_CONTEXT cryptContext;

		/* Try and create a DES object.  The following check for read-only
		   devices always works because the device object ACL is applied at
		   a much higher level than any device capability checking, the
		   device will never even see the create object message if it's
		   write-protected so all we have to do is make sure that whatever
		   we create is ephemeral */
		status = cryptDeviceCreateContext( cryptDevice, &cryptContext,
										   CRYPT_ALGO_DES );
		if( cryptStatusOK( status ) )
			cryptDestroyContext( cryptContext );
		if( status == CRYPT_ERROR_PERMISSION )
			isWriteProtected = TRUE;
		}

	/* To force the code not to try to create keys and certs in a writeable
	   device, uncomment the following line of code.  This requires that keys/
	   certs of the required type are already present in the device */
/*	KLUDGE_WARN( "write-protect status" );
	isWriteProtected = TRUE;				/**/
	if( !isWriteProtected && TEST_KEYGEN )
		{
		/* If it's a device that we can initialise (currently limited to 
		   soft-tokens only to avoid wiping crypto hardware that may have 
		   keys on it), go through a full initialisation */
		if( !strcmp( deviceInfo->name, "ERACOM Software Only" ) || \
			!strcmp( deviceInfo->name, "Software Only" ) || \
			TEST_INITIALISE_CARD )
			{
			status = initialiseDevice( cryptDevice, deviceType, 
									   deviceInfo );
			if( status == FALSE )
				{
				cryptDeviceClose( cryptDevice );
				return( FALSE );
				}
			}
		else
			{
			/* There may be test keys lying around from an earlier run, in 
			   which case we try to delete them to make sure they won't 
			   interfere with the current one */
			deleteTestKey( cryptDevice, "Test CA key", "CA" );
			deleteTestKey( cryptDevice, deviceInfo->keyLabel, "user" );
			if( deviceType == CRYPT_DEVICE_PKCS11 )
				{
				deleteTestKey( cryptDevice, RSA_PUBKEY_LABEL, "RSA public" );
				deleteTestKey( cryptDevice, RSA_PRIVKEY_LABEL, "RSA private" );
				deleteTestKey( cryptDevice, DSA_PUBKEY_LABEL, "DSA public" );
				deleteTestKey( cryptDevice, DSA_PRIVKEY_LABEL, "DSA private" );
				}
			if( deviceType == CRYPT_DEVICE_FORTEZZA )
				deleteTestKey( cryptDevice, "Test KEA key", "KEA" );
			}
		}

	/* Report what the device can do.  This is intended mostly for simple
	   crypto accelerators and may fail with for devices that work only
	   with the higher-level functions centered around certificates,
	   signatures,and key wrapping, so we skip the tests for devices that
	   allow only high-level access */
	if( deviceType != CRYPT_DEVICE_FORTEZZA )
		testResult = testDeviceCapabilities( cryptDevice, deviceName,
											 isWriteProtected );


	/* If it's a smart device, try various device-specific operations */
	if( deviceType == CRYPT_DEVICE_FORTEZZA || \
		deviceType == CRYPT_DEVICE_PKCS11 )
		partialSuccess = testDeviceHighlevel( cryptDevice, deviceType,
								deviceInfo->keyLabel, deviceInfo->password,
								isWriteProtected );

	/* Clean up */
	status = cryptDeviceClose( cryptDevice );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDeviceClose() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	if( !testResult && !partialSuccess )
		return( FALSE );
	if( testResult && partialSuccess )
		printf( "%s tests succeeded.\n\n", deviceName );
	else
		printf( "Some %s tests succeeded.\n\n", deviceName );
	return( TRUE );
	}

int testDevices( void )
	{
	int i, status;

	/* Test Fortezza devices */
#if 1
	status = testCryptoDevice( CRYPT_DEVICE_FORTEZZA, "Fortezza card",
							   &fortezzaDeviceInfo );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_NOTAVAIL )
		return( status );
#endif /* 0 */

	/* Test PKCS #11 devices */
#if 1
	for( i = 0; pkcs11DeviceInfo[ i ].name != NULL; i++ )
		{
		status = testCryptoDevice( CRYPT_DEVICE_PKCS11, "PKCS #11 crypto token",
								   &pkcs11DeviceInfo[ i ] );
		if( cryptStatusError( status ) && \
			!( status == CRYPT_ERROR_NOTAVAIL || \
			   ( i == 0 && status == CRYPT_ERROR_WRONGKEY ) ) )
			return( status );
		}
#endif /* 0 */

#if 0	/* For test purposes only to check CAPI data, don't use the CAPI code */
#ifdef __WINDOWS__
	for( i = 0; capiDeviceInfo[ i ].name != NULL; i++ )
		{
		status = testCryptoDevice( CRYPT_DEVICE_CRYPTOAPI, "Microsoft CryptoAPI",
								   &capiDeviceInfo[ i ] );
		if( cryptStatusError( status ) && \
			!( status == CRYPT_ERROR_NOTAVAIL || \
			   ( i == 0 && status == CRYPT_ERROR_WRONGKEY ) ) )
			return( status );
		}
#endif /* __WINDOWS__ */
#endif /* 0 */
	putchar( '\n' );
	return( TRUE );
	}

/****************************************************************************
*																			*
*							User Management Routines Test					*
*																			*
****************************************************************************/

int testUser( void )
	{
	CRYPT_USER cryptUser;
	int status;

	puts( "Testing (minimal) user management functions..." );

	/* Perform a zeroise.  This currently isn't done because (a) it would
	   zeroise all user data whenever anyone runs the self-test and (b) the
	   external API to trigger this isn't defined yet */
/*	status = cryptZeroise( ... ); */

	/* Log in as primary SO using the zeroisation password.  Because of the
	   above situation this currently performs an implicit zeroise */
	status = cryptLogin( &cryptUser, "Security officer", "zeroised" );
	if( cryptStatusError( status ) )
		{
		printf( "cryptLogin() (Primary SO) failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* Set the SO password */
	status = cryptSetAttributeString( cryptUser, CRYPT_USERINFO_PASSWORD,
									  "password", 8 );
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttributeString() failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* Log out and log in again with the new password.  At the moment it's
	   possible to use any password until the PKCS #15 attribute situation
	   is resolved */
	status = cryptLogout( cryptUser );
	if( cryptStatusError( status ) )
		{
		printf( "cryptLogout() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptLogin( &cryptUser, "Security officer", "password" );
	if( cryptStatusError( status ) )
		{
		printf( "cryptLogin() (SO) failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Clean up */
	cryptLogout( cryptUser );
	puts( "User management tests succeeded.\n" );
	return( TRUE );
	}

⌨️ 快捷键说明

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