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

📄 stress.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:

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 );
	printf( "\n" );
	}

/****************************************************************************
*																			*
*							Simple Threading Stress Test					*
*																			*
****************************************************************************/

/* 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_SIMPLE_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_SIMPLE_THREADS ];
	int i;

	/* Start the threads */
	for( i = 0; i < NO_SIMPLE_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_SIMPLE_THREADS, hThreadArray, TRUE,
								15000 ) == WAIT_TIMEOUT )
		puts( "\nNot all threads completed in 15s." );
	else
		puts( "." );
	for( i = 0; i < NO_SIMPLE_THREADS; i++ )
		CloseHandle( hThreadArray[ i ] );
	}
#endif /* WINDOWS_THREADS */

#if defined( UNIX_THREADS ) || defined( WINDOWS_THREADS )

#ifdef UNIX_THREADS
  void *envelopeDataThread( void *arg )
#else
  unsigned __stdcall envelopeDataThread( void *arg )
#endif /* Different threading models */
	{
	static const char *envData = "qwertyuiopasdfghjklzxcvbnm";
	BYTE fileBuffer[ BUFFER_SIZE ];
	const unsigned uThread = ( unsigned ) arg;
	const time_t startTime = time( NULL );
	int count, status;

	printf( "Thread %d started.\n", uThread );
	fflush( stdout );

	filenameFromTemplate( fileBuffer, CERT_FILE_TEMPLATE, 13 );

	for( count = 0; count < 150; count++ )
		{
		CRYPT_ENVELOPE cryptEnvelope;
		CRYPT_CERTIFICATE cryptCert;
		BYTE envBuffer[ BUFFER_SIZE ];
		int bytesCopied;

		/* Create the cert and envelope and add the cert to the envelope */
		status = importCertFile( &cryptCert, fileBuffer );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED,
										  CRYPT_FORMAT_CRYPTLIB );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope,
										CRYPT_ENVINFO_PUBLICKEY, cryptCert );
		if( cryptStatusError( status ) )
			break;

		/* Envelope data and destroy the envelope */
		status = cryptPushData( cryptEnvelope, envData, strlen( envData ),
								&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, NULL, 0, NULL );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, envBuffer, BUFFER_SIZE,
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			break;
		printf( "%c", uThread + '0' );
		}

	printf( "Thread %u exited after %d seconds.\n", uThread,
			time( NULL ) - startTime );
	fflush( stdout );
#ifdef UNIX_THREADS
	pthread_exit( NULL );
#else
	_endthreadex( 0 );
#endif /* Different threading models */
	return( 0 );
	}

static void testContinuousThreads( void )
	{
	unsigned threadID1, threadID2;
#ifdef UNIX_THREADS
	pthread_t thread1, thread2;
#else
	HANDLE hThread1, hThread2;
#endif /* Different threading models */

	cryptAddRandom( "xyzzy", 5 );
#ifdef UNIX_THREADS
	pthread_create( &thread1, NULL, envelopeDataThread, ( void * ) 1 );
	pthread_create( &thread2, NULL, envelopeDataThread, ( void * ) 2 );
#else
	hThread1 = ( HANDLE ) _beginthreadex( NULL, 0, envelopeDataThread,
										  ( void * ) 1, 0, &threadID1 );
	hThread2 = ( HANDLE ) _beginthreadex( NULL, 0, envelopeDataThread,
										  ( void * ) 2, 0, &threadID2 );
#endif /* Different threading models */
	delayThread( 30 );
	printf( "Hit a key..." );
	fflush( stdout );
	getchar();
	cryptEnd();
	exit( EXIT_SUCCESS );
	}
#endif /* UNIX_THREADS || WINDOWS_THREADS */

/****************************************************************************
*																			*
*							Complex Threading Stress Test					*
*																			*
****************************************************************************/

/* Unlike the previous test, there's enough nondeterminism added in this one
   that things go out of sync all by themselves */

#ifdef WINDOWS_THREADS

#define NO_COMPLEX_THREADS	4

unsigned __stdcall signTest( void *arg ) 
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CONTEXT privateKeyContext;
	CRYPT_ENVELOPE cryptEnvelope;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "SignTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, TEST_PRIVKEY_FILE, 
								  CRYPT_KEYOPT_READONLY);
		if( cryptStatusOK( status ) )
			status = cryptGetPrivateKey( cryptKeyset, &privateKeyContext, 
										 CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL, 
										 TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_SIGNATURE, 
										privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, "message", 7, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyContext( privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptKeysetClose( cryptKeyset );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}

unsigned __stdcall encTest( void *arg ) 
	{
	CRYPT_ENVELOPE cryptEnvelope;
	CRYPT_CERTIFICATE cryptCert;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "EncTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		FILE *filePtr;
		int certSize;

		if( ( filePtr = fopen( "testdata/cert5.der", "rb" ) ) != NULL ) 
			{
			certSize = fread( buffer, 1, 1024, filePtr );
			fclose( filePtr );
			}

		status = cryptImportCert( buffer, certSize, CRYPT_UNUSED, 
								  &certificate );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_PUBLICKEY, cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, buffer, 200, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
								   &bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyCert( cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}

int testStressThreadsComplex( void ) 
	{
	HANDLE hThreads[ NO_COMPLEX_THREADS ];
	int i;

	cryptAddRandom( NULL, CRYPT_RANDOM_SLOWPOLL );

	for( i = 0; i < 1000; i++ )
		{
		unsigned dwThreadId;
		int j;

		hThreads[ 0 ] = ( HANDLE ) \
			_beginthreadex( NULL, 0, encTest, &i, 0, &dwThreadId );
		hThreads[ 1 ] = ( HANDLE ) \
			_beginthreadex( NULL, 0, signTest, &i, 0, &dwThreadId );
		hThreads[ 2 ] = ( HANDLE ) \
			_beginthreadex( NULL, 0, encTest, &i, 0, &dwThreadId );
		hThreads[ 3 ] = ( HANDLE ) \
			_beginthreadex( NULL, 0, signTest, &i, 0, &dwThreadId );

		WaitForMultipleObjects( NO_COMPLEX_THREADS, hThreads, TRUE, 
								INFINITE );
	
		for( j = 0; j < NO_COMPLEX_THREADS; j++ ) 
			CloseHandle( hThreads[ j ] );
		}

	return 0;
	}
#endif /* WINDOWS_THREADS */

/****************************************************************************
*																			*
*									Test Interface							*
*																			*
****************************************************************************/

void smokeTest( void )
	{
	testDataProcessing();
	testKernelChecks();
	testStressObjects();
#if defined( UNIX_THREADS ) || defined( WINDOWS_THREADS )
	testStressThreadsSimple();
	testStressThreadsComplex();
#endif /* UNIX_THREADS || WINDOWS_THREADS */
	}
#endif /* SMOKE_TEST */

⌨️ 快捷键说明

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