📄 int_msg.c
字号:
/* Preconditions */
PRE( isValidObject( objectHandle ) );
PRE( attribute == CRYPT_PROPERTY_OWNER || \
attribute == CRYPT_PROPERTY_FORWARDCOUNT || \
attribute == CRYPT_PROPERTY_LOCKED || \
attribute == CRYPT_PROPERTY_USAGECOUNT || \
attribute == CRYPT_IATTRIBUTE_TYPE || \
attribute == CRYPT_IATTRIBUTE_SUBTYPE || \
attribute == CRYPT_IATTRIBUTE_STATUS || \
attribute == CRYPT_IATTRIBUTE_INTERNAL || \
attribute == CRYPT_IATTRIBUTE_ACTIONPERMS );
PRE( isWritePtr( messageDataPtr, sizeof( int ) ) );
switch( attribute )
{
/* User-accessible properties */
case CRYPT_PROPERTY_OWNER:
/* We allow this to be read since its value can be determined
anyway with a trial access */
if( !( objectInfoPtr->flags & OBJECT_FLAG_OWNED ) )
return( CRYPT_ERROR_NOTINITED );
#ifdef USE_THREADS
#ifdef NONSCALAR_THREADS
/* A very small number of pthreads implementations use non-
scalar thread IDs, which we can't easily handle when all that
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:
retIntError();
}
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 */
PRE( value == CRYPT_OK );
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 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;
}
/* Postcondition: The object is in a valid state */
POST( !isInvalidObjectState( objectHandle ) );
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 );
ENSURES( objectInfoPtr->lockCount > 0 );
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:
retIntError();
}
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 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -