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

📄 testsess.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
			the SmartTrust server name below to override the AIA value.  
	#3 - Identrus aka Xetex: 
			AuthorityInfoAccess doesn't match the real server URL, requires
			the Xetex server name below to override the AIA value.
	#4 - Thawte aka Valicert
			No AuthorityInfoAccess, requires the Valicert server name below 
			to provide a server
	#5 - Verisign
			No AuthorityInfoAccess, requires the Verisign server name below 
			to provide a server */

#define OCSP_SERVER_NO		5
#if OCSP_SERVER_NO == 2
  #define OCSP_SERVER_NAME	"http://ocsp.smarttrust.com:82/ocsp"
#elif OCSP_SERVER_NO == 3
  #define OCSP_SERVER_NAME	"http://ocsp.xetex.com:8080/servlet/ocsp"
#elif OCSP_SERVER_NO == 4
  #define OCSP_SERVER_NAME	"http://ocsp2.valicert.net"
#elif OCSP_SERVER_NO == 5
  #define OCSP_SERVER_NAME	"http://ocsp.verisign.com/ocsp/status"
#endif /* OCSP server name kludge */

/* Perform an OCSP test */

static int connectOCSP( const CRYPT_SESSION_TYPE sessionType,
						const BOOLEAN revokedCert, 
						const BOOLEAN multipleCerts,
						const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CERTIFICATE cryptOCSPRequest, cryptOCSPResponse;
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_OCSP_SERVER ) ? \
							   TRUE : FALSE;
	int status;

	printf( "Testing %sOCSP %ssession...\n", localSession ? "local " : "",
			isServer ? "server " : "client " );

	/* Create the OCSP session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( status == CRYPT_ERROR_PARAM3 )	/* OCSP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	if( isServer )
		{
		CRYPT_CONTEXT cryptPrivateKey;
		CRYPT_KEYSET cryptCertStore;

		if( !setLocalConnect( cryptSession, 80, TRUE ) )
			return( FALSE );

		/* Add the responder private key */
		status = getPrivateKey( &cryptPrivateKey, SERVER_PRIVKEY_FILE, 
								USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession, 
							CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
			cryptDestroyContext( cryptPrivateKey );
			}
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "cryptSetAttribute()", 
								   status, __LINE__ ) );

		/* Add the cert store which we'll be using to provide revocation
		   information */
		status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED, 
								  DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME, 
								  CRYPT_KEYOPT_READONLY );
		if( status == CRYPT_ERROR_PARAM3 )
			{
			/* This type of keyset access isn't available, return a special 
			   error code to indicate that the test wasn't performed, but 
			   that this isn't a reason to abort processing */
			puts( "No certificate store available, aborting OCSP responder "
				  "test.\n" );
			cryptDestroySession( cryptSession );
			return( CRYPT_ERROR_NOTAVAIL );
			}
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession, 
							CRYPT_SESSINFO_KEYSET, cryptCertStore );
			cryptKeysetClose( cryptCertStore );
			}
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "cryptSetAttribute()", 
								   status, __LINE__ ) );
		}
	else
		{
		/* Create the OCSP request */
		if( !initOCSP( &cryptOCSPRequest, localSession ? 1 : OCSP_SERVER_NO,
					   ( OCSP_SERVER_NO == 1 || localSession ) ? TRUE : FALSE, 
					   revokedCert, multipleCerts, CRYPT_UNUSED ) )
			return( FALSE );

		/* Set up the server information and activate the session.  In 
		   theory the OCSP request will contain all the information needed 
		   for the session so there'd be nothing else to add before we 
		   activate it, however many certs contain incorrect server URLs so 
		   we set the server name manually if necessary, overriding the 
		   value present in the OCSP request (via the cert) */
		status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST, 
									cryptOCSPRequest );
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptSession, "cryptSetAttribute()", 
								   status, __LINE__ ) );
		cryptDestroyCert( cryptOCSPRequest );
		if( localSession && !setLocalConnect( cryptSession, 80, FALSE ) )
			return( FALSE );
#ifdef OCSP_SERVER_NAME
		if( !localSession )
			{
			printf( "Setting OCSP server to %s.\n", OCSP_SERVER_NAME );
			status = cryptSetAttributeString( cryptSession, 
								CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME, 
								strlen( OCSP_SERVER_NAME ) );
			if( cryptStatusError( status ) )
				return( attrErrorExit( cryptSession, 
									   "cryptSetAttributeString()", status, 
									   __LINE__ ) );
			}
#endif /* Kludges for incorrect authorityInfoAccess values */
		if( OCSP_SERVER_NO == 1 || localSession )
			{
			/* The cryptlib server doesn't handle the weird v1 certIDs */
			status = cryptSetAttribute( cryptSession, 
										CRYPT_SESSINFO_PROTOCOLVERSION, 2 );
			if( cryptStatusError( status ) )
				return( attrErrorExit( cryptSession, "cryptSetAttribute()", 
									   status, __LINE__ ) );
			}
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( isServer )
		printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, isServer ? \
					   "Attempt to activate OCSP server session" : \
					   "Attempt to activate OCSP client session", status, 
					   __LINE__ );
		cryptDestroySession( cryptSession );
		if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_BUSY || \
			status == CRYPT_ERROR_PERMISSION )
			{
			/* These servers are constantly appearing and disappearing so if 
			   we get a straight connect error we don't treat it as a serious
			   failure.  In addition we can get server busy and no permission
			   to access errors which are also treated as soft errors */
			puts( "  (Server could be down or busy or unavailable, faking it "
				  "and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		return( FALSE );
		}

	/* Obtain the response information */
	if( !isServer )
		{
		status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, 
									&cryptOCSPResponse );
		if( cryptStatusError( status ) )
			{
			printf( "cryptGetAttribute() failed with error code %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		printCertInfo( cryptOCSPResponse );
		}

	/* There are so many weird ways to delegate trust and signing authority 
	   mentioned in the OCSP RFC without any indication of which one 
	   implementors will follow that we can't really perform any sort of
	   automated check since every responder seems to interpret this
	   differently, and many require manual installation of responder certs
	   in order to function */
#if 0
	status = cryptCheckCert( cryptOCSPResponse , CRYPT_UNUSED );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptOCSPResponse , "cryptCheckCert()", 
							   status, __LINE__ ) );
#endif /* 0 */
	cryptDestroyCert( cryptOCSPResponse );

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	puts( isServer ? "OCSP server session succeeded.\n" : \
					 "OCSP client session succeeded.\n" );
	return( TRUE );
	}

int testSessionOCSP( void )
	{
	if( !connectOCSP( CRYPT_SESSION_OCSP, FALSE, FALSE, FALSE ) )
		return( FALSE );
#if OCSP_SERVER_NO == 1
	if( !( connectOCSP( CRYPT_SESSION_OCSP, TRUE, FALSE, FALSE ) ) )
		return( FALSE );
	return( connectOCSP( CRYPT_SESSION_OCSP, FALSE, TRUE, FALSE ) );
#else
	return( TRUE );
#endif /* Server which has a revoked cert */
	}
int testSessionOCSPServer( void )
	{
	return( connectOCSP( CRYPT_SESSION_OCSP_SERVER, FALSE, FALSE, FALSE ) );
	}

/* Perform a local client/server test */

#ifdef WINDOWS_THREADS

