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

📄 testsess.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	   but require explicit use of an update request */
	status = cryptSetAttributeString( cryptSession, 
									  CRYPT_SESSINFO_USERNAME, user, 
									  strlen( user ) );
	if( cryptStatusOK( status ) )
		if( privateKey != CRYPT_UNUSED )
			{
			cryptSetAttribute( cryptSession, CRYPT_SESSINFO_CMP_REQUESTTYPE,
							   isRevocation ? CRYPT_REQUESTTYPE_REVOCATION : \
							   isUpdate ? CRYPT_REQUESTTYPE_KEYUPDATE : \
										  CRYPT_REQUESTTYPE_CERTIFICATE );
			status = cryptSetAttribute( cryptSession, 
										CRYPT_SESSINFO_PRIVATEKEY,
										privateKey );
			}
		else
			{
			cryptSetAttribute( cryptSession, CRYPT_SESSINFO_CMP_REQUESTTYPE,
							   isRevocation ? CRYPT_REQUESTTYPE_REVOCATION : \
											  CRYPT_REQUESTTYPE_INITIALISATION );
			status = cryptSetAttributeString( cryptSession, 
										CRYPT_SESSINFO_PASSWORD, password, 
										strlen( password ) );
			}
	if( cryptStatusOK( status ) )
		status = cryptSetAttributeString( cryptSession, 
										CRYPT_SESSINFO_SERVER_NAME, server, 
										strlen( server ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptSession,
					CRYPT_SESSINFO_CMP_CACERTIFICATE, cryptCACert );
	if( cryptStatusError( status ) )
		{
		printf( "Addition of session information failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	return( cryptSession );
	}

/* Request a particular cert type */

static int requestCert( const char *description, const CA_INFO *caInfoPtr, 
						const char *readKeysetName,  const char *writeKeysetName, 
						const CERT_DATA *requestData, const CRYPT_ALGO cryptAlgo, 
						const CRYPT_CONTEXT cryptCACert, 
						CRYPT_CERTIFICATE *issuedCert )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_KEYSET cryptKeyset = CRYPT_UNUSED;
	CRYPT_CONTEXT privateKey = CRYPT_UNUSED;
	CRYPT_CERTIFICATE cryptCmpRequest, cryptCmpResponse;
	const BOOLEAN useExistingKey = ( requestData == NULL ) ? TRUE : FALSE;
	int status;

#ifdef SERVER_PROVIDES_DN
	printf( "Testing %s processing...\n", description );
#else
	printf( "Testing %s processing with absent subject DN...\n", description );
#endif /* SERVER_PROVIDES_DN */

	/* Read the key needed to request a new cert from a keyset if necessary,
	   and create a keyset to save a new key to if required.  We have to do 
	   the write last in case the read and write keyset are the same */
	if( readKeysetName != NULL )
		{
		status = getPrivateKey( &privateKey, readKeysetName, 
								USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't get private key to request new certificate, "
					"status = %d.\n", status );
			return( FALSE );
			}
		}
	if( writeKeysetName != NULL )
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, writeKeysetName, 
								  CRYPT_KEYOPT_CREATE );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't create keyset to store certificate to, "
					"status = %d.\n", status );
			return( FALSE );
			}
		}

	/* Create the CMP session and certification request.  Some CAs explicitly
	   disallow multiple dissimilar certs to exist for the same key (in fact
	   for non-test servers other CAs probably enforce this as well) but
	   generating a new key for each request is time-consuming so we only do
	   it if it's enforced by the CA */
	cryptSession = createCmpSession( cryptCACert, caInfoPtr->serverName, 
									 caInfoPtr->userName, caInfoPtr->password,
									 privateKey, FALSE, useExistingKey );
	if( cryptSession <= 0 )
		{
		if( cryptKeyset != CRYPT_UNUSED )
			cryptKeysetClose( cryptKeyset );
		return( cryptSession );
		}
#if ( CA_NO == 1 ) || ( CA_NO == 7 )
	cryptCmpRequest = createCmpRequest( requestData, 
								useExistingKey ? privateKey : CRYPT_UNUSED, 
								cryptAlgo, FALSE, cryptKeyset );
#else
	KLUDGE_WARN( "fixed key for request" );
	cryptCmpRequest = createCmpRequest( requestData, 
								useExistingKey ? privateKey : CRYPT_UNUSED, 
								cryptAlgo, TRUE, cryptKeyset );
#endif /* cryptlib and Initech won't allow two certs for same key */
	if( !cryptCmpRequest )
		return( FALSE );
	if( privateKey != CRYPT_UNUSED )
		cryptDestroyContext( privateKey );

	/* Set up the request and activate the session */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST, 
								cryptCmpRequest );
	cryptDestroyCert( cryptCmpRequest );
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute() failed with error code %d, line %d.\n", 
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		if( cryptKeyset != CRYPT_UNUSED )
			cryptKeysetClose( cryptKeyset );
		printExtError( cryptSession, "Attempt to activate CMP session",
					   status, __LINE__ );
		cryptDestroySession( cryptSession );
		if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_READ )
			{
			/* These servers are constantly appearing and disappearing so if 
			   we get a straight connect error we don't treat it as a serious
			   failure */
			puts( "  (Server could be down, faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		if( status == CRYPT_ERROR_FAILED )
			{
			/* A general failed response is more likely to be due to the 
			   server doing something unexpected than a cryptlib problem so 
			   we don't treat it as a fatal error */
			puts( "  (This is more likely to be an issue with the server than "
				  "with cryptlib,\n   faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		return( FALSE );
		}

	/* Obtain the response information */
	status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, 
								&cryptCmpResponse );
	cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptGetAttribute() failed with error code %d, line %d.\n", 
				status, __LINE__ );
		return( FALSE );
		}
#if CA_NO != 1
	puts( "Returned certificate details are:" );
	printCertInfo( cryptCmpResponse );
#endif /* Keep the cryptlib results on one screen */
	if( cryptKeyset != CRYPT_UNUSED )
		{
		status = cryptAddPublicKey( cryptKeyset, cryptCmpResponse );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't write certificate to keyset, status = %d.\n",
					status );
			return( FALSE );
			}
		cryptKeysetClose( cryptKeyset );
		}
	if( issuedCert != NULL )
		*issuedCert = cryptCmpResponse;
	else
		cryptDestroyCert( cryptCmpResponse );

	/* Clean up */
	printf( "%s processing succeeded.\n\n", description );
	return( TRUE );
	}

/* Revoke a previously-issued cert */

static int revokeCert( const char *description, const CA_INFO *caInfoPtr, 
					   const char *keysetName, 
					   const CRYPT_CERTIFICATE certToRevoke,
					   const CRYPT_CONTEXT cryptCACert, 
					   const BOOLEAN signRequest )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CONTEXT privateKey = CRYPT_UNUSED;
	CRYPT_CERTIFICATE cryptCmpRequest, cryptCert = certToRevoke;
	int status;

	printf( "Testing %s revocation processing...\n", description );

	/* Get the cert to revoke if necessary.  In some cases the server won't
	   accept a revocation password, so we have to get the private key as 
	   well to sign the request */
	if( signRequest || cryptCert == CRYPT_UNUSED )
		{
		CRYPT_KEYSET cryptKeyset;

		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, keysetName, 
								  CRYPT_KEYOPT_READONLY );
		if( cryptStatusOK( status ) && signRequest )
			status = getPrivateKey( &privateKey, keysetName, 
									USER_PRIVKEY_LABEL, 
									TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) && cryptCert == CRYPT_UNUSED )
			status = cryptGetPublicKey( cryptKeyset, &cryptCert,
										CRYPT_KEYID_NAME, 
										USER_PRIVKEY_LABEL );
		cryptKeysetClose( cryptKeyset );
		if( cryptStatusError( status ) )
			{
			puts( "Couldn't fetch certificate/key to revoke.\n" );
			return( FALSE );
			}
		}

	/* Create the CMP session and revocation request */
	cryptSession = createCmpSession( cryptCACert, caInfoPtr->serverName, 
									 caInfoPtr->userName, caInfoPtr->password,
									 privateKey, TRUE, FALSE );
	if( privateKey != CRYPT_UNUSED )
		cryptDestroyContext( privateKey );
	if( cryptSession <= 0 )
		return( cryptSession );
	cryptCmpRequest = createCmpRevRequest( cryptCert );
	if( !cryptCmpRequest )
		return( FALSE );

	/* Set up the request and activate the session */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST, 
								cryptCmpRequest );
	cryptDestroyCert( cryptCmpRequest );
	if( cryptStatusError( status ) )
		{
		printf( "cryptSetAttribute() failed with error code %d, line %d.\n", 
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "Attempt to activate CMP session",
					   status, __LINE__ );
		cryptDestroySession( cryptSession );
		if( cryptCert != certToRevoke )
			cryptDestroyCert( cryptCert );
		if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_READ )
			{
			/* These servers are constantly appearing and disappearing so if 
			   we get a straight connect error we don't treat it as a serious
			   failure */
			puts( "  (Server could be down, faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		if( status == CRYPT_ERROR_FAILED )
			{
			/* A general failed response is more likely to be due to the 
			   server doing something unexpected than a cryptlib problem so 
			   we don't treat it as a fatal error */
			puts( "  (This is more likely to be an issue with the server than "
				  "with cryptlib,\n   faking it and continuing...)\n" );
			return( CRYPT_ERROR_FAILED );
			}
		return( FALSE );
		}

	/* Clean up */
	if( cryptCert != certToRevoke )
		cryptDestroyCert( cryptCert );
	cryptDestroySession( cryptSession );
	printf( "%s processing succeeded.\n\n", description );
	return( TRUE );
	}

/* Test the full range of CMP functionality.  This performs the following
   tests:

	RSA sign:
		ir + ip + reject (requires cmp.c mod)
		ir + ip + certconf + pkiconf
		kur + kup + certconf + pkiconf
		cr + cp + certconf + pkiconf (not performed since same as kur)
		rr + rp (of ir cert)
		rr + rp (of kur cert)
	RSA encr.:
		ir + ip + reject (requires cmp.c mod)
		ir + ip + certconf + pkiconf
		rr + rp (of ir cert)
	DSA:		
		cr + cp + certconf + pkiconf (success implies that ir/kur/rr 
						works since they've already been tested for RSA) */

int testSessionCMP( void )
	{
	CRYPT_CERTIFICATE cryptCACert, cryptCert;
	BYTE readFileName[ BUFFER_SIZE ], writeFileName[ BUFFER_SIZE ];
#if CA_NO == 1
	CA_INFO cryptlibCAInfo, *caInfoPtr = &cryptlibCAInfo;
	char userID[ 64 ], issuePW[ 64 ], revPW[ 64 ];
#else
	CA_INFO *caInfoPtr = &caInfo[ CA_NO ];
#endif /* cryptlib */
	int status;
	
	/* Get the cert of the CA who will issue the cert */
	status = importCertFromTemplate( &cryptCACert, CMP_CA_FILE_TEMPLATE, 
									 CA_NO );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't get CMP CA certificate, status = %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Test each cert request type: Initialisation, cert request using cert
	   from initialisation for authentication, key update of cert from 
	   initialisation, revocation of both certs.  We don't write the updated 
	   existing key to a keyset because it's already present as a side-effect 
	   of the way the all-in-one test code reuses existing keys where 
	   required.  In addition we insert a 1s delay in between requests to 
	   give the server time to recycle */
#ifdef TEST_IR
  #if CA_NO == 1
	{
	CRYPT_KEYSET cryptCertStore;
	CRYPT_CERTIFICATE cryptPKIUser;
	int length;

	/* cryptlib implements per-user (rather than shared interop) IDs and
	   passwords so we need to read the user ID and password information
	   before we can perform any operations */
	status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED, 
							  CERTSTORE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
							  CRYPT_KEYOPT_NONE );
	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 */
		cryptDestroyCert( cryptCACert );
		puts( "No certificate store available, aborting CMP test.\n" );
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptCAGetItem( cryptCertStore, &cryptPKIUser, 
							 CRYPT_CERTTYPE_PKIUSER, CRYPT_KEYID_NAME,
							 "Test PKI user" );
	cryptKeysetClose( cryptCertStore );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCAGetItem()", status,
							  __LINE__ ) );
	status = cryptGetAttributeString( cryptPKIUser, 
									  CRYPT_CERTINFO_PKIUSER_ID, 
									  userID, &length );
	if( cryptStatusOK( status ) )
		{
		userID[ length ] = '\0';
		status = cryptGetAttributeString( cryptPKIUser, 
									CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD, 
									issuePW, &length );
		}
	if( cryptStatusOK( status ) )
		{
		issuePW[ length ] = '\0';
		status = cryptGetAttributeString( cryptPKIUser, 
									CRYPT_CERTINFO_PKIUSER_RE

⌨️ 快捷键说明

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