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

📄 certproc.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
			return( TRUE );
		if( isExpired && status == CRYPT_ERROR_INVALID )
			{
			puts( "The short-expiry-time certificate has already expired at "
				  "the time of issue.\nThis happened because there was a "
				  "delay of more than 5s between adding the\nrequest and "
				  "issuing the certificate for it.  Try re-running the test "
				  "on a\nless-heavily-loaded system, or increase the expiry "
				  "delay to more than 5s." );
			return( FALSE );
			}
		return( extErrorExit( cryptCertStore, "cryptCACertManagement()",
							  status, __LINE__ ) );
		}

	return( issueShouldFail ? FALSE : TRUE );
	}

/* Issue a CRL.  Although we can't do this directly (see the comment above
   for the revocation request code) we can at least test the ability to
   create an empty CRL (and if the CMP code has been run there will probably
   be a few revocation entries present to fill the CRL) */

static int issueCRL( const CRYPT_KEYSET cryptCertStore,
					 const CRYPT_CONTEXT cryptCAKey )
	{
	CRYPT_CERTIFICATE cryptCRL;
	int noEntries = 0, status;

	/* Issue the CRL via the cert store */
	status = cryptCACertManagement( &cryptCRL, CRYPT_CERTACTION_ISSUE_CRL,
									cryptCertStore, cryptCAKey,
									CRYPT_UNUSED );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCACertManagement()",
							  status, __LINE__ ) );

	/* Print information on the CRL */
	if( cryptStatusOK( cryptSetAttribute( cryptCRL,
										  CRYPT_CERTINFO_CURRENT_CERTIFICATE,
										  CRYPT_CURSOR_FIRST ) ) )
		do
			noEntries++;
		while( cryptSetAttribute( cryptCRL,
								  CRYPT_CERTINFO_CURRENT_CERTIFICATE,
								  CRYPT_CURSOR_NEXT ) == CRYPT_OK );
	printf( "CRL has %d entr%s.\n", noEntries,
			( noEntries == 1 ) ? "y" : "ies" );
	if( !noEntries )
		puts( "  (This is probably because there haven't been any revocation "
			  "entries added\n   via the CMP test yet)." );

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

/* Fetch the issued cert that was created from a given cert template */

static CRYPT_CERTIFICATE getCertFromTemplate( const CRYPT_KEYSET cryptCertStore,
											  const CERT_DATA *certReqData )
	{
	CRYPT_CERTIFICATE cryptCert;
	int i, status;

	for( i = 0; certReqData[ i ].componentType != CRYPT_ATTRIBUTE_NONE; i++ )
		if( certReqData[ i ].type == CRYPT_CERTINFO_COMMONNAME )
			break;
	status = cryptGetPublicKey( cryptCertStore, &cryptCert, CRYPT_KEYID_NAME,
							    certReqData[ i ].stringValue );
	return( cryptStatusOK( status ) ? cryptCert : status );
	}

int testCertManagement( void )
	{
	CRYPT_CERTIFICATE cryptCert, cryptCertRequest;
	CRYPT_CONTEXT cryptCAKey;
	CRYPT_KEYSET cryptCertStore;
	time_t certTime;
	int dummy, status;

	puts( "Testing certificate management using cert store..." );

	/* Get the CA's private key */
	status = getPrivateKey( &cryptCAKey, CA_PRIVKEY_FILE,
							CA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
	if( cryptStatusError( status ) )
		{
		printf( "CA private key read failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the cert store keyset with a check to make sure that this
	   access method exists so we can return an appropriate error message.
	   If the database table already exists, this will return a duplicate
	   data error so we retry the open with no flags to open the existing
	   database keyset for write access */
	status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
							  CERTSTORE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
							  CRYPT_KEYOPT_CREATE );
	if( cryptStatusOK( status ) )
		puts( "Created new certificate store '" CERTSTORE_KEYSET_NAME_ASCII
			  "'." );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* This type of keyset access isn't available, return a special error
		   code to indicate that the test wasn't performed, but that this
		   isn't a reason to abort processing */
		cryptDestroyContext( cryptCAKey );
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_DUPLICATE )
		status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
								  CERTSTORE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
								  CRYPT_KEYOPT_NONE );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		if( status == CRYPT_ERROR_OPEN )
			{
			cryptDestroyContext( cryptCAKey );
			return( CRYPT_ERROR_FAILED );
			}
		return( FALSE );
		}

	/* Create a cert request, add it to the store, and destroy it, simulating
	   a delayed cert issue in which the request can't immediately be
	   converted into a cert.  Then read the request back from the store and
	   issue a certificate based on it */
	puts( "Issuing certificate for 'Test user 1'..." );
	cryptCertRequest = addCertRequest( cryptCertStore, cert1Data, FALSE );
	if( !cryptCertRequest )
		return( FALSE );
	cryptDestroyCert( cryptCertRequest );
	status = cryptCAGetItem( cryptCertStore, &cryptCertRequest,
							 CRYPT_CERTTYPE_REQUEST_CERT, CRYPT_KEYID_NAME,
							 TEXT( "Test user 1" ) );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCAGetItem()", status,
							  __LINE__ ) );
	status = cryptCACertManagement( &cryptCert, CRYPT_CERTACTION_ISSUE_CERT,
									cryptCertStore, cryptCAKey,
									cryptCertRequest );
	cryptDestroyCert( cryptCertRequest );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCACertManagement()",
							  status, __LINE__ ) );
	cryptDestroyCert( cryptCert );

	/* Issue some more certs, this time directly from the request and without
	   bothering to obtain the resulting cert.  The first two have a validity
	   time that expires in a few seconds so that we can use them to test
	   cert expiry processing, we issue these first to ensure that as much
	   time as possible passes due to other operations occurring before we
	   run the expiry.  The second two are for revocation and CRL testing */
	if( !issueCert( cryptCertStore, cryptCAKey, expiredCert1Data, TRUE, FALSE ) )
		return( FALSE );
	if( !issueCert( cryptCertStore, cryptCAKey, expiredCert2Data, TRUE, FALSE ) )
		return( FALSE );
	if( !issueCert( cryptCertStore, cryptCAKey, revokableCert1Data, FALSE, FALSE ) )
		return( FALSE );
	if( !issueCert( cryptCertStore, cryptCAKey, revokableCert2Data, FALSE, FALSE ) )
		return( FALSE );

	/* The following tests are specifically inserted at this point (rather
	   than at some other point in the test run) because they'll add some
	   further delay before the expiry operation */

	/* Try and get a CA cert issued.  This should fail, since new CAs can
	   only be created if the issuing CA specifies it (either directly when
	   it creates the cert manually or via the PKI user info), but never at
	   the request of the user */
	if( !issueCert( cryptCertStore, cryptCAKey, certCAData, FALSE, TRUE ) )
		{
		printf( "Issue of cert from invalid request succeeded when it "
				"should have failed,\nline %d.\n", __LINE__ );
		return( FALSE );
		}

	/* Get a cert and (to-be-)revoked cert from the store and save them to
	   disk for later tests */
	status = cryptCert = getCertFromTemplate( cryptCertStore, cert1Data );
	if( !cryptStatusError( status ) )
		{
		BYTE fileName[ BUFFER_SIZE ];
		FILE *filePtr;
		int length;

		/* First save the CA cert */
		filenameFromTemplate( fileName, OCSP_CA_FILE_TEMPLATE, 1 );
		status = cryptExportCert( certBuffer, BUFFER_SIZE, &length,
								  CRYPT_CERTFORMAT_CERTIFICATE, 
								  cryptCAKey );
		if( cryptStatusOK( status ) && \
			( filePtr = fopen( fileName, "wb" ) ) != NULL )
			{
			fwrite( certBuffer, length, 1, filePtr );
			fclose( filePtr );
			}

		/* Then the EE cert */
		filenameFromTemplate( fileName, OCSP_EEOK_FILE_TEMPLATE, 1 );
		status = cryptExportCert( certBuffer, BUFFER_SIZE, &length,
								  CRYPT_CERTFORMAT_CERTIFICATE, 
								  cryptCert );
		if( cryptStatusOK( status ) && \
			( filePtr = fopen( fileName, "wb" ) ) != NULL )
			{
			fwrite( certBuffer, length, 1, filePtr );
			fclose( filePtr );
			}
		cryptDestroyCert( cryptCert );
		}
	if( !cryptStatusError( status ) )
		status = cryptCert = getCertFromTemplate( cryptCertStore,
												  revokableCert1Data );
	if( !cryptStatusError( status ) )
		{
		BYTE fileName[ BUFFER_SIZE ];
		FILE *filePtr;
		int length;

		filenameFromTemplate( fileName, OCSP_EEREV_FILE_TEMPLATE, 1 );
		status = cryptExportCert( certBuffer, BUFFER_SIZE, &length,
								  CRYPT_CERTFORMAT_CERTIFICATE, 
								  cryptCert );
		if( cryptStatusOK( status ) && \
			( filePtr = fopen( fileName, "wb" ) ) != NULL )
			{
			fwrite( certBuffer, length, 1, filePtr );
			fclose( filePtr );
			}
		cryptDestroyCert( cryptCert );
		}
	if( cryptStatusError( status ) )
		{
		puts( "Issued certificates couldn't be fetched from the cert store "
			  "and written to\ndisk, the OCSP server test will abort when it "
			  "fails to find these\ncertificates." );
		}

	/* Issue a CRL.  This will probably be a zero-length CRL unless we've run
	   the CMP tests because we can't directly revoke a cert.  Again, we
	   perform it before the expiry test because it'll add some further
	   delay */
	if( !issueCRL( cryptCertStore, cryptCAKey ) )
		return( FALSE );

	/* Get the most recent of the expired certs and wait for it to expire
	   if necessary */
	status = cryptCert = getCertFromTemplate( cryptCertStore,
											  expiredCert1Data );
	if( !cryptStatusError( status ) )
		status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_VALIDTO,
										  &certTime, &dummy );
	if( cryptStatusError( status ) )
		{
		puts( "Couldn't get expiry information for expired cert." );
		return( FALSE );
		}
#ifndef _WIN32_WCE
	if( certTime >= time( NULL ) )
		{
		printf( "Waiting for certificates to expire.." );
		while( certTime >= time( NULL ) )
			{
			delayThread( 1 );
			printf( "." );
			}
		puts( " done." );
		}
#endif /* _WIN32_WCE */
	cryptDestroyCert( cryptCert );

	/* Expire the certs */
	puts( "Expiring certificates..." );
	status = cryptCACertManagement( NULL, CRYPT_CERTACTION_EXPIRE_CERT,
									cryptCertStore, CRYPT_UNUSED,
									CRYPT_UNUSED );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptCertStore, "cryptCACertManagement()",
							  status, __LINE__ ) );

	/* Clean up */
	cryptDestroyContext( cryptCAKey );
	cryptKeysetClose( cryptCertStore );
	puts( "Certificate management using cert store succeeded.\n" );
	return( TRUE );
	}

⌨️ 快捷键说明

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