📄 testdev.c
字号:
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 + -