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

📄 cryptdbx.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
			return( CRYPT_ERROR_INCOMPLETE );

		/* Items in a cert store can be expired or revoked by never directly
		   deleted */
		if( keysetInfoPtr->keysetDBMS.isCertStore )
			unlockResourceExit( keysetInfoPtr, CRYPT_ERROR_PERMISSION );

		/* If we've been passed a full issuerAndSerialNumber as a key ID and 
		   the keyset needs an issuerID, convert it */
		if( keyIDtype == CRYPT_IKEYID_ISSUERANDSERIALNUMBER && \
			( keysetInfoPtr->type == KEYSET_DBMS || \
			  ( keysetInfoPtr->type == KEYSET_FILE && \
			    keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 ) ) )
			{
			HASHFUNCTION hashFunction;
			int hashSize;

			/* Get the hash algorithm information */
			getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );

			/* Hash the full iAndS to get an issuerID and use that for the keyID */
			hashFunction( NULL, keyIDbuffer, ( BYTE * ) keyID, keyIDlength, 
						  HASH_ALL );
			keyIDtype = CRYPT_IKEYID_ISSUERID;
			keyID = keyIDbuffer;
			keyIDlength = hashSize;
			}

		/* Delete the key */
		status = keysetInfoPtr->deleteItemFunction( keysetInfoPtr, 
													messageValue, keyIDtype, 
													keyID, keyIDlength );
		if( cryptStatusOK( status ) )
			/* The update succeeded, remember that the data in the keyset has 
			   changed */
			keysetInfoPtr->isDirty = TRUE;
		unlockResourceExit( keysetInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_GETFIRSTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status;

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

		/* Make sure we can query this keyset type */
		if( keysetInfoPtr->getFirstItemFunction == NULL )
			unlockResourceExit( keysetInfoPtr, CRYPT_ERROR_NOTAVAIL );

		/* Fetch the first cert in a sequence from the keyset */
		status = keysetInfoPtr->getFirstItemFunction( keysetInfoPtr,
						&getnextcertInfo->cryptHandle, getnextcertInfo->auxInfo,
						getnextcertInfo->keyIDtype, getnextcertInfo->keyID, 
						getnextcertInfo->keyIDlength, messageValue,
						getnextcertInfo->flags );
		unlockResourceExit( keysetInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_GETNEXTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status;

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

		/* Make sure we can query this keyset type */
		if( keysetInfoPtr->getFirstItemFunction == NULL )
			unlockResourceExit( keysetInfoPtr, CRYPT_ERROR_NOTAVAIL );

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

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

		/* Make sure the access is valid for this keyset type */
		if( keysetInfoPtr->certMgmtFunction == NULL )
			unlockResourceExit( keysetInfoPtr, CRYPT_ERROR_NOTAVAIL );

		/* If we're in the middle of a query, we can't do anything else */
		if( keysetInfoPtr->queryInProgress )
			return( CRYPT_ERROR_INCOMPLETE );

		/* Perform the cert management operation */
		status = keysetInfoPtr->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->isDirty = TRUE;
		unlockResourceExit( keysetInfoPtr, 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 char *param,
					   const CRYPT_KEYOPT_TYPE options,
					   KEYSET_INFO **keysetInfoPtrPtr )
	{
	KEYSET_INFO *keysetInfoPtr;
	const int subType = \
		( keysetType == CRYPT_KEYSET_FILE ) ? SUBTYPE_KEYSET_FILE : \
		( keysetType == CRYPT_KEYSET_HTTP ) ? SUBTYPE_KEYSET_HTTP : \
		( keysetType == CRYPT_KEYSET_LDAP ) ? SUBTYPE_KEYSET_LDAP : \
		( keysetType == CRYPT_KEYSET_MYSQL || \
		  keysetType == CRYPT_KEYSET_ODBC || \
		  keysetType == CRYPT_KEYSET_DATABASE ) ? SUBTYPE_KEYSET_DBMS : \
		SUBTYPE_KEYSET_DBMS_STORE;
	int status;

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

	/* Perform general checks which can be done before we create the object */
	if( ( subType == SUBTYPE_KEYSET_HTTP && \
		  options != CRYPT_KEYOPT_READONLY ) || \
		( subType == SUBTYPE_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 );

	/* Wait for any async keyset driver binding to complete */
	waitSemaphore( SEMAPHORE_DRIVERBIND );

	/* Create the keyset object */
	status = krnlCreateObject( ( void ** ) &keysetInfoPtr, cryptOwner,
							   OBJECT_TYPE_KEYSET, subType,
							   sizeof( KEYSET_INFO ), 0, 0, 
							   keysetMessageFunction );
	if( cryptStatusError( status ) )
		return( status );
	initResourceLock( keysetInfoPtr ); 
	lockResource( keysetInfoPtr ); 
	*keysetInfoPtrPtr = keysetInfoPtr;
	*iCryptKeyset = keysetInfoPtr->objectHandle = status;
	keysetInfoPtr->ownerHandle = cryptOwner;
	keysetInfoPtr->options = options;

	/* If it's a flat-file keyset, open a handle to it */
	if( keysetType == CRYPT_KEYSET_FILE )
		{
		int openMode;

		keysetInfoPtr->type = KEYSET_FILE;

		/* Remember the key file's name */
		if( strlen( name ) > MAX_PATH_LENGTH - 1 )
			return( CRYPT_ARGERROR_STR1 );
		strcpy( keysetInfoPtr->keysetFile.fileName, name );

		/* If the file is read-only, put the keyset into read-only mode.  We
		   have to perform this test before we try to open it because some
		   OS's don't allow a file to be reopened for write access when it's
		   already open, and it's better to have it appear read-only than
		   not at all */
		if( fileReadonly( name ) )
			{
			/* If we want to create a new file, we can't do it if we don't
			   have write permission */
			if( options == CRYPT_KEYOPT_CREATE )
				return( CRYPT_ERROR_PERMISSION );

			/* Open the file in readonly mode */
			keysetInfoPtr->options = CRYPT_KEYOPT_READONLY;
			openMode = FILE_READ;
			}
		else
			/* If we're creating the file, open it in write-only mode.  Since
			   we'll (presumably) be storing private keys in it, we mark it 
			   as both private (owner-access-only ACL) and sensitive (store 
			   in secure storage if possible) */
			if( options == CRYPT_KEYOPT_CREATE )
				openMode = FILE_WRITE | FILE_EXCLUSIVE_ACCESS | \
						   FILE_PRIVATE | FILE_SENSITIVE;
			else
				/* Open it for read or read/write depending on whether the
				   readonly flag is set */
				openMode = ( options != CRYPT_KEYOPT_READONLY ) ? \
						   FILE_READ | FILE_WRITE : FILE_READ;
		if( options == CRYPT_IKEYOPT_EXCLUSIVEACCESS )
			openMode |= FILE_EXCLUSIVE_ACCESS;

		/* Pre-open the file containing the keyset.  This initially opens it
		   in read-only mode for auto-detection of the file type so we can
		   check for various problems (eg trying to open a non-writeable file
		   format type for write access) */
		status = sFileOpen( &keysetInfoPtr->keysetFile.stream, name,
							FILE_READ );
		if( cryptStatusError( status ) )
			{
			/* The file doesn't exit, if the create flag isn't set return an
			   error */
			if( options != CRYPT_KEYOPT_CREATE )
				return( status );

			/* Try and create a new file */
			status = sFileOpen( &keysetInfoPtr->keysetFile.stream, name,
								openMode );
			if( cryptStatusError( status ) )
				return( status );
			keysetInfoPtr->subType = KEYSET_SUBTYPE_PKCS15;
			setAccessMethodPKCS15( keysetInfoPtr );
			}
		else
			{
			/* The file exists, get its type */
			keysetInfoPtr->subType = getKeysetType( &keysetInfoPtr->keysetFile.stream );
			if( keysetInfoPtr->subType == KEYSET_SUBTYPE_ERROR )
				/* If we're creating a new keyset and there's already 
				   something there, make it look like a cryptlib keyset so 
				   it'll get overwritten later */
				if( options == CRYPT_KEYOPT_CREATE )
					keysetInfoPtr->subType = KEYSET_SUBTYPE_PKCS15;
				else
					{
					/* "It doesn't look like anything from here" */
					sFileClose( &keysetInfoPtr->keysetFile.stream );
					return( CRYPT_ERROR_BADDATA );
					}

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

				case KEYSET_SUBTYPE_PKCS15:
					setAccessMethodPKCS15( keysetInfoPtr );
					break;

				case KEYSET_SUBTYPE_PGP_PUBLIC:
				case KEYSET_SUBTYPE_PGP_PRIVATE:
					setAccessMethodPGP( keysetInfoPtr );
					break;

				default:
					assert( NOTREACHED );
				}

			/* If it's a cryptlib keyset we can open it in any mode */
			if( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 )
				{
				/* If we're opening it something other than readonly mode, 
				   reopen it in that mode */
				if( openMode != FILE_READ )
					{
					sFileClose( &keysetInfoPtr->keysetFile.stream );
					status = sFileOpen( &keysetInfoPtr->keysetFile.stream, 
										name, openMode );
					if( cryptStatusError( status ) )
						return( status );	/* Exit with file closed */
					}
				}
			else
				/* If it's a non-cryptlib keyset we can't open it for 
				   anything other than read-only access */
				if( options != CRYPT_KEYOPT_READONLY )
					status = CRYPT_ERROR_PERMISSION;
			}
		if( cryptStatusOK( status ) )
			status = keysetInfoPtr->initFunction( keysetInfoPtr, NULL, NULL, 
												  options );
		if( cryptStatusError( status ) )
			{
			sFileClose( &keysetInfoPtr->keysetFile.stream );
			return( status );
			}
		if( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 && \
			openMode == FILE_READ )
			/* If we've got the keyset open in read-only mode we don't need
			   to touch it again so we can close the file stream */
			sFileClose( &keysetInfoPtr->keysetFile.stream );
		keysetInfoPtr->isOpen = TRUE;
		if( options == CRYPT_KEYOPT_CREATE )
			keysetInfoPtr->isEmpty = TRUE;
		return( CRYPT_OK );
		}

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

		case CRYPT_KEYSET_HTTP:
			keysetInfoPtr->type = KEYSET_HTTP;
			status = setAccessMethodHTTP( keysetInfoPtr );
			break;

		case CRYPT_KEYSET_LDAP:
			keysetInfoPtr->type = KEYSET_LDAP;
			status = setAccessMethodLDAP( keysetInfoPtr );
			break;

		default:
			assert( NOTREACHED );
		}
	if( cryptStatusOK( status ) )
		{
		assert( keysetInfoPtr->initFunction != NULL );
		assert( keysetInfoPtr->getItemFunction != NULL );

		status = keysetInfoPtr->initFunction( keysetInfoPtr, name, param, 
											  options );
		}
	if( cryptStatusError( status ) )
		return( status );
	keysetInfoPtr->isOpen = TRUE;
	if( options == CRYPT_KEYOPT_CREATE )
		keysetInfoPtr->isEmpty = TRUE;
	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 ];
	char argBuffer[ MAX_ATTRIBUTE_SIZE + 1 ], *argBufPtr = NULL;
	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 < 2 || \
		createInfo->strArgLen1 >= MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ARGERROR_STR1 );
	memcpy( nameBuffer, createInfo->strArg1, createInfo->strArgLen1 );
	nameBuffer[ createInfo->strArgLen1 ] = '\0';
	if( createInfo->strArgLen2 > 0 )
		{
		if( createInfo->strArgLen2 < 2 || \
			createInfo->strArgLen2 >= MAX_ATTRIBUTE_SIZE )
			return( CRYPT_ARGERROR_STR2 );
		memcpy( argBuffer, createInfo->strArg2, createInfo->strArgLen1 );
		argBuffer[ createInfo->strArgLen1 ] = '\0';
		argBufPtr = argBuffer;
		}
	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, argBufPtr, options, 
							 &keysetInfoPtr );
	if( keysetInfoPtr == NULL )
		return( initStatus );	/* Create object failed, return immediately */
	if( cryptStatusError( initStatus ) )
		/* The keyset open failed, make sure the object gets destroyed when 
		   we notify the kernel that the setup process is complete */
		krnlSendNotifier( iCryptKeyset, RESOURCE_IMESSAGE_DESTROY );

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

⌨️ 快捷键说明

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