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

📄 cryptacm.h

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 H
📖 第 1 页 / 共 3 页
字号:
*																			*
*						Key Management Mechanism ACL Handling				*
*																			*
****************************************************************************/

/* Key management ACL information.  These work in the same general way as the
   crypto mechanism ACL checks enforced by the kernel.  The ACL entries are:

	Valid keyset types for general access.
	Valid keyset types for query access.
	Valid keyset types for getNextCert access.
	Valid object types to write.
	Valid access types.
	Valid key management flags in the mechanism info.
	Access type for which an ID parameter is required.
	Access type for which a password (or other aux.info) is required

  The last two entries are used for parameter checking and represent all 
  access types for which these parameters are required, even if those 
  access types aren't currently allowed by the valid access types entry.  
  This is to allow them to be enabled by changing only the valid access 
  types entry without having to update the other two entries as well */

static const KEYMGMT_ACL keyManagementACL[] = {
	MK_KEYACL(				/* No item type */
		KEYMGMT_ITEM_NONE, ST_NONE, ST_NONE, ST_NONE, ST_NONE,
		ACCESS_KEYSET_xxxxx, KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_xxxxx, ACCESS_KEYSET_xxxxx ),
	MK_KEYACL(				/* Access public key */
		KEYMGMT_ITEM_PUBLICKEY,
		ST_KEYSET_ANY | ST_DEV_FORT | ST_DEV_P11,
		ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_KEYSET_LDAP,
		ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_KEYSET_FILE | ST_DEV_FORT,
		ST_CTX_PKC | ST_CERT_CERT | ST_CERT_CERTCHAIN | ST_CERT_ATTRCERT,
		ACCESS_KEYSET_FNRWD, KEYMGMT_FLAG_CHECK_ONLY | KEYMGMT_FLAG_LABEL_ONLY | \
			KEYMGMT_MASK_CERTOPTIONS,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),
	MK_KEYACL(				/* Access private key */
		KEYMGMT_ITEM_PRIVATEKEY,
		ST_KEYSET_FILE | ST_DEV_FORT | ST_DEV_P11, ST_NONE, ST_NONE,
		ST_CTX_PKC,
		ACCESS_KEYSET_xxRWD, KEYMGMT_FLAG_CHECK_ONLY | KEYMGMT_FLAG_LABEL_ONLY,
		ACCESS_KEYSET_xxRxD, ACCESS_KEYSET_xxXXx ),
	MK_KEYACL(				/* Access secret key */
		KEYMGMT_ITEM_SECRETKEY,
		ST_KEYSET_FILE, ST_NONE, ST_NONE,
		ST_CTX_CONV,
		ACCESS_KEYSET_xxRWD, KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_xxRxD, ACCESS_KEYSET_xxRWx ),
	MK_KEYACL(				/* Access cert request */
		KEYMGMT_ITEM_REQUEST,
		ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS_STORE, ST_NONE,
		ST_CERT_CERTREQ | ST_CERT_REQ_CERT | ST_CERT_REQ_REV,
		ACCESS_KEYSET_xxRWx, KEYMGMT_FLAG_UPDATE,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),
	MK_KEYACL(				/* Access PKI user info */
		KEYMGMT_ITEM_PKIUSER,
		ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS_STORE, ST_NONE,
		ST_CERT_PKIUSER,
		ACCESS_KEYSET_xxRWx, KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),
	MK_KEYACL(				/* Access revocation info/CRL */
		KEYMGMT_ITEM_REVOCATIONINFO,
		ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE, ST_NONE, ST_NONE,
		ST_CERT_CRL,
		ACCESS_KEYSET_xxRWx, KEYMGMT_FLAG_CHECK_ONLY,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),
	MK_KEYACL(				/* Other data (for PKCS #15 tokens) */
		KEYMGMT_ITEM_DATA,
		ST_KEYSET_FILE,
		ST_NONE, ST_NONE, ST_NONE,
		ACCESS_KEYSET_xxRWx, KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_xxRWD, ACCESS_KEYSET_FNxxx ),
	MK_KEYACL(				/* Last item type */
		KEYMGMT_ITEM_LAST, ST_NONE, ST_NONE, ST_NONE, ST_NONE,
		ACCESS_KEYSET_xxxxx, KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_xxxxx, ACCESS_KEYSET_xxxxx )
	};

/* It's a keyset action message, check the access conditions for the mechanism
   objects */

static int preDispatchCheckKeysetAccess( const int objectHandle,
										 const RESOURCE_MESSAGE_TYPE message,
										 const void *messageDataPtr,
										 const int messageValue,
										 const void *dummy )
	{
	const RESOURCE_MESSAGE_TYPE localMessage = message & RESOURCE_MESSAGE_MASK;
	const MESSAGE_KEYMGMT_INFO *mechanismInfo = \
		  ( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
	const KEYMGMT_ACL *keymgmtACL = \
		  &keyManagementACL[ messageValue ];
	const int accessType = \
			( localMessage == RESOURCE_MESSAGE_KEY_GETKEY ) ? ACCESS_FLAG_R : \
			( localMessage == RESOURCE_MESSAGE_KEY_SETKEY ) ? ACCESS_FLAG_W : \
			( localMessage == RESOURCE_MESSAGE_KEY_DELETEKEY ) ? ACCESS_FLAG_D : \
			( localMessage == RESOURCE_MESSAGE_KEY_GETFIRSTCERT ) ? ACCESS_FLAG_F : \
			( localMessage == RESOURCE_MESSAGE_KEY_GETNEXTCERT ) ? ACCESS_FLAG_N : 0;
	OBJECT_TYPE subType;

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );
	PRE( localMessage == RESOURCE_MESSAGE_KEY_GETKEY || \
		 localMessage == RESOURCE_MESSAGE_KEY_SETKEY || \
		 localMessage == RESOURCE_MESSAGE_KEY_DELETEKEY || \
		 localMessage == RESOURCE_MESSAGE_KEY_GETFIRSTCERT || \
		 localMessage == RESOURCE_MESSAGE_KEY_GETNEXTCERT );
	PRE( messageDataPtr != NULL );
	PRE( messageValue > KEYMGMT_ITEM_NONE && \
		 messageValue < KEYMGMT_ITEM_LAST );
	PRE( keymgmtACL->itemType == messageValue );
	PRE( accessType != 0 );

	/* Make sure the item type being accessed is appropriate for this keyset 
	   type, and that the access type is valid */
	subType = objectTable[ objectHandle ].subType;
	if( !isValidSubtype( keymgmtACL->keysetSubTypeA, subType ) && \
		!isValidSubtype( keymgmtACL->keysetSubTypeB, subType ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( !( keymgmtACL->allowedAccess & accessType ) )
		return( CRYPT_ARGERROR_OBJECT );

	/* If this is a non-general-purpose access, make sure it's allowed for 
	   this keyset type */
	if( localMessage == RESOURCE_MESSAGE_KEY_GETFIRSTCERT || \
		localMessage == RESOURCE_MESSAGE_KEY_GETNEXTCERT )
		{
		/* The two special-purpose accesses are differentiated by whether
		   there's state information provided, for a general query the result
		   set is determined by an initially-submitted query which is 
		   followed by a sequence of fetches, for a getFirst/getNext the
		   results are determined by a cert identifier with state held
		   externally in the location pointed to by the auxiliary info 
		   pointer */
		if( mechanismInfo->auxInfo == NULL )
			{
			/* Keyset query.  We report this as an arg error since we'll 
			   have been passed a CRYPT_KEYID_NONE or empty keyID, this is 
			   more sensible than an object error since there's nothing 
			   wrong with the object, the problem is that there's no keyID 
			   present */
			if( !isValidSubtype( keymgmtACL->querySubTypeA, subType ) && \
				!isValidSubtype( keymgmtACL->querySubTypeB, subType ) )
				return( ( mechanismInfo->keyIDtype == CRYPT_KEYID_NONE ) ? \
						CRYPT_ARGERROR_NUM1 : CRYPT_ARGERROR_STR1 );
			}
		else
			{
			/* getFirst/next.  We can report an object error here since this
			   message is only sent internally */
			if( !isValidSubtype( keymgmtACL->getNextSubTypeA, subType ) && \
				!isValidSubtype( keymgmtACL->getNextSubTypeB, subType ) )
				return( CRYPT_ARGERROR_OBJECT );

			/* Inner precondition: The state information points to an 
			   integer value containing a reference to the currently 
			   fetched object */
			PRE( mechanismInfo->auxInfo != NULL && \
				 mechanismInfo->auxInfoLength == sizeof( int ) );
			}
		}

	/* Make sure there's ID information present if required */
	if( keymgmtACL->idUseFlags & accessType )
		{
		if( mechanismInfo->keyIDtype == CRYPT_KEYID_NONE )
			return( CRYPT_ARGERROR_NUM1 );
		if( mechanismInfo->keyID == NULL || mechanismInfo->keyIDlength < 1 )
			return( CRYPT_ARGERROR_STR1 );
		}

	/* Make sure there's a password present/not present if required.  We 
	   only check for incorrect parameters here if they were supplied by the 
	   user, non-user-supplied parameters (which come from within cryptlib) 
	   are checked by an assertion later on.  For keyset objects the 
	   password is optional on reads since it may be a label-only read or an 
	   opportunistic read which tries to read the key without a password
	   initially and falls back to retrying with a password if this fails,
	   for device objects the password is never used since it was supplied
	   when the user logged on to the device.
	   
	   Since the semantics of passwords for private keys are too complex to 
	   express with a simple ACL entry, this check is hardcoded */
	if( messageValue == KEYMGMT_ITEM_PRIVATEKEY )
		if( objectTable[ objectHandle ].type == OBJECT_TYPE_KEYSET )
			{
			if( localMessage == RESOURCE_MESSAGE_KEY_SETKEY && \
				( mechanismInfo->auxInfo == NULL || \
				  mechanismInfo->auxInfoLength < 1 ) )
				/* Private key writes to a keyset must provide a password */
				return( CRYPT_ARGERROR_STR1 );
			}
		else
			if( ( mechanismInfo->auxInfo != NULL || \
				  mechanismInfo->auxInfoLength != 0 ) )
				/* Private key access to a device doesn't use a password */
				return( ( keymgmtACL->idUseFlags & accessType ) ? \
						CRYPT_ARGERROR_STR2 : CRYPT_ARGERROR_STR1 );

	/* Inner precondition: Only allowed flags are set, there's only one of 
	   the usage preference flags set, and the object handle to get/set is
	   not present if required (the presence and validity check when it is
	   required is performed further down) */
	PRE( !( ~keymgmtACL->allowedFlags & mechanismInfo->flags ) );
	PRE( mechanismInfo->flags >= KEYMGMT_FLAG_NONE && \
		 mechanismInfo->flags < KEYMGMT_FLAG_LAST );
	PRE( ( mechanismInfo->flags & KEYMGMT_MASK_USAGEOPTIONS ) != \
		 KEYMGMT_MASK_USAGEOPTIONS );
	PRE( localMessage == RESOURCE_MESSAGE_KEY_SETKEY || \
		 mechanismInfo->cryptHandle == CRYPT_ERROR );

	/* Inner precondition: There's ID information and a password/aux.data 
	   present/not present as required.  For a private key read the password
	   is optional so we don't check it, for a getFirst/getNext the aux.data
	   (a pointer to query state) is used when assembling a cert chain (state
	   held in the cert) and not used when performing a general query (state
	   held in the keyset) */
	PRE( ( ( keymgmtACL->idUseFlags & accessType ) && \
		   mechanismInfo->keyIDtype != CRYPT_KEYID_NONE && \
		   mechanismInfo->keyID != NULL && \
		   mechanismInfo->keyIDlength >= 1 ) || 
		 ( !( keymgmtACL->idUseFlags & accessType ) && \
		   mechanismInfo->keyIDtype == CRYPT_KEYID_NONE && \
		   mechanismInfo->keyID == NULL && \
		   mechanismInfo->keyIDlength == 0 ) );
	PRE( ( messageValue == KEYMGMT_ITEM_PRIVATEKEY && \
		   localMessage == RESOURCE_MESSAGE_KEY_GETKEY ) || 
		 localMessage == RESOURCE_MESSAGE_KEY_GETFIRSTCERT ||
		 localMessage == RESOURCE_MESSAGE_KEY_GETNEXTCERT ||
		 ( ( keymgmtACL->pwUseFlags & accessType ) && \
		   mechanismInfo->auxInfo != NULL && \
		   mechanismInfo->auxInfoLength >= 1 ) || 
		 ( !( keymgmtACL->pwUseFlags & accessType ) && \
		   mechanismInfo->auxInfo == NULL && \
		   mechanismInfo->auxInfoLength == 0 ) );

	/* Perform message-type-specific checking of parameters */
	switch( localMessage )
		{
		case RESOURCE_MESSAGE_KEY_GETKEY:
			break;

		case RESOURCE_MESSAGE_KEY_SETKEY:
			/* Make sure the object being sent is valid and its type is 
			   appropriate for this item (and via previous checks, keyset) 
			   type */
			if( !isValidObject( mechanismInfo->cryptHandle ) )
				return( CRYPT_ARGERROR_NUM1 );
			if( !isSameOwner( objectHandle, mechanismInfo->cryptHandle ) )
				return( CRYPT_ARGERROR_NUM1 );
			subType = objectTable[ mechanismInfo->cryptHandle ].subType;
			if( !isValidSubtype( keymgmtACL->objSubTypeA, subType ) && \
				!isValidSubtype( keymgmtACL->objSubTypeB, subType ) )
				{
				int altCryptHandle;

				/* If we're only allowed to add contexts, this could be a
				   cert object with an associated context, in which case
				   we look for an associated context and try again */
				if( keymgmtACL->objSubTypeA != ST_CTX_PKC )
					return( CRYPT_ARGERROR_NUM1 );
				altCryptHandle = findTargetType( mechanismInfo->cryptHandle, 
												 OBJECT_TYPE_CONTEXT );
				if( cryptStatusError( altCryptHandle ) || \
					objectTable[ altCryptHandle ].subType != ST_CTX_PKC )
					return( CRYPT_ARGERROR_NUM1 );
				}
			break;

		case RESOURCE_MESSAGE_KEY_DELETEKEY:
			break;

		case RESOURCE_MESSAGE_KEY_GETFIRSTCERT:
			break;

		case RESOURCE_MESSAGE_KEY_GETNEXTCERT:
			break;

		default:
			assert( NOTREACHED );
		}

	/* Postcondition: The access and parameters are valid and the object 
	   being passed in is of the correct type if present.  We don't 
	   explicitly state this since it's just regurgitating the checks 
	   already performed above */

	return( CRYPT_OK );
	}
#endif /* _CRYPTACM_DEFINED */

⌨️ 快捷键说明

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