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

📄 dbxdca.c

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

	/* Extract the information we need from the cert request */
	status = getKeyID( certID, iCertRequest, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusOK( status ) )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, certData, MAX_CERT_SIZE );
		status = krnlSendMessage( iCertRequest, IMESSAGE_CRT_EXPORT, 
					&msgData,
					( requestType == CRYPT_CERTTYPE_REQUEST_REVOCATION ) ? \
					CRYPT_ICERTFORMAT_DATA : CRYPT_CERTFORMAT_CERTIFICATE );
		certDataLength = msgData.length;
		}
	if( cryptStatusOK( status ) )
		{
		status = getKeyID( reqCertID, iCertRequest,
						   CRYPT_IATTRIBUTE_AUTHCERTID );
		if( cryptStatusError( status ) )
			{
			/* If the request is being added directly by the user, there's no
			   authorising certificate/PKI user info present */
			reqCertIDptr = NULL;
			status = CRYPT_OK;
			}
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Update the cert store.  Since a revocation request generally won't
	   have any fields of any significance set, we have to use a special cut-
	   down insert statement that doesn't expect to find any fields except
	   the cert ID */
	if( requestType == CRYPT_CERTTYPE_REQUEST_REVOCATION )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		if( !hasBinaryBlobs( dbmsInfo ) )
			{
			char encodedCertData[ MAX_ENCODED_CERT_SIZE ];

			base64encode( encodedCertData, certData, certDataLength,
						  CRYPT_CERTTYPE_NONE );
			dbmsFormatSQL( sqlBuffer,
				"INSERT INTO certRequests VALUES ("
				TEXT_CERTTYPE_REQUEST_REVOCATION ", '', '', '', '', '', '', "
				"'', '$', '$')",
						   certID, encodedCertData );
			}
		else
			{
			dbmsFormatSQL( sqlBuffer,
				"INSERT INTO certRequests VALUES ("
				TEXT_CERTTYPE_REQUEST_REVOCATION ", '', '', '', '', '', '', "
				"'', '$', ?)",
						   certID );
			}
		status = dbmsUpdate( sqlBuffer, hasBinaryBlobs( dbmsInfo ) ? \
							 certData : NULL, certDataLength, 0,
							 DBMS_UPDATE_BEGIN );
		}
	else
		status = addCert( dbmsInfo, iCertRequest, CRYPT_CERTTYPE_REQUEST_CERT,
						  CERTADD_NORMAL, DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo,
						( requestType == CRYPT_CERTTYPE_REQUEST_REVOCATION ) ? \
							CRYPT_CERTACTION_REQUEST_REVOCATION : \
						( isRenewal ) ? \
							CRYPT_CERTACTION_REQUEST_RENEWAL : \
							CRYPT_CERTACTION_REQUEST_CERT,
						certID, reqCertIDptr, NULL, certData,
						certDataLength, DBMS_UPDATE_COMMIT );
	else
		/* Something went wrong, abort the transaction */
		dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );

	return( status );
	}

/****************************************************************************
*																			*
*							Miscellaneous CA Functions						*
*																			*
****************************************************************************/

/* Get the PKI user that originally authorised the issuing of a cert */

int caGetIssuingUser( DBMS_INFO *dbmsInfo, CRYPT_CERTIFICATE *iPkiUser,
					  const char *initialCertID )
	{
	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( isWritePtr( iPkiUser, sizeof( CRYPT_CERTIFICATE ) ) );
	assert( isReadPtr( initialCertID, MAX_ENCODED_DBXKEYID_SIZE ) );

	return( getIssuingUser( dbmsInfo, iPkiUser, initialCertID ) );
	}

/* Perform a cleanup operation on the certificate store, removing incomplete,
   expired, and otherwise leftover certificates */

static int caCleanup( DBMS_INFO *dbmsInfo,
					  const CRYPT_CERTACTION_TYPE action )
	{
	BYTE prevCertData[ 128 ];
	char sqlBuffer[ MAX_SQL_QUERY_SIZE ];
	const time_t currentTime = getTime();
	int status;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( action == CRYPT_CERTACTION_EXPIRE_CERT || \
			action == CRYPT_CERTACTION_CLEANUP );

	/* If the time is screwed up we can't perform time-based cleanup 
	   actions */
	if( currentTime < MIN_TIME_VALUE )
		return( CRYPT_ERROR_FAILED );

	/* Rumble through the cert store either deleting leftover requests or
	   expiring every cert which is no longer current.  Since we're cleaning
	   up the cert store we try and continue even if an error occurs */
	memset( prevCertData, 0, 8 );
	do
		{
		char certID[ MAX_QUERY_RESULT_SIZE ];
		int certIDsize;

		/* Find the cert ID of the next expired cert or next cert request
		   (revocation requests are handled later by completing the
		   revocation).  Note that the select requires that the database
		   glue code return a single result and then finish the query, for
		   some backends there may be a need to explicitly cancel the query
		   after the first result is returned if the database returns an
		   entire result set */
		if( action == CRYPT_CERTACTION_EXPIRE_CERT )
			status = dbmsQuery(
						"SELECT certID FROM certificates WHERE validTo < ?",
								certID, &certIDsize, currentTime,
								DBMS_QUERY_NORMAL );
		else
			status = dbmsQuery(
						"SELECT certID FROM certRequests WHERE type = "
							TEXT_CERTTYPE_REQUEST_CERT,
								certID, &certIDsize, 0, DBMS_QUERY_NORMAL );
		if( cryptStatusError( status ) || \
			certIDsize > MAX_ENCODED_DBXKEYID_SIZE )
			continue;
		certID[ certIDsize ] = '\0';
		if( !memcmp( prevCertData, certID, MAX_ENCODED_DBXKEYID_SIZE ) )
			/* We're stuck in a loop fetching the same value over and over,
			   make an emergency exit */
			break;
		memcpy( prevCertData, certID, MAX_ENCODED_DBXKEYID_SIZE );

		/* Clean up/expire the cert.  Since CRYPT_CERTACTION_CLEANUP is a
		   composite action that encompasses a whole series of operations,
		   we replace it with a more specific action code */
		status = updateCertLog( dbmsInfo,
								( action == CRYPT_CERTACTION_CLEANUP ) ? \
								CRYPT_CERTACTION_RESTART_CLEANUP : action,
								NULL, NULL, certID, NULL, 0,
								DBMS_UPDATE_BEGIN );
		if( cryptStatusOK( status ) )
			{
			dbmsFormatSQL( sqlBuffer,
					   ( action == CRYPT_CERTACTION_EXPIRE_CERT ) ? \
				"DELETE FROM certificates WHERE certID = '$'" : \
				"DELETE FROM certRequests WHERE certID = '$'",
						   certID );
			status = dbmsUpdate( sqlBuffer, NULL, 0, 0, DBMS_UPDATE_COMMIT );
			}
		else
			/* Something went wrong, abort the transaction */
			dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );
		}
	while( status != CRYPT_ERROR_NOTFOUND );

	/* If we ran into a problem, perform a fallback general delete of
	   entries that caused the problem */
	if( status != CRYPT_ERROR_NOTFOUND )
		{
		if( action == CRYPT_CERTACTION_EXPIRE_CERT )
			{
			updateCertErrorLogMsg( dbmsInfo, status, "Expire operation "
								   "failed, performing fallback straight "
								   "delete" );
			status = dbmsUpdate(
						"DELETE FROM certificates WHERE validTo < ?",
								 NULL, 0, currentTime, DBMS_UPDATE_NORMAL );
			}
		else
			{
			updateCertErrorLogMsg( dbmsInfo, status, "Cert request "
								   "cleanup operation failed, performing "
								   "fallback straight delete" );
			status = dbmsStaticUpdate(
						"DELETE FROM certRequests WHERE type = "
							TEXT_CERTTYPE_REQUEST_CERT );
			}
		if( cryptStatusError( status ) )
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
		}

	/* If it's an expiry action we've done the expired certs, now remove any
	   stale CRL entries and exit.  If there are no CRL entries in the
	   expiry period this isn't an error, so we remap the error code if
	   necessary */
	if( action == CRYPT_CERTACTION_EXPIRE_CERT )
		{
		status = dbmsUpdate(
					"DELETE FROM CRLs WHERE expiryDate < ?",
							 NULL, 0, currentTime, DBMS_UPDATE_NORMAL );
		return( ( status == CRYPT_ERROR_NOTFOUND ) ? CRYPT_OK : status );
		}

	/* It's a restart, process any incompletely-issued certificates in the
	   same manner as the expiry/cleanup is handled.  Since we don't know at
	   what stage the issue process was interrupted, we have to make a worst-
	   case assumption and do a full reversal */
	memset( prevCertData, 0, 8 );
	do
		{
		CRYPT_CERTIFICATE iCertificate;

		/* 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 );
			}
		}
	while( status != CRYPT_ERROR_NOTFOUND );

	/* 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 '--%'" );
		if( cryptStatusError( status ) )
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
		}

	/* Now process any partially-completed renewals */
	memset( prevCertData, 0, 8 );
	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 );
			}
		}
	while( status != CRYPT_ERROR_NOTFOUND );

	/* Finally, process any pending revocations */
	memset( prevCertData, 0, 8 );
	do
		{
		CRYPT_CERTIFICATE iCertRequest;
		const char *keyName = getKeyName( CRYPT_IKEYID_CERTID );
		char certID[ MAX_QUERY_RESULT_SIZE ];	/* Safety margin */
		int dummy, certIDsize;

		/* 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, &certIDsize, 0, DBMS_QUERY_NORMAL );
		if( cryptStatusError( status ) || \
			certIDsize > MAX_ENCODED_DBXKEYID_SIZE )
			continue;
		certID[ certIDsize ] = '\0';
		if( !memcmp( prevCertData, certID, MAX_ENCODED_DBXKEYID_SIZE ) )
			/* We're stuck in a loop fetching the same value over and over,
			   make an emergency exit */
			break;
		memcpy( prevCertData, certID, MAX_ENCODED_DBXKEYID_SIZE );
		status = getItemData( dbmsInfo, &iCertRequest, &dummy, keyName, certID,
							  KEYMGMT_ITEM_REQUEST, KEYMGMT_FLAG_NONE );
		if( cryptStatusError( status ) )
			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, just delete the entry */
			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 );

	/* 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( CRYPT_OK );
	}

/* Perform a cert management operation */

static int certMgmtFunction( KEYSET_INFO *keysetInfo,
							 CRYPT_CERTIFICATE *iCertificate,
							 const CRYPT_CERTIFICATE caKey,
							 const CRYPT_CERTIFICATE request,
		

⌨️ 快捷键说明

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