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

📄 ca_issue.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusOK( status ) )
		{
		const CRYPT_CERTIFICATE iTemplateCertificate = createInfo.cryptHandle;
		int value;

		/* Add the CA flag, CA-equivalent values (in this case the old 
		   Netscape usage flags, which (incredibly) are still used today by 
		   some CAs in place of the X.509 keyUsage extension), and the CA 
		   keyUsages, as disallowed values */
		status = krnlSendMessage( iTemplateCertificate, IMESSAGE_SETATTRIBUTE, 
								  MESSAGE_VALUE_TRUE, CRYPT_CERTINFO_CA );
		if( cryptStatusOK( status ) )
			{
			value = CRYPT_NS_CERTTYPE_SSLCA | CRYPT_NS_CERTTYPE_SMIMECA | \
					CRYPT_NS_CERTTYPE_OBJECTSIGNINGCA;
			status = krnlSendMessage( iTemplateCertificate, IMESSAGE_SETATTRIBUTE, 
									  &value, CRYPT_CERTINFO_NS_CERTTYPE );
			}
		if( cryptStatusOK( status ) )
			{
			value = CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN;
			status = krnlSendMessage( iTemplateCertificate, IMESSAGE_SETATTRIBUTE, 
									  &value, CRYPT_CERTINFO_KEYUSAGE );
			}
		if( cryptStatusOK( status ) )
			status = krnlSendMessage( iLocalCertificate, IMESSAGE_SETATTRIBUTE, 
									  ( void * ) &iTemplateCertificate,
									  CRYPT_IATTRIBUTE_BLOCKEDATTRS );
		if( status == CRYPT_ERROR_INVALID )
			/* If the request would have resulted in the creation of an 
			   invalid cert, report it as an error with the request */
			status = CAMGMT_ARGERROR_REQUEST;
		krnlSendNotifier( iTemplateCertificate, IMESSAGE_DECREFCOUNT );
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* Finally, sign the cert */
	status = krnlSendMessage( iLocalCertificate, IMESSAGE_CRT_SIGN, NULL, 
							  caKey );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		return( ( status == CRYPT_ARGERROR_VALUE ) ? \
				CAMGMT_ARGERROR_CAKEY : status );
		}

	/* Extract the information that we need from the newly-created cert */
	status = getKeyID( certID, iLocalCertificate, 
					   CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( !cryptStatusError( status ) )
		status = getKeyID( issuerID, iLocalCertificate,
						   CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( !cryptStatusError( status ) )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, certData, MAX_CERT_SIZE );
		status = krnlSendMessage( iLocalCertificate, IMESSAGE_CRT_EXPORT,
								  &msgData, CRYPT_CERTFORMAT_CERTIFICATE );
		certDataLength = msgData.length;
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		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 ESC1+keyID
				1: issue as keyID
				2: add as ESC1+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 */
		if( issueType == CERTADD_PARTIAL )
			{
			char keyID[ DBXKEYID_BUFFER_SIZE ];
			int length;

			status = length = getCertKeyID( keyID, iLocalCertificate );
			if( !cryptStatusError( status ) )
				status = cryptStatusOK( \
							dbmsQuery( \
				"SELECT certData FROM certificates WHERE keyID = ?",
									NULL, NULL, keyID, length, 0,
									DBMS_CACHEDQUERY_NONE,
									DBMS_QUERY_CHECK ) ) ? \
						 CRYPT_ERROR_DUPLICATE : CRYPT_OK;
			if( cryptStatusError( status ) )
				{
				krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
				return( status );
				}
			resetErrorInfo( dbmsInfo );
			}

		/* 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, iLocalCertificate, 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 );
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* The cert has been successfully issued, return it to the caller if
	   necessary */
	if( iCertificate != NULL )
		*iCertificate = iLocalCertificate;
	else
		/* The caller isn't interested in the cert, destroy it */
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
	return( CRYPT_OK );
	}

/* Complete a previously-started cert issue */

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

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

	/* Extract the information that we need from the cert */
	status = getKeyID( certID, iCertificate, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		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 );
		}

	/* 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 = '" KEYID_ESC1 "$'",
					   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 );
		}

	/* 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 ) );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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