📄 sendmsg.c
字号:
{
OBJECT_INFO *clonedObjectInfoPtr = &objectTable[ clonedObject ];
objectInfoPtr->clonedObject = \
clonedObjectInfoPtr->clonedObject = CRYPT_ERROR;
objectInfoPtr->flags &= ~OBJECT_FLAG_ALIASED;
clonedObjectInfoPtr->flags &= ~( OBJECT_FLAG_ALIASED | OBJECT_FLAG_CLONE );
clonedObjectInfoPtr->flags |= OBJECT_FLAG_HIGH;
}
return( status );
}
#endif /* 0 */
/****************************************************************************
* *
* Message Routing *
* *
****************************************************************************/
/* Find the ultimate target of an object attribute manipulation message by
walking down the chain of controlling -> dependent objects. For example
a message targeted at a device and sent to a certificate would be routed
to the cert's dependent object (which would typically be a context).
The device message targeted at the context would in turn be routed to the
context's dependent device, which is its final destination */
int findTargetType( const int originalObjectHandle, const int targets )
{
const OBJECT_TYPE target = targets & 0xFF;
const OBJECT_TYPE altTarget1 = ( targets >> 8 ) & 0xFF;
const OBJECT_TYPE altTarget2 = ( targets >> 16 ) & 0xFF;
OBJECT_INFO *objectTable = krnlData->objectTable;
OBJECT_TYPE type = objectTable[ originalObjectHandle ].type;
int objectHandle = originalObjectHandle, iterations;
/* Preconditions: Source is a valid object, destination(s) are valid
target(s) */
PRE( isValidObject( objectHandle ) );
PRE( isValidType( target ) );
PRE( altTarget1 == OBJECT_TYPE_NONE || isValidType( altTarget1 ) );
PRE( altTarget2 == OBJECT_TYPE_NONE || isValidType( altTarget2 ) );
/* Route the request through any dependent objects as required until we
reach the required target object type. "And thou shalt make
loops..." -- Exodus 26:4 */
for( iterations = 0; \
iterations < 3 && isValidObject( objectHandle ) && \
!( target == type || \
( altTarget1 != OBJECT_TYPE_NONE && altTarget1 == type ) || \
( altTarget2 != OBJECT_TYPE_NONE && altTarget2 == type ) ); \
iterations++ )
{
/* Loop invariants. "Fifty loops thou shalt make" -- Exodus 26:5
(some of the OT verses shouldn't be taken too literally,
apparently the 50 used here merely means "many" as in "more than
one or two" in the same way that "40 days and nights" is now
generally taken as meaning "Lots, but that's as far as we're
prepared to count") */
INV( isValidObject( objectHandle ) );
INV( iterations < 3 );
/* Find the next potential target object */
if( target == OBJECT_TYPE_DEVICE && \
objectTable[ objectHandle ].dependentDevice != CRYPT_ERROR )
objectHandle = objectTable[ objectHandle ].dependentDevice;
else
if( target == OBJECT_TYPE_USER )
objectHandle = objectTable[ objectHandle ].owner;
else
objectHandle = objectTable[ objectHandle ].dependentObject;
if( isValidObject( objectHandle ) )
type = objectTable[ objectHandle ].type;
/* If we've got a new object, it has the same owner as the original
target candidate */
POST( !isValidObject( objectHandle ) || \
isSameOwningObject( originalObjectHandle, objectHandle ) || \
objectTable[ originalObjectHandle ].owner == objectHandle );
}
if( iterations >= 3 )
{
/* The object table has been corrupted in some way, bail out */
assert( NOTREACHED );
return( CRYPT_ARGERROR_OBJECT );
}
/* Postcondition: We ran out of options or we reached the target object */
POST( iterations < 3 );
POST( objectHandle == CRYPT_ERROR || \
( isValidObject( objectHandle ) && \
( isSameOwningObject( originalObjectHandle, objectHandle ) || \
objectTable[ originalObjectHandle ].owner == objectHandle ) && \
( target == type || \
( altTarget1 != OBJECT_TYPE_NONE && altTarget1 == type ) || \
( altTarget2 != OBJECT_TYPE_NONE && altTarget2 == type ) ) ) );
return( isValidObject( objectHandle ) ? \
objectHandle : CRYPT_ARGERROR_OBJECT );
}
/* Find the ultimate target of a compare message by walking down the chain
of controlling -> dependent objects. For example a message targeted at a
device and sent to a certificate would be routed to the cert's dependent
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 */
static int routeCompareMessageTarget( const int originalObjectHandle,
const int 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:
assert( NOTREACHED );
return( CRYPT_ARGERROR_OBJECT );
}
/* 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_BOOLEAN, /* Data, value = boolean */
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_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, function
/* 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 OBJECT_TYPE routingTarget; /* Target type if routable */
int ( *routingFunction )( const int objectHandle, const int arg );
/* Object type checking information: Object subtypes for which this
message is valid (for object-type-specific message) */
const int 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 );
/* Message processing information. If the internal handler function is
non-null, it's handled by the kernel */
int ( *internalHandlerFunction )( const int objectHandle, const int arg1,
const void *arg2,
const BOOLEAN isInternal );
} MESSAGE_HANDLING_INFO;
static const FAR_BSS MESSAGE_HANDLING_INFO 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_BOOLEAN,
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -