📄 cryptses.c
字号:
zeroise( sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufSize );
free( sessionInfoPtr->receiveBuffer );
}
/* Clean up any session-related crypto objects if necessary */
if( sessionInfoPtr->iKeyexCryptContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iKeyexCryptContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iKeyexAuthContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iKeyexAuthContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iCryptInContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iCryptInContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iCryptOutContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iCryptOutContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iAuthInContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iAuthInContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iAuthOutContext != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iAuthOutContext,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iCertRequest != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iCertRequest,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->iCertResponse != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->iCertResponse,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->privateKey != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->privateKey,
RESOURCE_IMESSAGE_DECREFCOUNT );
if( sessionInfoPtr->cryptKeyset != CRYPT_ERROR )
krnlSendNotifier( sessionInfoPtr->cryptKeyset,
RESOURCE_IMESSAGE_DECREFCOUNT );
/* Delete the objects locking variables and the object itself */
unlockResource( sessionInfoPtr );
deleteResourceLock( sessionInfoPtr );
zeroise( sessionInfoPtr, sizeof( SESSION_INFO ) );
free( sessionInfoPtr );
return( CRYPT_OK );
}
/* Process attribute get/set/delete messages */
if( isAttributeMessage( message ) )
{
int status = CRYPT_ERROR;
assert( message == RESOURCE_MESSAGE_SETATTRIBUTE || \
message == RESOURCE_MESSAGE_GETATTRIBUTE || \
message == RESOURCE_MESSAGE_SETATTRIBUTE_S || \
message == RESOURCE_MESSAGE_GETATTRIBUTE_S );
/* If it's a protocol-specific attribute, forward it directly to
the low-level code */
if( ( messageValue >= CRYPT_SESSINFO_FIRST_SPECIFIC && \
messageValue <= CRYPT_SESSINFO_LAST_SPECIFIC ) || \
messageValue == CRYPT_IATTRIBUTE_ENC_TIMESTAMP )
{
assert( message == RESOURCE_MESSAGE_SETATTRIBUTE || \
message == RESOURCE_MESSAGE_GETATTRIBUTE || \
message == RESOURCE_MESSAGE_GETATTRIBUTE_S );
if( message == RESOURCE_MESSAGE_SETATTRIBUTE )
{
assert( sessionInfoPtr->setAttributeFunction != NULL );
status = sessionInfoPtr->setAttributeFunction( sessionInfoPtr,
messageDataPtr, messageValue );
}
else
{
assert( sessionInfoPtr->getAttributeFunction != NULL );
status = sessionInfoPtr->getAttributeFunction( sessionInfoPtr,
messageDataPtr, messageValue );
}
unlockResourceExit( sessionInfoPtr, status );
}
if( message == RESOURCE_MESSAGE_SETATTRIBUTE )
status = processSetAttribute( sessionInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_SETATTRIBUTE_S )
status = processSetAttributeS( sessionInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_GETATTRIBUTE )
status = processGetAttribute( sessionInfoPtr, messageDataPtr,
messageValue );
if( message == RESOURCE_MESSAGE_GETATTRIBUTE_S )
status = processGetAttributeS( sessionInfoPtr, messageDataPtr,
messageValue );
unlockResourceExit( sessionInfoPtr, status );
}
/* Process messages which lock/unlock an object for exclusive use */
if( message == RESOURCE_MESSAGE_LOCK )
/* Exit without unlocking the object. Any other threads trying to
use the object after this point will be blocked */
return( CRYPT_OK );
if( message == RESOURCE_MESSAGE_UNLOCK )
{
/* "Wenn drei Leute in ein Zimmer reingehen und fuenf kommen raus,
dann muessen erst mal zwei wieder reingehen bis das Zimmer leer
ist" */
unlockResource( sessionInfoPtr ); /* Undo RESOURCE_MESSAGE_LOCK lock */
unlockResourceExit( sessionInfoPtr, CRYPT_OK );
}
/* Process object-specific messages */
if( message == RESOURCE_MESSAGE_ENV_PUSHDATA )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
int status;
/* If the session isn't open yet, perform an implicit open. We have
to do this directly rather than sending ourselves a message since
it'll be enqueued for processing after the current one, however
there's no harm in this */
if( !sessionInfoPtr->sessionOpen )
{
status = processSetAttribute( sessionInfoPtr, MESSAGE_VALUE_TRUE,
CRYPT_SESSINFO_ACTIVE );
if( cryptStatusError( status ) )
unlockResourceExit( sessionInfoPtr, status );
}
assert( sessionInfoPtr->sessionOpen );
assert( sessionInfoPtr->sendBuffer != NULL );
assert( sessionInfoPtr->writeDataFunction != NULL );
/* Make sure everything is in order */
if( sessionInfoPtr->errorState != CRYPT_OK )
status = sessionInfoPtr->errorState;
else
status = putData( sessionInfoPtr, msgData->data,
msgData->length );
if( cryptStatusError( status ) )
{
sessionInfoPtr->errorState = status;
unlockResourceExit( sessionInfoPtr, status );
}
msgData->length = status;
unlockResourceExit( sessionInfoPtr, CRYPT_OK );
}
if( message == RESOURCE_MESSAGE_ENV_POPDATA )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
int status;
/* If the session isn't open, there's nothing to pop */
if( !sessionInfoPtr->sessionOpen )
unlockResourceExit( sessionInfoPtr, CRYPT_ERROR_NOTINITED );
assert( sessionInfoPtr->sessionOpen );
assert( sessionInfoPtr->receiveBuffer != NULL );
assert( sessionInfoPtr->readHeaderFunction != NULL );
assert( sessionInfoPtr->processBodyFunction != NULL );
/* Make sure everything is in order */
if( sessionInfoPtr->errorState != CRYPT_OK )
status = sessionInfoPtr->errorState;
else
status = getData( sessionInfoPtr, msgData->data,
msgData->length );
if( cryptStatusError( status ) )
{
sessionInfoPtr->errorState = status;
unlockResourceExit( sessionInfoPtr, status );
}
msgData->length = status;
unlockResourceExit( sessionInfoPtr, CRYPT_OK );
}
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;
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_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_NONE, CRYPT_SESSION_NONE, CRYPT_ERROR }
};
int 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 );
/* Wait for any async driver binding to complete */
waitSemaphore( SEMAPHORE_DRIVERBIND );
/* Create the session object */
status = krnlCreateObject( ( void ** ) &sessionInfoPtr, cryptOwner,
OBJECT_TYPE_SESSION, sessionTypes[ i ].subType,
sizeof( SESSION_INFO ), 0, 0,
sessionMessageFunction );
if( cryptStatusError( status ) )
return( status );
initResourceLock( sessionInfoPtr );
lockResource( sessionInfoPtr );
*sessionInfoPtrPtr = sessionInfoPtr;
*iCryptSession = sessionInfoPtr->objectHandle = status;
sessionInfoPtr->ownerHandle = cryptOwner;
sessionInfoPtr->type = sessionTypes[ i ].baseSessionType;
/* If it's a server session, mark it as such */
if( sessionTypes[ i ].sessionType != sessionTypes[ i ].baseSessionType )
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;
/* Set up the access information for the session and initialise it */
switch( sessionTypes[ i ].baseSessionType )
{
case CRYPT_SESSION_CMP:
status = setAccessMethodCMP( sessionInfoPtr );
break;
case CRYPT_SESSION_SSH:
status = setAccessMethodSSH( sessionInfoPtr );
break;
case CRYPT_SESSION_SSL:
status = setAccessMethodSSL( sessionInfoPtr );
break;
case CRYPT_SESSION_OCSP:
status = setAccessMethodOCSP( sessionInfoPtr );
break;
case CRYPT_SESSION_TSP:
status = setAccessMethodTSP( sessionInfoPtr );
break;
default:
assert( NOTREACHED );
}
if( cryptStatusOK( status ) )
{
assert( sessionInfoPtr->initFunction != NULL );
assert( sessionInfoPtr->connectFunction != NULL );
status = sessionInfoPtr->initFunction( sessionInfoPtr );
}
return( status );
}
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 session open failed, make sure the object gets destroyed when
we notify the kernel that the setup process is complete */
krnlSendNotifier( iCryptSession, RESOURCE_IMESSAGE_DESTROY );
/* We've finished setting up the object-type-specific info, tell the
kernel the object is ready for use */
unlockResource( sessionInfoPtr );
status = krnlSendMessage( iCryptSession, RESOURCE_IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
if( cryptStatusError( initStatus ) || cryptStatusError( status ) )
return( cryptStatusError( initStatus ) ? initStatus : status );
createInfo->cryptHandle = iCryptSession;
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -