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

📄 devices.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
		printf( "Device label is '%s'.\n", tokenLabel );
		}

	/* See if we need to authenticate ourselves */
	status = cryptGetAttribute( cryptDevice, CRYPT_DEVINFO_LOGGEDIN,
								&loggedOn );
	if( cryptStatusError( status ) )
		{
		puts( "Couldn't obtain device login status." );
		return( FALSE );
		}
	if( loggedOn )
		{
		/* Device may not require a login, or has already been logged in
		   via a keypad or similar mechanism */
		puts( "Device is already logged in, skipping login." );
		return( TRUE );
		}

	/* Try and log in */
	printf( "Logging on to the device..." );
	status = cryptSetAttributeString( cryptDevice,
								CRYPT_DEVINFO_AUTHENT_USER, userPIN,
								strlen( userPIN ) );
	if( status == CRYPT_ERROR_INITED )
		{
		/* Some devices may not require any login, in which case we're
		   done */
		puts( " device is already logged in." );
		return( TRUE );
		}
	if( status == CRYPT_ERROR_NOTINITED )
		{
		/* It's an uninitialised device, tell the user and exit */
		puts( " device needs to be initialised." );
		return( FALSE );
		}
	if( cryptStatusError( status ) )
		{
		printf( "\nDevice login failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( " done." );
	return( TRUE );
	}

/* Initialise a device */

static int initDevice( const CRYPT_DEVICE cryptDevice,
					   const char *defaultSSOPIN, const char *ssoPIN,
					   const char *userPIN )
	{
	int status;

	/* PKCS #11 doesn't distinguish between zeroisation and initialisation,
	   so we need to zeroise the device if it's a Fortezza card */
	if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
		{
		printf( "Zeroising device..." );
		status = cryptSetAttributeString( cryptDevice,
						CRYPT_DEVINFO_ZEROISE, FORTEZZA_ZEROISE_PIN,
						strlen( FORTEZZA_ZEROISE_PIN ) );
		if( cryptStatusError( status ) )
			{
			printf( "\nCouldn't zeroise device, status = %d, line %d.\n",
					status, __LINE__ );
			return( FALSE );
			}
		puts( " done." );
		}

	/* Initialise the device and set the SO PIN */
	printf( "Initialising device with default SO PIN '%s'...",
			defaultSSOPIN );
	status = cryptSetAttributeString( cryptDevice, CRYPT_DEVINFO_INITIALISE,
									  defaultSSOPIN, strlen( defaultSSOPIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\nCouldn't initialise device, status = %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( " done." );
	printf( "Setting SO PIN to '%s'...", ssoPIN );
	status = cryptSetAttributeString( cryptDevice,
									  CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR,
									  ssoPIN, strlen( ssoPIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\nCouldn't set SO PIN, status = %d, line %d.\n", status,
				__LINE__ );
		return( FALSE );
		}
	puts( " done." );

	/* If it's a Fortezza card, create a dummy PAA key and install its cert.
	   We have to do it at this point because the operation is only allowed
	   in the SSO initialised state.  In addition we can't use the card for
	   this operation 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 */
	if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
		{
		CRYPT_CERTIFICATE cryptCert;
		CRYPT_CONTEXT signContext;

		printf( "Loading PAA certificate..." );
		if( !loadDSAContexts( CRYPT_UNUSED, &signContext, NULL ) )
			return( FALSE );
		status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
								  CRYPT_CERTTYPE_CERTIFICATE );
		if( cryptStatusError( status ) )
			return( FALSE );
		status = cryptSetAttribute( cryptCert,
						CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, signContext );
		if( cryptStatusOK( status ) && \
			!addCertFields( cryptCert, paaCertData, __LINE__ ) )
			return( FALSE );
		if( cryptStatusOK( status ) )
			status = cryptSignCert( cryptCert, signContext );
		cryptDestroyContext( signContext );
		if( cryptStatusError( status ) )
			{
			cryptDestroyCert( cryptCert );
			printf( "\nCreation of certificate failed with error code %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptDevice, cryptCert );
		cryptDestroyCert( cryptCert );
		if( cryptStatusError( status ) )
			{
			printf( "\ncryptAddPublicKey() failed with error code %d, line "
					"%d.\n", status, __LINE__ );
			return( FALSE );
			}
		puts( " done." );
		}

	/* Set the user PIN and log on as the user.  Some devices automatically
	   log the user in when they set the user password, however, for some
	   devices this is a pseudo-login for which any subsequent operations
	   fail with a not-logged-in error or something similar, so rather than
	   relying on the existing login we always (re-)log in, which performs
	   an explicit logoff if we're already logged in at the time */
	printf( "Setting user PIN to '%s'...", userPIN );
	status = cryptSetAttributeString( cryptDevice,
									  CRYPT_DEVINFO_SET_AUTHENT_USER,
									  userPIN, strlen( userPIN ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttributeString( cryptDevice,
										  CRYPT_DEVINFO_AUTHENT_USER,
										  userPIN, strlen( userPIN ) );
	if( cryptStatusError( status ) )
		{
		printf( "\nCouldn't set user PIN/log on as user, status = %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	puts( " done." );

	return( TRUE );
	}

/* Open a cert store */

static int openCertStore( CRYPT_KEYSET *cryptCertStore )
	{
	int status;

	/* Clear return value */
	*cryptCertStore = -1;

	/* Open the cert store */
	printf( "Opening CA certificate store..." );
	status = cryptKeysetOpen( cryptCertStore, CRYPT_UNUSED,
							  CRYPT_KEYSET_ODBC_STORE, "testcertstore",
							  CRYPT_KEYOPT_CREATE );
	if( status == CRYPT_ERROR_DUPLICATE )
		status = cryptKeysetOpen( cryptCertStore, CRYPT_UNUSED,
								  CRYPT_KEYSET_ODBC_STORE, "testcertstore",
								  CRYPT_KEYOPT_NONE );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	puts( " done." );

	return( TRUE );
	}

/* Add a PKI user to a cert store */

static int initUserInfo( const CRYPT_KEYSET cryptCertStore,
						 const char *userName )
	{
	CRYPT_CERTIFICATE cryptPKIUser;
	int length, status;

	/* Create the PKI user object and add the user's identification
	   information */
	printf( "Creating PKI user..." );
	status = cryptCreateCert( &cryptPKIUser, CRYPT_UNUSED,
							  CRYPT_CERTTYPE_PKIUSER );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptCreateCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttributeString( cryptPKIUser,
									  CRYPT_CERTINFO_COMMONNAME, userName,
									  strlen( userName ) );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptPKIUser, "cryptSetAttributeString()",
							   status, __LINE__ ) );
	puts( " done." );

	/* Add the user info to the cert store */
	printf( "Adding PKI user to CA certificate store..." );
	status = cryptCAAddItem( cryptCertStore, cryptPKIUser );
	if( status == CRYPT_ERROR_DUPLICATE )
		{
		char userCN[ CRYPT_MAX_TEXTSIZE + 1 ];

		/* The PKI user info is already present from a previous run, get the
		   existing info */
		printf( "\nPKI user information is already present from a previous "
				"run, re-using existing\n  PKI user data..." );
		status = cryptGetAttributeString( cryptPKIUser,
										  CRYPT_CERTINFO_COMMONNAME,
										  userCN, &length );
		if( cryptStatusError( status ) )
			return( attrErrorExit( cryptPKIUser, "cryptGetAttribute()",
								   status, __LINE__ ) );
		userCN[ length ] = '\0';
		cryptDestroyCert( cryptPKIUser );
		status = cryptCAGetItem( cryptCertStore, &cryptPKIUser,
								 CRYPT_CERTTYPE_PKIUSER, CRYPT_KEYID_NAME,
								 userCN );
		}
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCAAddItem()", status,
							  __LINE__ ) );
	puts( " done." );

	/* Display the information for the user */
	if( !printCertInfo( cryptPKIUser ) )
		return( FALSE );

	/* Clean up */
	cryptDestroyCert( cryptPKIUser );
	return( TRUE );
	}

/* Get details for a PKI user */

static int getUserInfo( char *userID, char *issuePW )
	{
#ifndef CLIENT_ID
	CRYPT_KEYSET cryptCertStore;
	CRYPT_CERTIFICATE cryptPKIUser;
	int length, status;

	/* Get the PKIUser object from the cert store */
	status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
							  CRYPT_KEYSET_ODBC_STORE, "testcertstore",
							  CRYPT_KEYOPT_NONE );
	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__ ) );

	/* Extract the information from the PKIUser object */
	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';
	cryptDestroyCert( cryptPKIUser );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptPKIUser, "cryptGetAttribute()", status,
							   __LINE__ ) );
#else
	strcpy( userID, CLIENT_ID );
	strcpy( issuePW, CLIENT_AUTHENTICATOR );
#endif /* CLIENT_ID */

	/* We've got what we need, tell the user what we're doing */
	printf( "Using user name %s, password %s.\n", userID, issuePW );
	return( TRUE );
	}

/* Run the PnP PKI server */

static int pnpServer( const CRYPT_DEVICE cryptDevice,
					  const CRYPT_KEYSET cryptCertStore )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_CONTEXT cryptPrivateKey;
	int caCertTrusted, status;

	/* Perform a cleanup action to remove any leftover requests from
	   previous runs */
	cryptCACertManagement( NULL, CRYPT_CERTACTION_CLEANUP, cryptCertStore,
						   CRYPT_UNUSED, CRYPT_UNUSED );

	/* Get the CA's key from the device and make it trusted for PKIBoot
	   functionality.  If we're running the test in loopback mode with the
	   Fortezza interface we can't have both the client and server using
	   Fortezza cards due to Spyrus driver bugs, and also can't have the
	   client and server as PKCS #11 and Fortezza due to other driver bugs,
	   so we have to fake the CA key using a software-only implementation */
	printf( "Making CA cert trusted for PKIBoot..." );
#ifndef CLIENT_ID
	if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
		status = getPrivateKey( &cryptPrivateKey, CA_PRIVKEY_FILE,
								CA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
	else
#endif /* CLIENT_ID */
		status = cryptGetPrivateKey( cryptDevice, &cryptPrivateKey,
									 CRYPT_KEYID_NAME, "CA key", NULL );
	if( cryptStatusError( status ) )
		{
		printf( "\nCA private key read failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	cryptGetAttribute( cryptPrivateKey, CRYPT_CERTINFO_TRUSTED_IMPLICIT,
					   &caCertTrusted );
	cryptSetAttribute( cryptPrivateKey, CRYPT_CERTINFO_TRUSTED_IMPLICIT, 1 );
	puts( " done." );

	/* Create the CMP session and add the CA key and cert store */
	printf( "Creating CMP server session..." );
	status = cryptCreateSession( &cr

⌨️ 快捷键说明

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