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

📄 dbx_rd.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		   If it's a point query this means we didn't find anything, 
		   otherwise we try again with the next result */
		if( certificate[ 0 ] == 0xFF )
			{
			/* If it's a multi-cert query, try again with the next result */
			if( multiCertQuery )
				continue;
			
			/* It's a point query, we found something but it isn't there.
			   "Can't you understand English you arse, we're not at home"
			   -- Jeremy Black, "The Boys from Brazil" */
			return( CRYPT_ERROR_NOTFOUND );
			}

		/* If more than one cert is present and the requested key usage
		   doesn't match the one indicated in the cert, try again */
		if( multiCertQuery && \
			!checkCertUsage( certificate, certDataLength, options ) )
			continue;

		/* We got what we wanted, exit */
		continueFetch = FALSE;
		}
	if( iterationCount >= 100 )
		return( CRYPT_ERROR_NOTFOUND );

	/* If we've been looking through multiple certs, cancel the outstanding
	   query, which will still be in progress */
	if( multiCertQuery )
		dbmsStaticQuery( NULL, cachedQueryType, DBMS_QUERY_CANCEL );

	/* Create a certificate object from the encoded cert.  If we're reading 
	   revocation information the data is a single CRL entry so we have to 
	   tell the cert import code to treat it as a special case of a CRL.  If
	   we're reading a request, it could be one of several types so we have
	   to use auto-detection rather than specifying an exact format */
	setMessageCreateObjectIndirectInfo( &createInfo, certificate, 
										certDataLength,
		( itemType == KEYMGMT_ITEM_PUBLICKEY || \
		  itemType == KEYMGMT_ITEM_NONE ) ? CRYPT_CERTTYPE_CERTIFICATE : \
		( itemType == KEYMGMT_ITEM_REQUEST ) ? CRYPT_CERTTYPE_NONE : \
		( itemType == KEYMGMT_ITEM_PKIUSER ) ? CRYPT_CERTTYPE_PKIUSER : \
		( itemType == KEYMGMT_ITEM_REVOCATIONINFO ) ? CERTFORMAT_REVINFO : \
		CRYPT_CERTTYPE_NONE );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	*iCertificate = createInfo.cryptHandle;

	/* If this was a read with state held externally, remember where we got
	   to so that we can fetch the next cert in the sequence */
	if( stateInfo != NULL )
		*stateInfo = *iCertificate;
	return( CRYPT_OK );
	}

static int getFirstItemFunction( KEYSET_INFO *keysetInfo,
								 CRYPT_CERTIFICATE *iCertificate,
								 int *stateInfo,
								 const CRYPT_KEYID_TYPE keyIDtype,
								 const void *keyID, const int keyIDlength,
								 const KEYMGMT_ITEM_TYPE itemType,
								 const int options )
	{
	DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;
	char keyIDbuffer[ CRYPT_MAX_TEXTSIZE * 2 ];
	int length, status;

	/* If it's a general query, submit the query to the database */
	if( stateInfo == NULL )
		{
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];
		int sqlLength;

		assert( itemType == KEYMGMT_ITEM_PUBLICKEY || \
				itemType == KEYMGMT_ITEM_REQUEST );
		assert( options == KEYMGMT_FLAG_NONE );

		if( keyIDlength > MAX_SQL_QUERY_SIZE - 64 )
			return( CRYPT_ARGERROR_STR1 );

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

		assert( !keysetInfo->isBusyFunction( keysetInfo ) );

		/* 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 */
		dbmsFormatSQL( sqlBuffer,
			"SELECT certData FROM $ WHERE ",
					   getTableName( itemType ) );
		sqlLength = strlen( sqlBuffer );
		dbmsFormatQuery( sqlBuffer + sqlLength, keyID, keyIDlength,
						 ( MAX_SQL_QUERY_SIZE - 1 ) - sqlLength );
		return( dbmsStaticQuery( sqlBuffer, DBMS_CACHEDQUERY_NONE, 
								 DBMS_QUERY_START ) );
		}

	/* Fetch the first data item */
	status = length = makeKeyID( keyIDbuffer, CRYPT_MAX_TEXTSIZE * 2, 
								 keyIDtype, keyID, keyIDlength );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_STR1 );
	return( getItemData( dbmsInfo, iCertificate, stateInfo, keyIDtype, 
						 keyIDbuffer, length, itemType, options ) );
	}

static int getNextItemFunction( KEYSET_INFO *keysetInfo,
								CRYPT_CERTIFICATE *iCertificate,
								int *stateInfo, const int options )
	{
	DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;

	/* If we're fetching the next cert in a sequence based on externally-held
	   state information, set the key ID to the nameID of the previous cert's
	   issuer.  This is a special-case ID that isn't used outside the database
	   keysets, so we use the non-ID type CRYPT_KEYID_LAST to signify its use */
	if( stateInfo != NULL )
		{
		char keyIDbuffer[ CRYPT_MAX_TEXTSIZE * 2 ];
		int length, status;

		status = length = getKeyID( keyIDbuffer, *stateInfo,
									CRYPT_IATTRIBUTE_ISSUER );
		if( cryptStatusError( status ) )
			return( status );
		return( getItemData( dbmsInfo, iCertificate, stateInfo, 
							 CRYPT_KEYID_LAST, keyIDbuffer, length, 
							 KEYMGMT_ITEM_PUBLICKEY, options ) );
		}

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

/* Retrieve a key record from the database */

static int getItemFunction( KEYSET_INFO *keysetInfo,
							CRYPT_HANDLE *iCryptHandle,
							const KEYMGMT_ITEM_TYPE itemType,
							const CRYPT_KEYID_TYPE keyIDtype,
							const void *keyID,  const int keyIDlength,
							void *auxInfo, int *auxInfoLength,
							const int flags )
	{
	DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;
	int status;

	assert( auxInfo == NULL ); assert( *auxInfoLength == 0 );

	/* There are some query types that can only be satisfied by a cert 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 cert ID in the revocation
		   information since the CRL it's populated from only contains an
		   issuerAndSerialNumber, so we can't resolve queries for revocation
		   info using a cert ID */
		if( itemType == KEYMGMT_ITEM_REVOCATIONINFO && \
			keyIDtype == CRYPT_IKEYID_CERTID )
			return( CRYPT_ERROR_NOTFOUND );
		}

	/* If this is a CA management item fetch, fetch the data from the CA cert
	   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 cert that the user 
		   owns rather than that of the user themselves, fetch the user info 
		   via a special function */
		if( itemType == KEYMGMT_ITEM_PKIUSER && \
			( flags & KEYMGMT_FLAG_GETISSUER ) )
			{
			char certID[ DBXKEYID_BUFFER_SIZE ];
			int certIDlength;

			assert( keyIDtype == CRYPT_IKEYID_CERTID );
			assert( isCertStore( dbmsInfo ) );

			/* The information required to locate the PKI user from one of 
			   their certs is only present in a cert store */
			if( !isCertStore( dbmsInfo ) )
				return( CRYPT_ERROR_NOTFOUND );

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

		/* This is just a standard read from a non-certificate table rather
		   than the cert table so we call the get first cert function directly
		   (rather than going via the indirect-cert-import code).  Since it's
		   a direct call, we need to provide a dummy return variable for the
		   state information which is normally handled by the indirect-cert-
		   import code */
		return( getFirstItemFunction( keysetInfo, iCryptHandle, &dummy,
									  keyIDtype, keyID, keyIDlength,
									  itemType, 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 )
		{
		char keyIDbuffer[ DBXKEYID_BUFFER_SIZE ];
		char sqlBuffer[ MAX_SQL_QUERY_SIZE ];
		int length;

		assert( itemType == KEYMGMT_ITEM_PUBLICKEY || \
				itemType == KEYMGMT_ITEM_REVOCATIONINFO );
		assert( keyIDlength == KEYID_SIZE );
		assert( keyIDtype == CRYPT_IKEYID_ISSUERID || \
				keyIDtype == CRYPT_IKEYID_CERTID );

		/* Check whether this item is present.  We don't care about the
		   result, 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 = length = makeKeyID( keyIDbuffer, DBXKEYID_BUFFER_SIZE, 
									 keyIDtype, keyID, KEYID_SIZE );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_STR1 );
		dbmsFormatSQL( sqlBuffer,
			"SELECT certData FROM $ WHERE $ = ?",
					   getTableName( itemType ), getKeyName( keyIDtype ) );
		return( dbmsQuery( sqlBuffer, NULL, 0, keyIDbuffer, length, 0,
						   getCachedQueryType( itemType, keyIDtype ),
						   DBMS_QUERY_CHECK ) );
		}

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

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

void initDBMSread( KEYSET_INFO *keysetInfo )
	{
	keysetInfo->getItemFunction = getItemFunction;
	keysetInfo->getFirstItemFunction = getFirstItemFunction;
	keysetInfo->getNextItemFunction = getNextItemFunction;
	}
#endif /* USE_DBMS */

⌨️ 快捷键说明

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