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

📄 cryptses.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
		assert( sessionInfoPtr->sendBuffer != NULL );
		assert( sessionInfoPtr->preparePacketFunction != 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;
		assert( ( cryptStatusError( status ) && bytesCopied == 0 ) || \
				( cryptStatusOK( status ) && bytesCopied >= 0 ) );
		return( status );
		}
	if( message == MESSAGE_ENV_POPDATA )
		{
		RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
		const int length = msgData->length;
		int bytesCopied, status;

		/* 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 );

		assert( sessionInfoPtr->flags & SESSION_ISOPEN );
		assert( sessionInfoPtr->receiveBuffer != NULL );
		assert( sessionInfoPtr->readHeaderFunction != NULL );
		assert( sessionInfoPtr->processBodyFunction != 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;
		assert( ( cryptStatusError( status ) && bytesCopied == 0 ) || \
				( cryptStatusOK( status ) && bytesCopied >= 0 ) );
		return( status );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

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

static int openSession( CRYPT_SESSION *iCryptSession,
						const CRYPT_USER cryptOwner,
						const CRYPT_SESSION_TYPE sessionType,
						SESSION_INFO **sessionInfoPtrPtr )
	{
	SESSION_INFO *sessionInfoPtr;
	const PROTOCOL_INFO *protocolInfoPtr;
	static const struct {
		const CRYPT_SESSION_TYPE sessionType;
		const CRYPT_SESSION_TYPE baseSessionType;
		const int subType;
		} sessionTypes[] = {
	{ CRYPT_SESSION_SSH, CRYPT_SESSION_SSH, SUBTYPE_SESSION_SSH },
	{ CRYPT_SESSION_SSH_SERVER, CRYPT_SESSION_SSH, SUBTYPE_SESSION_SSH_SVR },
	{ CRYPT_SESSION_SSL, CRYPT_SESSION_SSL, SUBTYPE_SESSION_SSL },
	{ CRYPT_SESSION_SSL_SERVER, CRYPT_SESSION_SSL, SUBTYPE_SESSION_SSL_SVR },
	{ CRYPT_SESSION_RTCS, CRYPT_SESSION_RTCS, SUBTYPE_SESSION_RTCS },
	{ CRYPT_SESSION_RTCS_SERVER, CRYPT_SESSION_RTCS, SUBTYPE_SESSION_RTCS_SVR },
	{ CRYPT_SESSION_OCSP, CRYPT_SESSION_OCSP, SUBTYPE_SESSION_OCSP },
	{ CRYPT_SESSION_OCSP_SERVER, CRYPT_SESSION_OCSP, SUBTYPE_SESSION_OCSP_SVR },
	{ CRYPT_SESSION_TSP, CRYPT_SESSION_TSP, SUBTYPE_SESSION_TSP },
	{ CRYPT_SESSION_TSP_SERVER, CRYPT_SESSION_TSP, SUBTYPE_SESSION_TSP_SVR },
	{ CRYPT_SESSION_CMP, CRYPT_SESSION_CMP, SUBTYPE_SESSION_CMP },
	{ CRYPT_SESSION_CMP_SERVER, CRYPT_SESSION_CMP, SUBTYPE_SESSION_CMP_SVR },
	{ CRYPT_SESSION_SCEP, CRYPT_SESSION_SCEP, SUBTYPE_SESSION_SCEP },
	{ CRYPT_SESSION_SCEP_SERVER, CRYPT_SESSION_SCEP, SUBTYPE_SESSION_SCEP_SVR },
	{ CRYPT_SESSION_CERTSTORE_SERVER, CRYPT_SESSION_CERTSTORE_SERVER, SUBTYPE_SESSION_CERT_SVR },
	{ CRYPT_SESSION_NONE, CRYPT_SESSION_NONE, CRYPT_ERROR }
	};
	int storageSize = 0, i, status;

	assert( sessionInfoPtrPtr != NULL );

	/* Clear the return values */
	*iCryptSession = CRYPT_ERROR;
	*sessionInfoPtrPtr = NULL;

	/* Map the external session type to a base type and internal object
	   subtype */
	for( i = 0; sessionTypes[ i ].sessionType != CRYPT_SESSION_NONE; i++ )
		if( sessionTypes[ i ].sessionType == sessionType )
			break;
	assert( sessionTypes[ i ].sessionType != CRYPT_SESSION_NONE );

	/* Set up subtype-specific information */
	switch( sessionTypes[ i ].baseSessionType )
		{
		case CRYPT_SESSION_SSH:
			storageSize = sizeof( SSH_INFO );
			break;

		case CRYPT_SESSION_SSL:
			storageSize = sizeof( SSL_INFO );
			break;

		case CRYPT_SESSION_TSP:
			storageSize = sizeof( TSP_INFO );
			break;

		case CRYPT_SESSION_CMP:
			storageSize = sizeof( CMP_INFO );
			break;
		}

	/* Create the session object */
	status = krnlCreateObject( ( void ** ) &sessionInfoPtr, 
							   sizeof( SESSION_INFO ) + storageSize, 
							   OBJECT_TYPE_SESSION, sessionTypes[ i ].subType,
							   CREATEOBJECT_FLAG_NONE, cryptOwner, 
							   ACTION_PERM_NONE_ALL, sessionMessageFunction );
	if( cryptStatusError( status ) )
		return( status );
	*sessionInfoPtrPtr = sessionInfoPtr;
	*iCryptSession = sessionInfoPtr->objectHandle = status;
	sessionInfoPtr->ownerHandle = cryptOwner;
	sessionInfoPtr->type = sessionTypes[ i ].baseSessionType;
	switch( sessionTypes[ i ].baseSessionType )
		{
		case CRYPT_SESSION_SSH:
			sessionInfoPtr->sessionSSH = ( SSH_INFO * ) sessionInfoPtr->storage;
			break;

		case CRYPT_SESSION_SSL:
			sessionInfoPtr->sessionSSL = ( SSL_INFO * ) sessionInfoPtr->storage;
			break;

		case CRYPT_SESSION_TSP:
			sessionInfoPtr->sessionTSP = ( TSP_INFO * ) sessionInfoPtr->storage;
			break;

		case CRYPT_SESSION_CMP:
			sessionInfoPtr->sessionCMP = ( CMP_INFO * ) sessionInfoPtr->storage;
			break;
		}
	sessionInfoPtr->storageSize = storageSize;

	/* If it's a server session, mark it as such.  An HTTP certstore session 
	   is a special case in that it's always a server session */
	if( ( sessionTypes[ i ].sessionType != \
		  sessionTypes[ i ].baseSessionType ) || \
		( sessionTypes[ i ].sessionType == CRYPT_SESSION_CERTSTORE_SERVER ) )
		sessionInfoPtr->flags = SESSION_ISSERVER;

	/* Set up any internal objects to contain invalid handles */
	sessionInfoPtr->iKeyexCryptContext = \
		sessionInfoPtr->iKeyexAuthContext = CRYPT_ERROR;
	sessionInfoPtr->iCryptInContext = \
		sessionInfoPtr->iCryptOutContext = CRYPT_ERROR;
	sessionInfoPtr->iAuthInContext = \
		sessionInfoPtr->iAuthOutContext = CRYPT_ERROR;
	sessionInfoPtr->iCertRequest = \
		sessionInfoPtr->iCertResponse = CRYPT_ERROR;
	sessionInfoPtr->privateKey = CRYPT_ERROR;
	sessionInfoPtr->cryptKeyset = CRYPT_ERROR;
	sessionInfoPtr->privKeyset =  CRYPT_ERROR;
	sessionInfoPtr->transportSession = CRYPT_ERROR;
	sessionInfoPtr->networkSocket = CRYPT_ERROR;
	sessionInfoPtr->readTimeout = \
		sessionInfoPtr->writeTimeout = \
			sessionInfoPtr->connectTimeout = CRYPT_ERROR;

	/* Set up any additinal values */
	sessionInfoPtr->authResponse = CRYPT_UNUSED;

	/* Set up the access information for the session and initialise it */
	switch( sessionTypes[ i ].baseSessionType )
		{
		case CRYPT_SESSION_CERTSTORE_SERVER:
			status = setAccessMethodCertstore( sessionInfoPtr );
			break;

		case CRYPT_SESSION_CMP:
			status = setAccessMethodCMP( sessionInfoPtr );
			break;

		case CRYPT_SESSION_RTCS:
			status = setAccessMethodRTCS( sessionInfoPtr );
			break;

		case CRYPT_SESSION_OCSP:
			status = setAccessMethodOCSP( sessionInfoPtr );
			break;

		case CRYPT_SESSION_SCEP:
			status = setAccessMethodSCEP( sessionInfoPtr );
			break;

		case CRYPT_SESSION_SSH:
			status = setAccessMethodSSH( sessionInfoPtr );
			break;

		case CRYPT_SESSION_SSL:
			status = setAccessMethodSSL( sessionInfoPtr );
			break;

		case CRYPT_SESSION_TSP:
			status = setAccessMethodTSP( sessionInfoPtr );
			break;

		default:
			assert( NOTREACHED );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Check that the protocol info is OK */
	protocolInfoPtr = sessionInfoPtr->protocolInfo;
	assert( ( protocolInfoPtr->isReqResp && \
			  protocolInfoPtr->bufSize == 0 && \
			  protocolInfoPtr->sendBufStartOfs == 0 && \
			  protocolInfoPtr->maxPacketSize == 0 ) || 
			( !protocolInfoPtr->isReqResp && \
			  protocolInfoPtr->bufSize >= MIN_BUFFER_SIZE && \
			  protocolInfoPtr->sendBufStartOfs >= 5 && \
			  protocolInfoPtr->maxPacketSize <= protocolInfoPtr->bufSize ) );
	assert( ( ( protocolInfoPtr->flags & SESSION_ISHTTPTRANSPORT ) && \
			  protocolInfoPtr->port == 80 ) || \
			( protocolInfoPtr->port != 80 ) );
	assert( protocolInfoPtr->port > 21 );
	assert( protocolInfoPtr->version >= 0 );
	assert( ( protocolInfoPtr->isReqResp && \
			  protocolInfoPtr->clientContentType != NULL && \
			  protocolInfoPtr->serverContentType != NULL ) || 
			( !protocolInfoPtr->isReqResp && \
			  protocolInfoPtr->clientContentType == NULL && \
			  protocolInfoPtr->serverContentType == NULL ) );

	/* Copy mutable protocol-specific information into the session info */
	sessionInfoPtr->flags |= protocolInfoPtr->flags;
	sessionInfoPtr->clientReqAttrFlags = protocolInfoPtr->clientReqAttrFlags;
	sessionInfoPtr->serverReqAttrFlags = protocolInfoPtr->serverReqAttrFlags;
	sessionInfoPtr->version = protocolInfoPtr->version;
	if( protocolInfoPtr->isReqResp )
		{
		sessionInfoPtr->sendBufSize = CRYPT_UNUSED;
		sessionInfoPtr->receiveBufSize = MIN_BUFFER_SIZE;
		}
	else
		{
		sessionInfoPtr->sendBufSize = sessionInfoPtr->receiveBufSize = \
				protocolInfoPtr->bufSize;
		sessionInfoPtr->sendBufStartOfs = sessionInfoPtr->receiveBufStartOfs = \
				protocolInfoPtr->sendBufStartOfs;
		sessionInfoPtr->maxPacketSize = protocolInfoPtr->maxPacketSize;
		}

	/* Install default handlers if no session-specific ones are provided */
	initSessionIO( sessionInfoPtr );

	/* Check that the handlers are all OK */
	assert( sessionInfoPtr->connectFunction != NULL );
	assert( sessionInfoPtr->transactFunction != NULL );
	assert( ( protocolInfoPtr->isReqResp && \
			  sessionInfoPtr->readHeaderFunction == NULL && \
			  sessionInfoPtr->processBodyFunction == NULL && \
			  sessionInfoPtr->preparePacketFunction == NULL ) || \
			( !protocolInfoPtr->isReqResp && \
			  sessionInfoPtr->readHeaderFunction != NULL && \
			  sessionInfoPtr->processBodyFunction != NULL && \
			  sessionInfoPtr->preparePacketFunction != NULL ) );

	return( CRYPT_OK );
	}

int createSession( MESSAGE_CREATEOBJECT_INFO *createInfo,
				   const void *auxDataPtr, const int auxValue )
	{
	CRYPT_SESSION iCryptSession;
	SESSION_INFO *sessionInfoPtr;
	int initStatus, status;

	assert( auxDataPtr == NULL );
	assert( auxValue == 0 );

	/* Perform basic error checking */
	if( createInfo->arg1 <= CRYPT_SESSION_NONE || \
		createInfo->arg1 >= CRYPT_SESSION_LAST )
		return( CRYPT_ARGERROR_NUM1 );

	/* Pass the call on to the lower-level open function */
	initStatus = openSession( &iCryptSession, createInfo->cryptOwner,
							  createInfo->arg1, &sessionInfoPtr );
	if( sessionInfoPtr == NULL )
		return( initStatus );	/* Create object failed, return immediately */
	if( cryptStatusError( initStatus ) )
		/* The init failed, make sure that the object gets destroyed when we 
		   notify the kernel that the setup process is complete */
		krnlSendNotifier( iCryptSession, IMESSAGE_DESTROY );

	/* We've finished setting up the object-type-specific info, tell the
	   kernel that the object is ready for use */
	status = krnlSendMessage( iCryptSession, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusError( initStatus ) || cryptStatusError( status ) )
		return( cryptStatusError( initStatus ) ? initStatus : status );
	createInfo->cryptHandle = iCryptSession;
	return( CRYPT_OK );
	}

/* Generic management function for this class of object */

int sessionManagementFunction( const MANAGEMENT_ACTION_TYPE action )
	{
	static int initLevel = 0;
	int status;

	assert( action == MANAGEMENT_ACTION_INIT || \
			action == MANAGEMENT_ACTION_PRE_SHUTDOWN || \
			action == MANAGEMENT_ACTION_SHUTDOWN );

	switch( action )
		{
		case MANAGEMENT_ACTION_INIT:
			status = netInitTCP();
			if( cryptStatusOK( status ) )
				{
				initLevel++;
				if( krnlIsExiting() )
					/* The kernel is shutting down, exit */
					return( CRYPT_ERROR_PERMISSION );
				status = initSessionCache();
				}
			if( cryptStatusOK( status ) )
				initLevel++;
			return( status );

		case MANAGEMENT_ACTION_PRE_SHUTDOWN:
			/* We have to wait for the driver binding to complete before we
			   can start the

⌨️ 快捷键说明

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