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

📄 ca_misc.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Get the next partially-issued cert */
		status = getNextPartialCert( dbmsInfo, &iCertificate, prevCertData,
									 FALSE );
		if( status == CRYPT_ERROR_DUPLICATE )
			/* We're stuck in a loop fetching the same cert over and over,
			   exit */
			break;
		if( cryptStatusOK( status ) )
			{
			/* We found a cert to revoke, complete the revocation */
			status = revokeCertDirect( dbmsInfo, iCertificate,
									   CRYPT_CERTACTION_CERT_CREATION_REVERSE );
			krnlSendNotifier( iCertificate, IMESSAGE_DECREFCOUNT );
			}
		else
			errorCount++;
		}
	while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );

	/* If we ran into a problem, perform a fallback general delete of
	   entries that caused the problem */
	if( status != CRYPT_ERROR_NOTFOUND )
		{
		updateCertErrorLogMsg( dbmsInfo, status, "Partially-issued "
							   "certificate cleanup operation failed, "
							   "performing fallback straight delete" );
		status = dbmsStaticUpdate(
			"DELETE FROM certificates WHERE keyID LIKE '" KEYID_ESC1 "%'" );
		if( cryptStatusError( status ) )
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
		}

	/* Now process any partially-completed renewals */
	memset( prevCertData, 0, 8 );
	errorCount = 0;
	do
		{
		CRYPT_CERTIFICATE iCertificate;

		/* Get the next partially-completed cert */
		status = getNextPartialCert( dbmsInfo, &iCertificate, prevCertData,
									 TRUE );
		if( status == CRYPT_ERROR_DUPLICATE )
			/* We're stuck in a loop fetching the same cert over and over,
			   exit */
			break;
		if( cryptStatusOK( status ) )
			{
			/* We found a partially-completed cert, complete the renewal */
			status = completeCertRenewal( dbmsInfo, iCertificate );
			krnlSendNotifier( iCertificate, IMESSAGE_DECREFCOUNT );
			}
		else
			errorCount++;
		}
	while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );

	/* Finally, process any pending revocations */
	memset( prevCertData, 0, 8 );
	errorCount = 0;
	do
		{
		CRYPT_CERTIFICATE iCertRequest;
		char certID[ MAX_QUERY_RESULT_SIZE ];
		int certIDlength, dummy;

		/* Find the next revocation request and import it.  This is slightly
		   ugly since we could grab it directly by fetching the data based on
		   the request type field, but there's no way to easily get to the
		   low-level import functions from here so we have to first fetch the
		   cert ID and then pass that down to the lower-level functions to
		   fetch the actual request */
		status = dbmsQuery(
					"SELECT certID FROM certRequests WHERE type = "
						TEXT_CERTTYPE_REQUEST_REVOCATION,
							certID, &certIDlength, NULL, 0, 0, 
							DBMS_CACHEDQUERY_NONE, DBMS_QUERY_NORMAL );
		if( cryptStatusError( status ) || \
			certIDlength > MAX_ENCODED_DBXKEYID_SIZE )
			{
			errorCount++;
			continue;
			}
		if( !memcmp( prevCertData, certID, certIDlength ) )
			/* We're stuck in a loop fetching the same value over and over,
			   make an emergency exit */
			break;
		memcpy( prevCertData, certID, certIDlength );
		status = getItemData( dbmsInfo, &iCertRequest, &dummy, 
							  CRYPT_IKEYID_CERTID, certID, certIDlength, 
							  KEYMGMT_ITEM_REQUEST, KEYMGMT_FLAG_NONE );
		if( cryptStatusError( status ) )
			{
			errorCount++;
			continue;
			}

		/* Complete the revocation */
		status = caRevokeCert( dbmsInfo, iCertRequest, CRYPT_UNUSED,
							   CRYPT_CERTACTION_RESTART_REVOKE_CERT );
		if( status == CRYPT_ERROR_NOTFOUND )
			{
			/* This is an allowable error type since the cert may have 
			   expired or been otherwise removed after the revocation 
			   request was received, just delete the entry */
			certID[ certIDlength ] = '\0';
			dbmsFormatSQL( sqlBuffer,
				"DELETE FROM certRequests WHERE certID = '$'",
						   certID );
			status = dbmsStaticUpdate( sqlBuffer );
			updateCertErrorLog( dbmsInfo, status, "Deleted revocation "
								"request for non-present certificate",
								NULL, NULL, certID, NULL, 0 );
			}
		krnlSendNotifier( iCertRequest, IMESSAGE_DECREFCOUNT );
		}
	while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );

	/* If we ran into a problem, perform a fallback general delete of
	   entries that caused the problem */
	if( status != CRYPT_ERROR_NOTFOUND )
		{
		updateCertErrorLogMsg( dbmsInfo, status, "Revocation request "
							   "cleanup operation failed, performing "
							   "fallback straight delete" );
		status = dbmsStaticUpdate(
					"DELETE FROM certRequests WHERE type = "
						TEXT_CERTTYPE_REQUEST_REVOCATION );
		if( cryptStatusError( status ) )
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
		return( status );
		}

	return( resetErrorInfo( dbmsInfo ) );
	}

/****************************************************************************
*																			*
*							CA Cert Management Interface					*
*																			*
****************************************************************************/

/* Perform a cert management operation */

static int certMgmtFunction( KEYSET_INFO *keysetInfo,
							 CRYPT_CERTIFICATE *iCertificate,
							 const CRYPT_CERTIFICATE caKey,
							 const CRYPT_CERTIFICATE request,
							 const CRYPT_CERTACTION_TYPE action )
	{
	DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;
	char reqCertID[ DBXKEYID_BUFFER_SIZE ];
	int length, status;

	/* In order for various SQL query strings to use the correct values the
	   type values have to match their text equivalents defined at the start
	   of this file.  Since we can't check this at compile time we have to
	   do it here via an assertion */
	assert( TEXT_CERTTYPE_REQUEST_CERT[ 0 ] - '0' == \
			CRYPT_CERTTYPE_REQUEST_CERT );
	assert( TEXT_CERTTYPE_REQUEST_REVOCATION[ 0 ] - '0' == \
			CRYPT_CERTTYPE_REQUEST_REVOCATION );
	assert( TEXT_CERTACTION_CREATE[ 0 ] - '0' == \
			CRYPT_CERTACTION_CREATE );
	assert( TEXTCH_CERTACTION_ADDUSER - '0' == \
			CRYPT_CERTACTION_ADDUSER );
	assert( TEXT_CERTACTION_REQUEST_CERT[ 0 ] - '0' == \
			CRYPT_CERTACTION_REQUEST_CERT );
	assert( TEXTCH_CERTACTION_REQUEST_CERT - '0' == \
			CRYPT_CERTACTION_REQUEST_CERT );
	assert( TEXT_CERTACTION_REQUEST_RENEWAL[ 0 ] - '0' == \
			CRYPT_CERTACTION_REQUEST_RENEWAL );
	assert( TEXTCH_CERTACTION_REQUEST_RENEWAL - '0' == \
			CRYPT_CERTACTION_REQUEST_RENEWAL );
	assert( TEXT_CERTACTION_CERT_CREATION[ 0 ] - '0' == \
			CRYPT_CERTACTION_CERT_CREATION / 10 );
	assert( TEXT_CERTACTION_CERT_CREATION[ 1 ] - '0' == \
			CRYPT_CERTACTION_CERT_CREATION % 10 );

	/* Clear the return value */
	if( iCertificate != NULL )
		*iCertificate = CRYPT_ERROR;

	/* If it's a simple cert expire or cleanup, there are no parameters to
	   check so we can perform the action immediately */
	if( action == CRYPT_CERTACTION_EXPIRE_CERT || \
		action == CRYPT_CERTACTION_CLEANUP )
		{
		assert( caKey == CRYPT_UNUSED );
		assert( request == CRYPT_UNUSED );

		return( caCleanup( dbmsInfo, action ) );
		}

	/* If it's the completion of a cert creation, process it */
	if( action == CRYPT_CERTACTION_CERT_CREATION_COMPLETE || \
		action == CRYPT_CERTACTION_CERT_CREATION_DROP || \
		action == CRYPT_CERTACTION_CERT_CREATION_REVERSE )
		{
		assert( caKey == CRYPT_UNUSED );

		return( caIssueCertComplete( dbmsInfo, request, action ) );
		}

	/* Check that the CA key that we've been passed is in order.  These 
	   checks are performed automatically during the issue process by the 
	   kernel when we try and convert the request into a cert, however we 
	   perform them explicitly here so that we can return a more meaningful 
	   error message to the caller */
	if( action == CRYPT_CERTACTION_ISSUE_CRL )
		{
		int value;

		/* If we're issuing a CRL, the key must be capable of CRL signing */
		status = krnlSendMessage( caKey, IMESSAGE_GETATTRIBUTE, &value, 
								  CRYPT_CERTINFO_KEYUSAGE );
		if( cryptStatusError( status ) || \
			!( value & CRYPT_KEYUSAGE_CRLSIGN ) )
			return( CAMGMT_ARGERROR_CAKEY );
		}
	else
		/* For anything other than a revocation action (which just updates the 
		   cert store without doing anything else), the key must be a CA key */
		if( action != CRYPT_CERTACTION_REVOKE_CERT && \
			cryptStatusError( \
				krnlSendMessage( caKey, IMESSAGE_CHECK, NULL, 
								 MESSAGE_CHECK_CA ) ) )
			return( CAMGMT_ARGERROR_CAKEY );

	/* If it's a CRL issue, it's a read-only operation on the CRL store
	   for which we only need the CA cert (there's no request involved) */
	if( action == CRYPT_CERTACTION_ISSUE_CRL )
		{
		assert( request == CRYPT_UNUSED );

		return( caIssueCRL( dbmsInfo, iCertificate, caKey ) );
		}

	/* We're processing an action that request an explicit cert request, 
	   perform further checks on the request */
	if( !checkRequest( request, action ) )
		return( CAMGMT_ARGERROR_REQUEST );

	/* Make sure that the request is present in the request table in order 
	   to issue a certificate for it.  Again, this will be checked later, 
	   but we can return a more meaningful error here */
	status = length = getKeyID( reqCertID, request, 
								CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		return( CAMGMT_ARGERROR_REQUEST );
	status = dbmsQuery( 
		"SELECT certData FROM certRequests WHERE certID = ?",
						NULL, 0, reqCertID, length, 0, 
						DBMS_CACHEDQUERY_NONE, DBMS_QUERY_CHECK );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_NOTFOUND );

	/* If it's a revocation request, process it */
	if( action == CRYPT_CERTACTION_REVOKE_CERT )
		{
		assert( caKey == CRYPT_UNUSED );

		return( caRevokeCert( dbmsInfo, request, CRYPT_UNUSED,
							  CRYPT_CERTACTION_REVOKE_CERT ) );
		}

	/* It's a cert issue request, issue the certificate */
	assert( action == CRYPT_CERTACTION_ISSUE_CERT || \
			action == CRYPT_CERTACTION_CERT_CREATION );
	assert( isHandleRangeValid( caKey ) );

	return( caIssueCert( dbmsInfo, iCertificate, caKey, request, action ) );
	}

/* Set up the function pointers to the keyset methods */

int initDBMSCA( KEYSET_INFO *keysetInfo )
	{
	keysetInfo->keysetDBMS->certMgmtFunction = certMgmtFunction;

	return( CRYPT_OK );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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