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

📄 testdev.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:

	/* Generate a key in the device */
	printf( "Generating a %s key in the device...", description );
	status = cryptDeviceCreateContext( cryptDevice, &cryptContext,
									   cryptAlgo );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptDeviceCreateContext() failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL, labelBuffer,
							 strlen( labelBuffer ) );
	status = cryptGenerateKey( cryptContext );
	if( cryptStatusError( status ) )
		{
		cryptDestroyContext( cryptContext );
		printf( "\ncryptGenerateKey() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( " succeeded." );

	/* Create a certificate for the key */
	printf( "Generating a certificate for the key..." );
	cryptCreateCert( &cryptCert, CRYPT_UNUSED, ( isCA ) ? \
					 CRYPT_CERTTYPE_CERTIFICATE : CRYPT_CERTTYPE_CERTCHAIN );
	status = cryptSetAttribute( cryptCert,
						CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptContext );
	if( cryptStatusOK( status ) && \
		!addCertFields( cryptCert, certData ) )
		return( FALSE );
	if( cryptStatusOK( status ) )
		status = cryptSignCert( cryptCert, isCA ? cryptContext : signingKey );
	cryptDestroyContext( cryptContext );
	if( cryptStatusError( status ) )
		{
		cryptDestroyCert( cryptCert );
		printf( "\nCreation of certificate failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	puts( " succeeded." );

	/* Dump the resulting cert for debugging */
	if( dumpName != NULL )
		{
		status = cryptExportCert( certBuffer, &certificateLength, isCA ? \
					CRYPT_CERTFORMAT_CERTIFICATE : CRYPT_CERTFORMAT_CERTCHAIN,
					cryptCert );
		if( cryptStatusOK( status ) )
			debugDump( dumpName, certBuffer, certificateLength );
		}

	/* Update the key with the cert */
	printf( "Updating device with certificate..." );
	status = cryptAddPublicKey( cryptDevice, cryptCert );
	cryptDestroyCert( cryptCert );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptAddPublicKey() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( " succeeded." );

	return( TRUE );
	}

/* Test the high-level functionality provided by a device */

static BOOLEAN testDeviceHighlevel( const CRYPT_DEVICE cryptDevice,
									const CRYPT_DEVICE_TYPE deviceType,
									const char *keyLabel,
									const char *password,
									const BOOLEAN isWriteProtected )
	{
	CRYPT_CONTEXT pubKeyContext, privKeyContext, sigKeyContext;
	int status;

	if( !isWriteProtected )
		{
		const CRYPT_ALGO cryptAlgo = ( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
									 CRYPT_ALGO_RSA : CRYPT_ALGO_DSA;

		/* Create a CA key in the device */
		if( !createKey( cryptDevice, cryptAlgo, "CA",
						( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
						"dp_cacert" : "df_cacert", CRYPT_UNUSED ) )
			return( FALSE );

		/* Read back the CA key for use in generating end entity certs */
		status = cryptGetPrivateKey( cryptDevice, &sigKeyContext,
									 CRYPT_KEYID_NAME, "Test CA key",
									 NULL );
		if( cryptStatusError( status ) )
			{
			printf( "\nRead of CA key failed with error code %d, line %d.\n",
					status, __LINE__ );
			return( FALSE );
			}

		/* Create end-entity certificate(s) for keys using the previously-
		   generated CA key.  If it's a Fortezza card we have to generate two
		   sets of keys/certs, one for signing and one for encryption */
		status = createKey( cryptDevice, cryptAlgo, "user",
							( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
							"dp_usrcert" : "df_usrcert", sigKeyContext );
		if( status && deviceType == CRYPT_DEVICE_FORTEZZA )
			status = createKey( cryptDevice, CRYPT_ALGO_KEA, "KEA",
								"df_keacert", sigKeyContext );
		cryptDestroyContext( sigKeyContext );
		if( !status )
			return( FALSE );
		}

	/* See whether there are any existing keys or certs - some tokens have
	   these built in and don't allow anything new to be created, after this
	   point the handling is somewhat special-case but we can at least report
	   their presence.  Although generally we can reuse a private key context
	   for both public and private operations, some devices or drivers (and
	   by extension the cryptlib kernel) don't allow public-key ops with
	   private keys so we have to eplicitly handle public and private keys.
	   This gets somewhat messy because some devices don't have public keys
	   but allow public-key ops with their private keys, while others
	   separate public and private keys and don't allow the private key to do
	   public-key ops */
	status = cryptGetPublicKey( cryptDevice, &pubKeyContext,
								CRYPT_KEYID_NAME, keyLabel );
	if( cryptStatusOK( status ) )
		{
		puts( "Found a public key in the device, details follow..." );
		printCertChainInfo( pubKeyContext );
		}
	else
		{
		puts( "Error: Couldn't locate public key in device." );
		pubKeyContext = CRYPT_UNUSED;
		}
	status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
								 CRYPT_KEYID_NAME, keyLabel, NULL );
	if( cryptStatusOK( status ) )
		{
		puts( "Found a private key in the device, details follow..." );
		printCertChainInfo( privKeyContext );
		if( pubKeyContext == CRYPT_UNUSED )
			{
			/* No explicit public key found, try using the private key for
			   both key types */
			puts( "No public key found, attempting to continue using the "
				  "private key as both a\npublic and a private key." );
			pubKeyContext = privKeyContext;
			}
		}
	else
		{
		puts( "Error: Couldn't locate private key in device." );
		privKeyContext = CRYPT_UNUSED;
		}
	sigKeyContext = privKeyContext;
	if( deviceType == CRYPT_DEVICE_FORTEZZA )
		{
		cryptDestroyContext( pubKeyContext );	/* pubK is sig.only */
		status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
									 CRYPT_KEYID_NAME, "Test KEA key", NULL );
		if( cryptStatusOK( status ) )
			{
			puts( "Found a key agreement key in the device, details follow..." );
			printCertChainInfo( privKeyContext );
			pubKeyContext = privKeyContext;		/* Fortezza allows both uses */
			}
		else
			{
			pubKeyContext = CRYPT_UNUSED;
			privKeyContext = CRYPT_UNUSED;
			}
		}

	/* If we got something, try some simple operations with it */
	if( pubKeyContext != CRYPT_UNUSED )
		{
		if( !testCMSEnvelopePKCCryptEx( pubKeyContext, cryptDevice, password ) )
			return( FALSE );
		}
	else
		puts( "Public-key enveloping tests skipped because no key was "
			  "available." );
	if( sigKeyContext != CRYPT_UNUSED )
		{
		if( !testCMSEnvelopeSignEx( sigKeyContext ) )
			return( FALSE );
		}
	else
		puts( "Signed enveloping tests skipped because no key was "
			  "available." );

	/* Test the key with a server session, meant to imitate use with an HSM.
	   This is disabled by default since it requires the simultaneous use of
	   both a client and server session, which has to be done manually */
#if 0
	testSessionTSPServerEx( sigKeyContext );
#endif /* 0 */

	/* Clean up */
	if( pubKeyContext == CRYPT_UNUSED && sigKeyContext == CRYPT_UNUSED )
		return( FALSE );
	if( privKeyContext != CRYPT_UNUSED )
		{
		cryptDestroyContext( privKeyContext );
		if( privKeyContext != sigKeyContext )
			cryptDestroyContext( sigKeyContext );
		}
	if( pubKeyContext != CRYPT_UNUSED && pubKeyContext != privKeyContext )
		cryptDestroyContext( pubKeyContext );
	return( TRUE );
	}

/* Test cryptlib's CAW functionality with a Fortezza card.  Note that these
   operations have to be done in a more or less continuous sequence (ie
   without an intervening device open call) because it's not possible to
   escape from some of the states if the card is closed and reopened in
   between */

static int testCAW( void )
	{
	CRYPT_DEVICE cryptDevice;
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_CONTEXT signContext;
	int status;

	puts( "Testing Certificate Authority Workstation (CAW) functionality..." );
	status = cryptDeviceOpen( &cryptDevice, CRYPT_UNUSED,
							  CRYPT_DEVICE_FORTEZZA, NULL );
	if( status == CRYPT_ERROR_PARAM2 )
		{
		puts( "Support for Fortezza cards isn't enabled in this build of "
			  "cryptlib." );
		return( CRYPT_ERROR_NOTAVAIL );	/* Device access not available */
		}
	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ERROR_PARAM3 )
			puts( "Fortezza card not detected, skipping test." );
		else
			printf( "cryptDeviceOpen() failed with error code %d, line %d.\n",
					status, __LINE__ );
		return( FALSE );
		}

	/* Zeroise the card prior to initialising it */
	printf( "Zeroising device... " );
	status = cryptSetAttributeString( cryptDevice,
						CRYPT_DEVINFO_ZEROISE, FORTEZZA_ZEROISE_PIN,
						strlen( FORTEZZA_ZEROISE_PIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\nZeroise failed with error code %d, line %d.\n", status,
				__LINE__ );
		return( FALSE );
		}
	puts( "succeeded." );

	/* Initialise the card */
	printf( "Initialising device... " );
	status = cryptSetAttributeString( cryptDevice,
					CRYPT_DEVINFO_INITIALISE, FORTEZZA_SSO_DEFAULT_PIN,
					strlen( FORTEZZA_SSO_DEFAULT_PIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\nInitialisation failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( "succeeded." );

	/* Set the SSO PIN */
	printf( "Setting SSO PIN... " );
	status = cryptDeviceControlEx( cryptDevice,
					CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR,
					FORTEZZA_SSO_DEFAULT_PIN, strlen( FORTEZZA_SSO_DEFAULT_PIN ),
					FORTEZZA_SSO_PIN, strlen( FORTEZZA_SSO_PIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptDeviceControlEx() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( "set to " FORTEZZA_SSO_PIN "." );

	/* Create a CA root key and install its cert.  We can't use the card to
	   do this because cert slot 0 is a data-only slot (that is, it can't
	   correspond to a key held on the card), so we create a dummy external
	   cert and use that */
	printf( "Loading PAA certificate... " );
	if( !loadDSAContexts( CRYPT_UNUSED, &signContext, NULL ) )
		return( FALSE );

⌨️ 快捷键说明

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