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

📄 msg_acl.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*							Message ACLs Handlers							*
*						Copyright Peter Gutmann 1997-2005					*
*																			*
****************************************************************************/

#if defined( INC_ALL )
  #include "crypt.h"
  #include "acl.h"
  #include "kernel.h"
#elif defined( INC_CHILD )
  #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;

/****************************************************************************
*																			*
*									Message ACLs							*
*																			*
****************************************************************************/

/* Compare ACL for compare messages */

static const FAR_BSS COMPARE_ACL compareACLTbl[] = {
	/* Hash/MAC value */
	{ MESSAGE_COMPARE_HASH,
	  MK_CMPACL_S( ST_CTX_HASH | ST_CTX_MAC, 
				   16, CRYPT_MAX_HASHSIZE ) },

	/* PKC keyID */
	{ MESSAGE_COMPARE_KEYID,
	  MK_CMPACL_S( ST_CTX_PKC, 
				   2, 128 ) },

	/* PGP keyID */
	{ MESSAGE_COMPARE_KEYID_PGP,
	  MK_CMPACL_S( ST_CTX_PKC, 
				   PGP_KEYID_SIZE, PGP_KEYID_SIZE ) },

	/* OpenPGP keyID */
	{ MESSAGE_COMPARE_KEYID_OPENPGP,
	  MK_CMPACL_S( ST_CTX_PKC, 
				   PGP_KEYID_SIZE, PGP_KEYID_SIZE ) },

	/* X.509 subject DN */
	{ MESSAGE_COMPARE_SUBJECT,
	  MK_CMPACL_S( ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN, 
				   2, MAX_ATTRIBUTE_SIZE ) },

	/* PKCS #7 issuerAndSerialNumber */
	{ MESSAGE_COMPARE_ISSUERANDSERIALNUMBER,
	  MK_CMPACL_S( ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN, 
				   2, MAX_ATTRIBUTE_SIZE ) },

	/* Cert SHA-1 fingerprint */
	{ MESSAGE_COMPARE_FINGERPRINT,
	  MK_CMPACL_S( ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN, 
				   20, 20 ) },

	/* Certificate object */
	{ MESSAGE_COMPARE_CERTOBJ,
	  MK_CMPACL_O( ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN, 
				   ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN ) },

	/* End-of-ACL marker */
	{ MESSAGE_COMPARE_NONE,
	  MK_CMPACL_END() }
	};

/* Check ACL for check messages */

#define PUBKEY_CERT_OBJECT		( ST_CERT_CERT | ST_CERT_ATTRCERT | \
								  ST_CERT_CERTCHAIN | ST_CERT_CERTREQ | \
								  ST_CERT_REQ_CERT )
#define PUBKEY_KEYSET_OBJECT	( ST_KEYSET_FILE | ST_KEYSET_FILE_PARTIAL | \
								  ST_KEYSET_DBMS | ST_KEYSET_DBMS_STORE | \
								  ST_KEYSET_HTTP | ST_KEYSET_LDAP | \
								  ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI )
#define PRIVKEY_KEYSET_OBJECT	( ST_KEYSET_FILE | ST_KEYSET_FILE_PARTIAL | \
								  ST_DEV_FORT | ST_DEV_P11 | ST_DEV_CAPI )

static const FAR_BSS CHECK_ALT_ACL checkCAACLTbl[] = {
	/* The CA capability is spread across certs (the CA flag) 
	   and contexts (the signing capability), which requires a two-phase 
	   check.  First we check the primary object, and then we check the
	   secondary one.  Since the primary object has a dependent object but
	   the secondary one doesn't, we have to change the check type that we 
	   perform on the secondary to reflect this.  The checking performed is
	   therefore:

		Type				Target	Object	Action		Dep.Obj.	Fded chk
		----				------	------	------		-------		--------
		Privkey + CA cert	Context	PKC		SIGN		Cert		CACERT
		Cert + pubkey		Cert	Cert	SIGCHECK	PKC			SIGCHECK

	   In theory we'd need to perform some sort of generic sign-or-sigcheck
	   check for the case where the cert is the primary object, but since the
	   cert + context combination can only occur for public-key contexts it's 
	   safe to check for a SIGCHECK capability.  Similarly, when the context
	   is the primary object it's always a private key, so we can check for a
	   SIGN capability */
	{ OBJECT_TYPE_CONTEXT, MESSAGE_CHECK_PKC_SIGN, 
	  MK_CHKACL_ALT( OBJECT_TYPE_CERTIFICATE, ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN, 
					 MESSAGE_CHECK_CACERT ) },
	{ OBJECT_TYPE_CERTIFICATE, MESSAGE_CHECK_PKC_SIGCHECK, 
	  MK_CHKACL_ALT( OBJECT_TYPE_CONTEXT, ST_CTX_PKC,
					 MESSAGE_CHECK_PKC_SIGCHECK ) },

	/* End-of-ACL marker */
	{ OBJECT_TYPE_NONE,
	  MK_CHKACL_ALT_END() }
	};

