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

📄 testsess.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
			puts( "  (Server could be down, faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		return( FALSE );
		}

	/* There's not much more we can do in the client at this point since the 
	   TSP data is only used internally by cryptlib, OTOH if we get to here 
	   then we've received a valid response from the TSA so all is OK */

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

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

int testSessionTSP( void )
	{
	return( connectTSP( CRYPT_SESSION_TSP, CRYPT_UNUSED, FALSE ) );
	}
int testSessionTSPServer( void )
	{
	return( connectTSP( CRYPT_SESSION_TSP_SERVER, CRYPT_UNUSED, FALSE ) );
	}
int testSessionTSPServerEx( const CRYPT_CONTEXT privKeyContext )
	{
	return( connectTSP( CRYPT_SESSION_TSP_SERVER, privKeyContext, FALSE ) );
	}

/* Perform a local client/server test */

#ifdef WINDOWS_THREADS

unsigned __stdcall tspServerThread( void *dummy )
	{
	connectTSP( CRYPT_SESSION_TSP_SERVER, CRYPT_UNUSED, TRUE );
	_endthreadex( 0 );
	return( 0 );
	}

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

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

	/* Connect to the local server */
	status = connectTSP( CRYPT_SESSION_TSP, CRYPT_UNUSED, 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 */

/****************************************************************************
*																			*
*								CMP Routines Test							*
*																			*
****************************************************************************/

/* There are various CMP test CAs available, the following mappings can be 
   used to test different ones.  Implementation peculiarities:

	#1 - cryptlib: Implicitly revokes cert being replaced during a kur.
			Tested: ir, cr/kur, rr
	#2 - Certicom: Requires signature for revocation rather than MAC,
			requires that all certs created after the ir one have the same
			DN as the ir cert.
			Tested: ir, cr/kur, rr
	#3 - ssh: None (recently re-issued their CA cert which is broken, CA 
			couldn't be re-tested.  In addition since CMP identifies the
			sender by DN the new cert can't be distinguished from the old
			one, causing sig checks to fail).
			Tested (late 2000): ir, cr/kur, rr
	#4 - Entrust: Won't allow altNames, changes sender and request DN,
			returns rejected response under an altered DN belonging to a
			completely different EE for anything but ir.
			Tested: ir
	#5 - Trustcenter: Requires HTTPS and pre-existing trusted private key
			distributed as PKCS #12 file, couldn't be tested.
	#6 - Baltimore: Server unavailable for testing.
			Tested: -
	#7 - Initech: Needs DN cn=CryptLIB EE 1,o=INITECH,c=KR.
			Tested: ir, cr/kur, rr
	#8 - RSA labs: Rejects signed requests, couldn't be tested beyond initial
			(MACd) ir.  Attempt to revoke newly-issued cert with MACd rr 
			returns error indicating that the cert is already revoked.
			Tested: ir */

#define CA_NO	1

typedef struct {
	const char *serverName, *userName, *password;
	} CA_INFO;

static const CA_INFO caInfo[] = {
	{ NULL, NULL, NULL },	/* Dummy so index == CA_NO */
	{ /*1*/ "cmp://localhost", "interop", "interop" },
	{ /*2*/ "cmp://gandalf.trustpoint.com:8081", "interop", "interop" },
	{ /*3*/ "cmp://interop-ca.ssh.com:8290", "123456", "interop" },
	{ /*4*/ "cmp://204.101.128.45:829", "39141091", "ABCDEFGHIJK" },
	{ /*5*/ "cmp://demo.trustcenter.de/cgi-bin/cmp:829", "interop", "interop" },
	{ /*6*/ "cmp://hip.baltimore.ie:8290", "pgutmann", "the-magical-land-near-oz" },
	{ /*7*/ "cmp://61.74.133.49:8290", "interop", "interop" },
	{ /*8*/ "cmp://ca1.kcspilot.com:32829", "interop", "interop" }
	};

/* The following defines can be used to selectively enable or disable some 
   of the test (for example to do an ir + rr, or ir + kur + rr) */

#if CA_NO == 1
  #define TEST_IR		/**/
  #define TEST_KUR		/**/
  #define TEST_CR		/**/
  #define TEST_RR
  #define NO_CA_REQUESTS	4	/* 3 cert reqs, 1 rev.req (kur = impl.rev) */
#else
  #define TEST_IR		/**/
  #define TEST_KUR		/**/
  #define TEST_CR		/**/
  #define TEST_RR		/**/
#endif /* CA_NO == 1 */

/* Define the following to enable testing of servers where the initial DN is 
   supplied by the server (ie the user supplies a null DN) */

#define SERVER_PROVIDES_DN	/**/

/* Cert request data for the various types of certs which a CMP CA can return */

static const CERT_DATA cmpRsaSignRequestData[] = {
	/* Identification information */
  #if CA_NO == 7
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "KR" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "INITECH" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "CryptLIB EE 1" },
  #else
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Procurement" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's Signature Key" },
  #endif /* Initech requires fixed DN */

	/* Subject altName */
#if CA_NO != 4
	{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, "dave@wetas-r-us.com" },
	{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.wetas-r-us.com" },
#endif /* Entrust doesn't allow altName */

	/* Signature-only key */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_DIGITALSIGNATURE },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};
static const CERT_DATA cmpRsaSignRequestNoDNData[] = {
	/* Identification information - none, it's provided by the server */

	/* Subject altName */
	{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, "dave@wetas-r-us.com" },
	{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.wetas-r-us.com" },

	/* Signature-only key */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_DIGITALSIGNATURE },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};
static const CERT_DATA cmpRsaEncryptRequestData[] = {
	/* Identification information */
#if CA_NO == 7
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "KR" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "INITECH" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "CryptLIB EE 1" },
#else
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Procurement" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's Encryption Key" },
#endif /* Initech requires fixed DN */

	/* Subject altName */
#if CA_NO != 4
	{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, "dave@wetas-r-us.com" },
	{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.wetas-r-us.com" },
#endif /* Entrust doesn't allow altName */

	/* Encryption-only key */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_KEYENCIPHERMENT },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};
static const CERT_DATA cmpDsaRequestData[] = {
	/* Identification information */
#if CA_NO == 7
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "KR" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "INITECH" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "CryptLIB EE 1" },
#else
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Procurement" },
  #if CA_NO == 2
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's Signature Key" },
  #else
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's DSA Key" },
  #endif /* Certicom requires same DN as for init.request */
#endif /* Initech requires fixed DN */

	/* Subject altName */
