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

📄 dbxdca.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
		return( status );
	status = addCert( dbmsInfo, iCertificate, CRYPT_CERTTYPE_CERTIFICATE,
					  ( addType == CERTADD_PARTIAL_RENEWAL ) ? \
						CERTADD_PARTIAL_RENEWAL : CERTADD_NORMAL,
					  DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		{
		dbmsFormatSQL( sqlBuffer, ( addType == CERTADD_RENEWAL_COMPLETE ) ? \
			"DELETE FROM certificates WHERE certID = '++$'" : \
			"DELETE FROM certificates WHERE certID = '--$'",
					   certID + 2 );
		status = dbmsUpdate( sqlBuffer, NULL, 0, 0,
							 ( addType == CERTADD_PARTIAL_RENEWAL ) ? \
							 DBMS_UPDATE_COMMIT : DBMS_UPDATE_CONTINUE );
		}
	if( cryptStatusOK( status ) )
		{
		if( addType != CERTADD_PARTIAL_RENEWAL )
			status = updateCertLog( dbmsInfo,
									CRYPT_CERTACTION_CERT_CREATION_COMPLETE,
									NULL, NULL, certID, NULL, 0,
									DBMS_UPDATE_COMMIT );
		}
	else
		/* Something went wrong, abort the transaction */
		dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );

	/* If the operation failed, record the details */
	if( cryptStatusError( status ) )
		updateCertErrorLog( dbmsInfo, status,
							"Certificate creation - completion operation "
							"failed", NULL, NULL, certID, NULL, 0 );

	return( status );
	}

/* Complete a certificate renewal operation by revoking the cert to be
   replaced and replacing it with the newly-issued cert */

static int completeCertRenewal( DBMS_INFO *dbmsInfo,
								const CRYPT_CERTIFICATE iReplaceCertificate )
	{
	CRYPT_CERTIFICATE iOrigCertificate;
	const char *keyName = getKeyName( CRYPT_IKEYID_KEYID );
	char keyID[ DBXKEYID_BUFFER_SIZE ];
	int dummy, status;

	/* Extract the key ID from the new cert and use it to fetch the existing
	   cert issued for the same key */
	status = getCertKeyID( keyID, iReplaceCertificate );
	if( cryptStatusOK( status ) )
		status = getItemData( dbmsInfo, &iOrigCertificate, &dummy,
							  keyName, keyID, KEYMGMT_ITEM_PUBLICKEY,
							  KEYMGMT_FLAG_NONE );
	if( status == CRYPT_ERROR_NOTFOUND )
		/* If the original cert fetch fails with a notfound error this is OK
		   since we may be resuming from a point where the revocation has
		   already occurred, or the cert may have already expired or been
		   otherwise replaced, so we just slide in the new cert */
		return( completeCert( dbmsInfo, iReplaceCertificate,
							  CERTADD_RENEWAL_COMPLETE ) );
	if( cryptStatusError( status ) )
		return( status );

	/* Replace the original cert with the new one */
	status = revokeCertDirect( dbmsInfo, iOrigCertificate,
							   CRYPT_CERTACTION_REVOKE_CERT );
	if( cryptStatusOK( status ) )
		status = completeCert( dbmsInfo, iReplaceCertificate,
							   CERTADD_RENEWAL_COMPLETE );
	krnlSendNotifier( iOrigCertificate, IMESSAGE_DECREFCOUNT );

	return( status );
	}

/* Issue a cert from a cert request */

static int caIssueCert( DBMS_INFO *dbmsInfo,
						const CRYPT_CERTIFICATE iCertificate,
						const CRYPT_CERTIFICATE iCertRequest,
						const CRYPT_CERTACTION_TYPE action )
	{
	BYTE certData[ MAX_CERT_SIZE ];
	char issuerID[ DBXKEYID_BUFFER_SIZE ], certID[ DBXKEYID_BUFFER_SIZE ];
	char reqCertID[ DBXKEYID_BUFFER_SIZE ];
	CERTADD_TYPE addType = CERTADD_NORMAL;
	int certDataLength, status;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( checkHandleRange( iCertificate ) );
	assert( checkHandleRange( iCertRequest ) );
	assert( action == CRYPT_CERTACTION_ISSUE_CERT || \
			action == CRYPT_CERTACTION_CERT_CREATION );

	/* Extract the information that we need from the cert */
	status = getKeyID( certID, iCertificate, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusOK( status ) )
		status = getKeyID( issuerID, iCertificate,
						   CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( cryptStatusOK( status ) )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, certData, MAX_CERT_SIZE );
		status = krnlSendMessage( iCertificate, IMESSAGE_CRT_EXPORT,
								  &msgData, CRYPT_CERTFORMAT_CERTIFICATE );
		certDataLength = msgData.length;
		}
	if( cryptStatusOK( status ) )
		status = getKeyID( reqCertID, iCertRequest,
						   CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		return( status );

	/* If we're doing a partial cert creation, handle the complexities
	   created by things like cert renewals that create pseudo-duplicates
	   while the update is taking place */
	if( action == CRYPT_CERTACTION_CERT_CREATION )
		{
		/* Make sure that this cert hasn't been added yet.  In theory we 
		   wouldn't need to do this since the keyID uniqueness constraint 
		   will catch duplicates, however duplicates are allowed for updates 
		   and won't automatically be caught for partial adds because the 
		   keyID has to be added in a special form to enable the completion 
		   of the partial add to work.  What we therefore need to check for 
		   is that a partial add (which will add the keyID in special form) 
		   won't in the future clash with a keyID in standard form.  The 
		   checking for a keyID clash in special form happens automagically 
		   through the uniqueness constraint.

		   There are two special cases in which the issue can fail during
		   the completion rather than initial add phase, one is during an
		   update (which can't be avoided, since clashes are legal for this
		   and we can't resolve things until the completion phase), and the
		   other is through a race condition caused by the following sequence
		   of updates:

				1: check keyID -> OK
				2: check keyID -> OK
				1: add as --keyID
				1: issue as keyID
				2: add as --keyID
				2: issue -> fails

		   This condition will be fairly rare.  Note that in neither case are
		   the integrity constraints of the cert issuing process violated,
		   the only thing that happens is that a failure due to duplicates
		   is detected at a later stage than it normally would be */
		status = getCertIssueType( dbmsInfo, iCertRequest, FALSE );
		if( status == CERTADD_PARTIAL )
			{
			char sqlBuffer[ MAX_SQL_QUERY_SIZE ];
			char keyID[ DBXKEYID_BUFFER_SIZE ];

			status = getCertKeyID( keyID, iCertificate );
			if( cryptStatusError( status ) )
				return( status );
			dbmsFormatSQL( sqlBuffer,
				"SELECT certData FROM certificates WHERE keyID = '$'",
						   keyID );
			status = cryptStatusOK( dbmsStaticQuery( sqlBuffer, \
													 DBMS_QUERY_CHECK ) ) ? \
					 CRYPT_ERROR_DUPLICATE : CRYPT_OK;
			}
		if( cryptStatusError( status ) )
			return( status );

		/* This is a partial add, make sure that the cert is added in the
		   appropriate manner */
		addType = CERTADD_PARTIAL;
		}

	/* Update the cert store */
	status = addCert( dbmsInfo, iCertificate, CRYPT_CERTTYPE_CERTIFICATE,
					  addType, DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo, action, certID, reqCertID, NULL,
								certData, certDataLength,
								DBMS_UPDATE_CONTINUE );
	if( cryptStatusOK( status ) )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		dbmsFormatSQL( sqlBuffer,
			"DELETE FROM certRequests WHERE certID = '$'",
					   reqCertID );
		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 the operation failed, record the details */
	if( cryptStatusError( status ) )
		updateCertErrorLog( dbmsInfo, status,
							( action == CRYPT_CERTACTION_ISSUE_CERT ) ? \
								"Certificate issue operation failed" : \
								"Certificate creation operation failed",
							NULL, reqCertID, NULL, NULL, 0 );

	return( status );
	}

/* Complete a previously-started cert issue */

static int caIssueCertComplete( DBMS_INFO *dbmsInfo,
								const CRYPT_CERTIFICATE iCertificate,
								const CRYPT_CERTACTION_TYPE action )
	{
	char certID[ DBXKEYID_BUFFER_SIZE ];
	int status;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( checkHandleRange( iCertificate ) );
	assert( action == CRYPT_CERTACTION_CERT_CREATION_COMPLETE || \
			action == CRYPT_CERTACTION_CERT_CREATION_DROP || \
			action == CRYPT_CERTACTION_CERT_CREATION_REVERSE );

	/* Extract the information we need from the cert */
	status = getKeyID( certID, iCertificate, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		return( status );

	/* If we're abandoning the certificate issue process, delete the
	   incomplete cert and exit */
	if( action == CRYPT_CERTACTION_CERT_CREATION_DROP )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];

		dbmsFormatSQL( sqlBuffer,
			"DELETE FROM certificates WHERE certID = '--$'",
					   certID + 2 );
		status = dbmsUpdate( sqlBuffer, NULL, 0, 0, DBMS_UPDATE_BEGIN );
		if( cryptStatusOK( status ) )
			status = updateCertLog( dbmsInfo, action, NULL, NULL, certID,
									NULL, 0, DBMS_UPDATE_COMMIT );
		else
			/* Something went wrong, abort the transaction */
			dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );
		if( cryptStatusOK( status ) )
			return( CRYPT_OK );

		/* The operation failed, record the details and fall back to a
		   straight delete */
		updateCertErrorLog( dbmsInfo, status,
							"Certificate creation - drop operation failed, "
							"performing straight delete", NULL, NULL,
							certID, NULL, 0 );
		status = dbmsStaticUpdate( sqlBuffer );
		if( cryptStatusError( status ) )
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
		return( status );
		}

	/* If we're completing the certificate issue process, replace the
	   incomplete cert with the completed one and exit */
	if( action == CRYPT_CERTACTION_CERT_CREATION_COMPLETE )
		{
		CERTADD_TYPE issueType;

		status = getCertIssueType( dbmsInfo, iCertificate, TRUE );
		if( !cryptStatusError( status ) )
			{
			issueType = status;
			status = completeCert( dbmsInfo, iCertificate, issueType );
			}
		if( cryptStatusError( status ) )
			return( status );

		/* If we're doing a cert renewal, complete the multi-phase update
		   required to replace an existing cert */
		if( issueType == CERTADD_PARTIAL_RENEWAL )
			status = completeCertRenewal( dbmsInfo, iCertificate );
		return( status );
		}

	/* We're reversing a cert creation, we need to explicitly revoke the cert
	   rather than just deleting it */
	assert( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE );

	return( revokeCertDirect( dbmsInfo, iCertificate,
							  CRYPT_CERTACTION_CERT_CREATION_REVERSE ) );
	}

/****************************************************************************
*																			*
*								Cert Add Functions							*
*																			*
****************************************************************************/

/* Add a new PKI user to the cert store */

int caAddPKIUser( DBMS_INFO *dbmsInfo, const CRYPT_CERTIFICATE iPkiUser )
	{
	RESOURCE_DATA msgData;
	BYTE certData[ MAX_CERT_SIZE ];
	char certID[ DBXKEYID_BUFFER_SIZE ];
	int certDataLength, status;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( checkHandleRange( iPkiUser ) );

	/* Extract the information we need from the PKI user object.  In
	   addition to simply obtaining the information for logging purposes we
	   also need to perform this action to tell the cert management code to
	   fill in the remainder of the (implicitly-added) user info before we
	   start querying fields as we add it to the cert store.  Because of this
	   we also need to place the certID read after the object export, since 
	   it's in an incomplete state before this point */
	setMessageData( &msgData, certData, MAX_CERT_SIZE );
	status = krnlSendMessage( iPkiUser, IMESSAGE_CRT_EXPORT, &msgData, 
							  CRYPT_ICERTFORMAT_DATA );
	if( cryptStatusOK( status ) )
		status = getKeyID( certID, iPkiUser, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		return( status );
	certDataLength = msgData.length;

	/* Update the cert store */
	status = addCert( dbmsInfo, iPkiUser, CRYPT_CERTTYPE_PKIUSER,
					  CERTADD_NORMAL, DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo, CRYPT_CERTACTION_ADDUSER, certID,
								NULL, NULL, certData, certDataLength,
								DBMS_UPDATE_COMMIT );
	else
		/* Something went wrong, abort the transaction */
		dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );

	return( status );
	}

/* Add a cert issue or revocation request to the cert store */

int caAddCertRequest( DBMS_INFO *dbmsInfo, 
					  const CRYPT_CERTIFICATE iCertRequest,
					  const CRYPT_CERTTYPE_TYPE requestType, 
					  const BOOLEAN isRenewal )
	{
	BYTE certData[ MAX_CERT_SIZE ];
	char certID[ DBXKEYID_BUFFER_SIZE ];
	char reqCertID[ DBXKEYID_BUFFER_SIZE ], *reqCertIDptr = reqCertID;
	int certDataLength, status;

	assert( isWritePtr( dbmsInfo, DBMS_INFO ) );
	assert( checkHandleRange( iCertRequest ) );
	assert( requestType == CRYPT_CERTTYPE_CERTREQUEST || \
			requestType == CRYPT_CERTTYPE_REQUEST_CERT || \
			requestType == CRYPT_CERTTYPE_REQUEST_REVOCATION );

	/* Make sure that the request is OK, and if it's a revocation request 
	   make sure that it refers to a cert which is both present in the store 
	   and currently active */
	if( !checkRequest( iCertRequest, CRYPT_CERTACTION_NONE ) )
		return( CRYPT_ARGERROR_NUM1 );
	if( requestType == CRYPT_CERTTYPE_REQUEST_REVOCATION )
		{
		status = checkRevRequest( dbmsInfo, iCertRequest );

⌨️ 快捷键说明

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