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

📄 s_cmp.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif /* !SERVER_IS_CRYPTLIB */
#ifndef SERVER_PKIBOOT
	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 );
		}
#endif /* !SERVER_PKIBOOT */

	/* 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 insert a 1s delay
	   between requests to give the server time to recycle */

	/* Initialisation request */
#ifdef TEST_IR
  #ifdef SERVER_IS_CRYPTLIB
	/* 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 = pkiGetUserInfo( userID, issuePW, NULL,
							 TEXT( "Test PKI user" ) );
	if( status == CRYPT_ERROR_NOTAVAIL )
		{
		/* Cert store operations aren't available, exit but continue with
		   other tests */
	#ifndef SERVER_PKIBOOT
		cryptDestroyCert( cryptCACert );
	#endif /* !SERVER_PKIBOOT */
		return( TRUE );
		}
	else
		if( !status )
			{
	#ifndef SERVER_PKIBOOT
			cryptDestroyCert( cryptCACert );
	#endif /* !SERVER_PKIBOOT */
			return( FALSE );
			}

	/* Set up the variable info in the CA info record */
	cryptlibCAInfo.user = userID;
	cryptlibCAInfo.password = issuePW;
  #endif /* SERVER_IS_CRYPTLIB */
	/* Initialisation.  We define REVOKE_FIRST_CERT to indicate that we can
	   revoke this one later on */
	#define REVOKE_FIRST_CERT
	filenameParamFromTemplate( writeFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
	status = requestCert( "RSA signing cert.init.request", caInfoPtr, NULL,
						  usePKIBoot ? NULL : writeFileName,
#if defined( SERVER_PROVIDES_DN )
						  cmpRsaSignRequestNoDNData,
#else
						  cmpRsaSignRequestData,
#endif /* SERVER_PROVIDES_DN */
						  CRYPT_ALGO_RSA, cryptCACert, usePKIBoot, FALSE,
						  &cryptCert );
	if( status != TRUE )
		{
		/* If this is the self-test and there's a non-fatal error, make sure
		   we don't fail with a CRYPT_ERROR_INCOMPLETE when we're finished */
		cryptDestroyCert( cryptCACert );
		return( status );
		}
	if( usePKIBoot )
		{
		/* If we're testing the PKIBoot capability, there's only a single
		   request to process */
		cryptDestroyCert( cryptCACert );
		return( TRUE );
		}
	delayThread( 2 );
#endif /* TEST_IR */
#ifdef TEST_DUP_IR
	/* Attempt a second ir using the same PKI user data.  This should fail,
	   since the cert store only allows a single ir per user */
	if( requestCert( "Duplicate init.request", caInfoPtr, NULL, NULL,
					 cmpRsaSignRequestNoDNData, CRYPT_ALGO_RSA, cryptCACert,
					 FALSE, TRUE, NULL ) )
		{
		printf( "Duplicate init request wasn't detected by the CMP server, "
				"line %d.\n\n", __LINE__ );
		cryptDestroyCert( cryptCACert );
		return( FALSE );
		}
#endif /* TEST_DUP_IR */

	/* Cert request.  We have to perform this test before the kur since some
	   CAs implicitly revoke the cert being replaced, which means we can't
	   use it to authenticate requests any more once the kur has been
	   performed */
#ifdef TEST_CR
	/* We define REVOKE_SECOND_CERT to indicate that we can revoke this one
	   later on alongside the ir/kur'd cert, and save a copy to a file for
	   later use */
	#define REVOKE_SECOND_CERT
	filenameParamFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
	filenameParamFromTemplate( writeFileName, CMP_PRIVKEY_FILE_TEMPLATE, 2 );
	status = requestCert( "RSA signing certificate request", caInfoPtr,
						  readFileName, writeFileName, cmpRsaSignRequestData,
						  CRYPT_ALGO_RSA, cryptCACert, FALSE, FALSE, NULL );
	if( status != TRUE )
		{
  #if defined( TEST_IR )
		cryptDestroyCert( cryptCert );
  #endif /* TEST_IR || TEST_KUR */
		cryptDestroyCert( cryptCACert );
		return( status );
		}
	delayThread( 2 );
#endif /* TEST_CR */

	/* Key update request */
#ifdef TEST_KUR
  #ifdef TEST_IR
	/* We just created the cert, delete it so we can replace it with the
	   updated form */
	cryptDestroyCert( cryptCert );
  #endif /* TEST_IR */

	/* If it's a CA that implicitly revokes the cert being replaced (in
	   which case tracking things gets a bit too complicated since we now
	   need to use the updated rather than original cert to authenticate the
	   request) we just leave it unrevoked (the first cert is always
	   revoked) */
  #ifdef SERVER_IS_CRYPTLIB
	#undef REVOKE_FIRST_CERT
  #endif /* SERVER_IS_CRYPTLIB */

	/* Key update */
	filenameParamFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
	status = requestCert( "RSA signing certificate update", caInfoPtr,
						  readFileName, NULL, NULL, CRYPT_UNUSED,
						  cryptCACert, FALSE, FALSE, &cryptCert );
	if( status != TRUE )
		{
		cryptDestroyCert( cryptCACert );
		return( status );
		}
	delayThread( 2 );
#endif /* TEST_KUR */
#if 0
	/* DSA cert request.  We have to get this now because we're about to
	   revoke the cert we're using to sign the requests */
	filenameParamFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
	status = requestCert( "DSA certificate", caInfoPtr, readFileName, NULL,
						  cmpDsaRequestData, CRYPT_ALGO_DSA, cryptCACert,
						  FALSE, FALSE, NULL );
	if( status != TRUE )
		return( status );
	delayThread( 2 );
#endif /* 0 */
#if 0
	/* Encryption-only cert request.  This test requires a change in
	   certsign.c because when creating a cert request cryptlib always
	   allows signing for the request even if it's an encryption-only key
	   (this is required for PKCS #10, see the comment in the kernel code).
	   Because of this a request will always appear to be associated with a
	   signature-enabled key so it's necessary to make a code change to
	   disallow this.  Disallowing sigs for encryption-only keys would break
	   PKCS #10 since it's then no longer possible to create the self-signed
	   request, this is a much bigger concern than CMP.  Note that this
	   functionality is tested by the PnP PKI test, which creates the
	   necessary encryption-only requests internally and can do things that
	   we can't do from the outside */
	status = requestCert( "RSA encryption certificate", caInfoPtr,
						  readFileName, writeFileName, cmpRsaEncryptRequestData,
						  CRYPT_ALGO_RSA, cryptCACert, FALSE, FALSE, NULL );
	if( status != TRUE )
		return( status );
	delayThread( 2 );
#endif /* 0 */

	/* Revocation request */
#ifdef TEST_RR
	filenameParamFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
  #ifdef REVOKE_FIRST_CERT
	#ifdef SERVER_IR_DN
	status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
						 readFileName, cryptCert, cryptCACert, TRUE );
	#else
	status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
						 readFileName, cryptCert, cryptCACert, FALSE );
	#endif /* Certicom requires signed request */
	cryptDestroyCert( cryptCert );
	delayThread( 2 );
  #elif !defined( TEST_KUR ) || !defined( SERVER_IS_CRYPTLIB )
	/* We didn't issue the first cert in this run, try revoking it from
	   the cert stored in the key file unless we're talking to a CA that
	   implicitly revokes the cert being replaced during a kur */
	status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
						 readFileName, CRYPT_UNUSED, cryptCACert, TRUE );
  #else
	/* This is a kur'd cert for which the original has been implicitly
	   revoked, we can't do much else with it */
	cryptDestroyCert( cryptCert );
  #endif /* REVOKE_FIRST_CERT */
	if( status != TRUE )
		{
		cryptDestroyCert( cryptCACert );
		return( status );
		}
  #ifdef REVOKE_SECOND_CERT
	/* We requested a second cert, revoke that too.  Note that we have to
	   sign this with the second cert since the first one may have just been
	   revoked */
	filenameParamFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 2 );
	status = revokeCert( "RSA signing certificate", caInfoPtr, readFileName,
						 CRYPT_UNUSED, cryptCACert, TRUE );
	if( status != TRUE )
		{
		cryptDestroyCert( cryptCACert );
		return( status );
		}
  #endif /* REVOKE_SECOND_CERT */
#endif /* TEST_RR */

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

int testSessionCMP( void )
	{
	return( connectCMP( FALSE, FALSE ) );
	}

/* Test the plug-and-play PKI functionality */

static int connectPNPPKI( const BOOLEAN isCaUser, const BOOLEAN useDevice,
						  const BOOLEAN localSession )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_KEYSET cryptKeyset;
	C_CHR userID[ 64 ], issuePW[ 64 ];
	int status;

	/* Create the CMP session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_CMP );
	if( status == CRYPT_ERROR_PARAM3 )	/* CMP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Open the device/create the keyset to contain the keys.  This doesn't
	   perform a full device.c-style auto-configure but assumes that it's
	   talking to a device that's already been initialised and is ready to
	   go */
	if( useDevice )
		{
		status = cryptDeviceOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_DEVICE_PKCS11,
								  TEXT( "[Autodetect]" ) );
		if( cryptStatusError( status ) )
			{
			printf( "Crypto device open failed with error code %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptSetAttributeString( cryptKeyset,
										  CRYPT_DEVINFO_AUTHENT_USER,
										  "test", 4 );
		if( cryptStatusError( status ) )
			{
			printf( "\nDevice login failed with error code %d, line %d.\n",
					status, __LINE__ );
			return( FALSE );
			}
		if( cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
							TEXT( "Signature key" ) ) == CRYPT_OK )
			puts( "(Deleted a signature key object, presumably a leftover "
				  "from a previous run)." );
		if( cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
							TEXT( "Encryption key" ) ) == CRYPT_OK )
			puts( "(Deleted an encryption key object, presumably a leftover "
				  "from a previous run)." );
		}
	else
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_KEYSET_FILE, isCaUser ? \
										PNPCA_PRIVKEY_FILE : PNP_PRIVKEY_FILE,
								  CRYPT_KEYOPT_CREATE );
		if( cryptStatusError( status ) )
			{
			printf( "User keyset create failed with error code %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		}

	/* Wait for the server to finish initialising */
	if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT )
		{
		printf( "Timed out waiting for server to initialise, line %d.\n",
				__LINE__ );
		return( FALSE );
		}

	/* Get information needed for enrolment */
	status = pkiGetUserInfo( userID, issuePW, NULL, isCaUser ? \
								TEXT( "Test CA PKI user" ) : \
								TEXT( "Test PKI user" ) );
	if( status == CRYPT_ERROR_NOTAVAIL )
		/* Cert store operations aren't available, exit but continue with
		   other tests */
		return( TRUE );
	else
		if( !status )
			return( FALSE );

	/* Set up the information we need for the plug-and-play PKI process */
	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 = cryptSetAttributeString( cryptSession,
										  CRYPT_SESSINFO_SERVER_NAME,
										  caInfo[ CA_CRYPTLIB_PNPPKI ].url,
										  paramStrlen( caInfo[ CA_CRYPTLIB_PNPPKI ].url ) );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptSession,
									CRYPT_SESSINFO_CMP_PRIVKEYSET,
									cryptKeyset );
	if( cryptStatusOK( status ) && useDevice )
		{
		/* Keygen on a device can take an awfully long time for some devices,
		   so we set an extended timeout to allow for this */
		cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_READTIMEOUT,
						   NET_TIMEOUT );
		status = cryptSetAttribute( cryptSession,
									CRYPT_OPTION_NET_WRITETIMEOUT,
									NET_TIMEOUT );
		}
	if( useDevice )
		cryptDeviceClose( cryptKeyset );
	else
		cryptKeysetClose( cryptKeyset );
	if( cryptStatusError( status ) )
		{
		printf( "Addition of session information failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* Activate the session */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "Attempt to activate plug-and-play PKI "
					   "client session", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* Clean up */
	cryptDestroySession( cryptSession );

	/* If this is the intermediate CA cert, change the password to allow it
	   to be used with the standard PnP PKI test */
	if( isCaUser )
		{
		CRYPT_CONTEXT cryptKey;

		/* Get the newly-issued key */
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_KEYSET_FILE, PNPCA_PRIVKEY_FILE,
								  CRYPT_KEYOPT_NONE );
		if( cryptStatusOK( status ) )
			{
			status = cryptGetPrivateKey( cryptKeyset, &cryptKey,
										 CRYPT_KEYID_NAME,
										 TEXT( "Signature key" ), issuePW );
			cryptKeysetClose( cryptKeyset );
			}
		if( cryptStatusError( status ) )
			{
			printf( "Certified private-key read failed with error code %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}

		/* Replace the keyset with one with the key protected with a
		   different password */
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_KEYSET_FILE, PNPCA_PRIVKEY_FILE,
								  CRYPT_KEYOPT_CREATE );
		if( cryptStatusOK( status ) )
			{
			status = cryptAddPrivateKey( cryptKeyset, cryptKey,
										 TEST_PRIVKEY_PASSWORD );
			cryptKeysetClose( cryptKeyset );
			}
		cryptDestroyContext( cryptKey );
		if( cryptStatusError( status ) )
			{
			printf( "Certified private-key password change failed with error "
					"code %d, line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		}

	return( TRUE );
	}

⌨️ 快捷键说明

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