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

📄 devices.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*						  cryptlib Device Test Routines						*
*						Copyright Peter Gutmann 1997-2004					*
*																			*
****************************************************************************/

#ifdef _MSC_VER
  #include "../cryptlib.h"
  #include "test.h"
#else
  #include "cryptlib.h"
  #include "test/test.h"
#endif /* Braindamaged MSC include handling */

#if defined( __MVS__ ) || defined( __VMCMS__ )
  /* Suspend conversion of literals to ASCII. */
  #pragma convlit( suspend )
#endif /* IBM big iron */
#if defined( __ILEC400__ )
  #pragma convert( 0 )
#endif /* IBM medium iron */

/* Set the following to a nonzero value to test cryptlib's device init
   capability.  THIS WILL ZEROISE/ERASE THE DEVICE BEING TESTED AS A PART
   OF THE PROCESS.  All data contained in it will be destroyed */

#define TEST_INITIALISE_CARD	0

/* If the device is very slow (e.g. a smart card), clear the following to
   not test the keygen capabilities of the device.  You can set this once
   initially to generate the test keys and then re-clear it to use the
   initially-generated keys from then on */

#define TEST_KEYGEN				1
#if TEST_INITIALISE_CARD > 0
  #undef TEST_KEYGEN
  #define TEST_KEYGEN			1	/* Must be 1 if initialising card */
#endif /* TEST_INITIALISE_CARD */

/* When testing high-level functionality, it's useful to be able to disable
   the low-level algorithm tests and go straight to the high-level tests.
   The following define can be used to disable the algorithm tests */

#define TEST_ALGORITHMS			1

/* The device code will produce a large number of warnings because of ASCII
   <-> Unicode issues, since there aren't any PKCS #11 drivers for WinCE
   it's not worth adding a mountain of special-case code to handle this so
   we no-op it out under WinCE */

#ifndef _WIN32_WCE

/****************************************************************************
*																			*
*								Device Information							*
*																			*
****************************************************************************/

/* Device information tables for PKCS #11 device types.  This lists all the
   devices we know about and can check for.  If you have a PKCS #11 device
   that isn't listed below, you need to add an entry with its name and a
   password and key object label usable for testing to the table, and also
   add the name of the driver as a CRYPT_OPTION_DEVICE_PKCS11_DVRxx entry so
   cryptlib can load the appropriate driver for it.  To add this, use the
   updateConfig() function in testlib.c, see the code comments there for more
   details.

   The ActivCard driver is so broken that it's incredible it works at all,
   it's more of a PKCS #11-like API that only works if you use it in exactly
   the same way as the single test case that ActivCard must have used to
   evaluate it.  The Telesec driver is even more broken than that (it's so
   bad that it doesn't even work with Netscape), it just fakes a PKCS #11
   API while doing something completely different.

   The SEIS EID cards name their private key objects slightly differently
   from the name used in the software-only eID driver, if you're using a
   card-based version you need to switch the commented lines below to the
   alternate name.

   The Rainbow iKey uses Datakey drivers, so the Datakey test below will work
   for both Datakey cards/keys and iKeys.  The newer Rainbow USB tokens
   (using DataKey 232 drivers) can't be usefully initialised via PKCS #11
   but have to be initialised using the vendor utility or operations fail in
   strange and illogical ways.  In addition the driver partially ignores
   user-specified key attributes such as encrypt-only or sign-only and uses
   its own internal defaults.  Finally, operations with these keys then fail
   with a key-type-inconsistent error even though there's nothing wrong with
   them.  The solution to these problems is to use the Datakey 201 drivers
   (intended for Entrust compatibility, which means they actually test them
   properly), which work properly.

   The iD2 driver implements multiple virtual slots, one for each key type,
   so the entry is given in the extended driver::slot name format to tell
   cryptlib which slot to use.

   To reset the Rainbow card after it locks up and stops responding to
   commands, run /samples/cryptoki20/sample.exe, enter 1 CR, 4 CR, 5 CR,
   7 CR 2 CR "rainbow" CR, g CR "test" CR q CR (you need to follow that
   sequence exactly for it to work).

   To (try to) get the Eracom 3.09 CProv to work, delete the /cryptoki
   directory (where it dumps all its config data, ignoring the settings in
   cryptoki.ini), run ctconf.exe to set up a new device config, then
   run ctconf -v -n0.  Then set TEST_INITIALISE_CARD to a nonzero value
   and things should run OK (as with the Rainbow tests, you need to follow
   this exactly for it to work).  Re-running the test with the initialised
   device, or trying to re-run the initialisation, both fail.  The re-init
   reports that no login is required for the token, returns an already-
   logged-in error if an attempt is made to log in, and returns a not-logged-
   in error of an attempt is made to do anything that needs a login.  The
   re-use of the initialised device fails with an invalid object handle
   for every object that's created (that is, it's possible to create any
   object, but any attempt to use it returns an invalid object handle
   error).  The Eracom 2.10 CProv works OK (it may be necessary to manually
   initialise the token using ctinit after the initial install).

   The Spyrus USB drivers don't get on with various drivers for other USB
   devices such as USB printers (basic devices like USB storage keys are
   OK).  To get the Spyrus driver to see the USB token, it may be necessary
   to completely remove (not just disable) other USB device drivers.  The
   Rosetta cards/USB tokens are very flaky, in general it's only possible
   to safely generate new keys and add certs to a freshly-initialised token,
   trying to add/update objects when there are already existing objects
   present tends to fail with internal errors, and deleting the existing
   objects isn't possible, the delete call succeeds but the object isn't
   touched.  In addition with most versions of the Spyrus drivers data
   isn't persisted to the token correctly, so some information (and even
   complete objects) are only visible for the duration of the session that
   created them.

   The presence of a device entry in this table doesn't necessarily mean
   that the PKCS #11 driver that it comes with functions correctly, or at
   all.  In particular the iButton driver is still in beta so it has some
   features unimplemented, and the Utimaco driver apparently has some really
   strange bugs, as well as screwing up Windows power management so that
   suspends either aren't possible any more or will crash apps.  At the
   other end of the scale the Datakey (before Rainbow got to them), Eracom
   (usually), iD2, and nCipher drivers are pretty good */

typedef struct {
	const char *name;
	const char *description;
	const char *password;
	const char *keyLabel;
	} DEVICE_CONFIG_INFO;

static const DEVICE_CONFIG_INFO pkcs11DeviceInfo[] = {
	{ "[Autodetect]", "Automatically detect device", "test", "Test user key" },
	{ "ActivCard Cryptoki Library", "ActivCard", "test", "Test user key" },
	{ "Chrystoki", "Chrysalis Luna", "test", "Test user key" },
	{ "CryptoFlex", "CryptoFlex", "ABCD1234", "012345678901234567890123456789ME" },
	{ "Cryptographic Token Interface", "AET SafeSign", "test", "Test user key" },
	{ "Cryptoki for CardMan API", "Utimaco", "test", "Test user key" },
	{ "Cryptoki for eID", "Nexus soft-token", "1234", "Private key" },
	{ "Cryptoki for eID", "Nexus signature token", "1234", "eID private nonrepudiation key" },
	{ "Cryptoki for eID", "Nexus signature token", "1234", "eID private key encipherment key" },
	{ "Cryptoki PKCS-11", "Gemplus", "test", "Test user key" },
	{ "CryptoKit Extended Version", "Eutron (via Cylink)", "12345678", "Test user key" },
	{ "Datakey Cryptoki DLL - NETSCAPE", "Datakey pre-4.1, post-4.4 driver", "test", "Test user key" },
	{ "Datakey Cryptoki DLL - Version", "Datakey 4.1-4.4 driver", "test", "Test user key" },
	{ "Eracom Cryptoki", "Eracom", "test", "Test user key" },
	{ "ERACOM Software Only", "Eracom 1.x soft-token", "test", "Test user key" },
	{ "Software Only", "Eracom 2.x soft-token", "test", "Test user key" },
	{ "eToken PKCS#11", "Aladdin eToken", "test", "Test user key" },
	{ "G&D PKCS#11 Library", "Giesecke and Devrient", "test", "Test user key" },
	{ "iButton", "Dallas iButton", "test", "Test user key" },
	{ "iD2 Cryptographic Library::iD2 Smart Card (PIN1)", "iD2 signature token::Slot 1", "1234", "Digital Signature" },
	{ "iD2 Cryptographic Library::iD2 Smart Card (PIN2)", "iD2 signature token::Slot 2", "5678", "Non Repudiation" },
	{ "ISG", "CryptoSwift HSM", "test", "Test user key" },
	{ "ISG Cryptoki API library", "CryptoSwift card", "test", "Test user key" },
	{ "Lynks/EES Token in SpyrusNATIVE", "Spyrus Lynks/EES", "test", "Test user key" },
	{ "NShield 75", "nCipher", "test", "Test user key" },
	{ "PKCS#11 Private Cryptoki", "GemSAFE", "1234", "Test user key" },
	{ "Safelayer PKCS#11", "Safelayer", "test", "Test user key" },
	{ "Schlumberger", "Schlumberger", "QWERTYUI", "Test user key" },
	{ "SignLite security module", "IBM SignLite", "test", "Test user key" },
	{ "Spyrus Rosetta", "Spyrus Rosetta", "test", "Test user key" },
	{ "Spyrus Lynks", "Spyrus Lynks", "test", "Test user key" },
	{ "TCrypt", "Telesec", "123456", "Test user key" },
	{ "TrustCenter PKCS#11 Library", "GPKCS11", "12345678", "Test user key" },
	{ NULL, NULL, NULL }
	};

/* Device information for Fortezza cards */

#define FORTEZZA_ZEROISE_PIN		"ZeroizedCard"
#define FORTEZZA_SSO_DEFAULT_PIN	"Mosaic"
#define FORTEZZA_SSO_PIN			"test"
#define FORTEZZA_USER_PIN			"test"

static const DEVICE_CONFIG_INFO fortezzaDeviceInfo = \
	{ "[Autodetect]", "Automatically detect device", FORTEZZA_USER_PIN, "Test user key" };

/* Device information for CryptoAPI */

static const DEVICE_CONFIG_INFO capiDeviceInfo[] = {
	{ "[Autodetect]", "Automatically detect device", "", "Encryption key" },
	{ "Microsoft Base Cryptographic Provider v1.0::MY", "Microsoft Base Cryptographic Provider", "", "Encryption key" },
	{ NULL, NULL, NULL }
	};

/* Data used to create certs in the device */

static const CERT_DATA paaCertData[] = {
	/* Identification information */
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Honest Dave's PAA" },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Certification Policy Division" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave the PAA" },

	/* Self-signed X.509v3 CA certificate */
	{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
	{ CRYPT_CERTINFO_CA, IS_NUMERIC, TRUE },
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC,
	  CRYPT_KEYUSAGE_KEYCERTSIGN },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

static const CERT_DATA cACertData[] = {
	/* Identification information */
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers and CA" },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Certification Division" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave Himself" },

	/* Self-signed X.509v3 CA certificate */
	{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
	{ CRYPT_CERTINFO_CA, IS_NUMERIC, TRUE },
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC,
	  CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

static const CERT_DATA userCertData[] = {
	/* Identification information */
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's key" },

	/* X.509v3 general-purpose certificate */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC,
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_KEYENCIPHERMENT },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

static const CERT_DATA userSigOnlyCertData[] = {
	/* Identification information */
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's signing key" },

	/* X.509v3 signature-only certificate */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_DIGITALSIGNATURE },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

static const CERT_DATA userKeyAgreeCertData[] = {
	/* Identification information */
	{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers" },
	{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's key agreement key" },

	/* X.509v3 key agreement certificate */
	{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_KEYAGREEMENT },

	{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
	};

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Delete leftover keys created during testing */

static void deleteTestKey( const CRYPT_DEVICE cryptDevice,
						   const C_STR keyName, const char *keyDescription )
	{
	if( cryptDeleteKey( cryptDevice, CRYPT_KEYID_NAME, keyName ) == CRYPT_OK )
		printf( "(Deleted a %s key object, presumably a leftover from a "
				"previous run).\n", keyDescription );
	}

/* Create a key and certificate in a device */

static BOOLEAN createKey( const CRYPT_DEVICE cryptDevice,
						  const CRYPT_ALGO_TYPE cryptAlgo,
						  const char *description, const char *dumpName,
						  const CRYPT_CONTEXT signingKey )
	{
	CRYPT_CONTEXT cryptContext;
	CRYPT_CERTIFICATE cryptCert;
	BYTE certBuffer[ BUFFER_SIZE ], labelBuffer[ CRYPT_MAX_TEXTSIZE ];
	const BOOLEAN isCA = ( signingKey == CRYPT_UNUSED ) ? TRUE : FALSE;
	const CERT_DATA *certData = ( isCA ) ? cACertData : \
			( cryptAlgo == CRYPT_ALGO_RSA ) ? userCertData : \
			( cryptAlgo == CRYPT_ALGO_DSA ) ? userSigOnlyCertData : \
			userKeyAgreeCertData;
	int certificateLength, status;

	sprintf( labelBuffer, "Test %s key", description );

	/* 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, BUFFER_SIZE, &certificateLength,
				isCA ? CRYPT_CERTFORMAT_CERTIFICATE : CRYPT_CERTFORMAT_CERTCHAIN,
				cryptCert );
		if( cryptStatusOK( status ) )

⌨️ 快捷键说明

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