📄 cryptses.c
字号:
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 + -