📄 msg_acl.c
字号:
if( !isWritePtr( ( void * ) messageDataPtr, sizeof( int ) ) )
return( CRYPT_ARGERROR_STR1 );
break;
}
/* Inner precondition: We're sending data to the object */
PRE( localMessage == MESSAGE_SETATTRIBUTE );
/* If it's a standard range check, make sure that the attribute
value is within the allowed range */
if( !isSpecialRange( attributeACL ) )
{
if( !checkNumericRange( *valuePtr, attributeACL->lowRange,
attributeACL->highRange ) )
return( CRYPT_ARGERROR_NUM1 );
break;
}
/* It's a special-case range check */
assert( isSpecialRange( attributeACL ) );
switch( getSpecialRangeType( attributeACL ) )
{
case RANGEVAL_ANY:
break;
case RANGEVAL_SELECTVALUE:
if( *valuePtr != CRYPT_UNUSED )
return( CRYPT_ARGERROR_NUM1 );
break;
case RANGEVAL_ALLOWEDVALUES:
if( !checkAttributeRangeSpecial( RANGEVAL_ALLOWEDVALUES,
getSpecialRangeInfo( attributeACL ),
*valuePtr ) )
return( CRYPT_ARGERROR_NUM1 );
break;
case RANGEVAL_SUBRANGES:
if( !checkAttributeRangeSpecial( RANGEVAL_SUBRANGES,
getSpecialRangeInfo( attributeACL ),
*valuePtr ) )
return( CRYPT_ARGERROR_NUM1 );
break;
default:
retIntError();
}
break;
}
case ATTRIBUTE_VALUE_OBJECT:
{
const OBJECT_ACL *objectACL = attributeACL->extendedInfo;
const int *valuePtr = messageDataPtr;
int objectParamHandle, objectParamSubType;
/* Inner precondition: If it's an internal message, it must be
a numeric value */
PRE( !isInternalMessage || \
localMessage == MESSAGE_GETATTRIBUTE || \
localMessage == MESSAGE_SETATTRIBUTE );
PRE( isReadPtr( messageDataPtr, sizeof( int ) ) );
/* Must be a numeric value */
if( localMessage != MESSAGE_GETATTRIBUTE && \
localMessage != MESSAGE_SETATTRIBUTE )
return( CRYPT_ARGERROR_VALUE );
/* If we're sending the data back to the caller, the only thing
that we can check is the presence of a writeable output
buffer */
if( localMessage == MESSAGE_GETATTRIBUTE )
{
if( !isWritePtr( ( void * ) messageDataPtr, sizeof( int ) ) )
return( CRYPT_ARGERROR_STR1 );
break;
}
/* Inner precondition: We're sending data to the object */
PRE( localMessage == MESSAGE_SETATTRIBUTE );
/* Must contain a valid object handle */
if( !fullObjectCheck( *valuePtr, message ) || \
!isSameOwningObject( objectHandle, *valuePtr ) )
return( CRYPT_ARGERROR_NUM1 );
/* Object must be of the correct type */
if( objectACL->flags & ACL_FLAG_ROUTE_TO_CTX )
objectParamHandle = findTargetType( *valuePtr,
OBJECT_TYPE_CONTEXT );
else
{
if( objectACL->flags & ACL_FLAG_ROUTE_TO_CERT )
objectParamHandle = findTargetType( *valuePtr,
OBJECT_TYPE_CERTIFICATE );
else
objectParamHandle = *valuePtr;
}
if( cryptStatusError( objectParamHandle ) )
return( CRYPT_ARGERROR_NUM1 );
objectParamSubType = objectTable[ objectParamHandle ].subType;
if( !isValidSubtype( objectACL->subTypeA, objectParamSubType ) && \
!isValidSubtype( objectACL->subTypeB, objectParamSubType ) )
return( CRYPT_ARGERROR_NUM1 );
if( ( objectACL->flags & ACL_FLAG_STATE_MASK ) && \
!checkObjectState( objectACL->flags, objectParamHandle ) )
return( CRYPT_ARGERROR_NUM1 );
/* Postcondition: Object parameter is valid and accessible,
object is of the correct type and state */
POST( fullObjectCheck( *valuePtr, message ) && \
isSameOwningObject( objectHandle, *valuePtr ) );
POST( isValidSubtype( objectACL->subTypeA, objectParamSubType ) || \
isValidSubtype( objectACL->subTypeB, objectParamSubType ) );
POST( !( objectACL->flags & ACL_FLAG_STATE_MASK ) || \
checkObjectState( objectACL->flags, objectParamHandle ) );
break;
}
case ATTRIBUTE_VALUE_STRING:
case ATTRIBUTE_VALUE_WCSTRING:
{
const MESSAGE_DATA *msgData = messageDataPtr;
/* Inner precondition: If it's an internal message, it must be
a valid string value or a null value if we're obtaining a
length. Polled entropy data can be arbitrarily large so we
don't check its length */
PRE( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );
PRE( !isInternalMessage || \
( ( localMessage == MESSAGE_GETATTRIBUTE_S && \
( ( msgData->data == NULL && msgData->length == 0 ) || \
( msgData->length >= 1 && \
msgData->length < MAX_INTLENGTH && \
isWritePtr( msgData->data, msgData->length ) ) ) ) || \
( localMessage == MESSAGE_SETATTRIBUTE_S && \
isReadPtr( msgData->data, msgData->length ) && \
( msgData->length > 0 && \
msgData->length < MAX_INTLENGTH_SHORT || \
messageValue == CRYPT_IATTRIBUTE_ENTROPY ) ) ) );
/* Must be a string value */
if( localMessage != MESSAGE_GETATTRIBUTE_S && \
localMessage != MESSAGE_SETATTRIBUTE_S )
return( CRYPT_ARGERROR_VALUE );
/* If we're sending the data back to the caller, the only thing
that we can check is the presence of a writeable output
buffer. We return a string arg error for both the buffer and
length, since the length isn't explicitly specified by an
external caller */
if( localMessage == MESSAGE_GETATTRIBUTE_S )
{
if( !( ( msgData->data == NULL && msgData->length == 0 ) || \
( msgData->length > 0 && \
isWritePtr( msgData->data, msgData->length ) ) ) )
return( CRYPT_ARGERROR_STR1 );
break;
}
/* Inner precondition: We're sending data to the object */
PRE( localMessage == MESSAGE_SETATTRIBUTE_S );
/* Make sure that the string length is within the allowed
range */
if( isSpecialRange( attributeACL ) )
{
if( !checkAttributeRangeSpecial( \
getSpecialRangeType( attributeACL ),
getSpecialRangeInfo( attributeACL ),
msgData->length ) )
return( CRYPT_ARGERROR_NUM1 );
}
else
{
if( attributeACL->valueType == ATTRIBUTE_VALUE_WCSTRING )
{
if( !checkAttributeRangeWidechar( msgData->data,
msgData->length,
attributeACL->lowRange,
attributeACL->highRange ) )
return( CRYPT_ARGERROR_NUM1 );
}
else
{
if( msgData->length < attributeACL->lowRange || \
msgData->length > attributeACL->highRange )
return( CRYPT_ARGERROR_NUM1 );
}
}
if( msgData->length > 0 && \
!isReadPtr( msgData->data, msgData->length ) )
return( CRYPT_ARGERROR_STR1 );
break;
}
case ATTRIBUTE_VALUE_TIME:
{
const MESSAGE_DATA *msgData = messageDataPtr;
/* Inner precondition: If it's an internal message, it must be
a string value corresponding to a time_t */
PRE( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );
PRE( !isInternalMessage || \
( ( localMessage == MESSAGE_GETATTRIBUTE_S || \
localMessage == MESSAGE_SETATTRIBUTE_S ) && \
isReadPtr( msgData->data, msgData->length ) && \
msgData->length == sizeof( time_t ) ) );
/* Must be a string value */
if( localMessage != MESSAGE_GETATTRIBUTE_S && \
localMessage != MESSAGE_SETATTRIBUTE_S )
return( CRYPT_ARGERROR_VALUE );
/* If we're sending the data back to the caller, the only thing
that we can check is the presence of a writeable output
buffer. We return a string arg error for both the buffer and
length, since the length isn't explicitly specified by an
external caller */
if( localMessage == MESSAGE_GETATTRIBUTE_S )
{
if( !( ( msgData->data == NULL && msgData->length == 0 ) || \
( msgData->length > 0 && \
isWritePtr( msgData->data, msgData->length ) ) ) )
return( CRYPT_ARGERROR_STR1 );
break;
}
/* If we're sending the data back to the caller, we can't check
it yet */
if( localMessage == MESSAGE_GETATTRIBUTE_S )
break;
/* Inner precondition: We're sending data to the object */
PRE( localMessage == MESSAGE_SETATTRIBUTE_S );
/* Must contain a time_t in a sensible range */
if( !isReadPtr( msgData->data, sizeof( time_t ) ) || \
*( ( time_t * ) msgData->data ) <= MIN_TIME_VALUE )
return( CRYPT_ARGERROR_STR1 );
if( msgData->length != sizeof( time_t ) )
return( CRYPT_ARGERROR_NUM1 );
break;
}
case ATTRIBUTE_VALUE_SPECIAL:
{
int iterationCount = 0;
/* It's an ACL with an object-subtype-specific sub-ACL, find the
precise ACL for this object subtype */
for( attributeACL = getSpecialRangeInfo( attributeACL );
attributeACL->valueType != ATTRIBUTE_VALUE_NONE && \
iterationCount++ < FAILSAFE_ITERATIONS_MED;
attributeACL++ )
{
if( isValidSubtype( attributeACL->subTypeA, subType ) || \
isValidSubtype( attributeACL->subTypeB, subType ) )
break;
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
ENSURES( attributeACL->valueType != ATTRIBUTE_VALUE_NONE );
/* Recursively check the message against the sub-ACL */
return( preDispatchCheckAttributeAccess( objectHandle, message,
messageDataPtr, messageValue, attributeACL ) );
}
default:
retIntError();
}
return( CRYPT_OK );
}
/* It's a compare message, make sure that the parameters are OK */
int preDispatchCheckCompareParam( const int objectHandle,
const MESSAGE_TYPE message, /* Unused */
const void *messageDataPtr,
const int messageValue,
const void *dummy )
{
const OBJECT_INFO *objectTable = krnlData->objectTable;
const OBJECT_INFO *objectInfoPtr = &objectTable[ objectHandle ];
const COMPARE_ACL *compareACL = NULL;
/* Precondition: It's a valid compare message type */
PRE( isValidMessage( message & MESSAGE_MASK ) );
PRE( fullObjectCheck( objectHandle, message ) );
PRE( messageValue > MESSAGE_COMPARE_NONE && \
messageValue < MESSAGE_COMPARE_LAST );
/* Find the appropriate ACL for this compare type */
if( messageValue > MESSAGE_COMPARE_NONE && \
messageValue < MESSAGE_COMPARE_LAST )
compareACL = &compareACLTbl[ messageValue - 1 ];
ENSURES( compareACL != NULL );
/* Inner precondition: We have the correct ACL, and the full object
check has been performed by the kernel */
PRE( compareACL->compareType == messageValue );
/* Check the message target. The full object check has already been
performed by the message dispatcher so all we need to check is the
compare-specific subtype. We throw an exception if we find an
invalid parameter, both because this is an internal message and this
situation shouldn't occur, and because an error return from a compare
message is perfectly valid (it denotes a non-match) so parameter
errors won't otherwise be caught by the caller */
ENSURES( isValidSubtype( compareACL->objectACL.subTypeA, \
objectInfoPtr->subType ) );
if( ( compareACL->objectACL.flags & ACL_FLAG_STATE_MASK ) && \
!checkObjectState( compareACL->objectACL.flags, objectHandle ) )
retIntError();
/* Check the message parameters. We throw an exception if we find an
invalid parameter for the reason given above */
if( paramInfo( compareACL, 0 ).valueType == PARAM_VALUE_OBJECT )
{
STDC_UNUSED \
const CRYPT_HANDLE iCryptHandle = *( ( CRYPT_HANDLE * ) messageDataPtr );
PRE( fullObjectCheck( iCryptHandle, message ) && \
isSameOwningObject( objectHandle, iCryptHandle ) );
PRE( checkParamObject( paramInfo( compareACL, 0 ), iCryptHandle ) );
}
else
{
STDC_UNUSED \
const MESSAGE_DATA *msgData = messageDataPtr;
PRE( checkParamString( paramInfo( compareACL, 0 ),
msgData->data, msgData->length ) );
}
/* Postconditions: The compare parameters are valid, either an object
handle or a string value at least as big as a minimal-length DN */
POST( ( messageValue == MESSAGE_COMPARE_CERTOBJ && \
isValidHandle( *( ( CRYPT_HANDLE * ) messageDataPtr ) ) ) || \
( messageValue != MESSAGE_COMPARE_CERTOBJ && \
isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) && \
( ( MESSAGE_DATA * ) messageDataPtr )->length >= 2 && \
isReadPtr( ( ( MESSAGE_DATA * ) messageDataPtr )->data, \
( ( MESSAGE_DATA * ) messageDataPtr )->length ) ) );
return( CRYPT_OK );
}
/* It's a check message, make sure that the parameters are OK */
int preDispatchCheckCheckParam( const int objectHandle,
const MESSAGE_TYPE message,
const void *messageDataPtr, /* Unused */
const int messageValue,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -