📄 sendmsg.c
字号:
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
{ MESSAGE_DEV_CREATEOBJECT_INDIRECT,/* Device: Create obj.from data */
ROUTE_FIXED( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
PARAMTYPE_DATA_OBJTYPE,
PRE_POST_DISPATCH( CheckCreate, MakeObjectExternal ),
MESSAGE_HANDLING_FLAG_MAYUNLOCK },
/* Object-type-specific messages: Envelopes */
{ MESSAGE_ENV_PUSHDATA, /* Envelope: Push data */
ROUTE_FIXED_ALT( OBJECT_TYPE_ENVELOPE, OBJECT_TYPE_SESSION ),
ST_NONE, ST_ENV_ANY | ST_SESS_ANY_DATA,
PARAMTYPE_DATA_NONE,
PRE_DISPATCH( CheckData ) },
{ MESSAGE_ENV_POPDATA, /* Envelope: Pop data */
ROUTE_FIXED_ALT( OBJECT_TYPE_ENVELOPE, OBJECT_TYPE_SESSION ),
ST_NONE, ST_ENV_ANY | ST_SESS_ANY_DATA,
PARAMTYPE_DATA_NONE,
PRE_DISPATCH( CheckData ) },
/* Object-type-specific messages: Keysets */
{ MESSAGE_KEY_GETKEY, /* Keyset: Instantiate ctx/cert */
ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
PARAMTYPE_DATA_ITEMTYPE,
PRE_POST_DISPATCH( CheckKeysetAccess, MakeObjectExternal ) },
{ MESSAGE_KEY_SETKEY, /* Keyset: Add ctx/cert */
ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
PARAMTYPE_DATA_ITEMTYPE,
PRE_DISPATCH( CheckKeysetAccess ) },
{ MESSAGE_KEY_DELETEKEY, /* Keyset: Delete key */
ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
PARAMTYPE_DATA_ITEMTYPE,
PRE_DISPATCH( CheckKeysetAccess ) },
{ MESSAGE_KEY_GETFIRSTCERT, /* Keyset: Get first cert in sequence */
ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
PARAMTYPE_DATA_ITEMTYPE,
PRE_DISPATCH( CheckKeysetAccess ) },
{ MESSAGE_KEY_GETNEXTCERT, /* Keyset: Get next cert in sequence */
ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
PARAMTYPE_DATA_ITEMTYPE,
PRE_POST_DISPATCH( CheckKeysetAccess, MakeObjectExternal ) },
{ MESSAGE_KEY_CERTMGMT, /* Keyset: Cert management */
ROUTE_FIXED( OBJECT_TYPE_KEYSET ),
ST_KEYSET_DBMS_STORE, ST_NONE,
PARAMTYPE_DATA_CERTMGMTTYPE,
PRE_POST_DISPATCH( CheckCertMgmtAccess, MakeObjectExternal ) },
/* Object-type-specific messages: Users */
{ MESSAGE_USER_USERMGMT, /* User: User management */
ROUTE_FIXED( OBJECT_TYPE_USER ), ST_NONE, ST_USER_SO,
PARAMTYPE_ANY_USERMGMTTYPE,
PRE_POST_DISPATCH( CheckUserMgmtAccess, HandleZeroise ) },
{ MESSAGE_USER_TRUSTMGMT, /* User: Trust management */
ROUTE_FIXED( OBJECT_TYPE_USER ), ST_NONE, ST_USER_SO,
PARAMTYPE_ANY_TRUSTMGMTTYPE,
PRE_DISPATCH( CheckTrustMgmtAccess ) }
};
/****************************************************************************
* *
* Init/Shutdown Functions *
* *
****************************************************************************/
int initSendMessage( KERNEL_DATA *krnlDataPtr )
{
int i;
PRE( isWritePtr( krnlDataPtr, sizeof( KERNEL_DATA ) ) );
/* Perform a consistency check on various things that need to be set
up in a certain way for things to work properly */
assert( MESSAGE_CTX_DECRYPT == MESSAGE_CTX_ENCRYPT + 1 );
assert( MESSAGE_CTX_SIGN == MESSAGE_CTX_DECRYPT + 1 );
assert( MESSAGE_CTX_SIGCHECK == MESSAGE_CTX_SIGN + 1 );
assert( MESSAGE_CTX_HASH == MESSAGE_CTX_SIGCHECK + 1 );
assert( MESSAGE_CTX_GENKEY == MESSAGE_CTX_HASH + 1 );
assert( MESSAGE_GETATTRIBUTE_S == MESSAGE_GETATTRIBUTE + 1 );
assert( MESSAGE_SETATTRIBUTE == MESSAGE_GETATTRIBUTE_S + 1 );
assert( MESSAGE_SETATTRIBUTE_S == MESSAGE_SETATTRIBUTE + 1 );
assert( MESSAGE_DELETEATTRIBUTE == MESSAGE_SETATTRIBUTE_S + 1 );
/* Perform a consistency check on various internal values and constants */
assert( ACTION_PERM_COUNT == 6 );
/* Perform a consistency check on the parameter ACL */
for( i = 0; messageParamACLTbl[ i ].type != MESSAGE_NONE && \
i < FAILSAFE_ARRAYSIZE( messageParamACLTbl, MESSAGE_ACL );
i++ )
{
const MESSAGE_ACL *messageParamACL = &messageParamACLTbl[ i ];
ENSURES( isParamMessage( messageParamACL->type ) && \
!( messageParamACL->objectACL.subTypeA & SUBTYPE_CLASS_B ) && \
!( messageParamACL->objectACL.subTypeB & SUBTYPE_CLASS_A ) );
}
ENSURES( i < FAILSAFE_ARRAYSIZE( messageParamACLTbl, MESSAGE_ACL ) );
/* Perform a consistency check on the message handling information */
for( i = MESSAGE_NONE + 1; i < MESSAGE_LAST; i++ )
{
const MESSAGE_HANDLING_INFO *messageInfo = &messageHandlingInfo[ i ];
ENSURES( messageInfo->messageType == i && \
messageInfo->paramCheck >= PARAMTYPE_NONE_NONE && \
messageInfo->paramCheck < PARAMTYPE_LAST );
ENSURES( ( messageInfo->messageType >= MESSAGE_ENV_PUSHDATA && \
messageInfo->messageType <= MESSAGE_KEY_GETNEXTCERT ) || \
( messageInfo->routingTarget >= OBJECT_TYPE_NONE && \
messageInfo->routingTarget <= OBJECT_TYPE_LAST ) );
ENSURES( messageInfo->messageType == MESSAGE_CLONE || \
messageInfo->messageType == MESSAGE_COMPARE || \
( messageInfo->routingTarget == OBJECT_TYPE_NONE && \
messageInfo->routingFunction == NULL ) || \
( messageInfo->routingTarget != OBJECT_TYPE_NONE && \
messageInfo->routingFunction != NULL ) );
ENSURES( !( messageInfo->subTypeA & SUBTYPE_CLASS_B ) && \
!( messageInfo->subTypeB & SUBTYPE_CLASS_A ) );
ENSURES( ( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) || \
messageInfo->messageType == MESSAGE_SELFTEST || \
messageInfo->messageType == MESSAGE_CHANGENOTIFY || \
messageInfo->messageType == MESSAGE_CTX_GENIV || \
messageInfo->messageType == MESSAGE_DEV_QUERYCAPABILITY || \
messageInfo->preDispatchFunction != NULL );
ENSURES( messageInfo->messageType == MESSAGE_SELFTEST || \
messageInfo->messageType == MESSAGE_CHANGENOTIFY || \
messageInfo->messageType == MESSAGE_CTX_GENIV || \
messageInfo->messageType == MESSAGE_DEV_QUERYCAPABILITY || \
( messageInfo->preDispatchFunction != NULL || \
messageInfo->postDispatchFunction != NULL || \
messageInfo->internalHandlerFunction != NULL ) );
ENSURES( ( ( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) && \
messageInfo->internalHandlerFunction != NULL ) || \
( !( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) && \
messageInfo->internalHandlerFunction == NULL ) );
}
/* Set up the reference to the kernel data block */
krnlData = krnlDataPtr;
return( CRYPT_OK );
}
void endSendMessage( void )
{
krnlData = NULL;
}
/****************************************************************************
* *
* Message Queue *
* *
****************************************************************************/
/* Enqueue a message */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int enqueueMessage( const int objectHandle,
const MESSAGE_HANDLING_INFO *handlingInfoPtr,
const MESSAGE_TYPE message,
IN_OPT const void *messageDataPtr,
const int messageValue )
{
MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
int queuePos, i, iterationCount;
ORIGINAL_INT_VAR( queueEnd, krnlData->queueEnd );
/* Precondition: It's a valid message being sent to a valid object */
PRE( isValidObject( objectHandle ) );
PRE( isReadPtr( handlingInfoPtr, sizeof( MESSAGE_HANDLING_INFO ) ) );
PRE( isValidMessage( message & MESSAGE_MASK ) );
/* Sanity-check the state/make sure that we don't overflow the queue
(this object is not responding to messages... now all we need is
GPF's). We return a timeout error on overflow to indicate that there
are too many messages queued for this (or other) objects */
if( krnlData->queueEnd < 0 || \
krnlData->queueEnd >= MESSAGE_QUEUE_SIZE - 1 )
{
ENSURES( krnlData->queueEnd >= 0 );
assert( DEBUG_WARN );
return( CRYPT_ERROR_TIMEOUT );
}
/* Precondition: There's room to enqueue the message */
PRE( krnlData->queueEnd >= 0 && \
krnlData->queueEnd < MESSAGE_QUEUE_SIZE - 1 );
/* Check whether a message to this object is already present in the
queue */
for( queuePos = krnlData->queueEnd - 1, iterationCount = 0;
queuePos >= 0 && iterationCount++ < MESSAGE_QUEUE_SIZE; queuePos-- )
{
if( messageQueue[ queuePos ].objectHandle == objectHandle )
break;
}
ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );
/* Postcondition: queuePos = -1 if not present, position in queue if
present */
POST( queuePos == -1 || \
( queuePos >= 0 && queuePos < krnlData->queueEnd ) );
/* Sanity-check the queue positioning */
ENSURES( queuePos >= -1 && queuePos < krnlData->queueEnd );
/* Enqueue the message:
+---------------+ +---------------+
|.|.|x|x|y|z| | -> |.|.|x|x|#|y|z| |
+---------------+ +---------------+
^ ^ ^ ^
qPos qEnd qPos qEnd */
queuePos++; /* Insert after current position */
for( i = krnlData->queueEnd - 1, iterationCount = 0;
i >= queuePos && iterationCount < MESSAGE_QUEUE_SIZE;
i--, iterationCount++ )
messageQueue[ i + 1 ] = messageQueue[ i ];
ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );
memset( &messageQueue[ queuePos ], 0, sizeof( MESSAGE_QUEUE_DATA ) );
messageQueue[ queuePos ].objectHandle = objectHandle;
messageQueue[ queuePos ].handlingInfoPtr = handlingInfoPtr;
messageQueue[ queuePos ].message = message;
messageQueue[ queuePos ].messageDataPtr = messageDataPtr;
messageQueue[ queuePos ].messageValue = messageValue;
krnlData->queueEnd++;
/* Postcondition: The queue is within bounds and has grown by one
element */
POST( krnlData->queueEnd > 0 && \
krnlData->queueEnd <= MESSAGE_QUEUE_SIZE - 1 );
POST( krnlData->queueEnd == ORIGINAL_VALUE( queueEnd ) + 1 );
/* If a message for this object is already present tell the caller to
defer processing */
if( queuePos > 0 )
return( OK_SPECIAL );
return( CRYPT_OK );
}
/* Dequeue a message */
CHECK_RETVAL \
static int dequeueMessage( const int messagePosition )
{
MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
int i, iterationCount;
ORIGINAL_INT_VAR( queueEnd, krnlData->queueEnd );
/* Precondition: We're deleting a valid queue position */
PRE( messagePosition >= 0 && messagePosition < krnlData->queueEnd );
/* Sanity-check the state */
ENSURES( messagePosition >= 0 && \
messagePosition < krnlData->queueEnd && \
krnlData->queueEnd > 0 && \
krnlData->queueEnd < MESSAGE_QUEUE_SIZE );
/* Move the remaining messages down and clear the last entry */
for( i = messagePosition, iterationCount = 0;
i < krnlData->queueEnd - 1 && \
iterationCount++ < MESSAGE_QUEUE_SIZE; i++ )
messageQueue[ i ] = messageQueue[ i + 1 ];
ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );
zeroise( &messageQueue[ krnlData->queueEnd - 1 ],
sizeof( MESSAGE_QUEUE_DATA ) );
krnlData->queueEnd--;
/* Postcondition: the queue is one element shorter, all queue entries
are valid, and all non-queue entries are empty */
POST( krnlData->queueEnd == ORIGINAL_VALUE( queueEnd ) - 1 );
POST( krnlData->queueEnd >= 0 && \
krnlData->queueEnd < MESSAGE_QUEUE_SIZE - 1 );
FORALL( i, 0, krnlData->queueEnd,
messageQueue[ i ].handlingInfoPtr != NULL );
FORALL( i, krnlData->queueEnd, MESSAGE_QUEUE_SIZE,
messageQueue[ i ].handlingInfoPtr == NULL );
return( CRYPT_OK );
}
/* Get the next message in the queue */
CHECK_RETVAL \
static BOOLEAN getNextMessage( const int objectHandle,
OUT_OPT MESSAGE_QUEUE_DATA *messageQueueInfo )
{
MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
int i;
/* Preconditions: It's a valid object table entry. It's not necessarily
a valid object since we may be de-queueing messages for it because
it's just been destroyed */
PRE( objectHandle == SYSTEM_OBJECT_HANDLE || \
objectHandle == DEFAULTUSER_OBJECT_HANDLE || \
isHandleRangeValid( objectHandle ) );
PRE( messageQueueInfo == NULL || \
isWritePtr( messageQueueInfo, sizeof( MESSAGE_QUEUE_DATA ) ) );
/* Clear return value */
if( messageQueueInfo != NULL )
memset( messageQueueInfo, 0, sizeof( MESSAGE_QUEUE_DATA ) );
/* Sanity-check the state */
ENSURES( krnlData->queueEnd >= 0 && \
krnlData->queueEnd < MESSAGE_QUEUE_SIZE );
/* Find the next message for this object. Since other messages can have
come and gone in the meantime, we have to scan from the start each
time */
for( i = 0; i < krnlData->queueEnd && i < MESSAGE_QUEUE_SIZE; i++ )
{
if( messageQueue[ i ].objectHandle == objectHandle )
{
int status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -