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

📄 ca_issue.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
						   iReplaceCertificate );
	if( cryptStatusOK( status ) )
		{
		status = getItemData( dbmsInfo, &iOrigCertificate, &dummy,
							  KEYMGMT_ITEM_PUBLICKEY, CRYPT_IKEYID_KEYID, 
							  keyID, keyIDlength, KEYMGMT_FLAG_NONE, 
							  errorInfo );
		if( status == CRYPT_ERROR_NOTFOUND )
			{
			/* If the original certificate 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 certificate may have 
			   already expired or been otherwise replaced, so we just slide 
			   in the new certificate */
			return( completeCert( dbmsInfo, iReplaceCertificate,
								  CERTADD_RENEWAL_COMPLETE, errorInfo ) );
			}
		}
	if( cryptStatusError( status ) )
		{
		retExtErr( status, 
				   ( status, errorInfo, getDbmsErrorInfo( dbmsInfo ),
					 "Couldn't get information for the certificate to be "
					 "renewed: " ) );
		}

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

	return( status );
	}

/* Issue a certificate from a certificate request */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
int caIssueCert( INOUT DBMS_INFO *dbmsInfo, 
				 OUT_OPT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
				 IN_HANDLE const CRYPT_CERTIFICATE caKey,
				 IN_HANDLE const CRYPT_CERTIFICATE iCertRequest,
				 IN_ENUM( CRYPT_CERTACTION ) const CRYPT_CERTACTION_TYPE action,
				 INOUT ERROR_INFO *errorInfo )
	{
	CRYPT_CERTIFICATE iLocalCertificate;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	BOUND_DATA boundData[ BOUND_DATA_MAXITEMS ], *boundDataPtr = boundData;
	BYTE certData[ MAX_CERT_SIZE + 8 ];
	char issuerID[ ENCODED_DBXKEYID_SIZE + 8 ];
	char certID[ ENCODED_DBXKEYID_SIZE + 8 ];
	char reqCertID[ ENCODED_DBXKEYID_SIZE + 8 ];
	CERTADD_TYPE addType = CERTADD_NORMAL, issueType;
	int certDataLength = DUMMY_INIT, issuerIDlength, certIDlength;
	int reqCertIDlength = DUMMY_INIT, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( ( iCertificate == NULL ) || \
			isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );

	REQUIRES( isHandleRangeValid( caKey ) );
	REQUIRES( isHandleRangeValid( iCertRequest ) );
	REQUIRES( action == CRYPT_CERTACTION_ISSUE_CERT || \
			  action == CRYPT_CERTACTION_CERT_CREATION );
	REQUIRES( errorInfo != NULL );

	/* Clear return value */
	if( iCertificate != NULL )
		*iCertificate = CRYPT_ERROR;

	/* Extract the information that we need from the certificate request */
	status = getCertIssueType( dbmsInfo, iCertRequest, &issueType, FALSE );
	if( cryptStatusOK( status ) )
		status = getKeyID( reqCertID, ENCODED_DBXKEYID_SIZE, &reqCertIDlength, 
						   iCertRequest, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		{
		if( cryptArgError( status ) )
			status = CAMGMT_ARGERROR_REQUEST;
		retExtArg( status, 
				   ( status, errorInfo, 
					 "Couldn't extract certificate request information "
					 "needed to issue certificate" ) );
		}

	/* We're ready to perform the certificate issue transaction.  First we 
	   turn the request into a certificate */
	setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_CERTIFICATE );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	iLocalCertificate = createInfo.cryptHandle;
	status = krnlSendMessage( iLocalCertificate, IMESSAGE_SETATTRIBUTE,
							  ( void * ) &iCertRequest,
							  CRYPT_CERTINFO_CERTREQUEST );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		retExt( status, 
				( status, errorInfo, 
				  "Couldn't create certificate from certificate request "
				  "data" ) );
		}

	/* Sanitise the new certificate of potentially dangerous attributes */
	status = sanitiseCertAttributes( iLocalCertificate );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		retExtArg( status, 
				   ( status, errorInfo, 
					 "Certificate request contains attributes that would "
					 "result in the creation of a CA rather than a normal "
					 "user certificate" ) );
		}

	/* Finally, sign the certificate */
	status = krnlSendMessage( iLocalCertificate, IMESSAGE_CRT_SIGN, NULL,
							  caKey );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		if( status == CRYPT_ARGERROR_VALUE )
			status = CAMGMT_ARGERROR_CAKEY;
		retExtArg( status, 
				   ( status, errorInfo, 
					 "Couldn't sign certificate created from certificate "
					 "request" ) );
		}

	/* Extract the information that we need from the newly-created 
	   certificate */
	status = getKeyID( certID, ENCODED_DBXKEYID_SIZE, &certIDlength, 
					   iLocalCertificate, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusOK( status ) )
		status = getKeyID( issuerID, ENCODED_DBXKEYID_SIZE, &issuerIDlength, 
						   iLocalCertificate,
						   CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( cryptStatusOK( status ) )
		status = extractCertData( iLocalCertificate, 
								  CRYPT_CERTFORMAT_CERTIFICATE, certData, 
								  MAX_CERT_SIZE, &certDataLength );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		retExt( status, 
				( status, errorInfo, 
				  "Couldn't extract new certificate data to add to "
				  "certificate store" ) );
		}

	/* If we're doing a partial certificate creation, handle the 
	   complexities created by things like certificate renewals that create 
	   pseudo-duplicates while the update is taking place */
	if( action == CRYPT_CERTACTION_CERT_CREATION )
		{
		status = checkDuplicateAdd( dbmsInfo, iLocalCertificate, issueType );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
			retExt( status, 
					( status, errorInfo, 
					  "Certificate already exists in certificate store" ) );
			}

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

	/* Update the certificate store */
	status = addCert( dbmsInfo, iLocalCertificate, CRYPT_CERTTYPE_CERTIFICATE,
					  addType, DBMS_UPDATE_BEGIN, errorInfo );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo, action, certID, certIDlength, 
								reqCertID, reqCertIDlength, NULL, 0,
								certData, certDataLength,
								DBMS_UPDATE_CONTINUE );
	if( cryptStatusOK( status ) )
		{
		initBoundData( boundDataPtr );
		setBoundData( boundDataPtr, 0, reqCertID, reqCertIDlength );
		status = dbmsUpdate( 
			"DELETE FROM certRequests WHERE certID = ?",
							 boundDataPtr, DBMS_UPDATE_COMMIT );
		}
	else
		{
		/* Something went wrong, abort the transaction */
		dbmsUpdate( NULL, NULL, 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, 0, reqCertID, reqCertIDlength, NULL, 0, 
							NULL, 0 );
		krnlSendNotifier( iLocalCertificate, IMESSAGE_DECREFCOUNT );
		retExtErr( status, 
				   ( status, errorInfo, getDbmsErrorInfo( dbmsInfo ),
					 ( action == CRYPT_CERTACTION_ISSUE_CERT ) ? \
						"Certificate issue operation failed: " : \
						"Certificate creation operation failed: " ) );
		}

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

/* Complete a previously-started certificate issue */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
int caIssueCertComplete( INOUT DBMS_INFO *dbmsInfo, 
						 IN_HANDLE const CRYPT_CERTIFICATE iCertificate,
						 IN_ENUM( CRYPT_CERTACTION ) \
							const CRYPT_CERTACTION_TYPE action,
						 INOUT ERROR_INFO *errorInfo )
	{
	char certID[ ENCODED_DBXKEYID_SIZE + 8 ];
	int certIDlength, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );

	REQUIRES( isHandleRangeValid( iCertificate ) );
	REQUIRES( action == CRYPT_CERTACTION_CERT_CREATION_COMPLETE || \
			  action == CRYPT_CERTACTION_CERT_CREATION_DROP || \
			  action == CRYPT_CERTACTION_CERT_CREATION_REVERSE );
	REQUIRES( errorInfo != NULL );

	/* Extract the information that we need from the certificate */
	status = getKeyID( certID, ENCODED_DBXKEYID_SIZE, &certIDlength, 
					   iCertificate, CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( cryptStatusError( status ) )
		return( status );

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

		status = getCertIssueType( dbmsInfo, iCertificate, &issueType, TRUE );
		if( cryptStatusError( status ) )
			{
			retExt( status, 
					( status, errorInfo, 
					  "Couldn't get original certificate issue type to "
					  "complete certificate issue operation: " ) );
			}
		status = completeCert( dbmsInfo, iCertificate, issueType, errorInfo );
		if( cryptStatusError( status ) )
			return( status );

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

		return( CRYPT_OK );
		}

	/* If we're abandoning the certificate issue process, delete the
	   incomplete certificate and exit */
	if( action == CRYPT_CERTACTION_CERT_CREATION_DROP )
		{
		BOUND_DATA boundData[ BOUND_DATA_MAXITEMS ], *boundDataPtr = boundData;
		char incompleteCertID[ ENCODED_DBXKEYID_SIZE + 8 ];

		memcpy( incompleteCertID, certID, certIDlength );
		memcpy( incompleteCertID, KEYID_ESC1, KEYID_ESC_SIZE );
		initBoundData( boundDataPtr );
		setBoundData( boundDataPtr, 0, incompleteCertID, certIDlength );
		status = dbmsUpdate( 
			"DELETE FROM certificates WHERE certID = ?",
							 boundDataPtr, DBMS_UPDATE_BEGIN );
		if( cryptStatusOK( status ) )
			status = updateCertLog( dbmsInfo, action, NULL, 0, NULL, 0, 
									certID, certIDlength, NULL, 0, 
									DBMS_UPDATE_COMMIT );
		else
			{
			/* Something went wrong, abort the transaction */
			dbmsUpdate( NULL, NULL, DBMS_UPDATE_ABORT );
			}
		if( cryptStatusOK( status ) )
			return( CRYPT_OK );

		/* The drop operation failed, record the details and fall back to a
		   straight delete */
		updateCertErrorLog( dbmsInfo, status,
							"Certificate creation - drop operation failed, "
							"performing straight delete", NULL, 0, NULL, 0, 
							certID, certIDlength, NULL, 0 );
		status = dbmsUpdate( 
			"DELETE FROM certificates WHERE certID = ?",
							 boundDataPtr, DBMS_UPDATE_NORMAL );
		if( cryptStatusError( status ) )
			{
			updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
								   "delete failed" );
			retExtErr( status, 
					   ( status, errorInfo, getDbmsErrorInfo( dbmsInfo ),
						 "Certificate creation - drop operation failed: " ) );
			}
		return( CRYPT_OK );
		}

	/* We're reversing a certificate creation as a compensating transaction 
	   for an aborted certificate issue, we need to explicitly revoke the 
	   certificate rather than just deleting it */
	ENSURES( action == CRYPT_CERTACTION_CERT_CREATION_REVERSE );

	return( revokeCertDirect( dbmsInfo, iCertificate,
							  CRYPT_CERTACTION_CERT_CREATION_REVERSE, 
							  errorInfo ) );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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