unsigned __stdcall ocspServerThread( void *dummy )
	{
	connectOCSP( CRYPT_SESSION_OCSP_SERVER, FALSE, FALSE, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}

int testSessionOCSPClientServer( void )
	{
	HANDLE hThread;
	unsigned threadID;
	int status;

	/* Start the server and wait for it to initialise */
	hThread = ( HANDLE ) _beginthreadex( NULL, 0, &ocspServerThread,
										 NULL, 0, &threadID );
	Sleep( 1000 );

	/* Connect to the local server */
	status = connectOCSP( CRYPT_SESSION_OCSP, FALSE, FALSE, TRUE );
	if( WaitForSingleObject( hThread, 15000 ) == WAIT_TIMEOUT )
		{
		puts( "Warning: Server thread is still active due to session "
			  "negotiation failure,\n         this will cause an error "
			  "condition when cryptEnd() is called due\n         to "
			  "resources remaining allocated.  Press a key to continue." );
		getchar();
		}
	CloseHandle( hThread );

	return( status );
	}
#endif /* WINDOWS_THREADS */

/****************************************************************************
*																			*
*								TSP Routines Test							*
*																			*
****************************************************************************/

/* There are various test OCSP servers running, the following remapping 
   allows us to switch between them.  Implementation peculiarities:

	#1 - cryptlib:
			None
	#2 - Peter Sylvester
			None
	#3 - Timeproof
			None
	#4 - ????
	#5 - IAIK Graz
			Never been seen active */

#define TSP_SERVER1_NAME	"localhost"
#define TSP_SERVER2_NAME	"http://www.edelweb.fr/cgi-bin/tspservice"
#define TSP_SERVER3_NAME	"test.timeproof.de"
#define TSP_SERVER4_NAME	"203.238.37.132:3318"
#define TSP_SERVER5_NAME	"193.171.241.44:318"

#define TSP_SERVER_NAME		TSP_SERVER3_NAME

/* Perform a timestamping test */

static int connectTSP( const CRYPT_SESSION_TYPE sessionType,
					   const CRYPT_HANDLE externalCryptContext,
					   const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CONTEXT hashContext;
	const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_TSP_SERVER ) ? \
							   TRUE : FALSE;
	int status;

	printf( "Testing %sTSP %ssession...\n", localSession ? "local " : "",
			isServer ? "server " : "" );

	/* Create the TSP session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType );
	if( status == CRYPT_ERROR_PARAM3 )	/* TSP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	if( isServer )
		{
		CRYPT_CONTEXT privateKey = externalCryptContext;

		if( !setLocalConnect( cryptSession, 318, TRUE ) )
			return( FALSE );
		if( externalCryptContext == CRYPT_UNUSED )
			status = getPrivateKey( &privateKey, TSA_PRIVKEY_FILE, 
									USER_PRIVKEY_LABEL, 
									TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			{
			status = cryptSetAttribute( cryptSession, 
							CRYPT_SESSINFO_PRIVATEKEY, privateKey );
			if( externalCryptContext == CRYPT_UNUSED )
				cryptDestroyContext( privateKey );
			}
#ifdef __UNIX__
		/* If we're running under Unix, set the port to a nonprivileged
		   one so we don't have to run as root */
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptSession, 
							CRYPT_SESSINFO_SERVER_PORT, 3318 );
#endif /* __UNIX__ */
		}
	else
		{
		/* Create the hash value to add to the TSP request */
		cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA );
		cryptEncrypt( hashContext, "12345678", 8 );
		cryptEncrypt( hashContext, "", 0 );

		/* Set up the server information and activate the session */
		status = cryptSetAttribute( cryptSession, 
							CRYPT_SESSINFO_TSP_MSGIMPRINT, hashContext );
		if( cryptStatusError( status ) )
			{
			printf( "cryptSetAttribute() failed with error code %d, line %d.\n", 
					status, __LINE__ );
			return( FALSE );
			}
		cryptDestroyContext( hashContext );
		if( localSession )
			{
			if( !setLocalConnect( cryptSession, 318, FALSE ) )
				return( FALSE );
			}
		else
			status = cryptSetAttributeString( cryptSession, 
							CRYPT_SESSINFO_SERVER_NAME, TSP_SERVER_NAME, 
							strlen( TSP_SERVER_NAME ) );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute/cryptSetAttributeString() failed with "
				"error code %d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( isServer )
		printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, isServer ? \
					   "Attempt to activate TSP server session" : \
					   "Attempt to activate TSP client session", status, 
					   __LINE__ );
		cryptDestroySession( cryptSession );
		if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_BUSY || \
			status == CRYPT_ERROR_PERMISSION )
			{
			/* These servers are constantly appearing and disappearing so if 
			   we get a straight connect error we don't treat it as a serious
			   failure.  In addition we can get server busy and no permission
			   to access errors which are also treated as soft errors */

⌨️ 快捷键说明

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