📄 testlib.c
字号:
}
status = cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
return( status );
/* Make sure the values match */
if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
{
if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) )
{
puts( "Error: Hash value of identical buffers differs." );
return( -1234 );
}
}
else
if( memcmp( buffer1, buffer2, DATABUFFER_SIZE ) )
{
printf( "Decrypted data != encrypted data for algorithm %d.\n",
cryptAlgo );
return( -1234 );
}
}
putchar( '\n' );
return( CRYPT_OK );
}
static void testDataProcessing( void )
{
CRYPT_QUERY_INFO cryptQueryInfo;
CRYPT_ALGO cryptAlgo;
int errorCount = 0, status;
for( cryptAlgo = CRYPT_ALGO_FIRST_CONVENTIONAL;
cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo,
&cryptQueryInfo ) ) )
{
if( cryptAlgo != CRYPT_ALGO_RC4 )
{
status = testProcessing( cryptAlgo, CRYPT_MODE_ECB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d ECB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
status = testProcessing( cryptAlgo, CRYPT_MODE_CBC,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d CBC mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
status = testProcessing( cryptAlgo, CRYPT_MODE_CFB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d CFB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
}
status = testProcessing( cryptAlgo, CRYPT_MODE_OFB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d OFB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
}
for( cryptAlgo = CRYPT_ALGO_FIRST_HASH;
cryptAlgo <= CRYPT_ALGO_LAST_HASH; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo, &cryptQueryInfo ) ) )
{
status = testProcessing( cryptAlgo, CRYPT_UNUSED,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d processing failed with status %d.\n",
cryptAlgo, status );
errorCount++;
}
}
for( cryptAlgo = CRYPT_ALGO_FIRST_MAC;
cryptAlgo <= CRYPT_ALGO_LAST_MAC; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo, &cryptQueryInfo ) ) )
{
status = testProcessing( cryptAlgo, CRYPT_UNUSED,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d processing failed with status %d.\n",
cryptAlgo, status );
errorCount++;
}
}
if( errorCount )
printf( "%d errors detected.\n", errorCount );
}
/* Kernel check test */
static void smokeTestAttributes( const CRYPT_HANDLE cryptHandle )
{
int attribute;
putchar( '.' );
for( attribute = CRYPT_ATTRIBUTE_NONE; attribute < 8000; attribute++ )
{
char buffer[ 1024 ];
int value;
cryptGetAttribute( cryptHandle, attribute, &value );
cryptGetAttributeString( cryptHandle, attribute, buffer, &value );
}
cryptDestroyObject( cryptHandle );
}
static void testKernelChecks( void )
{
CRYPT_HANDLE cryptHandle;
int subType;
printf( "Running kernel smoke test:\n Contexts" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateContext( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Certs" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateCert( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Envelopes" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateEnvelope( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Sessions" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateSession( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
putchar( '\n' );
}
/* Multi-threaded processing stress test. In order to add a little
nondeterminism on single-threaded machines, we need to add some sleep()
calls between crypto operations. Even this isn't perfect, there's no
real way to guarantee that they aren't simply executed in round-robin
fashion with only one thread in the kernel at a time without modifying
the kernel to provide diagnostic info */
#ifdef WINDOWS_THREADS
#define NO_THREADS 45
static void randSleep( void )
{
Sleep( ( rand() % 150 ) + 1 );
}
unsigned __stdcall processDataThread( void *arg )
{
CRYPT_CONTEXT cryptContext;
BYTE buffer[ 1024 ];
int threadNo = ( int ) arg;
int status;
randSleep();
memset( buffer, '*', 1024 );
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
CRYPT_ALGO_3DES );
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
"123456781234567812345678", 24 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptEncrypt( cryptContext, buffer, 1024 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptEncrypt( cryptContext, buffer, 0 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptDestroyContext( cryptContext );
}
if( cryptStatusError( status ) )
printf( "\nEncryption failed with status %d.\n", status );
else
printf( "%d ", threadNo );
_endthreadex( 0 );
return( 0 );
}
static void testStressThreads( void )
{
HANDLE hThreadArray[ NO_THREADS ];
int i;
/* Start the threads */
for( i = 0; i < NO_THREADS; i++ )
{
unsigned threadID;
hThreadArray[ i ] = ( HANDLE ) \
_beginthreadex( NULL, 0, &processDataThread, ( void * ) i, 0,
&threadID );
if( hThreadArray[ i ] == 0 )
printf( "Thread %d couldn't be created.\n", i );
}
printf( "Threads completed: " );
/* Wait for all the threads to complete */
if( WaitForMultipleObjects( NO_THREADS, hThreadArray, TRUE,
15000 ) == WAIT_TIMEOUT )
puts( "\nNot all threads completed in 15s." );
else
puts( "." );
for( i = 0; i < NO_THREADS; i++ )
CloseHandle( hThreadArray[ i ] );
}
#endif /* WINDOWS_THREADS */
static void smokeTest( void )
{
testDataProcessing();
testKernelChecks();
testStressObjects();
#ifdef WINDOWS_THREADS
testStressThreads();
#endif /* WINDOWS_THREADS */
}
#endif /* SMOKE_TEST */
/****************************************************************************
* *
* Misc.Kludges *
* *
****************************************************************************/
/* Update the cryptlib config file. This code can be used to set the
information required to load PKCS #11 device drivers:
- Set the driver path in the CRYPT_OPTION_DEVICE_PKCS11_DVR01 setting
below.
- Add a call to updateConfig() from somewhere (eg the test kludge function).
- Run the test code until it calls updateConfig().
- Remove the updateConfig() call, then run the test code as normal.
The testDevices() call will report the results of trying to use your
driver */
static void updateConfig( void )
{
#if 0
const char *driverPath = "d:/spool/nexus/nxpkcs11.dll"; /* Nexus */
const char *driverPath = "c:/program files/eracom/cprov sw/cryptoki.dll"; /* Eracom */
const char *driverPath = "c:/winnt/system32/dkck232.dll"; /* Datakey/iKey */
const char *driverPath = "c:/winnt/system32/slbck.dll"; /* Schlumberger */
const char *driverPath = "c:/winnt/system32/pkcs201n.dll";
const char *driverPath = "c:/winnt/system32/cryst32.dll"; /* Chrysalis */
const char *driverPath = "c:/winnt/system32/dkck201.dll"; /* Datakey */
const char *driverPath = "c:/winnt/system32/cryptoki22.dll";/* Rainbow */
const char *driverPath = "c:/winnt/system32/p11card.dll"; /* Safelayer */
const char *driverPath = "c:/winnt/system32/sadaptor.dll"; /* Eutron */
const char *driverPath = "c:/winnt/system32/pk2priv.dll"; /* Gemplus */
#endif /* 0 */
const char *driverPath = "c:/winnt/system32/pk2priv.dll"; /* Gemplus */
/* Set the path for a PKCS #11 device driver. We only enable one of
these at a time to speed the startup time */
cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_DEVICE_PKCS11_DVR01,
driverPath, strlen( driverPath ) );
/* Update the options */
cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE );
}
/* Generic test code insertion point. The following routine is called
before any of the other tests are run and can be used to handle special-
case tests which aren't part of the main test suite */
void testKludge( void )
{
/* Simple (brute-force) server code. NB: Remember to change
setLocalConnect() to not bind the server to localhost if expecting
external connections */
/* while( TRUE ) /**/
/* testSessionTSPServer(); /**/
/* Functions which can be pressed into service to generate custom certs/
keys */
/* testWriteFileCertChain(); /* To generate user priv.key+cert */
/* testReadWriteFileKey();
testDeleteFileKey();
testUpdateFileCert(); /* To generate CA priv.key+cert */
}
/****************************************************************************
* *
* Main Test Code *
* *
****************************************************************************/
#ifdef __WINDOWS__
#define INC_CHILD
#endif /* __WINDOWS__ */
/* Comprehensive cryptlib stress test */
int main( int argc, char **argv )
{
#ifdef TEST_LOWLEVEL
CRYPT_ALGO cryptAlgo;
#endif /* TEST_LOWLEVEL */
#ifdef TEST_CONFIG
int i;
#endif /* TEST_CONFIG */
int status;
void testSystemSpecific( void );
/* Get rid of compiler warnings */
if( argc || argv );
/* Make sure various system-specific features are set right */
testSystemSpecific();
/* VisualAge C++ doesn't set the TZ correctly. The check for this isn't
as simple as it would seem since most IBM compilers define the same
preprocessor values even though it's not documented anywhere, so we
have to enable the tzset() call for (effectively) all IBM compilers
and then disable it for ones other than VisualAge C++ */
#if ( defined( __IBMC__ ) || defined( __IBMCPP__ ) ) && !defined( __VMCMS__ )
tzset();
#endif /* VisualAge C++ */
/* Initialise cryptlib */
status = cryptInit();
if( cryptStatusError( status ) )
{
printf( "cryptInit() failed with error code %d.\n", status );
exit( EXIT_FAILURE );
}
#ifndef TEST_RANDOM
/* In order to avoid having to do a randomness poll for every test run,
we bypass the randomness-handling by adding some junk. This is only
enabled when cryptlib is built in debug mode, so it won't work with
any production systems */
cryptAddRandom( "a", 1 );
#endif /* TEST_RANDOM */
/* For general testing purposes we can insert test code at this point to
test special cases which aren't covered in the general tests below */
testKludge();
#ifdef SMOKE_TEST
/* Perform a general smoke test of the kernel */
smokeTest();
#endif /* SMOKE_TEST */
#ifdef TEST_SELFTEST
status = cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_SELFTESTOK, TRUE );
if( cryptStatusError( status ) )
{
printf( "cryptlib algorithm self-test failed with error code %d.\n",
status );
exit( EXIT_FAILURE );
}
puts( "cryptlib algorithm self-test succeeded.\n" );
#endif /* TEST_SELFTEST */
#ifdef TEST_LOWLEVEL
/* Test the conventional encryption routines */
for( cryptAlgo = CRYPT_ALGO_FIRST_CONVENTIONAL;
cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL; cryptAlgo++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -