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

📄 ca_rev.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		RESOURCE_DATA msgData;

		setMessageData( &msgData, certData, MAX_CERT_SIZE );
		status = krnlSendMessage( iLocalCRL, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_CRLENTRY );
		certDataLength = msgData.length;
		}
	if( cryptStatusError( status ) )
		{
		/* If we created the necessary objects locally rather than having
		   them passed in by the caller, we have to clean them up again
		   before we exit */
		if( iCertificate == CRYPT_UNUSED )
			{
			krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
			krnlSendNotifier( iLocalCRL, IMESSAGE_DECREFCOUNT );
			}
		return( status );
		}

	/* Update the cert store.  This is the ugliest CA operation since it
	   updates every table, luckily it's performed only rarely.  If this is
	   a reversal operation or revocation of a cert to be replaced, which is
	   a direct follow-on to a certificate creation, there's no corresponding
	   request present so we don't have to update the requests table */
	status = addCRL( dbmsInfo, iLocalCRL, iLocalCertificate,
					 DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo, action, NULL, reqCertIDptr,
								subjCertID, certData, certDataLength,
								DBMS_UPDATE_CONTINUE );
	if( cryptStatusOK( status ) && reqPresent )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		dbmsFormatSQL( sqlBuffer,
			"DELETE FROM certRequests WHERE certID = '$'",
					   reqCertID );
		status = dbmsUpdate( sqlBuffer, NULL, 0, 0, DBMS_UPDATE_CONTINUE );
		}
	if( cryptStatusOK( status ) )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		if( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE )
			dbmsFormatSQL( sqlBuffer,
				"DELETE FROM certificates WHERE certID = '" KEYID_ESC1 "$'",
						   subjCertID + 2 );
		else
			dbmsFormatSQL( sqlBuffer,
				"DELETE FROM certificates WHERE certID = '$'",
						   subjCertID );
		status = dbmsUpdate( sqlBuffer, NULL, 0, 0, DBMS_UPDATE_COMMIT );
		}
	else
		/* Something went wrong, abort the transaction */
		dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );
	if( iCertificate == CRYPT_UNUSED )
		{
		/* If we created the necessary objects locally rather than having
		   them passed in by the caller, we have to clean them up again
		   before we exit */
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		krnlSendNotifier( iLocalCRL, IMESSAGE_DECREFCOUNT );
		}

	/* If the operation failed, record the details and if it was a direct
	   revocation done invisibly as part of an internal cert management
	   operation, try again with a straight delete */
	if( cryptStatusError( status ) )
		{
		updateCertErrorLog( dbmsInfo, status,
							( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE ) ? \
							"Certificate issue reversal operation failed, "
								"performing straight delete" : \
							( action == CRYPT_CERTACTION_REVOKE_CERT && \
							  iCertificate != CRYPT_UNUSED ) ? \
							"Revocation of certificate to be replaced "
								"failed, performing straight delete" :
							"Certificate revocation operation failed",
							NULL, reqCertIDptr, NULL, NULL, 0 );
		if( !reqPresent )
			{
			char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

			assert( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE || \
					action == CRYPT_CERTACTION_REVOKE_CERT );

			if( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE )
				dbmsFormatSQL( sqlBuffer,
					"DELETE FROM certificates WHERE certID = '" KEYID_ESC1 "$'",
							   subjCertID + 2 );
			else
				dbmsFormatSQL( sqlBuffer,
					"DELETE FROM certificates WHERE certID = '$'",
							   subjCertID );
			status = dbmsStaticUpdate( sqlBuffer );
			if( cryptStatusError( status ) )
				updateCertErrorLogMsg( dbmsInfo, status, "Fallback "
									   "straight delete failed" );
			}
		}

	return( status );
	}

/* Create a CRL from revocation entries in the certificate store */

int caIssueCRL( DBMS_INFO *dbmsInfo, CRYPT_CERTIFICATE *iCryptCRL,
				const CRYPT_CONTEXT caKey )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	BYTE crlEntry[ MAX_QUERY_RESULT_SIZE ];
	BOOLEAN crlEntryAdded = FALSE;
	char crlEntryBuffer[ MAX_QUERY_RESULT_SIZE ];
	void *crlEntryPtr = crlEntryBuffer;
	char nameID[ DBXKEYID_BUFFER_SIZE ];
	char *operationString;
	int operationStatus = CRYPT_OK, errorCount = 0, length, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( isWritePtr( iCryptCRL, sizeof( CRYPT_CERTIFICATE * ) ) );
	assert( isHandleRangeValid( caKey ) );

	/* Extract the information that we need to build the CRL from the CA 
	   cert */
	status = length = getKeyID( nameID, caKey, CRYPT_IATTRIBUTE_SUBJECT );
	if( cryptStatusError( status ) )
		return( status );

	/* Create the CRL object to hold the entries */
	setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_CRL );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );

	/* If we have binary blob support, fetch the data directly into the
	   certificate buffer */
	if( hasBinaryBlobs( dbmsInfo ) )
		crlEntryPtr = crlEntry;

	/* Submit a query to fetch every CRL entry for this CA.  We don't have
	   to do a date check since the presence of revocation entries for
	   expired certs is controlled by whether the CA's policy involves
	   removing entries for expired certs or not */
	status = dbmsQuery(
		"SELECT certData FROM CRLs WHERE nameID = ?",
						NULL, 0, nameID, length, 0, DBMS_CACHEDQUERY_NONE,
						DBMS_QUERY_START );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Rumble through the cert store fetching every entry and adding it to
	   the CRL.  We only stop once we've run out of entries or we hit too 
	   many errors, which ensures that some minor error at some point won't 
	   prevent the CRL from being issued, however if there was a problem 
	   somewhere we create a log entry to record it */
	do
		{
		RESOURCE_DATA msgData;
		int crlEntryLength;

		/* Read the CRL entry data */
		status = dbmsQuery( NULL, crlEntryPtr, &crlEntryLength, NULL, 0, 0,
							DBMS_CACHEDQUERY_NONE, DBMS_QUERY_CONTINUE );
		if( status == CRYPT_ERROR_COMPLETE )
			{
			/* We've got all the entries, complete the query and exit */
			dbmsStaticQuery( NULL, DBMS_CACHEDQUERY_NONE,
							 DBMS_QUERY_CANCEL );
			break;
			}
		if( cryptStatusOK( status ) && !hasBinaryBlobs( dbmsInfo ) )
			{
			crlEntryLength = base64decode( crlEntry, MAX_CERT_SIZE,
										   crlEntryBuffer, crlEntryLength,
										   CRYPT_CERTFORMAT_NONE );
			if( cryptStatusError( crlEntryLength ) )
				{
				assert( NOTREACHED );
				status = crlEntryLength;
				}
			}
		if( cryptStatusError( status ) )
			{
			/* Remember the error details for later if necessary */
			if( cryptStatusOK( operationStatus ) )
				{
				operationStatus = status;
				operationString = "Some CRL entries couldn't be read from "
								  "the certificate store";
				}
			errorCount++;
			continue;
			}

		/* Add the entry to the CRL */
		setMessageData( &msgData, crlEntry, crlEntryLength );
		status = krnlSendMessage( createInfo.cryptHandle,
								  IMESSAGE_SETATTRIBUTE_S, &msgData,
								  CRYPT_IATTRIBUTE_CRLENTRY );
		if( cryptStatusError( status ) )
			{
			/* Remember the error details for later if necessary */
			if( cryptStatusOK( operationStatus ) )
				{
				operationStatus = status;
				operationString = "Some CRL entries couldn't be added to "
								  "the CRL";
				}
			errorCount++;
			continue;
			}

		crlEntryAdded = TRUE;
		}
	while( status != CRYPT_ERROR_COMPLETE && errorCount < 10 );
	if( cryptStatusError( operationStatus ) )
		{
		/* If nothing could be added to the CRL, something is wrong, don't
		   try and continue */
		if( !crlEntryAdded )
			{
			updateCertErrorLogMsg( dbmsInfo, status, "No CRL entries could "
								   "be added to the CRL" );
			return( status );
			}

		/* At least some entries could be added to the CRL, record that there
		   was a problem but continue */
		updateCertErrorLogMsg( dbmsInfo, operationStatus, operationString );
		}

	/* We've got all the CRL entries, sign the CRL and return it to the
	   caller */
	status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CRT_SIGN,
							  NULL, caKey );
	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ARGERROR_VALUE )
			status = CAMGMT_ARGERROR_CAKEY;	/* Map to correct error code */
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		updateCertErrorLogMsg( dbmsInfo, operationStatus,
							   "CRL creation failed" );
		}
	else
		{
		*iCryptCRL = createInfo.cryptHandle;
		updateCertLog( dbmsInfo, CRYPT_CERTACTION_ISSUE_CRL, NULL, NULL,
					   NULL, NULL, 0, DBMS_UPDATE_NORMAL );
		}

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

⌨️ 快捷键说明

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