static const FAR_BSS CHECK_ACL checkACLTbl[] = {
	/* PKC actions.  These get somewhat complex to check because the primary
	   message target may be a context or cert object with an associated 
	   public key, so we have to allow both object types */
	{ MESSAGE_CHECK_PKC,			/* Public or private key context */
	  MK_CHKACL( MESSAGE_NONE, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_PRIVATE,	/* Private key context */
	  MK_CHKACL( MESSAGE_NONE, 
				 ST_CTX_PKC | ST_CERT_CERT | ST_CERT_CERTCHAIN ) },

	{ MESSAGE_CHECK_PKC_ENCRYPT,	/* Public encryption context */
	  MK_CHKACL( MESSAGE_CTX_ENCRYPT, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_DECRYPT,	/* Private decryption context */
	  MK_CHKACL( MESSAGE_CTX_DECRYPT, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_SIGCHECK,	/* Public signature check context */
	  MK_CHKACL( MESSAGE_CTX_SIGCHECK, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_SIGN,		/* Private signature context */
	  MK_CHKACL( MESSAGE_CTX_SIGN, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_KA_EXPORT,	/* Key agreement - export context */
	  MK_CHKACL( MESSAGE_NONE, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	{ MESSAGE_CHECK_PKC_KA_IMPORT,	/* Key agreement - import context */
	  MK_CHKACL( MESSAGE_NONE, 
				 ST_CTX_PKC | PUBKEY_CERT_OBJECT ) },

	/* Conventional encryption/hash/MAC actions */
	{ MESSAGE_CHECK_CRYPT,			/* Conventional encryption capability */
	  MK_CHKACL( MESSAGE_CTX_ENCRYPT, 
				 ST_CTX_CONV ) },

	{ MESSAGE_CHECK_HASH,			/* Hash capability */
	  MK_CHKACL( MESSAGE_CTX_HASH, 
				 ST_CTX_HASH ) },

	{ MESSAGE_CHECK_MAC,			/* MAC capability */
	  MK_CHKACL( MESSAGE_CTX_HASH, 
				 ST_CTX_MAC ) },

	/* Checks that an object is ready to be initialised to perform this
	   operation */
	{ MESSAGE_CHECK_CRYPT_READY,	/* Ready for init for conv.encr.*/
	  MK_CHKACL_EX( MESSAGE_CTX_ENCRYPT, 
					ST_CTX_CONV, ACL_FLAG_LOW_STATE ) },

	{ MESSAGE_CHECK_MAC_READY,		/* Ready for init for MAC */
	  MK_CHKACL_EX( MESSAGE_CTX_HASH, 
					ST_CTX_MAC, ACL_FLAG_LOW_STATE ) },

	{ MESSAGE_CHECK_KEYGEN_READY,	/* Ready for init key generation */
	  MK_CHKACL_EX( MESSAGE_CTX_GENKEY, 
					ST_CTX_CONV | ST_CTX_PKC | ST_CTX_MAC, ACL_FLAG_LOW_STATE ) },

	/* Checks on purely passive container objects that constrain action 
	   objects (for example a cert being attached to a context) for which 
	   the state isn't important in this instance.  Usually we check to make 
	   sure that the cert is in the high state, but when a cert is being 
	   created/imported it may not be in the high state yet at the time the 
	   check is being carried out.
	   
	   In addition to certs the message can be sent to a keyset to check 
	   whether it contains keys capable of performing the required action */
	{ MESSAGE_CHECK_PKC_ENCRYPT_AVAIL,	/* Encryption available */
	  MK_CHKACL_EX( MESSAGE_CTX_ENCRYPT, 
					PUBKEY_CERT_OBJECT | PUBKEY_KEYSET_OBJECT, 
					ACL_FLAG_ANY_STATE ) },

	{ MESSAGE_CHECK_PKC_DECRYPT_AVAIL,	/* Decryption available */
	  MK_CHKACL_EX( MESSAGE_CTX_DECRYPT, 
					PUBKEY_CERT_OBJECT | PRIVKEY_KEYSET_OBJECT,
					ACL_FLAG_ANY_STATE ) },

	{ MESSAGE_CHECK_PKC_SIGCHECK_AVAIL,	/* Signature check available */
	  MK_CHKACL_EX( MESSAGE_CTX_SIGCHECK, 
					PUBKEY_CERT_OBJECT | PUBKEY_KEYSET_OBJECT,
					ACL_FLAG_ANY_STATE ) },
	
	{ MESSAGE_CHECK_PKC_SIGN_AVAIL,		/* Signature available */
	  MK_CHKACL_EX( MESSAGE_CTX_SIGN, 
					PUBKEY_CERT_OBJECT | PRIVKEY_KEYSET_OBJECT,
					ACL_FLAG_ANY_STATE ) },

	{ MESSAGE_CHECK_PKC_KA_EXPORT_AVAIL,/* Key agreement - export available */
	  MK_CHKACL_EX( MESSAGE_NONE, 
					PUBKEY_CERT_OBJECT, ACL_FLAG_ANY_STATE ) },

	{ MESSAGE_CHECK_PKC_KA_IMPORT_AVAIL,/* Key agreement - import available */
	  MK_CHKACL_EX( MESSAGE_NONE, 
					PUBKEY_CERT_OBJECT, ACL_FLAG_ANY_STATE ) },

	/* Misc.actions.  The CA capability is spread across certs (the CA flag) 
	   and contexts (the signing capability), which requires a two-phase 
	   check specified in a sub-ACL.  The CA-cert check is never applied
	   directly, but is the second part of the two-phase check performed for
	   the CA capability */
	{ MESSAGE_CHECK_CA,				/* Cert signing capability */
	  MK_CHKACL_EXT( MESSAGE_NONE, ST_NONE, checkCAACLTbl ) },
	{ MESSAGE_CHECK_CACERT,			/* CA cert, part two of CHECK_CA */
	  MK_CHKACL( MESSAGE_CHECK_NONE,
				 ST_CERT_CERT | ST_CERT_ATTRCERT | ST_CERT_CERTCHAIN ) },

	/* End-of-ACL marker */
	{ MESSAGE_CHECK_NONE,
	  MK_CHKACL_END() }
	};

/* When we export a cert the easiest way to handle the export check is via
   a pseudo-ACL that's checked via the standard attribute ACL-checking
   function.  The following ACL handles cert exports */

static const FAR_BSS ATTRIBUTE_ACL_ALT formatPseudoACL[] = {
	/* Encoded cert data */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_CERTIFICATE,
		ST_CERT_ANY_CERT | ST_CERT_ATTRCERT | ST_CERT_CRL | \
			ST_CERT_OCSP_RESP, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* Encoded cert.chain */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_CERTCHAIN,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* Base64-encoded certificate */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_TEXT_CERTIFICATE,
		ST_CERT_ANY_CERT | ST_CERT_ATTRCERT | ST_CERT_CRL, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* Base64-encoded cert.chain */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_TEXT_CERTCHAIN,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),
	
	/* XML-encoded certificate */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_XML_CERTIFICATE,
		ST_CERT_ANY_CERT | ST_CERT_ATTRCERT | ST_CERT_CRL, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* XML-encoded cert.chain */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_XML_CERTCHAIN,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* SET OF cert in chain */
	MKACL_S_ALT(
		CRYPT_ICERTFORMAT_CERTSET,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_INT_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 16, 8192 ) ),

	/* SEQUENCE OF cert in chain */
	MKACL_S_ALT(
		CRYPT_ICERTFORMAT_CERTSEQUENCE,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_INT_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 16, 8192 ) ),

	/* SSL certificate chain */
	MKACL_S_ALT(
		CRYPT_ICERTFORMAT_SSL_CERTCHAIN,
		ST_CERT_CERT | ST_CERT_CERTCHAIN, ST_NONE, ACCESS_INT_Rxx_xxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 16, 8192 ) ),

	/* Encoded non-signed object data.  We allow this attribute to be read 
	   for objects in the high as well as the low state even though in 
	   theory it's only present for low (non-signed) objects because the 
	   object can be in the high state if it was imported from its external 
	   encoded form */
	MKACL_S_ALT(	
		CRYPT_ICERTFORMAT_DATA,
		ST_CERT_CMSATTR | ST_CERT_REQ_REV | ST_CERT_RTCS_REQ | \
			ST_CERT_RTCS_RESP | ST_CERT_OCSP_REQ | ST_CERT_OCSP_RESP | \
			ST_CERT_PKIUSER, ST_NONE, ACCESS_INT_Rxx_Rxx,
		ROUTE( OBJECT_TYPE_CERTIFICATE ), RANGE( 64, 8192 ) ),

	/* End-of-ACL marker */
	MKACL_S_ALT(
		CRYPT_CERTFORMAT_NONE, ST_NONE, ST_NONE, ACCESS_xxx_xxx, 
		ROUTE( OBJECT_TYPE_NONE ), RANGE( 0, 0 ) ),
	};

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Check whether a numeric value falls within a range */

static BOOLEAN checkNumericRange( const int value, const int lowRange, 
								  const int highRange )
	{
	/* Precondition: The range values are either both negative or both 
	   positive.  This is needed for the range comparison to work */
	PRE( ( lowRange < 0 && highRange < 0 ) || \
		 ( lowRange >= 0 && highRange >= 0 ) );

	/* Check whether the value is within the allowed range.  Since some 
	   values can be negative (e.g. cursor movement codes) we have to 
	   reverse the range check for negative values */
	if( lowRange >= 0 )
		{
		/* Positive, it's a standard comparison */
		if( value >= lowRange && value <= highRange )
			return( TRUE );
		}
	else
		{
		PRE( highRange <= lowRange );

		/* Negative, reverse the comparison */
		if( value >= highRange && value <= lowRange )
			return( TRUE );
		}

	return( FALSE );
	}

/* Check whether a numeric value falls within a special-case range type */

static BOOLEAN checkAttributeRangeSpecial( const RANGEVAL_TYPE rangeType,

⌨️ 快捷键说明

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