📄 key_acl.c
字号:
/****************************************************************************
* *
* 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 + -