📄 cryptkrn.c
字号:
*( ( 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_OK );
}
static int setPropertyAttribute( const int objectHandle,
const CRYPT_ATTRIBUTE_TYPE attribute,
void *messageDataPtr )
{
OBJECT_INFO *objectInfoPtr = &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( messageDataPtr != NULL );
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 */
objectInfoPtr->objectOwner = THREAD_SELF();
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( __MVS__ ) || ( defined( __UNIX__ ) && defined( _MPRAS ) ) )
objectInfoPtr->objectOwner = ( THREAD_HANDLE ) value;
objectInfoPtr->flags |= OBJECT_FLAG_OWNED;
#endif /* Non-scalar threading environments */
}
break;
case CRYPT_PROPERTY_FORWARDCOUNT:
if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
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 ) )
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,
CRYPT_IATTRIBUTE_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 the 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 )
objectInfoPtr->flags |= OBJECT_FLAG_INTERNAL;
else
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++;
objectInfoPtr->lockOwner = THREAD_SELF();
}
else
{
/* Precondition: The lock count is positive */
PRE( objectInfoPtr->lockCount > 0 );
objectInfoPtr->lockCount--;
}
/* If it's a certificate, notify it to save/restore its internal
state */
if( objectInfoPtr->type == OBJECT_TYPE_CERTIFICATE )
objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
MESSAGE_CHANGENOTIFY, messageDataPtr,
CRYPT_IATTRIBUTE_LOCKED );
break;
default:
assert( NOTREACHED );
}
return( CRYPT_OK );
}
/* 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 */
static int incRefCount( const int objectHandle, const int dummy1,
const void *dummy2 )
{
ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );
/* Preconditions */
PRE( isValidObject( objectHandle ) );
/* 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 );
}
static int decRefCount( const int objectHandle, const int dummy1,
const void *dummy2 )
{
int status;
ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );
/* Preconditions */
PRE( isValidObject( objectHandle ) );
/* Decrement an object's reference count */
if( objectTable[ objectHandle ].referenceCount > 0 )
{
objectTable[ objectHandle ].referenceCount--;
/* Postconditions: We decremented the reference count and it's
greater than or equal to zero (the ground state) */
POST( objectTable[ objectHandle ].referenceCount >= 0 );
POST( objectTable[ objectHandle ].referenceCount == \
ORIGINAL_VALUE( refCt ) - 1 );
#if 0
if( objectInfoPtr->dependentDevice != CRYPT_ERROR )
/* Velisurmaaja */
decRefCount( objectInfoPtr->dependentDevice, 0, NULL );
if( objectInfoPtr->dependentObject != CRYPT_ERROR )
decRefCount( objectInfoPtr->dependentObject, 0, NULL );
#endif
return( CRYPT_OK );
}
/* We're already at a single reference, destroy the object. Since this
may take some time, we unlock the object table around the call */
unlockResource( objectTable );
status = krnlSendNotifier( objectHandle, IMESSAGE_DESTROY );
lockResource( objectTable );
/* Postconditions - none. We can't be sure that the object has been
destroyed at this point since the message will have been enqueued */
return( status );
}
/* Get/set dependent objects for an object */
static int getDependentObject( const int objectHandle,
const int targetType,
const void *messageDataPtr )
{
int *valuePtr = ( int * ) messageDataPtr, localObjectHandle;
/* Preconditions */
PRE( isValidObject( objectHandle ) );
PRE( isValidType( targetType ) );
PRE( messageDataPtr != NULL );
/* Clear return value */
*valuePtr = CRYPT_ERROR;
localObjectHandle = findTargetType( objectHandle, targetType );
if( cryptStatusError( localObjectHandle ) )
{
/* Postconditions: No dependent object found */
POST( *valuePtr == CRYPT_ERROR );
return( CRYPT_ARGERROR_OBJECT );
}
*valuePtr = localObjectHandle;
/* Postconditions: We found a dependent object */
POST( isValidObject( *valuePtr ) && \
isSameOwningObject( objectHandle, *valuePtr ) );
return( CRYPT_OK );
}
static int setDependentObject( const int objectHandle,
const int incReferenceCount,
const void *messageDataPtr )
{
const int dependentObject = *( ( int * ) messageDataPtr );
int *objectHandlePtr, status = CRYPT_OK;
/* Preconditions */
PRE( isValidObject( objectHandle ) );
PRE( incReferenceCount == TRUE || incReferenceCount == FALSE );
PRE( isValidHandle( dependentObject ) );
/* Determine which dependent object value to update based on its type */
if( !isValidObject( dependentObject ) )
/* The object was signalled after the message was
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -