📄 sendmsg.c
字号:
object (which would typically be a context). The device message targeted
at the context would be routed to the context's dependent device, which
is its final destination */
CHECK_RETVAL \
static int routeCompareMessageTarget( const int originalObjectHandle,
const long messageValue )
{
OBJECT_TYPE targetType = OBJECT_TYPE_NONE;
int objectHandle = originalObjectHandle;
/* Preconditions */
PRE( isValidObject( objectHandle ) );
PRE( messageValue == MESSAGE_COMPARE_HASH || \
messageValue == MESSAGE_COMPARE_KEYID || \
messageValue == MESSAGE_COMPARE_KEYID_PGP || \
messageValue == MESSAGE_COMPARE_KEYID_OPENPGP || \
messageValue == MESSAGE_COMPARE_SUBJECT || \
messageValue == MESSAGE_COMPARE_ISSUERANDSERIALNUMBER || \
messageValue == MESSAGE_COMPARE_FINGERPRINT || \
messageValue == MESSAGE_COMPARE_CERTOBJ );
/* Determine the ultimate target type for the message. We don't check for
keysets, envelopes and sessions as dependent objects since this never
occurs */
switch( messageValue )
{
case MESSAGE_COMPARE_HASH:
case MESSAGE_COMPARE_KEYID:
case MESSAGE_COMPARE_KEYID_PGP:
case MESSAGE_COMPARE_KEYID_OPENPGP:
targetType = OBJECT_TYPE_CONTEXT;
break;
case MESSAGE_COMPARE_SUBJECT:
case MESSAGE_COMPARE_ISSUERANDSERIALNUMBER:
case MESSAGE_COMPARE_FINGERPRINT:
case MESSAGE_COMPARE_CERTOBJ:
targetType = OBJECT_TYPE_CERTIFICATE;
break;
default:
retIntError();
}
/* Route the message through to the appropriate object */
objectHandle = findTargetType( objectHandle, targetType );
/* Postcondition */
POST( objectHandle == CRYPT_ARGERROR_OBJECT || \
( isValidObject( objectHandle ) && \
isSameOwningObject( originalObjectHandle, objectHandle ) ) );
return( objectHandle );
}
/****************************************************************************
* *
* Message Dispatch ACL *
* *
****************************************************************************/
/* Each message type has certain properties such as whether it's routable,
which object types it applies to, what checks are performed on it, whether
it's processed by the kernel or dispatched to an object, etc etc. These
are all defined in the following table.
In addition to the usual checks, we also make various assertions about the
parameters we're passed. Note that these don't check user data (that's
checked programmatically and an error code returned) but values passed by
cryptlib code */
typedef enum {
PARAMTYPE_NONE_NONE, /* Data = 0, value = 0 */
PARAMTYPE_NONE_ANY, /* Data = 0, value = any */
PARAMTYPE_NONE_BOOLEAN, /* Data = 0, value = boolean */
PARAMTYPE_NONE_CHECKTYPE,/* Data = 0, value = check type */
PARAMTYPE_DATA_NONE, /* Data, value = 0 */
PARAMTYPE_DATA_ANY, /* Data, value = any */
PARAMTYPE_DATA_LENGTH, /* Data, value >= 0 */
PARAMTYPE_DATA_OBJTYPE, /* Data, value = object type */
PARAMTYPE_DATA_MECHTYPE,/* Data, value = mechanism type */
PARAMTYPE_DATA_ITEMTYPE,/* Data, value = keymgmt.item type */
PARAMTYPE_DATA_FORMATTYPE,/* Data, value = cert format type */
PARAMTYPE_DATA_COMPARETYPE,/* Data, value = compare type */
PARAMTYPE_DATA_SETDEPTYPE,/* Data, value = setdep.option type */
PARAMTYPE_DATA_CERTMGMTTYPE,/* Data, value = cert.mgmt.type */
PARAMTYPE_ANY_USERMGMTTYPE,/* Data = any, value = user mgmt.type */
PARAMTYPE_ANY_TRUSTMGMTTYPE,/* Data = any, value = trust mgmt.type */
PARAMTYPE_LAST /* Last possible parameter check type */
} PARAMCHECK_TYPE;
/* Symbolic defines for message handling types, used to make it clearer
what's going on
PRE_DISPATCH - Action before message is dispatched
POST_DISPATCH - Action after message is dispatched
HANDLE_INTERNAL - Message handled by the kernel */
#define PRE_DISPATCH( function ) preDispatch##function, NULL
#define POST_DISPATCH( function ) NULL, postDispatch##function
#define PRE_POST_DISPATCH( preFunction, postFunction ) \
preDispatch##preFunction, postDispatch##postFunction
#define HANDLE_INTERNAL( function ) NULL, NULL, MESSAGE_HANDLING_FLAG_INTERNAL, function
/* Flags to indicate (potential) special-case handling for a message. These
are:
FLAG_INTERNAL: The message is handled internally by the kernel rather
than being sent to an external handler.
FLAG_MAYUNLOCK: The message handler may unlock the object (via
krnlReleaseObject()) to allow other threads access. In this
case the first parameter to the handler function should be a
MESSAGE_FUNCTION_EXTINFO structure to contain unlocking
information */
#define MESSAGE_HANDLING_FLAG_NONE 0 /* No special handling */
#define MESSAGE_HANDLING_FLAG_MAYUNLOCK 1 /* Handler may unlock object */
#define MESSAGE_HANDLING_FLAG_INTERNAL 2 /* Message handle by kernel */
/* The handling information, declared in the order in which it's applied */
typedef struct {
/* The message type, used for consistency checking */
const MESSAGE_TYPE messageType;
/* Message routing information if the message is routable. If the target
is implicitly determined via the message value, the routing target is
OBJECT_TYPE_NONE; if the target is explicitly determined, the routing
target is identified in the target. If the routing function is null,
the message isn't routed */
const long routingTarget; /* Target type if routable */
int ( *routingFunction )( const int objectHandle, const long arg );
/* Object type checking information: Object subtypes for which this
message is valid (for object-type-specific message) */
const OBJECT_SUBTYPE subTypeA, subTypeB;/* Object subtype for which msg.valid */
/* Message type checking information used to assertion-check the function
preconditions */
const PARAMCHECK_TYPE paramCheck; /* Parameter check assertion type */
/* Pre- and post-message-dispatch handlers. These perform any additional
checking and processing that may be necessary before and after a
message is dispatched to an object */
int ( *preDispatchFunction )( const int objectHandle,
const MESSAGE_TYPE message,
const void *messageDataPtr,
const int messageValue, const void *auxInfo );
int ( *postDispatchFunction )( const int objectHandle,
const MESSAGE_TYPE message,
const void *messageDataPtr,
const int messageValue, const void *auxInfo );
/* Flags to indicate (potential) special-case handling for this message,
and the (optional) internal handler function that's used if the
message is handled directly by the kernel */
int flags; /* Special-case handling flags */
int ( *internalHandlerFunction )( const int objectHandle, const int arg1,
const void *arg2,
const BOOLEAN isInternal );
} MESSAGE_HANDLING_INFO;
static const MESSAGE_HANDLING_INFO FAR_BSS messageHandlingInfo[] = {
{ MESSAGE_NONE, ROUTE_NONE, 0, PARAMTYPE_NONE_NONE },
/* Control messages. These messages aren't routed, are valid for all
object types and subtypes, take no (or minimal) parameters, and are
handled by the kernel */
{ MESSAGE_DESTROY, /* Destroy the object */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_NONE_NONE,
PRE_DISPATCH( SignalDependentObjects ) },
{ MESSAGE_INCREFCOUNT, /* Increment object ref.count */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_NONE_NONE,
HANDLE_INTERNAL( incRefCount ) },
{ MESSAGE_DECREFCOUNT, /* Decrement object ref.count */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_NONE_NONE,
HANDLE_INTERNAL( decRefCount ) },
{ MESSAGE_GETDEPENDENT, /* Get dependent object */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_OBJTYPE,
HANDLE_INTERNAL( getDependentObject ) },
{ MESSAGE_SETDEPENDENT, /* Set dependent object (e.g. ctx->dev) */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_SETDEPTYPE,
HANDLE_INTERNAL( setDependentObject ) },
{ MESSAGE_CLONE, /* Clone the object (only valid for ctxs) */
ROUTE_FIXED( OBJECT_TYPE_CONTEXT ), ST_CTX_CONV | ST_CTX_HASH, ST_NONE,
PARAMTYPE_NONE_ANY,
HANDLE_INTERNAL( cloneObject ) },
/* Attribute messages. These messages are implicitly routed by attribute
type, more specific checking is performed using the attribute ACL's */
{ MESSAGE_GETATTRIBUTE, /* Get numeric object attribute */
ROUTE_IMPLICIT, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_ANY,
PRE_POST_DISPATCH( CheckAttributeAccess, MakeObjectExternal ) },
{ MESSAGE_GETATTRIBUTE_S, /* Get string object attribute */
ROUTE_IMPLICIT, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_ANY,
PRE_DISPATCH( CheckAttributeAccess ) },
{ MESSAGE_SETATTRIBUTE, /* Set numeric object attribute */
ROUTE_IMPLICIT, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_ANY,
PRE_POST_DISPATCH( CheckAttributeAccess, ChangeStateOpt ) },
{ MESSAGE_SETATTRIBUTE_S, /* Set string object attribute */
ROUTE_IMPLICIT, ST_ANY_A, ST_ANY_B,
PARAMTYPE_DATA_ANY,
PRE_POST_DISPATCH( CheckAttributeAccess, ChangeStateOpt ) },
{ MESSAGE_DELETEATTRIBUTE, /* Delete object attribute */
ROUTE_IMPLICIT, ST_CTX_ANY | ST_CERT_ANY, ST_SESS_ANY | ST_USER_NORMAL | ST_USER_SO,
PARAMTYPE_NONE_ANY,
PRE_DISPATCH( CheckAttributeAccess ) },
/* General messages to objects */
{ MESSAGE_COMPARE, /* Compare objs.or obj.properties */
ROUTE_SPECIAL( CompareMessageTarget ), ST_CTX_ANY | ST_CERT_ANY, ST_NONE,
PARAMTYPE_DATA_COMPARETYPE,
PRE_DISPATCH( CheckCompareParam ) },
{ MESSAGE_CHECK, /* Check object info */
ROUTE_NONE, ST_ANY_A, ST_ANY_B,
PARAMTYPE_NONE_CHECKTYPE,
PRE_POST_DISPATCH( CheckCheckParam, ForwardToDependentObject ) },
{ MESSAGE_SELFTEST, /* Perform a self-test */
ROUTE_FIXED( OBJECT_TYPE_DEVICE ), ST_DEV_SYSTEM, ST_NONE,
PARAMTYPE_NONE_NONE,
NULL, NULL,
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
/* Messages sent from the kernel to object message handlers. These
messages are sent directly to the object from inside the kernel in
response to a control message, so we set the checking to disallow
everything to catch any that arrive from outside */
{ MESSAGE_CHANGENOTIFY, /* Notification of obj.status chge.*/
ROUTE_NONE, ST_NONE, ST_NONE, PARAMTYPE_NONE_NONE },
/* Object-type-specific messages: Contexts */
{ MESSAGE_CTX_ENCRYPT, /* Context: Action = encrypt */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_CONV | ST_CTX_PKC, ST_NONE,
PARAMTYPE_DATA_LENGTH,
PRE_POST_DISPATCH( CheckActionAccess, UpdateUsageCount ) },
{ MESSAGE_CTX_DECRYPT, /* Context: Action = decrypt */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_CONV | ST_CTX_PKC, ST_NONE,
PARAMTYPE_DATA_LENGTH,
PRE_POST_DISPATCH( CheckActionAccess, UpdateUsageCount ) },
{ MESSAGE_CTX_SIGN, /* Context: Action = sign */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_PKC, ST_NONE,
PARAMTYPE_DATA_LENGTH,
PRE_POST_DISPATCH( CheckActionAccess, UpdateUsageCount ) },
{ MESSAGE_CTX_SIGCHECK, /* Context: Action = sigcheck */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_PKC, ST_NONE,
PARAMTYPE_DATA_LENGTH,
PRE_POST_DISPATCH( CheckActionAccess, UpdateUsageCount ) },
{ MESSAGE_CTX_HASH, /* Context: Action = hash */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_HASH | ST_CTX_MAC, ST_NONE,
PARAMTYPE_DATA_LENGTH,
PRE_POST_DISPATCH( CheckActionAccess, UpdateUsageCount ) },
{ MESSAGE_CTX_GENKEY, /* Context: Generate a key */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_CONV | ST_CTX_PKC | ST_CTX_MAC, ST_NONE,
PARAMTYPE_NONE_NONE,
PRE_POST_DISPATCH( CheckState, ChangeState ) },
{ MESSAGE_CTX_GENIV, /* Context: Generate an IV */
ROUTE( OBJECT_TYPE_CONTEXT ), ST_CTX_CONV, ST_NONE,
PARAMTYPE_NONE_NONE },
/* Object-type-specific messages: Certificates */
{ MESSAGE_CRT_SIGN, /* Cert: Action = sign cert */
ROUTE( OBJECT_TYPE_CERTIFICATE ),
ST_CERT_ANY_CERT | ST_CERT_ATTRCERT | ST_CERT_CRL | \
ST_CERT_OCSP_REQ | ST_CERT_OCSP_RESP, ST_NONE,
PARAMTYPE_NONE_ANY,
PRE_POST_DISPATCH( CheckStateParamHandle, ChangeState ) },
{ MESSAGE_CRT_SIGCHECK, /* Cert: Action = check/verify cert */
ROUTE( OBJECT_TYPE_CERTIFICATE ),
ST_CERT_ANY_CERT | ST_CERT_ATTRCERT | ST_CERT_CRL | \
ST_CERT_RTCS_RESP | ST_CERT_OCSP_RESP, ST_NONE,
PARAMTYPE_NONE_ANY,
PRE_DISPATCH( CheckParamHandleOpt ) },
{ MESSAGE_CRT_EXPORT, /* Cert: Export encoded cert data */
ROUTE( OBJECT_TYPE_CERTIFICATE ), ST_CERT_ANY, ST_NONE,
PARAMTYPE_DATA_FORMATTYPE,
PRE_DISPATCH( CheckExportAccess ) },
/* Object-type-specific messages: Devices */
{ MESSAGE_DEV_QUERYCAPABILITY, /* Device: Query capability */
ROUTE_FIXED( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_ANY },
{ MESSAGE_DEV_EXPORT, /* Device: Action = export key */
ROUTE( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_MECHTYPE,
PRE_DISPATCH( CheckMechanismWrapAccess ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_IMPORT, /* Device: Action = import key */
ROUTE( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_MECHTYPE,
PRE_DISPATCH( CheckMechanismWrapAccess ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_SIGN, /* Device: Action = sign */
ROUTE( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_MECHTYPE,
PRE_DISPATCH( CheckMechanismSignAccess ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_SIGCHECK, /* Device: Action = sig.check */
ROUTE( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_MECHTYPE,
PRE_DISPATCH( CheckMechanismSignAccess ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_DERIVE, /* Device: Action = derive key */
ROUTE( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_MECHTYPE,
PRE_DISPATCH( CheckMechanismDeriveAccess ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_CREATEOBJECT, /* Device: Create object */
ROUTE_FIXED( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_OBJTYPE,
PRE_POST_DISPATCH( CheckCreate, MakeObjectExternal ),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -