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

📄 cryptdbx.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
				getnextcertInfo->auxInfoLength == sizeof( int ) );

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

		assert( keysetInfoPtr->getNextItemFunction != NULL );
		assert( getnextcertInfo->keyIDtype == CRYPT_KEYID_NONE && \
				getnextcertInfo->keyID == NULL && \
				getnextcertInfo->keyIDlength == 0 );
		assert( getnextcertInfo->auxInfo == NULL || \
				getnextcertInfo->auxInfoLength == sizeof( int ) );

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

		assert( keysetInfoPtr->keysetDBMS->certMgmtFunction != NULL );
		assert( messageValue >= CRYPT_CERTACTION_CERT_CREATION && \
				messageValue <= CRYPT_CERTACTION_LAST_USER );
		assert( keysetInfoPtr->isBusyFunction != NULL );

		/* Perform the cert management operation */
		status = initKeysetUpdate( keysetInfoPtr, NULL, NULL, TRUE );
		if( cryptStatusOK( 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 );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

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

static int openKeyset( CRYPT_KEYSET *iCryptKeyset,
					   const CRYPT_USER cryptOwner,
					   const CRYPT_KEYSET_TYPE keysetType,
					   const char *name, const CRYPT_KEYOPT_TYPE options,
					   KEYSET_INFO **keysetInfoPtrPtr )
	{
	KEYSET_INFO *keysetInfoPtr;
	STREAM stream;
	CRYPT_KEYOPT_TYPE localOptions = options;
	KEYSET_SUBTYPE keysetSubType;
	int subType, storageSize, status;

	/* 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 && \
		strlen( name ) > 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:
			assert( NOTREACHED );
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* 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 )
		{
		status = openKeysetStream( &stream, name, options, &localOptions, 
								   &keysetSubType );
		if( cryptStatusError( status ) )
			return( status );
		
		/* If the keyset contains the full set of search keys and index
		   information needed to handle all keyset operations (e.g. cert 
		   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( ( void ** ) &keysetInfoPtr, 
							   sizeof( KEYSET_INFO ) + storageSize, 
							   OBJECT_TYPE_KEYSET, subType, 
							   CREATEOBJECT_FLAG_NONE, cryptOwner, 
							   ACTION_PERM_NONE_ALL, keysetMessageFunction );
	if( cryptStatusError( status ) )
		{
		if( keysetType == CRYPT_KEYSET_FILE )
			sFileClose( &stream );
		return( status );
		}
	*keysetInfoPtrPtr = keysetInfoPtr;
	*iCryptKeyset = keysetInfoPtr->objectHandle = status;
	keysetInfoPtr->ownerHandle = cryptOwner;
	keysetInfoPtr->options = localOptions;
	switch( keysetType )
		{
		case CRYPT_KEYSET_FILE:
			keysetInfoPtr->type = KEYSET_FILE;
			keysetInfoPtr->keysetFile = ( FILE_INFO * ) keysetInfoPtr->storage;
			break;

		case CRYPT_KEYSET_HTTP:
			keysetInfoPtr->type = KEYSET_HTTP;
			keysetInfoPtr->keysetHTTP = ( HTTP_INFO * ) keysetInfoPtr->storage;
			break;

		case CRYPT_KEYSET_LDAP:
			keysetInfoPtr->type = KEYSET_LDAP;
			keysetInfoPtr->keysetLDAP = ( LDAP_INFO * ) keysetInfoPtr->storage;
			break;

		default:
			keysetInfoPtr->type = KEYSET_DBMS;
			keysetInfoPtr->keysetDBMS = ( DBMS_INFO * ) keysetInfoPtr->storage;
			break;
		}
	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 )
		{
		/* Remember the key file's name and I/O stream */
		keysetInfoPtr->subType = keysetSubType;
		strcpy( keysetInfoPtr->keysetFile->fileName, name );
		keysetInfoPtr->keysetFile->stream = stream;

		/* Set up the access information for the file */
		switch( keysetInfoPtr->subType )
			{
			case KEYSET_SUBTYPE_PKCS12:
				status = setAccessMethodPKCS12( keysetInfoPtr );
				break;

			case KEYSET_SUBTYPE_PKCS15:
				status = setAccessMethodPKCS15( keysetInfoPtr );
				break;

			case KEYSET_SUBTYPE_PGP_PUBLIC:
				status = setAccessMethodPGPPublic( keysetInfoPtr );
				break;

			case KEYSET_SUBTYPE_PGP_PRIVATE:
				status = setAccessMethodPGPPrivate( keysetInfoPtr );
				break;

			default:
				assert( NOTREACHED );
				status = CRYPT_ERROR;
			}
		if( cryptStatusOK( status ) )
			{
			BYTE buffer[ STREAM_BUFSIZE ];

			assert( keysetInfoPtr->initFunction != NULL && \
					keysetInfoPtr->getItemFunction != NULL );
			assert( subType != SUBTYPE_KEYSET_FILE || \
					( keysetInfoPtr->setItemFunction != NULL && \
					  keysetInfoPtr->deleteItemFunction != NULL && \
					  keysetInfoPtr->getFirstItemFunction != NULL && \
					  keysetInfoPtr->getNextItemFunction != NULL ) );

			sioctl( &keysetInfoPtr->keysetFile->stream, 
					STREAM_IOCTL_IOBUFFER, buffer, STREAM_BUFSIZE );
			status = keysetInfoPtr->initFunction( keysetInfoPtr, NULL,
												  keysetInfoPtr->options );
			sioctl( &keysetInfoPtr->keysetFile->stream, 
					STREAM_IOCTL_IOBUFFER, NULL, 0 );
			}
		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 );
			}
		if( ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS12 || \
			  keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 || \
			  keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE ) && \
			( keysetInfoPtr->options == CRYPT_KEYOPT_READONLY ) )
			/* If we've got the keyset open in read-only mode we don't need 
			   to touch it again since everything is cached in-memory, so we 
			   can close the file stream */
			sFileClose( &keysetInfoPtr->keysetFile->stream );
		else
			keysetInfoPtr->flags |= KEYSET_STREAM_OPEN;
		keysetInfoPtr->flags |= KEYSET_OPEN;
		if( keysetInfoPtr->options == CRYPT_KEYOPT_CREATE )
			keysetInfoPtr->flags |= KEYSET_EMPTY;
		return( CRYPT_OK );
		}

	/* Wait for any async keyset driver binding to complete.  We do this as 
	   late as possible to prevent file keyset reads on startup (for example
	   to get config options) from stalling the startup process */
	waitSemaphore( SEMAPHORE_DRIVERBIND );

	/* 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:
			assert( NOTREACHED );
		}
	if( cryptStatusOK( status ) )
		{
		assert( keysetInfoPtr->initFunction != NULL && \
				keysetInfoPtr->getItemFunction != NULL );
		assert( keysetType == CRYPT_KEYSET_HTTP || \
				( keysetInfoPtr->setItemFunction != NULL && \
				  keysetInfoPtr->deleteItemFunction != NULL && \
				  keysetInfoPtr->isBusyFunction != NULL ) );
		assert( keysetType == CRYPT_KEYSET_HTTP || \
				keysetType == CRYPT_KEYSET_LDAP || \
				( keysetInfoPtr->getFirstItemFunction != NULL && \
				  keysetInfoPtr->getNextItemFunction != NULL ) );

		status = keysetInfoPtr->initFunction( keysetInfoPtr, name, 
											  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 */

int createKeyset( MESSAGE_CREATEOBJECT_INFO *createInfo,
				  const void *auxDataPtr, const int auxValue )
	{
	CRYPT_KEYSET iCryptKeyset;
	const CRYPT_KEYSET_TYPE keysetType = createInfo->arg1;
	const CRYPT_KEYOPT_TYPE options = createInfo->arg2;
	KEYSET_INFO *keysetInfoPtr;
	char nameBuffer[ MAX_ATTRIBUTE_SIZE + 1 ];
	int initStatus, status;

	assert( auxDataPtr == NULL );
	assert( auxValue == 0 );

	/* Perform basic error checking */
	if( keysetType <= CRYPT_KEYSET_NONE || keysetType >= CRYPT_KEYSET_LAST )
		return( CRYPT_ARGERROR_NUM1 );
	if( createInfo->strArgLen1 < MIN_NAME_LENGTH || \
		createInfo->strArgLen1 >= MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ARGERROR_STR1 );
	memcpy( nameBuffer, createInfo->strArg1, createInfo->strArgLen1 );
	nameBuffer[ createInfo->strArgLen1 ] = '\0';
	if( options < CRYPT_KEYOPT_NONE || options >= CRYPT_KEYOPT_LAST )
		/* CRYPT_KEYOPT_NONE is a valid setting for this parameter */
		return( CRYPT_ARGERROR_NUM2 );

	/* Pass the call on to the lower-level open function */
	initStatus = openKeyset( &iCryptKeyset, createInfo->cryptOwner,
							 keysetType, nameBuffer, options,
							 &keysetInfoPtr );
	if( keysetInfoPtr == NULL )
		return( initStatus );	/* Create object failed, return immediately */
	if( cryptStatusError( 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 */

int keysetManagementFunction( const MANAGEMENT_ACTION_TYPE action )
	{
	static int initLevel = 0;
	int status;

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

	switch( action )
		{
		case MANAGEMENT_ACTION_INIT:
			status = dbxInitODBC();
			if( cryptStatusOK( status ) )
				{
				initLevel++;
				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 );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}
#endif /* USE_KEYSETS */

⌨️ 快捷键说明

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