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

📄 dbx_rd.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
						   &encodedKeyIDlength, *stateInfo, 
						   CRYPT_IATTRIBUTE_ISSUER );
		if( cryptStatusError( status ) )
			return( status );
		return( getItemData( dbmsInfo, iCertificate, stateInfo, 
							 KEYMGMT_ITEM_PUBLICKEY, CRYPT_KEYID_LAST, 
							 encodedKeyID, encodedKeyIDlength, options, 
							 KEYSET_ERRINFO ) );
		}

	/* Fetch the next data item in an ongoing query */
	return( getItemData( dbmsInfo, iCertificate, NULL, KEYMGMT_ITEM_NONE, 
						 CRYPT_KEYID_NONE, NULL, 0, options, 
						 KEYSET_ERRINFO ) );
	}

/* Retrieve a certificate object from the database */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
static int getItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
							OUT_HANDLE_OPT CRYPT_HANDLE *iCryptHandle,
							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,
							STDC_UNUSED void *auxInfo, 
							STDC_UNUSED int *auxInfoLength,
							IN_FLAGS_Z( KEYMGMT ) const int flags )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	int status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isWritePtr( iCryptHandle, sizeof( CRYPT_CERTIFICATE ) ) );
	assert( isReadPtr( keyID, keyIDlength ) );
	
	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
	REQUIRES( itemType == KEYMGMT_ITEM_NONE || \
			  itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_REQUEST || \
			  itemType == KEYMGMT_ITEM_PKIUSER || \
			  itemType == KEYMGMT_ITEM_REVOCATIONINFO );
	REQUIRES( keyIDtype > CRYPT_KEYID_NONE && \
			  keyIDtype < CRYPT_KEYID_LAST );
	REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
			  keyIDlength < MAX_ATTRIBUTE_SIZE );
	REQUIRES( auxInfo == NULL && *auxInfoLength == 0 );
	REQUIRES( flags >= KEYMGMT_FLAG_NONE && \
			  flags < KEYMGMT_FLAG_MAX );
	REQUIRES( ( flags & KEYMGMT_MASK_USAGEOPTIONS ) != \
			  KEYMGMT_MASK_USAGEOPTIONS );

	/* There are some query types that can only be satisfied by a 
	   certificate store since a standard database doesn't contain the 
	   necessary fields.  Before we do anything else we make sure that we 
	   can resolve the query using the current database type */
	if( !( dbmsInfo->flags & DBMS_FLAG_CERTSTORE_FIELDS ) )
		{
		/* A standard database doesn't contain a certificate ID in the 
		   revocation information since the CRL that it's populated from 
		   only contains an issuerAndSerialNumber, so we can't resolve 
		   queries for revocation information using a certificate ID */
		if( itemType == KEYMGMT_ITEM_REVOCATIONINFO && \
			keyIDtype == CRYPT_IKEYID_CERTID )
			{
			retExt( CRYPT_ERROR_NOTFOUND, 
					( CRYPT_ERROR_NOTFOUND, KEYSET_ERRINFO, 
					  "Operation is only valid for certificate stores" ) );
			}
		}

	/* If this is a CA management item fetch, fetch the data from the CA 
	   certificate store */
	if( itemType == KEYMGMT_ITEM_REQUEST || \
		itemType == KEYMGMT_ITEM_PKIUSER || \
		( itemType == KEYMGMT_ITEM_REVOCATIONINFO && \
		  !( flags & KEYMGMT_FLAG_CHECK_ONLY ) ) )
		{
		int dummy;

		/* If we're getting the issuing PKI user (which means that the key ID
		   that's being queried on is that of an issued certificate that the 
		   PKI user owns rather than that of the PKI user themselves) fetch 
		   the user information via a special function */
		if( itemType == KEYMGMT_ITEM_PKIUSER && \
			( flags & KEYMGMT_FLAG_GETISSUER ) )
			{
			char certID[ ENCODED_DBXKEYID_SIZE + 8 ];
			int certIDlength;

			REQUIRES( keyIDtype == CRYPT_IKEYID_CERTID );

			/* The information required to locate the PKI user from one of 
			   their certificates is only present in a certificate store */
			if( !isCertStore( dbmsInfo ) )
				{
				retExt( CRYPT_ERROR_NOTFOUND, 
						( CRYPT_ERROR_NOTFOUND, KEYSET_ERRINFO, 
						  "Operation is only valid for certificate stores" ) );
				}

			/* Get the PKI user based on the certificate */
			status = makeKeyID( certID, ENCODED_DBXKEYID_SIZE, &certIDlength,
								CRYPT_IKEYID_CERTID, keyID, keyIDlength );
			if( cryptStatusError( status ) )
				return( CRYPT_ARGERROR_STR1 );
			return( caGetIssuingUser( dbmsInfo, iCryptHandle, 
									  certID, certIDlength, 
									  KEYSET_ERRINFO ) );
			}

		/* This is just a standard read from a non-certificate table rather
		   than the certificate table so we call the get-first certificate 
		   function directly rather than going via the indirect certificate-
		   import code.  Since it's a direct call we need to provide a dummy 
		   return variable for the state information that's normally handled 
		   by the indirect-import code */
		return( getFirstItemFunction( keysetInfoPtr, iCryptHandle, &dummy,
									  itemType, keyIDtype, keyID, 
									  keyIDlength, KEYMGMT_FLAG_NONE ) );
		}

	/* If we're doing a check only, just check whether the item is present
	   without fetching any data */
	if( flags & KEYMGMT_FLAG_CHECK_ONLY )
		{
		BOUND_DATA boundData[ BOUND_DATA_MAXITEMS ], *boundDataPtr = boundData;
		char sqlBuffer[ MAX_SQL_QUERY_SIZE + 8 ];
		char encodedKeyID[ ENCODED_DBXKEYID_SIZE + 8 ];
		const char *keyName = getKeyName( keyIDtype );
		const char *selectString = getSelectString( itemType );
		int encodedKeyIDlength;

		REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
				  itemType == KEYMGMT_ITEM_REVOCATIONINFO );
		REQUIRES( keyIDlength == KEYID_SIZE );
		REQUIRES( keyIDtype == CRYPT_IKEYID_ISSUERID || \
				  keyIDtype == CRYPT_IKEYID_CERTID );
		ENSURES( keyName != NULL && selectString != NULL );

		/* Check whether this item is present.  We don't care about the 
		   result data, all we want to know is whether it's there or not so 
		   we just do a check rather than a fetch of any data */
		status = makeKeyID( encodedKeyID, ENCODED_DBXKEYID_SIZE, 
							&encodedKeyIDlength, keyIDtype, 
							keyID, KEYID_SIZE );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_STR1 );
		strlcpy_s( sqlBuffer, MAX_SQL_QUERY_SIZE, selectString );
		strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, keyName );
		strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, " = ?" );
		initBoundData( boundDataPtr );
		setBoundData( boundDataPtr, 0, encodedKeyID, encodedKeyIDlength );
		return( dbmsQuery( sqlBuffer, NULL, 0, NULL, boundDataPtr,
						   getCachedQueryType( itemType, keyIDtype ),
						   DBMS_QUERY_CHECK ) );
		}

	/* Import the certificate by doing an indirect read, which fetches 
	   either a single certificate or an entire chain if it's present */
	return( iCryptImportCertIndirect( iCryptHandle, keysetInfoPtr->objectHandle,
									  keyIDtype, keyID, keyIDlength,
									  flags & KEYMGMT_MASK_CERTOPTIONS ) );
	}

/* Add special data to the database.  Technically this is a set-function but 
   because it initiates a query-fetch it's included with the get-functions */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int setSpecialItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
								   IN_ATTRIBUTE \
									const CRYPT_ATTRIBUTE_TYPE dataType,
								   IN_BUFFER( dataLength ) const void *data, 
								   IN_LENGTH_SHORT const int dataLength )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	char sqlBuffer[ MAX_SQL_QUERY_SIZE + 8 ];
	const KEYMGMT_ITEM_TYPE itemType = \
						( dataType == CRYPT_KEYINFO_QUERY_REQUESTS ) ? \
						KEYMGMT_ITEM_REQUEST : KEYMGMT_ITEM_PUBLICKEY;
	const char *selectString = getSelectString( itemType );
	int sqlLength, sqlQueryLength, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isReadPtr( data, dataLength ) );

	ENSURES( dataType == CRYPT_KEYINFO_QUERY || \
			 dataType == CRYPT_KEYINFO_QUERY_REQUESTS );
	ENSURES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
			 itemType == KEYMGMT_ITEM_REQUEST );
	ENSURES( selectString != NULL );

	/* The kernel enforces a size range from 6...CRYPT_MAX_TEXTSIZE but we 
	   perform an explicit check here against possible database-specific 
	   values that may be more specific than the kernel's one-size-fits-all 
	   values */
	if( dataLength < 6 || dataLength > MAX_SQL_QUERY_SIZE - 64 )
		{
		retExtArg( CRYPT_ARGERROR_STR1, 
				   ( CRYPT_ARGERROR_STR1, KEYSET_ERRINFO, 
					 "Invalid query length, should be from 6...%d "
					 "characters", MAX_SQL_QUERY_SIZE - 64 ) );
		}

	/* If we're cancelling an existing query, pass it on down */
	if( dataLength == 6 && !strCompare( data, "cancel", dataLength ) )
		{
		return( dbmsStaticQuery( NULL, DBMS_CACHEDQUERY_NONE,
								 DBMS_QUERY_CANCEL ) );
		}

	ENSURES( !keysetInfoPtr->isBusyFunction( keysetInfoPtr ) );

	/* Rewrite the user-supplied portion of the query using the actual 
	   column names and append it to the SELECT statement.  This is a 
	   special case free-format query where we can't use bound parameters 
	   because the query data must be interpreted as SQL, unlike standard 
	   queries where we definitely don't want it (mis-)interpreted as SQL.  
	   dbmsFormatQuery() tries to sanitise the query as much as it can but 
	   in general we rely on developers reading the warnings in the 
	   documentation about the appropriate use of this capability */
	strlcpy_s( sqlBuffer, MAX_SQL_QUERY_SIZE, selectString );
	sqlLength = strlen( sqlBuffer );
	status = dbmsFormatQuery( sqlBuffer + sqlLength, 
							 ( MAX_SQL_QUERY_SIZE - 1 ) - sqlLength, 
							 &sqlQueryLength, data, dataLength );
	if( cryptStatusError( status ) )
		{
		retExtArg( CRYPT_ARGERROR_STR1, 
				   ( CRYPT_ARGERROR_STR1, KEYSET_ERRINFO, 
					 "Invalid query format" ) );
		}
	return( dbmsStaticQuery( sqlBuffer, DBMS_CACHEDQUERY_NONE, 
							 DBMS_QUERY_START ) );
	}

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

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

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );

	keysetInfoPtr->getItemFunction = getItemFunction;
	keysetInfoPtr->getFirstItemFunction = getFirstItemFunction;
	keysetInfoPtr->getNextItemFunction = getNextItemFunction;
	keysetInfoPtr->setSpecialItemFunction = setSpecialItemFunction;

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

⌨️ 快捷键说明

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