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

📄 key_acl.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*									Keyset ACLs								*
*						Copyright Peter Gutmann 1997-2004					*
*																			*
****************************************************************************/

#if defined( INC_ALL )
  #include "crypt.h"
  #include "acl.h"
  #include "kernel.h"
#else
  #include "crypt.h"
  #include "kernel/acl.h"
  #include "kernel/kernel.h"
#endif /* Compiler-specific includes */

/* A pointer to the kernel data block */

static KERNEL_DATA *krnlData = NULL;

/****************************************************************************
*																			*
*									Keyset ACLs								*
*																			*
****************************************************************************/

/* ID information.  This defines the ID types that are valid for retrieving
   each object type;

	Public/private keys: Any ID is valid.  There's some overlap here because 
		in some cases the private key is retrieved by first locating the
		corresponding public key (which is what the ID actually points to)
		and then using that to find the matching private key.

	Secret keys: Only lookups by name or keyID are possible (all other ID
		types are PKC-related).

	Cert requests: Lookups by name or URI are allowed for the user-level 
		CACertManagement() functions, lookups by certID are used for 
		cryptlib-internal access.

	PKI users: Lookups by name or URI are allowed for the user-level 
		CACertManagement() functions, lookups by keyID and certID are used 
		for cryptlib-internal access.  PKI users don't really have a keyID
		in the sense of a subjectKeyIdentifier, in this case it's a 
		randomly-generated value that's unique for each PKI user.

	Revocation info: Lookups by certID and issuerID are used for cryptlib-
		internal access.

	Data: No ID is used, data objects are implicitly identified by type */

static const CRYPT_KEYID_TYPE pubKeyIDs[] = { 
		CRYPT_KEYID_NAME, CRYPT_KEYID_URI, CRYPT_IKEYID_KEYID, 
		CRYPT_IKEYID_PGPKEYID, CRYPT_IKEYID_CERTID, CRYPT_IKEYID_ISSUERID,
		CRYPT_IKEYID_ISSUERANDSERIALNUMBER, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE privKeyIDs[] = { 
		CRYPT_KEYID_NAME, CRYPT_KEYID_URI, CRYPT_IKEYID_KEYID, 
		CRYPT_IKEYID_PGPKEYID, CRYPT_IKEYID_CERTID, CRYPT_IKEYID_ISSUERID,
		CRYPT_IKEYID_ISSUERANDSERIALNUMBER, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE secKeyIDs[] = { 
		CRYPT_KEYID_NAME, CRYPT_IKEYID_KEYID, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE certReqIDs[] = { 
		CRYPT_KEYID_NAME, CRYPT_KEYID_URI, CRYPT_IKEYID_CERTID, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE pkiUserIDs[] = { 
		CRYPT_KEYID_NAME, CRYPT_KEYID_URI, CRYPT_IKEYID_KEYID,
		CRYPT_IKEYID_CERTID, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE revInfoIDs[] = { 
		CRYPT_IKEYID_CERTID, CRYPT_IKEYID_ISSUERID, 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };
static const CRYPT_KEYID_TYPE dataIDs[] = { 
		CRYPT_KEYID_NONE, CRYPT_KEYID_NONE };

/* 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 R/W/D access.
	Valid keyset types for getFirst/Next access.
	Valid keyset types for query access.
	Valid object types to write.
	Valid key IDs for read/getFirst/query access.
	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
	[ Specific object types requires for some keyset types ]

  The access-type 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.

  In addition, there are a few access types (specifically getFirst/Next and
  private key reads) for which the semantics of password/aux info use are
  complex enough that we have to hardcode them, leaving only a
  representative entry in the ACL definition.  Examples of this are keyset
  vs. crypto device reads (keysets usually need passwords while a logged-
  in device doesn't), speculative reads from the keyset to determine
  presence (which don't require a password), and so on.

  The key ID values are the union of the key ID types that are valid for
  all of the keysets that can store the given object type.  These are
  used to implement a two-level check, first the main ACL checks whether
  this ID type is valid for this object type, and then a secondary ACL
  is used to determine whether the ID type is valid for the source that
  the object is being read from.

  The (optional) specific object types entry is required for some keysets
  that require a specific object (typically a certificate or cert chain)
  rather than just a generic PKC context for the overall keyset item type */

static const KEYMGMT_ACL FAR_BSS keyManagementACL[] = {
	/* Access public key */
	MK_KEYACL_EX( KEYMGMT_ITEM_PUBLICKEY,
		/* R */	ST_KEYSET_ANY | ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* W */	ST_KEYSET_FILE | ST_KEYSET_DBMS | ST_KEYSET_LDAP | \
				ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* D */	ST_KEYSET_FILE | ST_KEYSET_DBMS | ST_KEYSET_LDAP | \
				ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* Fn*/	ST_KEYSET_FILE | ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | \
				ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* Q */	ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_KEYSET_LDAP,
		/*Obj*/	ST_CTX_PKC | ST_CERT_CERT | ST_CERT_CERTCHAIN,
		/*IDs*/	pubKeyIDs,
		/*Flg*/	KEYMGMT_FLAG_CHECK_ONLY | KEYMGMT_FLAG_LABEL_ONLY | KEYMGMT_MASK_CERTOPTIONS,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx,
		ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_KEYSET_LDAP | \
						 ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		ST_CERT_CERT | ST_CERT_CERTCHAIN ),

	/* Access private key */
	MK_KEYACL_RWD( KEYMGMT_ITEM_PRIVATEKEY,
		/* R */	ST_KEYSET_FILE | ST_KEYSET_FILE_PARTIAL | ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* W */	ST_KEYSET_FILE | ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/* D */	ST_KEYSET_FILE | ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI,
		/*FnQ*/	ST_NONE, ST_NONE,
		/*Obj*/	ST_CTX_PKC,
		/*IDs*/	privKeyIDs,
		/*Flg*/	KEYMGMT_FLAG_CHECK_ONLY | KEYMGMT_FLAG_LABEL_ONLY | KEYMGMT_MASK_USAGEOPTIONS,
		ACCESS_KEYSET_xxRxD, ACCESS_KEYSET_xxXXx ),

	/* Access secret key */
	MK_KEYACL( KEYMGMT_ITEM_SECRETKEY,
		/*RWD*/	ST_KEYSET_FILE | ST_DEV_P11,
		/*FnQ*/	ST_NONE,
		/*Obj*/	ST_CTX_CONV,
		/*IDs*/	secKeyIDs,
		/*Flg*/	KEYMGMT_FLAG_CHECK_ONLY,
		ACCESS_KEYSET_xxRxD, ACCESS_KEYSET_xxXXx ),

	/* Access cert request */
	MK_KEYACL_RWD( KEYMGMT_ITEM_REQUEST,
		/*RWD*/	ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS_STORE, ST_NONE,
		/*FnQ*/	ST_NONE, ST_KEYSET_DBMS_STORE,
		/*Obj*/	ST_CERT_CERTREQ | ST_CERT_REQ_CERT | ST_CERT_REQ_REV,
		/*IDs*/	certReqIDs,
		/*Flg*/	KEYMGMT_FLAG_UPDATE,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),

	/* Access PKI user info */
	MK_KEYACL_RWD( KEYMGMT_ITEM_PKIUSER,
		/*RWD*/	ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS_STORE,
		/*FnQ*/	ST_NONE, ST_NONE,
		/*Obj*/	ST_CERT_PKIUSER,
		/*IDs*/	pkiUserIDs,
		/*Flg*/	KEYMGMT_FLAG_GETISSUER,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),

	/* Access revocation info/CRL */
	MK_KEYACL_RWD( KEYMGMT_ITEM_REVOCATIONINFO,
		/*RWD*/	ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE, ST_KEYSET_DBMS, ST_NONE,
		/*FnQ*/	ST_NONE, ST_NONE,
		/*Obj*/	ST_CERT_CRL,
		/*IDs*/	revInfoIDs,
		/*Flg*/	KEYMGMT_FLAG_CHECK_ONLY,
		ACCESS_KEYSET_FxRxD, ACCESS_KEYSET_FNxxx ),

	/* Other data (for PKCS #15 tokens) */
	MK_KEYACL_RWD( KEYMGMT_ITEM_DATA,
		/*RWD*/	ST_KEYSET_FILE, ST_KEYSET_FILE, ST_NONE,
		/*FnQ*/	ST_NONE, ST_NONE,
		/*Obj*/	ST_NONE,
		/*IDs*/	dataIDs,
		/*Flg*/	KEYMGMT_FLAG_NONE,
		ACCESS_KEYSET_xxRWD, ACCESS_KEYSET_FNxxx ),

	/* Last item type */
	MK_KEYACL( KEYMGMT_ITEM_NONE, ST_NONE, ST_NONE, ST_NONE, NULL, 
		KEYMGMT_FLAG_NONE, ACCESS_KEYSET_xxxxx, ACCESS_KEYSET_xxxxx ),
	MK_KEYACL( KEYMGMT_ITEM_NONE, ST_NONE, ST_NONE, ST_NONE, NULL, 
		KEYMGMT_FLAG_NONE, ACCESS_KEYSET_xxxxx, ACCESS_KEYSET_xxxxx )
	};

/* A secondary ACL matching key ID types with keyset types.  This is a 
   refinement of the generic list of permitted IDs per object type to
   read, since this is actually a three-way match of 
   keysetType :: itemType :: idType.  The keyManagementACL is used to
   check itemType :: idType, this supplementary ACL takes the result
   of that check and checks it against keysetType */

typedef struct {
	const CRYPT_KEYID_TYPE idType;
	const OBJECT_SUBTYPE keysetSubTypeA;
	} IDTYPE_ACL;

static const IDTYPE_ACL idTypeACL[] = {
	{ CRYPT_KEYID_NAME, 
	  ST_KEYSET_ANY | ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI },
	{ CRYPT_KEYID_URI, 
	  ST_KEYSET_ANY | ST_DEV_P11 },
	{ CRYPT_IKEYID_KEYID, 
	  ST_KEYSET_FILE | ST_KEYSET_FILE_PARTIAL | \
	  ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_DEV_P11 },
	{ CRYPT_IKEYID_PGPKEYID, 
	  ST_KEYSET_FILE | ST_KEYSET_FILE_PARTIAL },
	{ CRYPT_IKEYID_CERTID, 
	  ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE },
	{ CRYPT_IKEYID_ISSUERID, 
	  ST_KEYSET_FILE | ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE },
	{ CRYPT_IKEYID_ISSUERANDSERIALNUMBER, 
	  ST_KEYSET_FILE | ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | ST_DEV_P11 },
	{ CRYPT_KEYID_NONE, ST_NONE },
		{ CRYPT_KEYID_NONE, ST_NONE }
	};

/****************************************************************************
*																			*
*							Init/Shutdown Functions							*
*																			*
****************************************************************************/

int initKeymgmtACL( KERNEL_DATA *krnlDataPtr )
	{
	int i;

	PRE( isWritePtr( krnlDataPtr, sizeof( KERNEL_DATA ) ) );

	/* Perform a consistency check on the key management ACLs */
	for( i = 0; keyManagementACL[ i ].itemType != KEYMGMT_ITEM_NONE && \
				i < FAILSAFE_ARRAYSIZE( keyManagementACL, KEYMGMT_ACL ); 
		 i++ )
		{
		const KEYMGMT_ACL *keyMgmtACL = &keyManagementACL[ i ];
		int j;

		if( ( keyMgmtACL->keysetR_subTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->keysetR_subTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 || \
			keyMgmtACL->keysetR_subTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->keysetW_subTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->keysetW_subTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 || \
			keyMgmtACL->keysetW_subTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->keysetD_subTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->keysetD_subTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 || \
			keyMgmtACL->keysetD_subTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->keysetFN_subTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->keysetFN_subTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 || \
			keyMgmtACL->keysetFN_subTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->keysetQ_subTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->keysetQ_subTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | ST_DEV_P11 ) ) != 0 || \
			keyMgmtACL->keysetQ_subTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->objSubTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->objSubTypeA & \
				~( SUBTYPE_CLASS_A | ST_CERT_ANY | ST_CTX_PKC | ST_CTX_CONV ) ) != 0 || \
			keyMgmtACL->objSubTypeB != ST_NONE )
			retIntError();

		ENSURES( keyMgmtACL->allowedKeyIDs != NULL );
		for( j = 0; keyMgmtACL->allowedKeyIDs[ j ] != CRYPT_KEYID_NONE && \
					j < FAILSAFE_ITERATIONS_SMALL; j++ )
			{
			ENSURES( keyMgmtACL->allowedKeyIDs[ j ] > CRYPT_KEYID_NONE && \
					 keyMgmtACL->allowedKeyIDs[ j ] < CRYPT_KEYID_LAST );
			}
		ENSURES( j < FAILSAFE_ITERATIONS_SMALL );

		ENSURES( keyMgmtACL->allowedFlags >= KEYMGMT_FLAG_NONE && \
				 keyMgmtACL->allowedFlags < KEYMGMT_FLAG_LAST );

		if( ( keyMgmtACL->specificKeysetSubTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->specificKeysetSubTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 || \
			keyMgmtACL->specificKeysetSubTypeB != ST_NONE )
			retIntError();

		if( ( keyMgmtACL->specificObjSubTypeA & SUBTYPE_CLASS_B ) || \
			( keyMgmtACL->specificObjSubTypeA & \
				~( SUBTYPE_CLASS_A | ST_CERT_ANY ) ) != 0 || \
			keyMgmtACL->specificObjSubTypeB != ST_NONE )
			retIntError();
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( keyManagementACL, KEYMGMT_ACL ) );

	/* Perform a consistency check on the supplementary ID ACLs */
	for( i = 0; idTypeACL[ i ].idType != KEYMGMT_ITEM_NONE && \
				i < FAILSAFE_ARRAYSIZE( idTypeACL, IDTYPE_ACL ); 
		 i++ )
		{
		const IDTYPE_ACL *idACL = &idTypeACL[ i ];

		ENSURES( idACL->idType > CRYPT_KEYID_NONE && \
				 idACL->idType < CRYPT_KEYID_LAST );

		if( ( idACL->keysetSubTypeA & SUBTYPE_CLASS_B ) || \
			( idACL->keysetSubTypeA & \
				~( SUBTYPE_CLASS_A | ST_KEYSET_ANY | ST_DEV_FORT | \
									 ST_DEV_P11 | ST_DEV_CAPI ) ) != 0 )
			retIntError();
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( idTypeACL, IDTYPE_ACL ) );

	/* Set up the reference to the kernel data block */
	krnlData = krnlDataPtr;

	return( CRYPT_OK );
	}

void endKeymgmtACL( void )
	{
	krnlData = NULL;
	}

/****************************************************************************
*																			*
*							Keyset ACL Check Functions						*

⌨️ 快捷键说明

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