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

📄 cryptses.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*						cryptlib Secure Session Routines					*
*						Copyright Peter Gutmann 1998-2005					*
*																			*
****************************************************************************/

#include <stdio.h>
#include <stdarg.h>
#include "crypt.h"
#ifdef INC_ALL
  #include "asn1.h"
  #include "stream.h"
  #include "session.h"
#else
  #include "misc/asn1.h"
  #include "io/stream.h"
  #include "session/session.h"
#endif /* Compiler-specific includes */

/* The number of entries in the SSL session cache.  Note that when changing 
   the SESSIONCACHE_SIZE value you need to also change MAX_ALLOC_SIZE in 
   kernel/sec_mem.c to allow the allocation of such large amounts of secure 
   memory */

#if defined( CONFIG_CONSERVE_MEMORY )
  #define SESSIONCACHE_SIZE			64
#else
  #define SESSIONCACHE_SIZE			512
#endif /* CONFIG_CONSERVE_MEMORY */

static SCOREBOARD_INFO scoreboardInfo;

#ifdef USE_SESSIONS

/****************************************************************************
*																			*
*								Session Message Handler						*
*																			*
****************************************************************************/

/* Handle a message sent to a session object */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int sessionMessageFunction( INOUT TYPECAST( CONTEXT_INFO * ) \
									void *objectInfoPtr,
								   IN_MESSAGE const MESSAGE_TYPE message,
								   void *messageDataPtr,
								   IN_INT_Z const int messageValue )
	{
	SESSION_INFO *sessionInfoPtr = ( SESSION_INFO * ) objectInfoPtr;
	int status;

	assert( isWritePtr( objectInfoPtr, sizeof( SESSION_INFO ) ) );

	REQUIRES( message > MESSAGE_NONE && message < MESSAGE_LAST );
	REQUIRES( messageValue >= 0 && messageValue < MAX_INTLENGTH );

	/* Process destroy object messages */
	if( message == MESSAGE_DESTROY )
		{
		/* Shut down the session if required.  Nemo nisi mors */
		if( sessionInfoPtr->flags & SESSION_ISOPEN )
			{
			sessionInfoPtr->flags |= SESSION_ISCLOSINGDOWN;
			sessionInfoPtr->shutdownFunction( sessionInfoPtr );
			}

		/* Clear and free session state information if necessary */
		if( sessionInfoPtr->sendBuffer != NULL )
			{
			zeroise( sessionInfoPtr->sendBuffer,
					 sessionInfoPtr->sendBufSize );
			clFree( "sessionMessageFunction", sessionInfoPtr->sendBuffer );
			}
		if( sessionInfoPtr->receiveBuffer != NULL )
			{
			zeroise( sessionInfoPtr->receiveBuffer,
					 sessionInfoPtr->receiveBufSize );
			clFree( "sessionMessageFunction", sessionInfoPtr->receiveBuffer );
			}

		/* Clear session attributes if necessary */
		if( sessionInfoPtr->attributeList != NULL )
			deleteSessionInfoAll( &sessionInfoPtr->attributeList,
								  &sessionInfoPtr->attributeListCurrent );

		/* Clean up any session-related objects if necessary */
		if( sessionInfoPtr->iKeyexCryptContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iKeyexCryptContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iKeyexAuthContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iKeyexAuthContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iCryptInContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iCryptInContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iCryptOutContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iCryptOutContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iAuthInContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iAuthInContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iAuthOutContext != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iAuthOutContext,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iCertRequest != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iCertRequest,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->iCertResponse != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->iCertResponse,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->privateKey != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->privateKey,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->cryptKeyset != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->cryptKeyset,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->privKeyset != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->privKeyset,
							  IMESSAGE_DECREFCOUNT );
		if( sessionInfoPtr->transportSession != CRYPT_ERROR )
			krnlSendNotifier( sessionInfoPtr->transportSession,
							  IMESSAGE_DECREFCOUNT );

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		/* If it's a protocol-specific attribute, forward it directly to
		   the low-level code */
		if( message != MESSAGE_DELETEATTRIBUTE && \
			( ( messageValue >= CRYPT_SESSINFO_FIRST_SPECIFIC && \
				messageValue <= CRYPT_SESSINFO_LAST_SPECIFIC ) || \
			  messageValue == CRYPT_IATTRIBUTE_ENC_TIMESTAMP ) )
			{
			if( message == MESSAGE_SETATTRIBUTE || \
				message == MESSAGE_SETATTRIBUTE_S )
				{
				assert( sessionInfoPtr->setAttributeFunction != NULL );

				status = sessionInfoPtr->setAttributeFunction( sessionInfoPtr,
											messageDataPtr, messageValue );
				if( status == CRYPT_ERROR_INITED )
					{
					setErrorInfo( sessionInfoPtr, messageValue, 
								  CRYPT_ERRTYPE_ATTR_PRESENT );
					return( CRYPT_ERROR_INITED );
					}
				}
			else
				{
				REQUIRES( message == MESSAGE_GETATTRIBUTE || \
						  message == MESSAGE_GETATTRIBUTE_S );

				status = sessionInfoPtr->getAttributeFunction( sessionInfoPtr,
											messageDataPtr, messageValue );
				if( status == CRYPT_ERROR_NOTFOUND )
					{
					setErrorInfo( sessionInfoPtr, messageValue, 
								  CRYPT_ERRTYPE_ATTR_ABSENT );
					return( CRYPT_ERROR_NOTFOUND );
					}
				}
			return( status );
			}

		if( message == MESSAGE_GETATTRIBUTE )
			return( getSessionAttribute( sessionInfoPtr, 
										 ( int * ) messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_GETATTRIBUTE_S )
			return( getSessionAttributeS( sessionInfoPtr, 
										  ( MESSAGE_DATA * ) messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE )
			{
			/* CRYPT_IATTRIBUTE_INITIALISED is purely a notification message 
			   with no parameters so we don't pass it down to the attribute-
			   handling code */
			if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
				return( CRYPT_OK );

			return( setSessionAttribute( sessionInfoPtr, 
										 *( ( int * ) messageDataPtr ),
										 messageValue ) );
			}
		if( message == MESSAGE_SETATTRIBUTE_S )
			{
			const MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;

			return( setSessionAttributeS( sessionInfoPtr, msgData->data, 
										  msgData->length, messageValue ) );
			}
		if( message == MESSAGE_DELETEATTRIBUTE )
			return( deleteSessionAttribute( sessionInfoPtr, messageValue ) );

		retIntError();
		}

	/* Process object-specific messages */
	if( message == MESSAGE_ENV_PUSHDATA )
		{
		MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;
		const int length = msgData->length;
		int bytesCopied;

		/* Unless we're told otherwise, we've copied zero bytes */
		msgData->length = 0;

		/* If the session isn't open yet, perform an implicit open */
		if( !( sessionInfoPtr->flags & SESSION_ISOPEN ) )
			{
			status = krnlSendMessage( sessionInfoPtr->objectHandle, 
									  IMESSAGE_SETATTRIBUTE, MESSAGE_VALUE_TRUE,
									  CRYPT_SESSINFO_ACTIVE );
			if( cryptStatusError( status ) )
				return( status );

			/* The session is ready to process data, move it into the high
			   state */
			status = krnlSendMessage( sessionInfoPtr->objectHandle, 
									  IMESSAGE_SETATTRIBUTE, 
									  MESSAGE_VALUE_UNUSED, 
									  CRYPT_IATTRIBUTE_INITIALISED );
			if( cryptStatusError( status ) )
				return( status );
			}
		ENSURES( sessionInfoPtr->flags & SESSION_ISOPEN );
		ENSURES( sessionInfoPtr->sendBuffer != NULL );

		/* Make sure that everything is in order */
		if( sessionInfoPtr->flags & SESSION_SENDCLOSED )
			{
			/* If the other side has closed its receive channel (which is 
			   our send channel), we can't send any more data, although we 
			   can still get data on our receive channel if we haven't closed
			   it as well.  The closing of the other side's send channel is 
			   detected during a read and isn't a write error but a normal 
			   state change in the channel so we don't treat it as an error 
			   when it's seen at the read stage until the caller actually 
			   tries to write data to the closed channel */
			sessionInfoPtr->writeErrorState = CRYPT_ERROR_COMPLETE;
			}
		if( sessionInfoPtr->writeErrorState != CRYPT_OK )
			return( sessionInfoPtr->writeErrorState );

		/* Write the data */
		clearErrorInfo( sessionInfoPtr );
		status = putSessionData( sessionInfoPtr, msgData->data, length, 
								 &bytesCopied );
		if( cryptStatusOK( status ) )
			msgData->length = bytesCopied;
		ENSURES( ( cryptStatusError( status ) && bytesCopied == 0 ) || \
				 ( cryptStatusOK( status ) && bytesCopied >= 0 ) );
		return( status );
		}
	if( message == MESSAGE_ENV_POPDATA )
		{
		MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;
		const int length = msgData->length;
		int bytesCopied;

		/* Unless we're told otherwise, we've copied zero bytes */
		msgData->length = 0;

		/* If the session isn't open, there's nothing to pop */
		if( !( sessionInfoPtr->flags & SESSION_ISOPEN ) )
			return( CRYPT_ERROR_NOTINITED );

		ENSURES( sessionInfoPtr->flags & SESSION_ISOPEN );
		ENSURES( sessionInfoPtr->receiveBuffer != NULL );

		/* Make sure that everything is in order */
		if( sessionInfoPtr->readErrorState != CRYPT_OK )
			return( sessionInfoPtr->readErrorState );

		/* Read the data */
		clearErrorInfo( sessionInfoPtr );
		status = getSessionData( sessionInfoPtr, msgData->data, length,
								 &bytesCopied );
		if( cryptStatusOK( status ) )
			msgData->length = bytesCopied;
		ENSURES( ( cryptStatusError( status ) && bytesCopied == 0 ) || \
				 ( cryptStatusOK( status ) && bytesCopied >= 0 ) );
		return( status );
		}

	retIntError();
	}

/* Open a session.  This is a low-level function encapsulated by createSession()
   and used to manage error exits */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int openSession( OUT_HANDLE_OPT CRYPT_SESSION *iCryptSession,
						IN_HANDLE const CRYPT_USER iCryptOwner,
						IN_ENUM( CRYPT_SESSION ) \
							const CRYPT_SESSION_TYPE sessionType,
						OUT_PTR SESSION_INFO **sessionInfoPtrPtr )
	{
	CRYPT_SESSION_TYPE sessionBaseType;
	SESSION_INFO *sessionInfoPtr;
	const PROTOCOL_INFO *protocolInfoPtr;
	static const MAP_TABLE subtypeMapTbl[] = {
		{ CRYPT_SESSION_SSH, SUBTYPE_SESSION_SSH },
		{ CRYPT_SESSION_SSH_SERVER, SUBTYPE_SESSION_SSH_SVR },
		{ CRYPT_SESSION_SSL, SUBTYPE_SESSION_SSL },
		{ CRYPT_SESSION_SSL_SERVER, SUBTYPE_SESSION_SSL_SVR },
		{ CRYPT_SESSION_RTCS, SUBTYPE_SESSION_RTCS },
		{ CRYPT_SESSION_RTCS_SERVER, SUBTYPE_SESSION_RTCS_SVR },
		{ CRYPT_SESSION_OCSP, SUBTYPE_SESSION_OCSP },
		{ CRYPT_SESSION_OCSP_SERVER, SUBTYPE_SESSION_OCSP_SVR },
		{ CRYPT_SESSION_TSP, SUBTYPE_SESSION_TSP },
		{ CRYPT_SESSION_TSP_SERVER, SUBTYPE_SESSION_TSP_SVR },
		{ CRYPT_SESSION_CMP, SUBTYPE_SESSION_CMP },
		{ CRYPT_SESSION_CMP_SERVER, SUBTYPE_SESSION_CMP_SVR },
		{ CRYPT_SESSION_SCEP, SUBTYPE_SESSION_SCEP },
		{ CRYPT_SESSION_SCEP_SERVER, SUBTYPE_SESSION_SCEP_SVR },
		{ CRYPT_SESSION_CERTSTORE_SERVER, SUBTYPE_SESSION_CERT_SVR },
		{ CRYPT_ERROR, CRYPT_ERROR }, { CRYPT_ERROR, CRYPT_ERROR }
		};
	static const MAP_TABLE basetypeMapTbl[] = {
		{ CRYPT_SESSION_SSH, CRYPT_SESSION_SSH },
		{ CRYPT_SESSION_SSH_SERVER, CRYPT_SESSION_SSH },
		{ CRYPT_SESSION_SSL, CRYPT_SESSION_SSL },
		{ CRYPT_SESSION_SSL_SERVER, CRYPT_SESSION_SSL },
		{ CRYPT_SESSION_RTCS, CRYPT_SESSION_RTCS },
		{ CRYPT_SESSION_RTCS_SERVER, CRYPT_SESSION_RTCS },
		{ CRYPT_SESSION_OCSP, CRYPT_SESSION_OCSP },
		{ CRYPT_SESSION_OCSP_SERVER, CRYPT_SESSION_OCSP },
		{ CRYPT_SESSION_TSP, CRYPT_SESSION_TSP },
		{ CRYPT_SESSION_TSP_SERVER, CRYPT_SESSION_TSP },
		{ CRYPT_SESSION_CMP, CRYPT_SESSION_CMP },
		{ CRYPT_SESSION_CMP_SERVER, CRYPT_SESSION_CMP },
		{ CRYPT_SESSION_SCEP, CRYPT_SESSION_SCEP },
		{ CRYPT_SESSION_SCEP_SERVER, CRYPT_SESSION_SCEP },

⌨️ 快捷键说明

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