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( &paramACL[ 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 + -
显示快捷键?