📄 int_msg.c
字号:
scalar thread IDs, which we can't easily handle when all we
have is an integer handle. However, the need to bind threads
to objects only exists because of Win32 security holes
arising from the ability to perform thread injection, so this
isn't a big issue */
return( CRYPT_ERROR_FAILED );
#else
*valuePtr = ( int ) objectInfoPtr->objectOwner;
#endif /* Non-scalar threading environments */
#else
*valuePtr = 0;
#endif /* USE_THREADS */
break;
case CRYPT_PROPERTY_FORWARDCOUNT:
if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
return( CRYPT_ERROR_PERMISSION );
*valuePtr = objectInfoPtr->forwardCount;
break;
case CRYPT_PROPERTY_LOCKED:
/* We allow this to be read since its value can be determined
anyway with a trial write */
*( ( BOOLEAN * ) messageDataPtr ) = \
( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED ) ? \
TRUE : FALSE;
break;
case CRYPT_PROPERTY_USAGECOUNT:
*valuePtr = objectInfoPtr->usageCount;
break;
/* Internal properties */
case CRYPT_IATTRIBUTE_TYPE :
*valuePtr = objectInfoPtr->type;
break;
case CRYPT_IATTRIBUTE_SUBTYPE :
*valuePtr = objectInfoPtr->subType;
break;
case CRYPT_IATTRIBUTE_STATUS:
*valuePtr = objectInfoPtr->flags & OBJECT_FLAGMASK_STATUS;
break;
case CRYPT_IATTRIBUTE_INTERNAL:
*( ( BOOLEAN * ) messageDataPtr ) = \
( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL ) ? \
TRUE : FALSE;
break;
case CRYPT_IATTRIBUTE_ACTIONPERMS:
*valuePtr = objectInfoPtr->actionFlags;
break;
default:
assert( NOTREACHED );
return( CRYPT_ARGERROR_VALUE );
}
return( CRYPT_OK );
}
int setPropertyAttribute( const int objectHandle,
const CRYPT_ATTRIBUTE_TYPE attribute,
void *messageDataPtr )
{
OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
const int value = *( ( int * ) messageDataPtr );
/* Preconditions */
PRE( isValidObject( objectHandle ) );
PRE( attribute == CRYPT_PROPERTY_HIGHSECURITY || \
attribute == CRYPT_PROPERTY_OWNER || \
attribute == CRYPT_PROPERTY_FORWARDCOUNT || \
attribute == CRYPT_PROPERTY_LOCKED || \
attribute == CRYPT_PROPERTY_USAGECOUNT || \
attribute == CRYPT_IATTRIBUTE_STATUS || \
attribute == CRYPT_IATTRIBUTE_INTERNAL || \
attribute == CRYPT_IATTRIBUTE_ACTIONPERMS || \
attribute == CRYPT_IATTRIBUTE_LOCKED );
PRE( isReadPtr( messageDataPtr, sizeof( int ) ) );
PRE( objectHandle >= NO_SYSTEM_OBJECTS || \
attribute == CRYPT_IATTRIBUTE_STATUS );
switch( attribute )
{
/* User-accessible properties */
case CRYPT_PROPERTY_HIGHSECURITY:
/* This is a combination property that makes an object owned,
non-forwardable, and locked */
if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
return( CRYPT_ERROR_PERMISSION );
#ifdef USE_THREADS
objectInfoPtr->objectOwner = THREAD_SELF();
#endif /* USE_THREADS */
objectInfoPtr->forwardCount = 0;
objectInfoPtr->flags |= OBJECT_FLAG_ATTRLOCKED | OBJECT_FLAG_OWNED;
break;
case CRYPT_PROPERTY_OWNER:
/* This property can still be changed (even if the object is
locked) until the forwarding count drops to zero, otherwise
locking the object would prevent any forwarding */
if( objectInfoPtr->forwardCount != CRYPT_UNUSED )
{
if( objectInfoPtr->forwardCount <= 0 )
return( CRYPT_ERROR_PERMISSION );
objectInfoPtr->forwardCount--;
}
if( value == CRYPT_UNUSED )
objectInfoPtr->flags &= ~OBJECT_FLAG_OWNED;
else
{
#if defined( USE_THREADS ) && !defined( NONSCALAR_THREADS )
objectInfoPtr->objectOwner = ( THREAD_HANDLE ) value;
objectInfoPtr->flags |= OBJECT_FLAG_OWNED;
#endif /* USE_THREADS && scalar threading environments */
}
break;
case CRYPT_PROPERTY_FORWARDCOUNT:
if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
return( CRYPT_ERROR_PERMISSION );
if( objectInfoPtr->forwardCount != CRYPT_UNUSED && \
objectInfoPtr->forwardCount < value )
/* Once set the forward count can only be decreased, never
increased */
return( CRYPT_ERROR_PERMISSION );
objectInfoPtr->forwardCount = value;
break;
case CRYPT_PROPERTY_LOCKED:
/* Precondition: This property can only be set to true */
PRE( value );
objectInfoPtr->flags |= OBJECT_FLAG_ATTRLOCKED;
break;
case CRYPT_PROPERTY_USAGECOUNT:
if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED || \
( objectInfoPtr->usageCount != CRYPT_UNUSED && \
objectInfoPtr->usageCount < value ) )
/* Once set the usage count can only be decreased, never
increased */
return( CRYPT_ERROR_PERMISSION );
objectInfoPtr->usageCount = value;
break;
/* Internal properties */
case CRYPT_IATTRIBUTE_STATUS:
/* We're clearing an error/abnormal state or setting the object
to the busy state */
PRE( value == CRYPT_OK || value == CRYPT_ERROR_TIMEOUT );
if( isInvalidObjectState( objectHandle ) )
{
/* If the object is in an abnormal state, we can only (try to)
return it back to the normal state after the problem is
resolved */
PRE( value == CRYPT_OK );
/* If we're resetting the object status from busy to OK,
notify the object in case there's any extra processing to
be done */
if( objectInfoPtr->flags & OBJECT_FLAG_BUSY )
{
/* Precondition: Only contexts can be busy */
PRE( objectInfoPtr->type == OBJECT_TYPE_CONTEXT );
/* If the notification returns an error, the object is
still performing some sort of processing (e.g. cleanup/
shutdown), don't reset the status (it'll be done later
when the object is ready) */
if( objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
MESSAGE_CHANGENOTIFY, messageDataPtr,
MESSAGE_CHANGENOTIFY_STATUS ) == CRYPT_OK )
objectInfoPtr->flags &= ~OBJECT_FLAG_BUSY;
break;
}
/* If we're processing a notification from the caller that
the object init is complete and the object was destroyed
while it was being created (which sets its state to
CRYPT_ERROR_SIGNALLED), tell the caller to convert the
message to a destroy object message unless it's a system
object, which can't be explicitly destroyed. In this case
we just return an error so the cryptlib init fails */
if( objectInfoPtr->flags & OBJECT_FLAG_SIGNALLED )
return( ( objectHandle < NO_SYSTEM_OBJECTS ) ?
CRYPT_ERROR_SIGNALLED : OK_SPECIAL );
/* We're transitioning the object to the initialised state */
PRE( objectInfoPtr->flags & OBJECT_FLAG_NOTINITED );
objectInfoPtr->flags &= ~OBJECT_FLAG_NOTINITED;
POST( !( objectInfoPtr->flags & OBJECT_FLAG_NOTINITED ) );
break;
}
/* Inner precondition: The object is in a valid state */
PRE( !isInvalidObjectState( objectHandle ) );
/* We're setting the object's busy flag because it's about to
perform an async op */
if( value == CRYPT_ERROR_TIMEOUT )
objectInfoPtr->flags |= OBJECT_FLAG_BUSY;
break;
case CRYPT_IATTRIBUTE_INTERNAL:
if( value )
{
PRE( !( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL ) );
objectInfoPtr->flags |= OBJECT_FLAG_INTERNAL;
}
else
{
PRE( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL );
objectInfoPtr->flags &= ~OBJECT_FLAG_INTERNAL;
}
break;
case CRYPT_IATTRIBUTE_ACTIONPERMS:
objectInfoPtr->actionFlags = \
updateActionPerms( objectInfoPtr->actionFlags, value );
break;
case CRYPT_IATTRIBUTE_LOCKED:
/* Incremement or decrement the object's lock count depending on
whether we're locking or unlocking it */
if( value )
{
objectInfoPtr->lockCount++;
#ifdef USE_THREADS
objectInfoPtr->lockOwner = THREAD_SELF();
#endif /* USE_THREADS */
}
else
{
/* Precondition: The lock count is positive */
PRE( objectInfoPtr->lockCount > 0 );
if( objectInfoPtr->lockCount <= 0 )
{
assert( NOTREACHED );
return( CRYPT_ERROR_PERMISSION );
}
objectInfoPtr->lockCount--;
}
/* If it's a certificate, notify it that it should save/restore
its internal state */
if( objectInfoPtr->type == OBJECT_TYPE_CERTIFICATE )
objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
MESSAGE_CHANGENOTIFY, messageDataPtr,
MESSAGE_CHANGENOTIFY_STATE );
break;
default:
assert( NOTREACHED );
return( CRYPT_ARGERROR_VALUE );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Update Internal Properties *
* *
****************************************************************************/
/* Increment/decrement the reference count for an object. This adjusts the
reference count as appropriate and sends destroy messages if the reference
count goes negative */
int incRefCount( const int objectHandle, const int dummy1,
const void *dummy2, const BOOLEAN dummy3 )
{
OBJECT_INFO *objectTable = krnlData->objectTable;
ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );
/* Preconditions */
PRE( isValidObject( objectHandle ) );
POST( objectTable[ objectHandle ].referenceCount >= 0 );
/* Increment an object's reference count */
objectTable[ objectHandle ].referenceCount++;
/* Postcondition: We incremented the reference count and it's now greater
than zero (the ground state) */
POST( objectTable[ objectHandle ].referenceCount >= 1 );
POST( objectTable[ objectHandle ].referenceCount == \
ORIGINAL_VALUE( refCt ) + 1 );
return( CRYPT_OK );
}
int decRefCount( const int objectHandle, const int dummy1,
const void *dummy2, const BOOLEAN isInternal )
{
OBJECT_INFO *objectTable = krnlData->objectTable;
int status;
ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );
/* Preconditions */
PRE( isValidObject( objectHandle ) );
/* If the message is coming from an external source (in other words if
it's an external caller destroying the object), make the object
internal. This marks it as invalid for any external access, so that
to the caller it looks like it's been destroyed even if its reference
count keeps it active */
if( !isInternal )
{
PRE( !isInternalObject( objectHandle ) );
objectTable[ objectHandle ].flags |= OBJECT_FLAG_INTERNAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -