⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtcs.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		retExt( sessionInfoPtr, status, 
				"Unexpected RTCS encapsulation type %d", actionType );
	status = envelopeUnwrap( sessionInfoPtr->receiveBuffer, 
							 sessionInfoPtr->receiveBufEnd,
							 sessionInfoPtr->receiveBuffer, &dataLength, 
							 sessionInfoPtr->receiveBufSize, CRYPT_UNUSED );
	if( cryptStatusError( status ) )
		retExt( sessionInfoPtr, status,
				"Invalid RTCS request data (CMS enveloped data)" );

	/* Create an RTCS response.  We always create this since an empty 
	   response is sent to indicate an error condition */
	setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_RTCS_RESPONSE );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	sessionInfoPtr->iCertResponse = createInfo.cryptHandle;

	/* Import the request as a cryptlib object and try and read the nonce
	   from it */
	setMessageCreateObjectIndirectInfo( &createInfo,
							sessionInfoPtr->receiveBuffer, dataLength,
							CRYPT_CERTTYPE_RTCS_REQUEST );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		retExt( sessionInfoPtr, status, "Invalid RTCS request contents" );
	setMessageData( &msgData, protocolInfo->nonce, CRYPT_MAX_HASHSIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  IMESSAGE_GETATTRIBUTE_S, &msgData, 
							  CRYPT_CERTINFO_CMS_NONCE );
	if( cryptStatusOK( status ) )
		protocolInfo->nonceSize = msgData.length;

	/* Create an RTCS response and add the request information to it */
	status = krnlSendMessage( sessionInfoPtr->iCertResponse,
							  IMESSAGE_SETATTRIBUTE, 
							  &createInfo.cryptHandle,
							  CRYPT_IATTRIBUTE_RTCSREQUEST );
	krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		retExt( sessionInfoPtr, status, 
				"Couldn't create RTCS response from request" );
	return( CRYPT_OK );
	}

/* Return a response to an RTCS client */

static int sendServerResponse( SESSION_INFO *sessionInfoPtr,
							   RTCS_PROTOCOL_INFO *protocolInfo )
	{
	CRYPT_CERTIFICATE iCmsAttributes = CRYPT_UNUSED;
	RESOURCE_DATA msgData;
	int status;

	/* Check the entries from the request against the cert store and sign
	   the resulting status information ("Love, ken").  Note that
	   CRYPT_ERROR_INVALID is a valid return status for the sigcheck call
	   since it indicates that one (or more) of the certs was revoked */
	status = krnlSendMessage( sessionInfoPtr->iCertResponse,
							  IMESSAGE_CRT_SIGCHECK, NULL,
							  sessionInfoPtr->cryptKeyset );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_INVALID )
		retExt( sessionInfoPtr, status,
				"Couldn't check RTCS request against certificate store" );

	/* If there's a nonce present, create CMS attributes to contain it */
	if( protocolInfo->nonceSize > 0 )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;

		setMessageCreateObjectInfo( &createInfo, 
									CRYPT_CERTTYPE_CMS_ATTRIBUTES );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CERTIFICATE );
		if( cryptStatusError( status ) )
			return( status );
		iCmsAttributes = createInfo.cryptHandle;
		setMessageData( &msgData, protocolInfo->nonce, 
						protocolInfo->nonceSize );
		status = krnlSendMessage( iCmsAttributes, IMESSAGE_SETATTRIBUTE_S, 
								  &msgData, CRYPT_CERTINFO_CMS_NONCE );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		}

	/* Sign the response data using the responder's key and send it to the 
	   client */
	setMessageData( &msgData, sessionInfoPtr->receiveBuffer,
					sessionInfoPtr->receiveBufSize );
	status = krnlSendMessage( sessionInfoPtr->iCertResponse,
							  IMESSAGE_CRT_EXPORT, &msgData, 
							  CRYPT_ICERTFORMAT_DATA );
	if( cryptStatusOK( status ) )
		status = envelopeSign( sessionInfoPtr->receiveBuffer, msgData.length,
							   sessionInfoPtr->receiveBuffer, 
							   &sessionInfoPtr->receiveBufEnd, 
							   sessionInfoPtr->receiveBufSize, 
							   CRYPT_CONTENT_RTCSRESPONSE,
							   sessionInfoPtr->privateKey, iCmsAttributes );
	if( iCmsAttributes != CRYPT_UNUSED )
		krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		retExt( sessionInfoPtr, status,
				"Couldn't create RTCS response (CMS enveloped data)" );
	DEBUG_DUMP( "rtcs_sresp", sessionInfoPtr->receiveBuffer, 
				sessionInfoPtr->receiveBufEnd );
	return( writePkiDatagram( sessionInfoPtr ) );
	}

/****************************************************************************
*																			*
*								Init/Shutdown Functions						*
*																			*
****************************************************************************/

/* Exchange data with an RTCS client/server */

static int clientTransact( SESSION_INFO *sessionInfoPtr )
	{
	int status;

	/* Get cert status information from the server */
	status = sendClientRequest( sessionInfoPtr );
	if( cryptStatusOK( status ) )
		status = readServerResponse( sessionInfoPtr );
	return( status );
	}

static int serverTransact( SESSION_INFO *sessionInfoPtr )
	{
	RTCS_PROTOCOL_INFO protocolInfo;
	int status;

	/* Send cert status information to the client */
	memset( &protocolInfo, 0, sizeof( RTCS_PROTOCOL_INFO ) );
	status = readClientRequest( sessionInfoPtr, &protocolInfo );
	if( cryptStatusOK( status ) )
		status = sendServerResponse( sessionInfoPtr, &protocolInfo );
	return( status );
	}

/****************************************************************************
*																			*
*					Control Information Management Functions				*
*																			*
****************************************************************************/

static int setAttributeFunction( SESSION_INFO *sessionInfoPtr,
								 const void *data,
								 const CRYPT_ATTRIBUTE_TYPE type )
	{
	const CRYPT_CERTIFICATE rtcsRequest = *( ( CRYPT_CERTIFICATE * ) data );
	RESOURCE_DATA msgData = { NULL, 0 };
	int status;

	assert( type == CRYPT_SESSINFO_REQUEST );

	/* Make sure that everything is set up ready to go.  Since RTCS requests
	   aren't signed like normal cert objects, we can't just check the 
	   immutable attribute but have to perform a dummy export for which the 
	   cert export code will return an error status if there's a problem 
	   with the request.  If not, it pseudo-signs the request (if it hasn't 
	   already done so) and prepares it for use */
	status = krnlSendMessage( rtcsRequest, IMESSAGE_CRT_EXPORT, &msgData, 
							  CRYPT_ICERTFORMAT_DATA );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_NUM1 );

	/* If we haven't already got a server name explicitly set, try and get
	   it from the request */
	if( findSessionAttribute( sessionInfoPtr->attributeList,
							  CRYPT_SESSINFO_SERVER_NAME ) == NULL )
		{
		char buffer[ MAX_URL_SIZE ];

		setMessageData( &msgData, buffer, MAX_URL_SIZE );
		status = krnlSendMessage( rtcsRequest, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_RESPONDERURL );
		if( cryptStatusOK( status ) )
			krnlSendMessage( sessionInfoPtr->objectHandle, 
							 IMESSAGE_SETATTRIBUTE_S, &msgData, 
							 CRYPT_SESSINFO_SERVER_NAME );
		}

	/* Add the request and increment its usage count */
	krnlSendNotifier( rtcsRequest, IMESSAGE_INCREFCOUNT );
	sessionInfoPtr->iCertRequest = rtcsRequest;

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Session Access Routines							*
*																			*
****************************************************************************/

/* Open/close an RTCS session */

int setAccessMethodRTCS( SESSION_INFO *sessionInfoPtr )
	{
	static const PROTOCOL_INFO protocolInfo = {
		/* General session information */
		TRUE,						/* Request-response protocol */
		SESSION_ISHTTPTRANSPORT,	/* Flags */
		80,							/* HTTP port */
		SESSION_NEEDS_REQUEST,		/* Client flags */
		SESSION_NEEDS_PRIVATEKEY |	/* Server flags */
			SESSION_NEEDS_PRIVKEYSIGN | \
			SESSION_NEEDS_PRIVKEYCERT | \
			SESSION_NEEDS_KEYSET,
		1, 1, 1,					/* Version 1 */
		"application/rtcs-request",	/* Client content-type */
		"application/rtcs-response",/* Server content-type */
	
		/* Protocol-specific information */
		};

	/* Set the access method pointers */
	sessionInfoPtr->protocolInfo = &protocolInfo;
	if( sessionInfoPtr->flags & SESSION_ISSERVER )
		sessionInfoPtr->transactFunction = serverTransact;
	else
		sessionInfoPtr->transactFunction = clientTransact;
	sessionInfoPtr->setAttributeFunction = setAttributeFunction;

	return( CRYPT_OK );
	}
#endif /* USE_RTCS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -