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

📄 dbxdca.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
						   errorDataLength, DBMS_UPDATE_NORMAL ) );
	}

static int updateCertErrorLogMsg( DBMS_INFO *dbmsInfo,
								  const int errorStatus,
								  const char *errorString )
	{
	return( updateCertErrorLog( dbmsInfo, errorStatus, errorString,
								NULL, NULL, NULL, NULL, 0 ) );
	}

/****************************************************************************
*																			*
*							Cert Revocation Functions						*
*																			*
****************************************************************************/

/* Check that a revocation request is consistent with information held in the
   cert store */

static int checkRevRequest( DBMS_INFO *dbmsInfo,
							const CRYPT_CERTIFICATE iCertRequest )
	{
	char certID[ DBXKEYID_BUFFER_SIZE ], issuerID[ DBXKEYID_BUFFER_SIZE ];
	int status;

	/* Check that the cert being referred to in the request is present and
	   active */
	status = getKeyID( issuerID, iCertRequest,
					   CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( cryptStatusOK( status ) )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		dbmsFormatSQL( sqlBuffer,
			"SELECT certData FROM certificates WHERE issuerID = '$'",
					   issuerID );
		status = dbmsStaticQuery( sqlBuffer, DBMS_QUERY_CHECK );
		}
	if( cryptStatusOK( status ) )
		return( CRYPT_OK );

	/* The cert isn't an active cert, it's either not present or not active,
	   return an appropriate error code.  If this request has been entered
	   into the cert log then it's a duplicate request, otherwise it's a
	   request to revoke a non-present cert (either that or something really
	   obscure which is best reported as a non-present cert problem) */
	status = getKeyID( certID, iCertRequest, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusOK( status ) )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		dbmsFormatSQL( sqlBuffer,
			"SELECT certData FROM certLog WHERE certID = '$'",
					   certID );
		status = dbmsStaticQuery( sqlBuffer, DBMS_QUERY_CHECK );
		}
	return( cryptStatusOK( status ) ? \
			CRYPT_ERROR_DUPLICATE : CRYPT_ERROR_NOTFOUND );
	}

/* Get the cert indicated in a revocation request */

static int getCertToRevoke( DBMS_INFO *dbmsInfo,
							CRYPT_CERTIFICATE *iCertificate,
							const CRYPT_CERTIFICATE iCertRequest )
	{
	char issuerID[ DBXKEYID_BUFFER_SIZE ];
	int dummy, status;

	*iCertificate = CRYPT_ERROR;

	/* Extract the certificate identity information from the request and try
	   and fetch it from the cert store */
	status = getKeyID( issuerID, iCertRequest,
					   CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( cryptStatusError( status ) )
		return( status );
	return( getItemData( dbmsInfo, iCertificate, &dummy,
						 getKeyName( CRYPT_IKEYID_ISSUERID ), issuerID,
						 KEYMGMT_ITEM_PUBLICKEY, KEYMGMT_FLAG_NONE ) );
	}

/* Handle an indirect cert revocation (one where we need to reverse a cert
   issue or otherwise remove the cert without obtaining a direct revocation
   request from the user).  The various revocation situations are:

	Complete cert renewal				original cert supplied
		CERTACTION_REVOKE_CERT			reason = superseded
										fail -> straight delete

	Reverse issue due to cancel in CMP	original cert supplied
		CERTACTION_CREATION_REVERSE		reason = neverValid
										date = cert issue date
										fail -> straight delete

	Undo issue after restart			original cert supplied
		CERTACTION_CREATION_REVERSE		reason = neverValid
										date = cert issue date
										fail -> straight delete

	( Standard revocation				original cert not supplied
		CERTACTION_REVOKE_CERT			reason = <in request>
										delete request
										fail -> no action ) */

static int revokeCertDirect( DBMS_INFO *dbmsInfo,
							 const CRYPT_CERTIFICATE iCertificate,
							 const CRYPT_CERTACTION_TYPE action )
	{
	STATIC_FN int caRevokeCert( DBMS_INFO *dbmsInfo,
								const CRYPT_CERTIFICATE iCertRequest,
								const CRYPT_CERTIFICATE iCertificate,
								const CRYPT_CERTACTION_TYPE action );
	MESSAGE_CREATEOBJECT_INFO createInfo;
	time_t certDate;
	int status;

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

	/* Get any information needed for the revocation from the cert */
	if( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, &certDate, sizeof( time_t ) );
		status = krnlSendMessage( iCertificate, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CERTINFO_VALIDFROM );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Create a (single-entry) CRL to contain the revocation info for the
	   certificate and revoke it via the standard channels.  We go directly
	   to a CRL rather than doing it via a revocation request because we need
	   to add information that can only be added by a CA to a CRL */
	setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_CRL );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	status = krnlSendMessage( createInfo.cryptHandle,
							  IMESSAGE_SETATTRIBUTE, ( void * ) &iCertificate,
							  CRYPT_CERTINFO_CERTIFICATE );
	if( cryptStatusOK( status ) )
		{
		if( action == CRYPT_CERTACTION_REVOKE_CERT )
			{
			static const int crlReason = CRYPT_CRLREASON_SUPERSEDED;

			/* We're revoking the cert because we're about to replace it, set
			   the revocation reason to superseded */
			status = krnlSendMessage( createInfo.cryptHandle,
							IMESSAGE_SETATTRIBUTE, ( void * ) &crlReason, 
							CRYPT_CERTINFO_CRLREASON );
			}
		else
			{
			static const int crlReason = CRYPT_CRLREASON_NEVERVALID;
			RESOURCE_DATA msgData;

			/* We're revoking a cert issued in error, set the revocation and
			   invalidity dates to the same value (the time of cert issue) in
			   the hope of ensuring that it's regarded as never being valid.
			   This isn't too accurate, but since X.509 makes the assumption
			   that all CAs are perfect and never make mistakes there's no
			   way to indicate that a cert was issued in error.  In addition
			   to this we set the extended reason to neverValid, but not too
			   many implementations will check this */
			setMessageData( &msgData, &certDate, sizeof( time_t ) );
			status = krnlSendMessage( createInfo.cryptHandle,
							IMESSAGE_SETATTRIBUTE_S, &msgData, 
							CRYPT_CERTINFO_REVOCATIONDATE );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( createInfo.cryptHandle,
							IMESSAGE_SETATTRIBUTE_S, &msgData, 
							CRYPT_CERTINFO_INVALIDITYDATE );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( createInfo.cryptHandle,
							IMESSAGE_SETATTRIBUTE, ( void * ) &crlReason, 
							CRYPT_CERTINFO_CRLREASON );
			}
		}
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( createInfo.cryptHandle,
								  IMESSAGE_SETATTRIBUTE, MESSAGE_VALUE_UNUSED,
								  CRYPT_IATTRIBUTE_INITIALISED );
	if( cryptStatusOK( status ) )
		status = caRevokeCert( dbmsInfo, createInfo.cryptHandle,
							   iCertificate, action );
	krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	return( status );
	}

/* Revoke a cert from the revocation request */

static int caRevokeCert( DBMS_INFO *dbmsInfo,
						 const CRYPT_CERTIFICATE iCertRequest,
						 const CRYPT_CERTIFICATE iCertificate,
						 const CRYPT_CERTACTION_TYPE action )
	{
	CRYPT_CERTIFICATE iLocalCertificate = iCertificate;
	CRYPT_CERTIFICATE iLocalCRL = iCertRequest;
	BYTE certData[ MAX_CERT_SIZE ];
	char reqCertID[ DBXKEYID_BUFFER_SIZE ], *reqCertIDptr = reqCertID;
	char subjCertID[ DBXKEYID_BUFFER_SIZE ];
	const BOOLEAN reqPresent = \
					( action == CRYPT_CERTACTION_RESTART_REVOKE_CERT || \
					  ( action == CRYPT_CERTACTION_REVOKE_CERT && \
						iCertificate == CRYPT_UNUSED ) ) ? TRUE : FALSE;
	int certDataLength, status = CRYPT_OK;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( checkHandleRange( iCertRequest ) );
	assert( action == CRYPT_CERTACTION_REVOKE_CERT || \
			action == CRYPT_CERTACTION_RESTART_REVOKE_CERT || \
			action == CRYPT_CERTACTION_CERT_CREATION_REVERSE );

	/* This function handles a number of operations, summarised in the table
	   below:

		Operation			Action				Request	On disk	Cert
		---------			------				-------	-------	----
		Complete revocation	RESTART_REVOKE_CERT	Rev.req	  Yes	 --
		on restart

		Standard revocation	REVOKE_CERT			Rev.req	  Yes	 --

		Complete renewal	REVOKE_CERT			crlEntry   --	Supplied

		Reverse issue (CMP	CREATION_REVERSE	crlEntry   --	Supplied
		or due to restart)

	   The following assertion checks that the cert parameter is correct.
	   Checking the request parameter isn't so easy since it requires
	   multiple function calls, and is done as part of the code */
	assert( ( action == CRYPT_CERTACTION_RESTART_REVOKE_CERT && \
			  iCertificate == CRYPT_UNUSED ) || \
			( action == CRYPT_CERTACTION_REVOKE_CERT ) || \
			( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE && \
			  checkHandleRange( iCertificate ) ) );

	/* If it's a standard revocation (rather than one done as part of an
	   internal cert management operation, which passes in a single-entry
	   CRL), fetch the cert we're going to revoke and set up a CRL object
	   to contain the revocation information */
	if( iCertificate == CRYPT_UNUSED )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;

		/* Get the cert being revoked via the revocation request and create
		   the CRL to contain the revocation information */
		status = getKeyID( reqCertID, iCertRequest,
						   CRYPT_CERTINFO_FINGERPRINT_SHA );
		if( cryptStatusOK( status ) )
			status = getCertToRevoke( dbmsInfo, &iLocalCertificate,
									  iCertRequest );
		if( cryptStatusError( status ) )
			return( status );
		setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_CRL );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo, 
								  OBJECT_TYPE_CERTIFICATE );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		iLocalCRL = createInfo.cryptHandle;

		/* Fill in the CRL from the revocation request */
		status = krnlSendMessage( iLocalCRL, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &iCertRequest,
								  CRYPT_IATTRIBUTE_REVREQUEST );
		}
	else
		/* This is a direct revocation done as part of an internal cert
		   management operation, there's no explicit request for the
		   revocation present, and the caller has passed us a CRL ready to
		   use */
		reqCertIDptr = NULL;
	if( cryptStatusOK( status ) )
		status = getKeyID( subjCertID, iLocalCertificate,
						   CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusOK( status ) )
		{
		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 = '--$'",
						   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 ) )

⌨️ 快捷键说明

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