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

📄 sreqresp.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
			{
			printf( "cryptGetAttribute() failed with error code %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		printCertInfo( cryptRTCSResponse );
		}

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

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

static int connectRTCSDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct RTCS query...\n" );

	/* Get the EE cert */
	status = importCertFromTemplate( &cryptCert, RTCS_FILE_TEMPLATE,
									 RTCS_SERVER_NO );
	if( cryptStatusError( status ) )
		{
		printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the RTCS session and add the server URL */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_RTCS );
	if( status == CRYPT_ERROR_PARAM3 )	/* RTCS session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
#ifdef RTCS_SERVER_NAME
	status = cryptSetAttributeString( cryptSession,
								CRYPT_SESSINFO_SERVER_NAME, RTCS_SERVER_NAME,
								paramStrlen( RTCS_SERVER_NAME ) );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptSession, "cryptSetAttributeString()",
							   status, __LINE__ ) );
#endif /* Kludges for incorrect/missing authorityInfoAccess values */

	/* Check the cert directly against the server */
	status = cryptCheckCert( cryptCert, cryptSession );
	printf( "Certificate status check returned %d.\n", status );

	/* Clean up */
	cryptDestroyCert( cryptCert );
	cryptDestroySession( cryptSession );

	puts( "RTCS direct query succeeded.\n" );
	return( TRUE );
	}

int testSessionRTCS( void )
	{
	if( !connectRTCS( CRYPT_SESSION_RTCS, FALSE, FALSE ) )
		return( FALSE );
	if( !connectRTCSDirect() )
		return( FALSE );
#if RTCS_SERVER_NO == 1
	return( connectRTCS( CRYPT_SESSION_RTCS, TRUE, FALSE ) );
#else
	return( TRUE );
#endif /* Server that has a revoked cert */
	}
int testSessionRTCSServer( void )
	{
	return( connectRTCS( CRYPT_SESSION_RTCS_SERVER, FALSE, FALSE ) );
	}

/* Perform a client/server loopback test */

#ifdef WINDOWS_THREADS

unsigned __stdcall rtcsServerThread( void *dummy )
	{
	connectRTCS( CRYPT_SESSION_RTCS_SERVER, FALSE, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}

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

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

	/* Connect to the local server */
	status = connectRTCS( CRYPT_SESSION_RTCS, 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 */

/****************************************************************************
*																			*
*								OCSP Routines Test							*
*																			*
****************************************************************************/

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

	#1 - cryptlib:
			None
	#2 - iD2 aka SmartTrust
			AuthorityInfoAccess doesn't match the real server URL, requires
			the SmartTrust server name below to override the AIA value.
			Currently not active.
	#3 - Identrus aka Xetex:
			AuthorityInfoAccess doesn't match the real server URL, requires
			the Xetex server name below to override the AIA value.  Currently
			not active.
	#4 - Thawte aka Valicert
			No AuthorityInfoAccess, requires the Valicert server name below
			to provide a server.  Since all Thawte CA certs are invalid (no
			keyUsage, meaning they're non-CA certs) cryptlib will reject them
			for OCSPv1 queries.
	#5 - Verisign
			No AuthorityInfoAccess, requires the Verisign server name below
			to provide a server.
	#6 - Diginotar
			Have an invalid CA certificate, and (apparently) a broken OCSP
			implementation that gets the IDs wrong (this is par for the
			course for this particular CA) */

#define OCSP_SERVER_NO		5
#if OCSP_SERVER_NO == 2
  #define OCSP_SERVER_NAME	TEXT( "http://ocsp.smarttrust.com:82/ocsp" )
#elif OCSP_SERVER_NO == 3
  #define OCSP_SERVER_NAME	TEXT( "http://ocsp.xetex.com:8080/servlet/ocsp" )
#elif OCSP_SERVER_NO == 4
  #define OCSP_SERVER_NAME	TEXT( "http://ocsp2.valicert.net" )
#elif OCSP_SERVER_NO == 5
  #define OCSP_SERVER_NAME	TEXT( "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( "%sTesting %sOCSP session...\n", isServer ? "SVR: " : "",
			localSession ? "local " : "" );

	/* 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 ) )
			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 that 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( "SVR: 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,
					   FALSE, revokedCert, multipleCerts, 
					   CRYPT_SIGNATURELEVEL_NONE, 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 ) )
			return( FALSE );
#ifdef OCSP_SERVER_NAME
		if( !localSession )
			{
			printf( "Setting OCSP server to %s.\n", OCSP_SERVER_NAME );
			cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_NAME );
			status = cryptSetAttributeString( cryptSession,
								CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME,
								paramStrlen( OCSP_SERVER_NAME ) );
			if( cryptStatusError( status ) )
				return( attrErrorExit( cryptSession,
									   "cryptSetAttributeString()", status,
									   __LINE__ ) );
			}
#endif /* Kludges for incorrect/missing authorityInfoAccess values */
		if( OCSP_SERVER_NO == 1 || localSession )
			{
			/* The cryptlib server doesn't handle the weird v1 certIDs */
			status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION,
										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 ? \
					   "SVR: Attempt to activate OCSP server session" : \
					   "Attempt to activate OCSP client session", status,
					   __LINE__ );
		cryptDestroySession( cryptSession );
		if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_NOTFOUND || \
			status == CRYPT_ERROR_TIMEOUT || 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 that 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 ? "SVR: OCSP server session succeeded.\n" : \
					 "OCSP client session succeeded.\n" );
	return( TRUE );
	}

static int connectOCSPDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct OCSP query...\n" );

	/* Get the EE cert */
	status = importCertFromTemplate( &cryptCert, OCSP_EEOK_FILE_TEMPLATE,
									 OCSP_SERVER_NO );
	if( cryptStatusError( status ) )
		{
		printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the OCSP session and add the server URL */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_OCSP );
	if( status == CRYPT_ERROR_PARAM3 )	/* OCSP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
#ifdef OCSP_SERVER_NAME
	status = cryptSetAttributeString( cryptSession,
								CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME,
								paramStrlen( OCSP_SERVER_NAME ) );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptSession, "cryptSetAttributeString()",
							   status, __LINE__ ) );
#endif /* Kludges for incorrect/missing authorityInfoAccess values */

	/* Check the cert directly against the server.  This check quantises the
	   result into a basic pass/fail that doesn't provide as much detail as 
	   the low-level OCSP check, so it's not unusual to get 
	   CRYPT_ERROR_INVALID whent he low-level check returns
	   CRYPT_OCSPSTATUS_UNKNOWN */
	status = cryptCheckCert( cryptCert, cryptSession );
	printf( "Certificate status check returned %d.\n", status );

	/* Clean up */
	cryptDestroyCert( cryptCert );
	cryptDestroySession( cryptSession );

	puts( "OCSP direct query succeeded.\n" );
	return( TRUE );
	}

int testSessionOCSP( void )
	{

⌨️ 快捷键说明

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