#if CA_NO != 4
	{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, "dave@wetas-r-us.com" },
	{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.wetas-r-us.com" },
#endif /* Entrust doesn't allow altName */

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

/* Create various CMP objects */

static int createCmpRequest( const CERT_DATA *requestData,
							 const CRYPT_CONTEXT privateKey,
							 const CRYPT_ALGO cryptAlgo, 
							 const BOOLEAN useFixedKey, 
							 const CRYPT_KEYSET cryptKeyset )
	{
	CRYPT_CERTIFICATE cryptRequest;
	int status;

	/* Create the CMP (CRMF) request */
	if( privateKey != CRYPT_UNUSED )
		{
		time_t startTime;
		int dummy;

		/* If we're updating an existing cert we have to vary something in 
		   the request to make sure the result doesn't duplicate an existing
		   cert, to do this we fiddle the start time */
		status = cryptGetAttributeString( privateKey, CRYPT_CERTINFO_VALIDFROM,
										  &startTime, &dummy );
		if( cryptStatusError( status ) )
			return( FALSE );
		startTime++;

		/* It's an update of existing information, sign the request with the
		   given private key */
		status = cryptCreateCert( &cryptRequest, CRYPT_UNUSED, 
								  CRYPT_CERTTYPE_REQUEST_CERT );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptRequest,
						CRYPT_CERTINFO_USERCERTIFICATE, privateKey );
		if( cryptStatusOK( status ) )
			status = cryptSetAttributeString( cryptRequest, 
						CRYPT_CERTINFO_VALIDFROM, &startTime, sizeof( time_t ) );
		if( cryptStatusOK( status ) )
			status = cryptSignCert( cryptRequest, privateKey );
		if( cryptKeyset != CRYPT_UNUSED )
			{
			if( cryptStatusError( \
					cryptAddPrivateKey( cryptKeyset, privateKey, 
										TEST_PRIVKEY_PASSWORD ) ) )
				return( FALSE );
			}
		}
	else
		{
		CRYPT_CONTEXT cryptContext;

		/* It's a new request, generate a private key and create a self-
		   signed request */
		if( useFixedKey )
			{
			/* Use a fixed private key, for testing purposes */
			if( cryptAlgo == CRYPT_ALGO_RSA )
				loadRSAContextsEx( CRYPT_UNUSED, NULL, &cryptContext, NULL, 
								   USER_PRIVKEY_LABEL );
			else
				loadDSAContextsEx( CRYPT_UNUSED, &cryptContext, NULL, 
								   USER_PRIVKEY_LABEL, NULL );
			status = CRYPT_OK;
			}
		else
			{
			cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
			cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL, 
									 USER_PRIVKEY_LABEL, 
									 strlen( USER_PRIVKEY_LABEL ) );
			cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYSIZE, 64 );
			status = cryptGenerateKey( cryptContext );
			}
		if( cryptStatusOK( status ) )
			status = cryptCreateCert( &cryptRequest, CRYPT_UNUSED, 
									  CRYPT_CERTTYPE_REQUEST_CERT );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptRequest,
						CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptContext );
		if( cryptStatusOK( status ) && \
			!addCertFields( cryptRequest, requestData ) )
			status = CRYPT_ERROR_FAILED;
		if( cryptStatusOK( status ) )
			status = cryptSignCert( cryptRequest, cryptContext );
		if( cryptKeyset != CRYPT_UNUSED )
			{
			if( cryptStatusError( \
					cryptAddPrivateKey( cryptKeyset, cryptContext, 
										TEST_PRIVKEY_PASSWORD ) ) )
				return( FALSE );
			}
		cryptDestroyContext( cryptContext );
		}
	if( cryptStatusError( status ) )
		{
		printf( "Creation of CMP request failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}

	return( cryptRequest );
	}

static int createCmpRevRequest( const CRYPT_CERTIFICATE cryptCert )
	{
	CRYPT_CERTIFICATE cryptRequest;
	int status;

	/* Create the CMP (CRMF) revocation request */
	status = cryptCreateCert( &cryptRequest, CRYPT_UNUSED, 
							  CRYPT_CERTTYPE_REQUEST_REVOCATION );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptRequest, CRYPT_CERTINFO_CERTIFICATE, 
									cryptCert );
	if( cryptStatusError( status ) )
		{
		printf( "Creation of CMP revocation request failed with error code "
				"%d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	return( cryptRequest );
	}

static int createCmpSession( const CRYPT_CONTEXT cryptCACert,
							 const char *server, const char *user, 
							 const char *password, 
							 const CRYPT_CONTEXT privateKey, 
							 const BOOLEAN isRevocation,
							 const BOOLEAN isUpdate )
	{
	CRYPT_SESSION cryptSession;
	int status;

	/* Create the CMP session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, 
								 CRYPT_SESSION_CMP );
	if( status == CRYPT_ERROR_PARAM3 )	/* CMP 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 );
		}

	/* Set up the user and server information.  Revocation requests can be 
	   signed or MACd so we handle either.  When requesting a cert using a
	   signed request (ie not an initialisation request) we use an update
	   since we're reusing the previously-generated cert data to request a
	   new one and some CAs won't allow this reuse for a straight request

⌨️ 快捷键说明

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