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

📄 cryptkey.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:

		REQUIRES( keyIDinfo.keyIDtype != CRYPT_KEYID_NONE && \
				  keyIDinfo.keyID != NULL && \
				  keyIDinfo.keyIDlength >= MIN_NAME_LENGTH && \
				  keyIDinfo.keyIDlength < MAX_ATTRIBUTE_SIZE );
		REQUIRES( ( getnextcertInfo->auxInfo == NULL && \
					getnextcertInfo->auxInfoLength == 0 ) || \
				  ( getnextcertInfo->auxInfo != NULL && \
					getnextcertInfo->auxInfoLength == sizeof( int ) ) );

		/* Fetch the first certificate in a sequence from the keyset */
		resetErrorInfo( keysetInfoPtr );
		status = initKeysetUpdate( keysetInfoPtr, &keyIDinfo, keyIDbuffer, 
								   KEYID_SIZE, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		return( keysetInfoPtr->getFirstItemFunction( keysetInfoPtr,
									&getnextcertInfo->cryptHandle, 
									getnextcertInfo->auxInfo, messageValue, 
									keyIDinfo.keyIDtype, keyIDinfo.keyID, 
									keyIDinfo.keyIDlength, 
									getnextcertInfo->flags ) );
		}
	if( message == MESSAGE_KEY_GETNEXTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;

		REQUIRES( getnextcertInfo->keyIDtype == CRYPT_KEYID_NONE && \
				  getnextcertInfo->keyID == NULL && \
				  getnextcertInfo->keyIDlength == 0 );
		REQUIRES( ( getnextcertInfo->auxInfo == NULL && \
					getnextcertInfo->auxInfoLength == 0 ) || \
				  ( getnextcertInfo->auxInfo != NULL && \
					getnextcertInfo->auxInfoLength == sizeof( int ) ) );
		REQUIRES( getnextcertInfo->flags >= KEYMGMT_FLAG_NONE && \
				  getnextcertInfo->flags < KEYMGMT_FLAG_MAX && \
				  ( getnextcertInfo->flags & ~KEYMGMT_MASK_CERTOPTIONS ) == 0 );

		/* Fetch the next certificate in a sequence from the keyset */
		return( keysetInfoPtr->getNextItemFunction( keysetInfoPtr,
							&getnextcertInfo->cryptHandle, 
							getnextcertInfo->auxInfo,
							getnextcertInfo->flags ) );
		}
#ifdef USE_DBMS
	if( message == MESSAGE_KEY_CERTMGMT )
		{
		MESSAGE_CERTMGMT_INFO *certMgmtInfo = \
								( MESSAGE_CERTMGMT_INFO * ) messageDataPtr;

		REQUIRES( messageValue >= CRYPT_CERTACTION_CERT_CREATION && \
				  messageValue <= CRYPT_CERTACTION_LAST_USER );

		/* Perform the certificate management operation */
		resetErrorInfo( keysetInfoPtr );
		status = initKeysetUpdate( keysetInfoPtr, NULL, NULL, 0, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		status = keysetInfoPtr->keysetDBMS->certMgmtFunction( keysetInfoPtr,
							( certMgmtInfo->cryptCert != CRYPT_UNUSED ) ? \
								&certMgmtInfo->cryptCert : NULL, 
							certMgmtInfo->caKey, certMgmtInfo->request, 
							messageValue );
		if( cryptStatusOK( status ) )
			{
			/* The update succeeded, remember that the data in the keyset has
			   changed */
			keysetInfoPtr->flags |= KEYSET_DIRTY;
			}
		return( status );
		}
#endif /* USE_DBMS */

	retIntError();
	}

/* Open a keyset.  This is a low-level function encapsulated by createKeyset()
   and used to manage error exits */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 7 ) ) \
