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

📄 dbx_wr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
	if( cryptStatusError( status ) )
		{
		/* Convert any low-level certificate-specific error into something 
		   generic that makes a bit more sense to the caller */
		retExtArg( CRYPT_ARGERROR_NUM1, 
				   ( CRYPT_ARGERROR_NUM1, errorInfo, 
					 "Couldn't extract CRL data from CRL" ) );
		}

	/* Set up the certificate object data to be written and send it to the 
	   database.  Certificate stores contain extra inforomation that's 
	   needed to build a CRL so we have to vary the SQL string depending on 
	   the keyset type */
	initBoundData( boundDataPtr );
	if( isCertStore( dbmsInfo ) )
		{
		setBoundDataDate( boundDataPtr, 0, &expiryDate );
		setBoundData( boundDataPtr, 1, crlIdData.nameID, 
					  crlIdData.nameIDlength );
		setBoundData( boundDataPtr, 2, crlIdData.issuerID, 
					  crlIdData.issuerIDlength );
		setBoundData( boundDataPtr, 3, crlIdData.certID, 
					  crlIdData.certIDlength );
		boundDataIndex = 4;
		sqlString = "INSERT INTO CRLs VALUES (?, ?, ?, ?, ?)";

		}
	else
		{
		setBoundData( boundDataPtr, 0, crlIdData.issuerID, 
					  crlIdData.issuerIDlength );
		boundDataIndex = 1;
		sqlString = "INSERT INTO CRLs VALUES (?, ?)";
		}
	if( hasBinaryBlobs( dbmsInfo ) )
		{
		setBoundDataBlob( boundDataPtr, boundDataIndex, certData, 
						  certDataLength );
		}
	else
		{
		int encodedCertDataLength;
		
		status = base64encode( encodedCertData, MAX_ENCODED_CERT_SIZE,
							   &encodedCertDataLength, certData, 
							   certDataLength, CRYPT_CERTTYPE_NONE );
		if( cryptStatusError( status ) )
			{
			assert( DEBUG_WARN );
			retIntError();
			}
		setBoundData( boundDataPtr, boundDataIndex, encodedCertData, 
					  encodedCertDataLength );
		}
	status = dbmsUpdate( sqlString, boundDataPtr, updateType );
	if( cryptStatusError( status ) )
		{
		retExtErr( status, 
				   ( status, errorInfo, getDbmsErrorInfo( dbmsInfo ),
					 "CRL add operation failed: " ) );
		}

	return( CRYPT_OK );
	}

/* Add an item to the certificate store */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int setItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
							IN_HANDLE const CRYPT_HANDLE iCryptHandle,
							IN_ENUM( KEYMGMT_ITEM ) \
								const KEYMGMT_ITEM_TYPE itemType,
							STDC_UNUSED const char *password, 
							STDC_UNUSED const int passwordLength,
							IN_FLAGS( KEYMGMT ) const int flags )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	BOOLEAN seenNonDuplicate = FALSE;
	int type, iterationCount = 0, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
	REQUIRES( isHandleRangeValid( iCryptHandle ) );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_REVOCATIONINFO || \
			  itemType == KEYMGMT_ITEM_REQUEST || \
			  itemType == KEYMGMT_ITEM_PKIUSER );
	REQUIRES( password == NULL && passwordLength == 0 );
	REQUIRES( flags >= KEYMGMT_FLAG_NONE && flags < KEYMGMT_FLAG_MAX );

	/* Make sure that we've been given a certificate, certificate chain, or 
	   CRL (or a PKI user if it's a CA certificate store).  We can't do any 
	   more specific checking against the itemType because if it's coming 
	   from outside cryptlib it'll just be passed in as a generic 
	   certificate object with no distinction between object subtypes */
	status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE,
							  &type, CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_NUM1 );
	if( isCertStore( dbmsInfo ) )
		{
		/* The only item that can be inserted directly into a CA certificate
		   store is a CA request or PKI user information */
		if( type != CRYPT_CERTTYPE_CERTREQUEST && \
			type != CRYPT_CERTTYPE_REQUEST_CERT && \
			type != CRYPT_CERTTYPE_REQUEST_REVOCATION && \
			type != CRYPT_CERTTYPE_PKIUSER )
			{
			retExtArg( CRYPT_ARGERROR_NUM1, 
					   ( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO, 
						 "Invalid item type for CA certificate store" ) );
			}

		if( itemType == KEYMGMT_ITEM_PKIUSER )
			return( caAddPKIUser( dbmsInfo, iCryptHandle, KEYSET_ERRINFO ) );

		/* It's a certificate request being added to a CA certificate 
		   store */
		REQUIRES( itemType == KEYMGMT_ITEM_REQUEST );
		return( caAddCertRequest( dbmsInfo, iCryptHandle, type,
								  ( flags & KEYMGMT_FLAG_UPDATE ) ? \
									TRUE : FALSE, KEYSET_ERRINFO ) );
		}
	if( type != CRYPT_CERTTYPE_CERTIFICATE && \
		type != CRYPT_CERTTYPE_CERTCHAIN && \
		type != CRYPT_CERTTYPE_CRL )
		{
		retExtArg( CRYPT_ARGERROR_NUM1, 
				   ( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO, 
					 "Item being added must be a CRL or certificate" ) );
		}

	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_REVOCATIONINFO );

	/* Lock the certificate or CRL for our exclusive use and select the 
	   first sub-item (certificate in a certificate chain, entry in a CRL), 
	   update the keyset with the certificate(s)/CRL entries, and unlock it 
	   to allow others access */
	status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
								  MESSAGE_VALUE_CURSORFIRST,
								  CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	do
		{
		/* Add the certificate or CRL */
		if( type == CRYPT_CERTTYPE_CRL )
			status = addCRL( dbmsInfo, iCryptHandle, CRYPT_UNUSED,
							 DBMS_UPDATE_NORMAL, KEYSET_ERRINFO );
		else
			status = addCert( dbmsInfo, iCryptHandle,
							  CRYPT_CERTTYPE_CERTIFICATE, CERTADD_NORMAL,
							  DBMS_UPDATE_NORMAL, KEYSET_ERRINFO );

		/* An item being added may already be present but we can't fail
		   immediately because what's being added may be a chain containing
		   further certificates or a CRL containing further entries so we 
		   keep track of whether we've successfully added at least one item 
		   and clear data duplicate errors */
		if( status == CRYPT_OK )
			seenNonDuplicate = TRUE;
		else
			{
			if( status == CRYPT_ERROR_DUPLICATE )
				status = CRYPT_OK;
			}
		}
	while( cryptStatusOK( status ) && \
		   krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
							MESSAGE_VALUE_CURSORNEXT,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MED );
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
	( void ) krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusOK( status ) && !seenNonDuplicate )
		{
		/* We reached the end of the certificate chain/CRL without finding 
		   anything that we could add, return a data duplicate error */
		retExt( CRYPT_ERROR_DUPLICATE, 
				( CRYPT_ERROR_DUPLICATE, KEYSET_ERRINFO, 
				  "No new %s were found to add to the certificate store",
				  ( type == CRYPT_CERTTYPE_CRL ) ? \
					"CRL entries" : "certificates" ) );
		}

	return( status );
	}

/* Delete an item from the certificate store */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int deleteItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
							   IN_ENUM( KEYMGMT_ITEM ) \
								const KEYMGMT_ITEM_TYPE itemType,
							   IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
							   IN_BUFFER( keyIDlength ) const void *keyID, 
							   IN_LENGTH_KEYID const int keyIDlength )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	BOUND_DATA boundData[ BOUND_DATA_MAXITEMS ], *boundDataPtr = boundData;
	char sqlBuffer[ MAX_SQL_QUERY_SIZE + 8 ];
	char encodedKeyID[ ( CRYPT_MAX_TEXTSIZE * 2 ) + 8 ];
	const char *keyName = getKeyName( keyIDtype );
	const char *deleteString = getDeleteString( itemType );
	int encodedKeyIDlength, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isReadPtr( keyID, keyIDlength ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_PKIUSER );
	REQUIRES( ( !isCertStore( dbmsInfo ) && \
				itemType == KEYMGMT_ITEM_PUBLICKEY ) || \
			  ( isCertStore( dbmsInfo ) && \
				itemType == KEYMGMT_ITEM_PKIUSER ) );
	REQUIRES( keyIDtype > CRYPT_KEYID_NONE && \
			  keyIDtype < CRYPT_KEYID_LAST );
	REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
			  keyIDlength < MAX_ATTRIBUTE_SIZE );

	/* Delete the item from the certificate store */
	status = makeKeyID( encodedKeyID, CRYPT_MAX_TEXTSIZE * 2, 
						&encodedKeyIDlength, keyIDtype, keyID, keyIDlength );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_STR1 );
	if( isCertStore( dbmsInfo ) )
		{
		/* The only item that can be deleted from a CA certificate store is 
		   PKI user information */
		if( itemType != KEYMGMT_ITEM_PKIUSER )
			{
			retExtArg( CRYPT_ARGERROR_NUM1, 
					   ( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO, 
						 "Invalid operation for CA certificate store" ) );
			}

		return( caDeletePKIUser( dbmsInfo, keyIDtype, keyID, keyIDlength, 
								 KEYSET_ERRINFO ) );
		}
	ENSURES( keyName != NULL && deleteString != NULL );
	strlcpy_s( sqlBuffer, MAX_SQL_QUERY_SIZE, deleteString );
	strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, keyName );
	strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, " = ?" );
	initBoundData( boundDataPtr );
	setBoundData( boundDataPtr, 0, encodedKeyID, encodedKeyIDlength );
	status = dbmsUpdate( sqlBuffer, boundDataPtr, DBMS_UPDATE_NORMAL );
	if( cryptStatusError( status ) )
		{
		retExtErr( status, 
				   ( status, KEYSET_ERRINFO, getDbmsErrorInfo( dbmsInfo ),
					 "Certificate delete operation failed: " ) );
		}
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Database Access Routines						*
*																			*
****************************************************************************/

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initDBMSwrite( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );

	keysetInfoPtr->setItemFunction = setItemFunction;
	keysetInfoPtr->deleteItemFunction = deleteItemFunction;

	return( CRYPT_OK );
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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