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

📄 dbx_rd.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
			    itemType < KEYMGMT_ITEM_LAST && \
				keyIDtype > CRYPT_KEYID_NONE && \
				keyIDtype <= CRYPT_KEYID_LAST && \
				keyValue != NULL && \
				keyValueLength >= MIN_NAME_LENGTH && 
				keyValueLength < MAX_ATTRIBUTE_SIZE && \
				stateInfo != NULL ) );
			  /* As well as the standard values we can also have the 
			     special-case value CRYPT_KEYID_LAST (see the comment in 
				 getItemFunction() for details) which is mapped to the
				 database-use-only lookup value "nameID", the hashed DN */
	REQUIRES( itemType == KEYMGMT_ITEM_NONE || \
			  itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_REQUEST || \
			  itemType == KEYMGMT_ITEM_PKIUSER || \
			  itemType == KEYMGMT_ITEM_REVOCATIONINFO );
	REQUIRES( options >= KEYMGMT_FLAG_NONE && options < KEYMGMT_FLAG_MAX );
	REQUIRES( errorInfo != NULL );

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

	/* Make sure that we can never explicitly fetch anything with an ID that
	   indicates that it's physically but not logically present, for example
	   certificates that have been created but not fully issued yet, 
	   certificate items that are on hold, and similar items */
	if( keyValue != NULL && keyValueLength >= KEYID_ESC_SIZE && \
		( !memcmp( keyValue, KEYID_ESC1, KEYID_ESC_SIZE ) || \
		  !memcmp( keyValue, KEYID_ESC2, KEYID_ESC_SIZE ) ) )
		{
		/* Eheu, litteras istas reperire non possum */
		return( CRYPT_ERROR_NOTFOUND );
		}

	/* Perform a slight optimisation to eliminate unnecessary multi-
	   certificate queries: If we're querying by certID or issuerID only one 
	   certificate can ever match so there's no need to perform a multi-
	   certificate query even if key usage options are specified */
	if( keyIDtype == CRYPT_IKEYID_ISSUERID || \
		keyIDtype == CRYPT_IKEYID_CERTID )
		multiCertQuery = FALSE;

	/* Set the query to begin the fetch */
	if( stateInfo != NULL )
		{
		const char *keyName = getKeyName( keyIDtype );
		const char *selectString = getSelectString( itemType );

		ENSURES( keyName != NULL && selectString != NULL );
		strlcpy_s( sqlBuffer, MAX_SQL_QUERY_SIZE, selectString );
		strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, keyName );
		strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, " = ?" );
		queryString = sqlBuffer;
		initBoundData( boundDataPtr );
		setBoundData( boundDataPtr, 0, keyValue, keyValueLength );
		queryType = multiCertQuery ? DBMS_QUERY_START : DBMS_QUERY_NORMAL;
		}
	else
		{
		/* It's an ongoing query, just fetch the next set of results */
		queryString = NULL;
		boundDataPtr = NULL;
		queryType = DBMS_QUERY_CONTINUE;
		}

	/* Retrieve the results from the query */
	for( iterationCount = 0; iterationCount < FAILSAFE_ITERATIONS_MED; 
		 iterationCount++ )
		{
		/* Retrieve the certificate data and base64-decode it if necessary */
		status = dbmsQuery( queryString, certDataPtr, 
							hasBinaryBlobs( dbmsInfo ) ? \
								MAX_CERT_SIZE : MAX_SQL_QUERY_SIZE,
							&certDataLength, boundDataPtr, cachedQueryType, 
							queryType );
		if( cryptStatusError( status ) )
			{
			/* Convert the error code to a more appropriate value if
			   necessary */
			return( ( multiCertQuery && ( status == CRYPT_ERROR_COMPLETE ) ) ? \
					CRYPT_ERROR_NOTFOUND : status );
			}
		if( !hasBinaryBlobs( dbmsInfo ) )
			{
			status = base64decode( certificate, MAX_CERT_SIZE, 
								   &certDataLength, certDataBuffer, 
								   certDataLength, CRYPT_CERTFORMAT_NONE );
			if( cryptStatusError( status ) )
				{
				retExt( status, 
						( status, errorInfo, 
						  "Couldn't decode certificate from stored encoded "
						  "certificate data" ) );
				}
			}

		/* We've started the fetch, from now on we're only fetching further
		   results */
		queryString = NULL;
		boundDataPtr = NULL;
		if( queryType == DBMS_QUERY_START )
			queryType = DBMS_QUERY_CONTINUE;

		ENSURES( certDataLength >= 16 && certDataLength <= MAX_CERT_SIZE );
		ENSURES( ( stateInfo != NULL && \
				   ( queryType == DBMS_QUERY_NORMAL || \
					 queryType == DBMS_QUERY_CONTINUE ) ) || \
				 ( stateInfo == NULL && queryType == DBMS_QUERY_CONTINUE ) );

		/* If the first byte of the certificate data is 0xFF then this is an 
		   item that's physically but not logically present (see the comment 
		   above in the check for the keyValue), which means that we can't 
		   explicitly fetch it (te audire non possum, musa sapientum fixa 
		   est in aure) */
		if( certificate[ 0 ] == 0xFF )
			{
			/* If it's a multi-certificate 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 certificate is present and the requested key 
		   usage doesn't match the one indicated in the certificate, try 
		   again */
		if( multiCertQuery && \
			!checkCertUsage( certificate, certDataLength, options ) )
			continue;

		/* We got what we wanted, exit */
		break;
		}
	if( iterationCount >= FAILSAFE_ITERATIONS_MED )
		{
		retExt_IntError( CRYPT_ERROR_NOTFOUND, 
						 ( CRYPT_ERROR_NOTFOUND, errorInfo, 
						   "Couldn't find matching certificate after "
						   "processing %d items", FAILSAFE_ITERATIONS_MED ) );
		}

	/* If we've been looking through multiple certificates, 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 certificate data.  If 
	   we're reading revocation information the data is a single CRL entry 
	   so we have to tell the certificate 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 ) ? CRYPT_ICERTTYPE_REVINFO : \
		CRYPT_CERTTYPE_NONE );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		{
		retExt( status, 
				( status, errorInfo, 
				  "Couldn't recreate certificate from stored certificate "
				  "data" ) );
		}
	*iCertificate = createInfo.cryptHandle;

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

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 6 ) ) \
static int getFirstItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
								 OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
								 OUT int *stateInfo,
								 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,
								 IN_FLAGS_Z( KEYMGMT ) const int options )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
	char encodedKeyID[ ( CRYPT_MAX_TEXTSIZE * 2 ) + 8 ];
	int encodedKeyIDlength, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( iCertificate == NULL || \
			isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
	assert( isWritePtr( stateInfo, sizeof( int ) ) );
	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( options >= KEYMGMT_FLAG_NONE && \
			  options < KEYMGMT_FLAG_MAX );
	REQUIRES( ( options & KEYMGMT_MASK_USAGEOPTIONS ) != \
			  KEYMGMT_MASK_USAGEOPTIONS );

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

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
static int getNextItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
								OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
								INOUT int *stateInfo, 
								IN_FLAGS_Z( KEYMGMT ) const int options )
	{
	DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
	assert( ( stateInfo == NULL ) || \
			isWritePtr( stateInfo, sizeof( int ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
	REQUIRES( options >= KEYMGMT_FLAG_NONE && \
			  options < KEYMGMT_FLAG_MAX );
	REQUIRES( ( options & KEYMGMT_MASK_USAGEOPTIONS ) != \
			  KEYMGMT_MASK_USAGEOPTIONS );

	/* If we're fetching the next certificate in a sequence based on 
	   externally-held state information, set the key ID to the nameID of 
	   the previous certificate'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 encodedKeyID[ ENCODED_DBXKEYID_SIZE + 8 ];
		int encodedKeyIDlength, status;

		status = getKeyID( encodedKeyID, ENCODED_DBXKEYID_SIZE, 

⌨️ 快捷键说明

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