static int openKeyset( OUT_HANDLE_OPT CRYPT_KEYSET *iCryptKeyset,
					   IN_HANDLE const CRYPT_USER iCryptOwner,
					   IN_ENUM( CRYPT_KEYSET ) const CRYPT_KEYSET_TYPE keysetType,
					   IN_BUFFER( nameLength ) const char *name, 
					   IN_LENGTH_SHORT_MIN( MIN_NAME_LENGTH ) const int nameLength,
					   IN_ENUM_OPT( CRYPT_KEYOPT ) const CRYPT_KEYOPT_TYPE options,
					   OUT_PTR KEYSET_INFO **keysetInfoPtrPtr )
	{
	KEYSET_INFO *keysetInfoPtr;
	STREAM stream;
	CRYPT_KEYOPT_TYPE localOptions = options;
	KEYSET_SUBTYPE keysetSubType = DUMMY_INIT;
	OBJECT_SUBTYPE subType;
	int storageSize, status;

	assert( isWritePtr( iCryptKeyset, sizeof( CRYPT_KEYSET ) ) );
	assert( isReadPtr( name, nameLength ) );
	assert( isWritePtr( keysetInfoPtrPtr, sizeof( KEYSET_INFO * ) ) );

	REQUIRES( ( iCryptOwner == DEFAULTUSER_OBJECT_HANDLE ) || \
			  isHandleRangeValid( iCryptOwner ) );
	REQUIRES( keysetType > CRYPT_KEYSET_NONE && \
			  keysetType < CRYPT_KEYSET_LAST );
	REQUIRES( nameLength >= MIN_NAME_LENGTH && \
			  nameLength < MAX_ATTRIBUTE_SIZE );
	REQUIRES( options >= CRYPT_KEYOPT_NONE && options < CRYPT_KEYOPT_LAST );

	/* Clear the return values */
	*iCryptKeyset = CRYPT_ERROR;
	*keysetInfoPtrPtr = NULL;

	/* Perform general checks that can be done before we create the object */
	if( ( keysetType == CRYPT_KEYSET_HTTP && \
		  options != CRYPT_KEYOPT_READONLY ) || \
		( keysetType == CRYPT_KEYSET_LDAP && \
		  options == CRYPT_KEYOPT_CREATE ) )
		{
		/* We can't open an HTTP keyset for anything other than read-only
		   access, and we can't create an LDAP directory */
		return( CRYPT_ERROR_PERMISSION );
		}
	if( keysetType == CRYPT_KEYSET_FILE && nameLength > MAX_PATH_LENGTH - 1 )
		return( CRYPT_ARGERROR_STR1 );

	/* Set up subtype-specific information */
	switch( keysetType )
		{
		case CRYPT_KEYSET_FILE:
			subType = SUBTYPE_KEYSET_FILE_PARTIAL;
			storageSize = sizeof( FILE_INFO );
			break;

		case CRYPT_KEYSET_HTTP:
			subType = SUBTYPE_KEYSET_HTTP;
			storageSize = sizeof( HTTP_INFO );
			break;

		case CRYPT_KEYSET_LDAP:
			subType = SUBTYPE_KEYSET_LDAP;
			storageSize = sizeof( LDAP_INFO );
			break;

		case CRYPT_KEYSET_ODBC:
		case CRYPT_KEYSET_DATABASE:
		case CRYPT_KEYSET_PLUGIN:
			subType = SUBTYPE_KEYSET_DBMS;
			storageSize = sizeof( DBMS_INFO );
			break;

		case CRYPT_KEYSET_ODBC_STORE:
		case CRYPT_KEYSET_DATABASE_STORE:
		case CRYPT_KEYSET_PLUGIN_STORE:
			subType = SUBTYPE_KEYSET_DBMS_STORE;
			storageSize = sizeof( DBMS_INFO );
			break;
		
		default:
			retIntError();
		}

	/* Handle compiler warnings of uninitialised variables, unfortunately 
	   since it's non-scalar data we can't do this with the usual 
	   DUMMY_INIT */
	memset( &stream, 0, sizeof( STREAM ) );	

	/* If it's a flat-file keyset which is implemented on top of an I/O 
	   stream make sure that we can open the stream before we try and 
	   create the keyset object */
	if( keysetType == CRYPT_KEYSET_FILE )
		{
		BOOLEAN isReadOnly;

		status = openKeysetStream( &stream, name, nameLength, options, 
								   &isReadOnly, &keysetSubType );
		if( cryptStatusError( status ) )
			return( status );

		/* If we tried to open the file in read/write mode and it's 
		   read-only, change the access mode to read-only */
		if( isReadOnly )
			localOptions = CRYPT_KEYOPT_READONLY;

		/* If the keyset contains the full set of search keys and index
		   information needed to handle all keyset operations (e.g. 
		   certificate chain building, query by key usage types) we mark it 
		   as a full-function keyset with the same functionality as a DBMS 
		   keyset rather than just a generic flat-file store */
		if( keysetSubType == KEYSET_SUBTYPE_PKCS15 )
			subType = SUBTYPE_KEYSET_FILE;
		}

	/* Create the keyset object */
	status = krnlCreateObject( iCryptKeyset, ( void ** ) &keysetInfoPtr, 
							   sizeof( KEYSET_INFO ) + storageSize, 
							   OBJECT_TYPE_KEYSET, subType, 
							   CREATEOBJECT_FLAG_NONE, iCryptOwner, 
							   ACTION_PERM_NONE_ALL, keysetMessageFunction );
	if( cryptStatusError( status ) )
		{
		if( keysetType == CRYPT_KEYSET_FILE )
			sFileClose( &stream );
		return( status );
		}
	*keysetInfoPtrPtr = keysetInfoPtr;
	keysetInfoPtr->objectHandle = *iCryptKeyset;
	keysetInfoPtr->ownerHandle = iCryptOwner;
	keysetInfoPtr->options = localOptions;
	switch( keysetType )
		{
		case CRYPT_KEYSET_FILE:
			keysetInfoPtr->type = KEYSET_FILE;
			keysetInfoPtr->keysetFile = ( FILE_INFO * ) keysetInfoPtr->storage;
			break;

#ifdef USE_HTTP
		case CRYPT_KEYSET_HTTP:
			keysetInfoPtr->type = KEYSET_HTTP;
			keysetInfoPtr->keysetHTTP = ( HTTP_INFO * ) keysetInfoPtr->storage;
			break;
#endif /* USE_HTTP */

#ifdef USE_LDAP
		case CRYPT_KEYSET_LDAP:
			keysetInfoPtr->type = KEYSET_LDAP;
			keysetInfoPtr->keysetLDAP = ( LDAP_INFO * ) keysetInfoPtr->storage;
			break;
#endif /* USE_LDAP */

#ifdef USE_DBMS
		default:
			keysetInfoPtr->type = KEYSET_DBMS;
			keysetInfoPtr->keysetDBMS = ( DBMS_INFO * ) keysetInfoPtr->storage;
			break;
#endif /* USE_DBMS */
		}
	keysetInfoPtr->storageSize = storageSize;

	/* If it's a flat-file keyset which is implemented on top of an I/O 
	   stream, handle it specially */
	if( keysetType == CRYPT_KEYSET_FILE )
		{
		status = completeKeysetFileOpen( keysetInfoPtr, keysetSubType, 
										 &stream, name, nameLength );
		if( cryptStatusError( status ) )
			{
			sFileClose( &keysetInfoPtr->keysetFile->stream );
			if( options == CRYPT_KEYOPT_CREATE )
				{
				/* It's a newly-created file, make sure that we don't leave 
				   it lying around on disk */
				fileErase( keysetInfoPtr->keysetFile->fileName );
				}
			return( status );
			}
		
		return( CRYPT_OK );
		}

	/* Wait for any async keyset driver binding to complete.  We do this as 
	   late as possible to prevent file keyset reads that occur on startup 
	   (for example to get configuration options) from stalling the startup 
	   process */
	if( !krnlWaitSemaphore( SEMAPHORE_DRIVERBIND ) )
		{
		/* The kernel is shutting down, bail out */
		assert( DEBUG_WARN );
		return( CRYPT_ERROR_PERMISSION );
		}

	/* It's a specific type of keyset, set up the access information for it
	   and connect to it */
	switch( keysetType )
		{
		case CRYPT_KEYSET_ODBC:
		case CRYPT_KEYSET_DATABASE:
		case CRYPT_KEYSET_PLUGIN:
		case CRYPT_KEYSET_ODBC_STORE:
		case CRYPT_KEYSET_DATABASE_STORE:
		case CRYPT_KEYSET_PLUGIN_STORE:
			status = setAccessMethodDBMS( keysetInfoPtr, keysetType );
			break;

		case CRYPT_KEYSET_HTTP:
			status = setAccessMethodHTTP( keysetInfoPtr );
			break;

		case CRYPT_KEYSET_LDAP:
			status = setAccessMethodLDAP( keysetInfoPtr );
			break;

		default:
			retIntError();
		}
	if( cryptStatusError( status ) )
		return( status );
	ENSURES( keysetInfoPtr->initFunction != NULL && \
			 keysetInfoPtr->shutdownFunction != NULL && \
			 keysetInfoPtr->getItemFunction != NULL );
	ENSURES( keysetType == CRYPT_KEYSET_HTTP || \
			 ( keysetInfoPtr->setItemFunction != NULL && \
			   keysetInfoPtr->deleteItemFunction != NULL && \
			   keysetInfoPtr->isBusyFunction != NULL ) );
	ENSURES( keysetType == CRYPT_KEYSET_HTTP || \
			 keysetType == CRYPT_KEYSET_LDAP || \
			 ( keysetInfoPtr->getFirstItemFunction != NULL && \
			   keysetInfoPtr->getNextItemFunction != NULL ) );
#ifdef USE_LDAP
	ENSURES( keysetType != CRYPT_KEYSET_LDAP || \
			 ( keysetInfoPtr->getAttributeFunction != NULL && \
			   keysetInfoPtr->setAttributeFunction != NULL ) );
#endif /* USE_LDAP */

	/* Initialise keyset access */
	status = keysetInfoPtr->initFunction( keysetInfoPtr, name, nameLength,
										  keysetInfoPtr->options );
	if( cryptStatusOK( status ) )
		{
		keysetInfoPtr->flags |= KEYSET_OPEN;
		if( keysetInfoPtr->options == CRYPT_KEYOPT_CREATE )
			keysetInfoPtr->flags |= KEYSET_EMPTY;
		}
	return( status );
	}

/* Create a keyset object */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int createKeyset( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
				  STDC_UNUSED const void *auxDataPtr, 
				  STDC_UNUSED const int auxValue )
	{
	CRYPT_KEYSET iCryptKeyset;
	KEYSET_INFO *keysetInfoPtr = NULL;
	int initStatus, status;

	assert( isWritePtr( createInfo, sizeof( MESSAGE_CREATEOBJECT_INFO ) ) );

	REQUIRES( auxDataPtr == NULL && auxValue == 0 );
	REQUIRES( createInfo->arg1 > CRYPT_KEYSET_NONE && \
			  createInfo->arg1 < CRYPT_KEYSET_LAST );
	REQUIRES( createInfo->arg2 >= CRYPT_KEYOPT_NONE && \
			  createInfo->arg2 < CRYPT_KEYOPT_LAST );
	REQUIRES( createInfo->strArgLen1 >= MIN_NAME_LENGTH && \
			  createInfo->strArgLen1 < MAX_ATTRIBUTE_SIZE );

	/* Pass the call on to the lower-level open function */
	initStatus = openKeyset( &iCryptKeyset, createInfo->cryptOwner,
							 createInfo->arg1, createInfo->strArg1, 
							 createInfo->strArgLen1, createInfo->arg2,
							 &keysetInfoPtr );
	if( cryptStatusError( initStatus ) )
		{
		/* If the create object failed, return immediately */
		if( keysetInfoPtr == NULL )
			return( initStatus );

		/* The init failed, make sure that the object gets destroyed when we 
		   notify the kernel that the setup process is complete */
		krnlSendNotifier( iCryptKeyset, IMESSAGE_DESTROY );
		}

	/* We've finished setting up the object-type-specific info, tell the
	   kernel that the object is ready for use */
	status = krnlSendMessage( iCryptKeyset, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusError( initStatus ) || cryptStatusError( status ) )
		return( cryptStatusError( initStatus ) ? initStatus : status );
	createInfo->cryptHandle = iCryptKeyset;
	return( CRYPT_OK );
	}

/* Generic management function for this class of object */

CHECK_RETVAL \
int keysetManagementFunction( IN_ENUM( MANAGEMENT_ACTION ) \
								const MANAGEMENT_ACTION_TYPE action )
	{
	static int initLevel = 0;
	int status;

	REQUIRES( action == MANAGEMENT_ACTION_INIT || \
			  action == MANAGEMENT_ACTION_SHUTDOWN );

	switch( action )
		{
		case MANAGEMENT_ACTION_INIT:
			status = dbxInitODBC();
			if( cryptStatusOK( status ) )
				{
				initLevel++;
				if( krnlIsExiting() )
					{
					/* The kernel is shutting down, exit */
					return( CRYPT_ERROR_PERMISSION );
					}
				status = dbxInitLDAP();
				}
			if( cryptStatusOK( status ) )
				initLevel++;
			return( status );

		case MANAGEMENT_ACTION_SHUTDOWN:
			if( initLevel > 1 )
				dbxEndLDAP();
			if( initLevel > 0 )
				dbxEndODBC();
			initLevel = 0;
			return( CRYPT_OK );
		}

	retIntError();
	}
#endif /* USE_KEYSETS */

⌨️ 快捷键说明

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