cryptkrn.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,648 行 · 第 1/5 页
C
1,648 行
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_VAR( 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 */
unlockGlobalResource( objectTable );
krnlSendNotifier( objectHandle, RESOURCE_IMESSAGE_DESTROY );
lockGlobalResource( objectTable );
/* Postconditions - none. We can't be sure the object has been destroyed
at this point since the message will have been enqueued */
return( CRYPT_OK );
}
/* 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 ) && \
isSameOwner( 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 sent */
return( CRYPT_ERROR_SIGNALLED );
objectHandlePtr = \
( objectTable[ dependentObject ].type == OBJECT_TYPE_DEVICE ) ? \
&objectTable[ objectHandle ].dependentDevice : \
&objectTable[ objectHandle ].dependentObject;
/* Inner precondition */
PRE( *objectHandlePtr == CRYPT_ERROR );
PRE( isSameOwner( objectHandle, dependentObject ) );
/* Update the dependent object's reference count if required and record
the new status in the object table. Dependent objects can be
established in one of two ways, by taking an existing object and
attaching it to another object (which increments its reference count,
since it's now being referred to by the original owner and by the
object it's attached to), or by creating a new object and attaching
it to another object (which doesn't increment the reference count
since it's only referred to by the controlling object). An example of
the former operation is adding a context from a cert request to a cert
(the cert request is referenced by both the caller and the cert), an
example of the latter operation is attaching a data-only cert to a
context (the cert is only referenced by the context) */
if( incReferenceCount )
incRefCount( dependentObject, 0, NULL );
*objectHandlePtr = dependentObject;
/* Certs and contexts have special relationships in that the cert can
constrain the use of the context beyond its normal level. When we
attach a cert to a context or a public-key context to a cert, we have
to find the way in which the cert constrains the context and adjust
the context's action ACL as appropriate. In contrast when we attach
a private key context to a cert we don't change the context's action
ACL until the context/cert pair is re-instantiated (eg by writing it
to a keyset and then re-reading it, which instantiates it as a
context with a cert attached). The reason for this is that the cert
key usage may constrain the context in a way which renders its use
impossible (for example creating an encryption-only self-signed cert
would be impossible), or the context may be associated with multiple
mutually-exclusive certs (one signature-only, one encryption-only),
or the key usage in the cert may not be set until after the context
is attached, or any number of other variations. Because of this a
cert -> context attach (done when instantiating a context+cert object
pair) or a public key context -> cert attach (done when importing a
cert, which creates the cert as the primary object and attaches the
context for non-data-only certs) imposes the cert constraint on the
context, but a private key context -> cert attach (done when creating
a cert object) doesn't impose them.
Because a key with a certificate attached indicates that it's
(probably) being used for some function which involves interaction
with a relying party (ie that it probably has more value than a raw
key with no strings attached), we set the action permission to
ACTION_PERM_NONE_EXTERNAL rather than allowing ACTION_PERM_ALL to both
ensure that it's only used in a safe manner via the cryptlib internal
mechanisms, and to make sure that it's not possible to utilize the
signature/encryption duality of some algorithms to create a signature
where it's been disallowed */
if( ( objectTable[ objectHandle ].type == OBJECT_TYPE_CONTEXT && \
objectTable[ dependentObject ].type == OBJECT_TYPE_CERTIFICATE ) || \
( objectTable[ objectHandle ].type == OBJECT_TYPE_CERTIFICATE && \
objectTable[ dependentObject ].type == OBJECT_TYPE_CONTEXT && \
cryptStatusError( krnlSendMessage( dependentObject,
RESOURCE_IMESSAGE_CHECK, NULL, RESOURCE_MESSAGE_CHECK_PKC_PRIVATE ) ) ) )
status = updateDependentObjectPerms( objectHandle, dependentObject );
/* Postconditions */
POST( isValidObject( *objectHandlePtr ) && \
isSameOwner( objectHandle, *objectHandlePtr ) );
return( status );
}
/****************************************************************************
* *
* Misc *
* *
****************************************************************************/
/* Find the ACL for an object attribute */
static const ATTRIBUTE_ACL *findAttributeACL( const CRYPT_ATTRIBUTE_TYPE attribute,
const BOOLEAN isInternalMessage )
{
/* Precondition: If it's an internal message (ie not raw data from the user)
then the attribute is valid */
PRE( !isInternalMessage || \
isAttribute( attribute ) || isInternalAttribute( attribute ) );
/* Perform a hardcoded binary search for the attribute ACL, this minimises
the number of comparisons necessary to find a match */
if( attribute < CRYPT_CTXINFO_LAST )
{
if( attribute < CRYPT_GENERIC_LAST )
{
if( attribute > CRYPT_PROPERTY_FIRST && \
attribute < CRYPT_PROPERTY_LAST )
{
POST( propertyACL[ attribute - CRYPT_PROPERTY_FIRST - 1 ].attribute == attribute );
return( &propertyACL[ attribute - CRYPT_PROPERTY_FIRST - 1 ] );
}
if( attribute > CRYPT_GENERIC_FIRST && \
attribute < CRYPT_GENERIC_LAST )
{
POST( genericACL[ attribute - CRYPT_GENERIC_FIRST - 1 ].attribute == attribute );
return( &genericACL[ attribute - CRYPT_GENERIC_FIRST - 1 ] );
}
}
else
{
if( attribute > CRYPT_OPTION_FIRST && \
attribute < CRYPT_OPTION_LAST )
{
POST( optionACL[ attribute - CRYPT_OPTION_FIRST - 1 ].attribute == attribute );
return( &optionACL[ attribute - CRYPT_OPTION_FIRST - 1 ] );
}
if( attribute > CRYPT_CTXINFO_FIRST && \
attribute < CRYPT_CTXINFO_LAST )
{
POST( contextACL[ attribute - CRYPT_CTXINFO_FIRST - 1 ].attribute == attribute );
return( &contextACL[ attribute - CRYPT_CTXINFO_FIRST - 1 ] );
}
}
}
else
{
if( attribute < CRYPT_KEYINFO_LAST )
{
if( attribute > CRYPT_CERTINFO_FIRST && \
attribute < CRYPT_CERTINFO_LAST )
{
/* Certificate attributes are split into subranges so we have to
adjust the offsets to get the right ACL */
if( attribute < CRYPT_CERTINFO_FIRST_EXTENSION )
{
if( attribute > CRYPT_CERTINFO_FIRST_CERTINFO && \
attribute < CRYPT_CERTINFO_LAST_CERTINFO )
{
POST( certificateACL[ attribute - CRYPT_CERTINFO_FIRST_CERTINFO - 1 ].attribute == attribute );
return( &certificateACL[ attribute - CRYPT_CERTINFO_FIRST_CERTINFO - 1 ] );
}
if( attribute > CRYPT_CERTINFO_FIRST_NAME && \
attribute < CRYPT_CERTINFO_LAST_NAME )
{
POST( certNameACL[ attribute - CRYPT_CERTINFO_FIRST_NAME - 1 ].attribute == attribute );
return( &certNameACL[ attribute - CRYPT_CERTINFO_FIRST_NAME - 1 ] );
}
}
else
{
if( attribute > CRYPT_CERTINFO_FIRST_EXTENSION && \
attribute < CRYPT_CERTINFO_LAST_EXTENSION )
{
POST( certExtensionACL[ attribute - CRYPT_CERTINFO_FIRST_EXTENSION - 1 ].attribute == attribute );
return( &certExtensionACL[ attribute - CRYPT_CERTINFO_FIRST_EXTENSION - 1 ] );
}
if( attribute > CRYPT_CERTINFO_FIRST_CMS && \
attribute < CRYPT_CERTINFO_LAST_CMS )
{
POST( certSmimeACL[ attribute - CRYPT_CERTINFO_FIRST_CMS - 1 ].attribute == attribute );
return( &certSmimeACL[ attribute - CRYPT_CERTINFO_FIRST_CMS - 1 ] );
}
}
}
if( attribute > CRYPT_KEYINFO_FIRST && \
attribute < CRYPT_KEYINFO_LAST )
{
POST( keysetACL[ attribute - CRYPT_KEYINFO_FIRST - 1 ].attribute == attribute );
return( &keysetACL[ attribute - CRYPT_KEYINFO_FIRST - 1 ] );
}
}
else
{
if( attribute > CRYPT_DEVINFO_FIRST && \
attribute < CRYPT_DEVINFO_LAST )
{
POST( deviceACL[ attribute - CRYPT_DEVINFO_FIRST - 1 ].attribute == attribute );
return( &deviceACL[ attribute - CRYPT_DEVINFO_FIRST - 1 ] );
}
if( attribute > CRYPT_ENVINFO_FIRST && \
attribute < CRYPT_ENVINFO_LAST )
{
POST( envelopeACL[ attribute - CRYPT_ENVINFO_FIRST - 1 ].attribute == attribute );
return( &envelopeACL[ attribute - CRYPT_ENVINFO_FIRST - 1 ] );
}
if( attribute > CRYPT_SESSINFO_FIRST && \
attribute < CRYPT_SESSINFO_LAST )
{
POST( sessionACL[ attribute - CRYPT_SESSINFO_FIRST - 1 ].attribute == attribute );
return( &sessionACL[ attribute - CRYPT_SESSINFO_FIRST - 1 ] );
}
if( attribute > CRYPT_USERINFO_FIRST && \
attribute < CRYPT_USERINFO_LAST )
{
POST( userACL[ attribute - CRYPT_USERINFO_FIRST - 1 ].attribute == attribute );
return( &userACL[ attribute - CRYPT_USERINFO_FIRST - 1 ] );
}
/* If it's an external message then the internal attributes don't exist */
if( isInternalMessage && \
attribute > CRYPT_IATTRIBUTE_FIRST && \
attribute < CRYPT_IATTRIBUTE_LAST )
{
POST( isInternalMessage );
POST( internalACL[ attribute - CRYPT_IATTRIBUTE_FIRST - 1 ].attribute == attribute );
return( &internalACL[ attribute - CRYPT_IATTRIBUTE_FIRST - 1 ] );
}
}
}
return( NULL );
}
/* Find the ACL for a parameter object */
static const PARAMETER_ACL *findParamACL( const RESOURCE_MESSAGE_TYPE message )
{
static const PARAMETER_ACL paramACL[] = {
/* Certs can only be signed by (private-key) PKC contexts */
{ RESOURCE_MESSAGE_CRT_SIGN,
ST_CTX_PKC, ST_NONE },
/* Signatures can be checked with a raw PKC context or a cert or cert
chain. The object being checked can also be checked against a CRL
or against revocation data in a cert store */
{ RESOURCE_MESSAGE_CRT_SIGCHECK,
ST_CTX_PKC | ST_CERT_CERT | ST_CERT_CERTCHAIN | ST_CERT_CRL, ST_KEYSET_DBMS },
{ RESOURCE_MESSAGE_NONE }
};
int paramACLindex = 0;
/* Precondition: It's a message which takes an object parameter */
PRE( isParamMessage( message ) );
/* Find the ACL entry for this message type */
do
{
if( paramACL[ paramACLindex ].type == message )
return( ¶mACL[ paramACLindex ] );
paramACLindex++;
}
while( paramACL[ paramACLindex ].type != RESOURCE_MESSAGE_NONE );
/* Postcondition: We found a matching ACL entry */
POST( NOTREACHED );
return( NULL ); /* Get rid of compiler warning */
}
/****************************************************************************
* *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?