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

📄 devices.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 );
		cryptCreateCert( &cryptCert, CRYPT_UNUSED,
						 CRYPT_CERTTYPE_CERTIFICATE );
		status = cryptSetAttribute( cryptCert,
						CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, signContext );
		if( cryptStatusOK( status ) && \
			!addCertFields( cryptCert, paaCertData ) )
			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 );
		}
	else
		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( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_CMP_SERVER );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptCreateSession() failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptSession,
							CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptSession,
							CRYPT_SESSINFO_KEYSET, cryptCertStore );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptSession, "cryptSetAttribute()",
							   status, __LINE__ ) );
	if( !setConnectInfo( cryptSession, SERVER_MACHINE_ADDRESS,
						 SERVER_MACHINE_PORT, NET_TIMEOUT ) )
		return( FALSE );
	puts( " done." );

	/* Activate the session */
	status = activatePersistentServerSession( cryptSession );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptSession, "Attempt to activate CMP "
							  "server session", status, __LINE__ ) );

	/* Clean up */
	cryptDestroySession( cryptSession );
	if( !caCertTrusted )
		cryptSetAttribute( cryptPrivateKey,
						   CRYPT_CERTINFO_TRUSTED_IMPLICIT, 0 );

	return( TRUE );
	}

/* Run the PnP PKI client */

static int pnpClient( const CRYPT_DEVICE cryptDevice, const char *userID,
					  const char *issuePW )
	{
	CRYPT_SESSION cryptSession;
	int status;

	/* Create the CMP session and set up the information we need for the
	   plug-and-play PKI process */
	printf( "Creating CMP client session..." );
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_CMP );
	if( cryptStatusError( status ) )
		{
		printf( "\ncryptCreateSession() failed with error code %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttributeString( cryptSession,
									  CRYPT_SESSINFO_USERNAME, userID,
									  paramStrlen( userID ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_PASSWORD,
										  issuePW, paramStrlen( issuePW ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptSession,
									CRYPT_SESSINFO_CMP_PRIVKEYSET,
									cryptDevice );
	if( cryptStatusError( status ) )
		{
		printf( "\nAddition of session information failed with error code "
				"%d, line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	if( !setConnectInfo( cryptSession, SERVER_MACHINE_ADDRESS,
						 SERVER_MACHINE_PORT, NET_TIMEOUT ) )
		return( FALSE );
	puts( " done." );

	/* Activate the session */
	printf( "Obtaining keys and certs..." );
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "\nAttempt to activate plug-a

⌨️ 快捷键说明

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