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

📄 ca_add.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		dbmsUpdate( NULL, NULL, 0, 0, DBMS_UPDATE_ABORT );

	return( status );
	}

/* Delete a PKI user from the cert store */

int caDeletePKIUser( DBMS_INFO *dbmsInfo, const CRYPT_KEYID_TYPE keyIDtype,
					 const void *keyID, const int keyIDlength )
	{
	CRYPT_CERTIFICATE iPkiUser;
	char sqlBuffer[ MAX_SQL_QUERY_SIZE ];
	char certID[ DBXKEYID_BUFFER_SIZE ];
	int dummy, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( keyIDtype == CRYPT_KEYID_NAME || keyIDtype == CRYPT_KEYID_URI );
	assert( isReadPtr( keyID, keyIDlength ) );

	/* Get info on the user that we're about to delete */
	status = getItemData( dbmsInfo, &iPkiUser, &dummy, keyIDtype,
						  keyID, keyIDlength, KEYMGMT_ITEM_PKIUSER, 
						  KEYMGMT_FLAG_NONE );
	if( cryptStatusOK( status ) )
		{
		status = getKeyID( certID, iPkiUser, 
						   CRYPT_CERTINFO_FINGERPRINT_SHA );
		krnlSendNotifier( iPkiUser, IMESSAGE_DECREFCOUNT );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Delete the PKI user info and record the deletion */
	dbmsFormatSQL( sqlBuffer,
			"DELETE FROM pkiUsers WHERE certID = '$'",
				   certID );
	status = dbmsUpdate( sqlBuffer, NULL, 0, 0, DBMS_UPDATE_BEGIN );
	if( cryptStatusOK( status ) )
		status = updateCertLog( dbmsInfo, CRYPT_CERTACTION_DELETEUSER, 
								NULL, NULL, certID, NULL, 0, 
								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 reqCertIDlength, certDataLength, status;

	assert( isWritePtr( dbmsInfo, sizeof( DBMS_INFO ) ) );
	assert( isHandleRangeValid( 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 );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Extract the information that we need from the cert request */
	status = getKeyID( certID, iCertRequest,
					   CRYPT_CERTINFO_FINGERPRINT_SHA );
	if( !cryptStatusError( 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 = reqCertIDlength = 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;
			reqCertIDlength = 0;
			status = CRYPT_OK;
			}
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Check that the PKI user who authorised this cert issue still exists.
	   If the CA has deleted them, all further requests for certs fail */
	if( reqCertIDptr != NULL )
		{
		CRYPT_CERTIFICATE iPkiUser;

		status = caGetIssuingUser( dbmsInfo, &iPkiUser, reqCertID, 
								   reqCertIDlength );
		if( cryptStatusOK( status ) )
			krnlSendNotifier( iPkiUser, IMESSAGE_DECREFCOUNT );
		else
			{
			reqCertID[ reqCertIDlength ] = '\0';
			updateCertErrorLog( dbmsInfo, CRYPT_ERROR_DUPLICATE,
								"Cert request submitted for nonexistant PKI "
								"user", NULL, reqCertID, NULL, NULL, 0 );
			return( CRYPT_ERROR_PERMISSION );
			}
		}

	/* If there's an authorising PKI user present, make sure that it hasn't
	   already been used to authorise the issuance of a cert.  This is 
	   potentially vulnerable to the following race condition:

		1: check authCertID -> OK
		2: check authCertID -> OK
		1: add
		2: add

	   In theory we could detect this by requiring the reqCertID to be 
	   unique, however a PKI user can be used to request both a cert and 
	   a revocation for the cert, and a signing cert can be used to request
	   an update or revocation of both itself and one or more associated
	   encryption certs.  We could probably handle this via the ID-mangling
	   used for certIDs, but this makes tracing events through the audit log
	   complex since there'll now be different effective IDs for the 
	   authorising cert depending on what it was authorising.  In addition
	   it's not certain how many further operations a cert (rather than a PKI
	   user) can authorise, in theory a single signing cert can authorise at
	   least four further operations, these being the update of itself, the
	   update of an associated encryption cert, and the revocation of itself
	   and the encryption cert.  In addition its possible that a signing cert
	   could be used to authorise a series of short-duration encryption 
	   certs, or a variety of other combinations of operations.

	   Because of these issues, we can't use a uniqueness constraint on the
	   reqCertID to enforce a single use of issuing authorisation by the
	   database ifself, but have to do a manual check here, checking 
	   specifically for the case where a PKI user authorises a cert issue */
#if 0	/* This check is too restrictive because it blocks any further cert
		   issues after the first one.  This is because as soon as a single
		   issue has been authorised for a user, there'll be a request for
		   that user logged so all further attempts to submit a request (for
		   example for a renewal, or an encryption cert to go with a signing
		   one) will fail */
	if( reqCertIDptr != NULL )
		{
		status = dbmsQuery(
			"SELECT certID FROM certLog WHERE reqCertID = ? "
			"AND action = " TEXT_CERTACTION_REQUEST_CERT,
							NULL, 0, reqCertID, reqCertIDlength, 0,
							DBMS_CACHEDQUERY_NONE, DBMS_QUERY_CHECK );
		if( cryptStatusOK( status ) )
			{
			/* This user has already authorised the issue of a cert, it 
			   can't be used to issue a second cert */
			reqCertID[ reqCertIDlength ] = '\0';
			updateCertErrorLog( dbmsInfo, CRYPT_ERROR_DUPLICATE,
								"Attempt to authorise additional cert issue "
								"when a cert for this user has already been "
								"issued", NULL, reqCertID, NULL, NULL, 0 );
			return( CRYPT_ERROR_DUPLICATE );
			}
		}
#endif /* 0 */

	/* 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 ];
			int length;

			length = base64encode( encodedCertData, MAX_ENCODED_CERT_SIZE,
								   certData, certDataLength,
								   CRYPT_CERTTYPE_NONE );
			encodedCertData[ length ] = '\0';
			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 );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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