?? cryptses.c
字號:
{
/* Check server-specific required values */
if( ( sessionInfoPtr->requiredAttributeFlags & \
SESSION_SERVER_NEEDSPRIVATEKEY ) && \
sessionInfoPtr->privateKey == CRYPT_ERROR )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_PRIVATEKEY,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
if( ( sessionInfoPtr->requiredAttributeFlags & \
SESSION_SERVER_NEEDSCERTSTORE ) && \
sessionInfoPtr->cryptKeyset == CRYPT_ERROR )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_KEYSET,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
}
else
{
/* Check client-specific required values */
if( !strlen( sessionInfoPtr->serverName ) )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_SERVER_NAME,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
if( ( sessionInfoPtr->requiredAttributeFlags & \
SESSION_CLIENT_NEEDSUSERID ) && \
sessionInfoPtr->userNameLength == 0 )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_USERNAME,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
if( ( sessionInfoPtr->requiredAttributeFlags & \
SESSION_CLIENT_NEEDSPASSWORD ) && \
sessionInfoPtr->passwordLength == 0 )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_PASSWORD,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
if( ( sessionInfoPtr->requiredAttributeFlags & \
SESSION_CLIENT_NEEDSPRIVATEKEY ) && \
sessionInfoPtr->privateKey == CRYPT_ERROR )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_PRIVATEKEY,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
}
if( sessionInfoPtr->sendBuffer == NULL )
{
assert( sessionInfoPtr->receiveBufSize >= MIN_BUFFER_SIZE && \
( sessionInfoPtr->sendBufSize >= MIN_BUFFER_SIZE || \
sessionInfoPtr->sendBufSize == CRYPT_UNUSED ) );
/* Allocate the send and receive buffers. The send buffer
isn't used for stateless session objects which use the
receive buffer for both outgoing and incoming data, so we
only allocated it if necessary */
if( ( sessionInfoPtr->receiveBuffer = \
malloc( sessionInfoPtr->receiveBufSize ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
if( sessionInfoPtr->sendBufSize != CRYPT_UNUSED )
{
/* When allocating the send buffer we use the size for
the receive buffer since the user may have overridden
the default buffer size */
if( ( sessionInfoPtr->sendBuffer = \
malloc( sessionInfoPtr->receiveBufSize ) ) == NULL )
{
free( sessionInfoPtr->receiveBuffer );
sessionInfoPtr->receiveBuffer = NULL;
return( CRYPT_ERROR_MEMORY );
}
sessionInfoPtr->sendBufSize = \
sessionInfoPtr->receiveBufSize;
}
}
assert( ( sessionInfoPtr->flags & SESSION_ISSERVER ) || \
strlen( sessionInfoPtr->serverName ) );
assert( sessionInfoPtr->serverPort );
assert( sessionInfoPtr->receiveBuffer != NULL );
/* Activate the session */
status = sessionInfoPtr->connectFunction( sessionInfoPtr );
if( cryptStatusOK( status ) )
{
/* If it's an encrypted session, notify the kernel that
the session key context is attached to the session
object. This is an internal object used only by the
session object so we tell the kernel not to increment
its reference count when it attaches it */
if( sessionInfoPtr->iCryptInContext != CRYPT_ERROR )
krnlSendMessage( sessionInfoPtr->objectHandle,
RESOURCE_IMESSAGE_SETDEPENDENT,
&sessionInfoPtr->iCryptInContext,
SETDEP_OPTION_NOINCREF );
/* Remember that the session has been successfully
established */
sessionInfoPtr->sessionOpen = TRUE;
}
return( status );
case CRYPT_SESSINFO_SERVER_PORT:
sessionInfoPtr->serverPort = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_PROTOCOLVERSION:
sessionInfoPtr->version = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_PRIVATEKEY:
/* Make sure it's a private key */
status = krnlSendMessage( value, RESOURCE_MESSAGE_CHECK, NULL,
RESOURCE_MESSAGE_CHECK_PKC_PRIVATE );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
/* If we need a private key with a cert, make sure the
appropriate type of initialised cert object is present */
if( sessionInfoPtr->requiredAttributeFlags & \
( SESSION_CLIENT_NEEDSPRIVKEYCERT | SESSION_SERVER_NEEDSPRIVKEYCERT ) )
{
int type;
status = krnlSendMessage( value,
RESOURCE_IMESSAGE_GETATTRIBUTE, &type,
CRYPT_CERTINFO_IMMUTABLE );
if( cryptStatusError( status ) || !type )
return( CRYPT_ARGERROR_NUM1 );
status = krnlSendMessage( value,
RESOURCE_IMESSAGE_GETATTRIBUTE, &type,
CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) ||
( type != CRYPT_CERTTYPE_CERTIFICATE && \
type != CRYPT_CERTTYPE_CERTCHAIN ) )
return( CRYPT_ARGERROR_NUM1 );
}
if( ( sessionInfoPtr->flags & SESSION_ISSERVER ) && \
( sessionInfoPtr->requiredAttributeFlags & \
SESSION_SERVER_NEEDSPRIVKEYCACERT ) && \
cryptStatusError( \
krnlSendMessage( value, RESOURCE_IMESSAGE_CHECK, NULL,
RESOURCE_MESSAGE_CHECK_CA ) ) )
return( CRYPT_ARGERROR_NUM1 );
/* If we need a particular attribute set in the cert, make sure
it's present */
if( sessionInfoPtr->requiredCertAttribute != CRYPT_ATTRIBUTE_NONE )
{
int attrValue;
status = krnlSendMessage( value,
RESOURCE_IMESSAGE_GETATTRIBUTE, &attrValue,
sessionInfoPtr->requiredCertAttribute );
if( cryptStatusError( status ) || !attrValue )
{
setErrorInfo( sessionInfoPtr,
sessionInfoPtr->requiredCertAttribute,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ARGERROR_NUM1 );
}
}
/* Make sure the key meets the mininum height requirements. We
only perform this check if we're explicitly being asked to
perform the check and it's a server session (which has certain
minimum length requirements for private keys), for client
sessions the permitted length/security level is controlled by
the server so we can't really perform much checking */
if( sessionInfoPtr->requiredPrivateKeySize && \
( sessionInfoPtr->flags & SESSION_ISSERVER ) )
{
int length;
status = krnlSendMessage( value, RESOURCE_IMESSAGE_GETATTRIBUTE,
&length, CRYPT_CTXINFO_KEYSIZE );
if( cryptStatusError( status ) || \
length < sessionInfoPtr->requiredPrivateKeySize )
{
setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_PRIVATEKEY,
CRYPT_ERRTYPE_ATTR_SIZE );
return( CRYPT_ARGERROR_NUM1 );
}
}
/* Add the private key and increment its reference count */
krnlSendNotifier( value, RESOURCE_IMESSAGE_INCREFCOUNT );
sessionInfoPtr->privateKey = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_KEYSET:
/* In theory we should make sure that what's being added is a
cert store, however once user objects are fully implemented
the cert store will probably be implicitly associated with
the user object so it'll never be added directly. Because of
this we don't do any further checking here */
/* Add the keyset and increment its reference count */
krnlSendNotifier( value, RESOURCE_IMESSAGE_INCREFCOUNT );
sessionInfoPtr->cryptKeyset = value;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processGetAttributeS( SESSION_INFO *sessionInfoPtr,
void *messageDataPtr, const int messageValue )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
/* Handle the various information types */
switch( messageValue )
{
case CRYPT_ATTRIBUTE_INT_ERRORMESSAGE:
if( !*sessionInfoPtr->errorMessage )
return( CRYPT_ERROR_NOTFOUND );
return( attributeCopy( msgData, sessionInfoPtr->errorMessage,
strlen( sessionInfoPtr->errorMessage ) ) );
case CRYPT_SESSINFO_USERNAME:
if( !sessionInfoPtr->userNameLength )
return( CRYPT_ERROR_NOTINITED );
return( attributeCopy( msgData, sessionInfoPtr->userName,
sessionInfoPtr->userNameLength ) );
case CRYPT_SESSINFO_SERVER_NAME:
if( !strlen( sessionInfoPtr->serverName ) )
return( CRYPT_ERROR_NOTINITED );
return( attributeCopy( msgData, sessionInfoPtr->serverName,
strlen( sessionInfoPtr->serverName ) ) );
case CRYPT_SESSINFO_CLIENT_NAME:
if( !strlen( sessionInfoPtr->clientName ) )
return( CRYPT_ERROR_NOTINITED );
return( attributeCopy( msgData, sessionInfoPtr->clientName,
strlen( sessionInfoPtr->clientName ) ) );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttributeS( SESSION_INFO *sessionInfoPtr,
void *messageDataPtr, const int messageValue )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
/* Handle the various information types */
switch( messageValue )
{
case CRYPT_SESSINFO_USERNAME:
assert( msgData->length < CRYPT_MAX_TEXTSIZE );
if( isUserValue( msgData->data, msgData->length ) )
{
/* It's an encoded user value, make sure it's in order */
const int status = decodeUserValue( NULL, msgData->data,
msgData->length );
if( cryptStatusError( status ) )
return( status );
}
memcpy( sessionInfoPtr->userName, msgData->data,
msgData->length );
sessionInfoPtr->userNameLength = msgData->length;
return( CRYPT_OK );
case CRYPT_SESSINFO_PASSWORD:
assert( msgData->length < CRYPT_MAX_TEXTSIZE );
if( isUserValue( msgData->data, msgData->length ) )
{
/* It's an encoded user value, make sure it's in order */
const int status = decodeUserValue( NULL, msgData->data,
msgData->length );
if( cryptStatusError( status ) )
return( status );
}
memcpy( sessionInfoPtr->password, msgData->data,
msgData->length );
sessionInfoPtr->passwordLength = msgData->length;
return( CRYPT_OK );
case CRYPT_SESSINFO_SERVER_NAME:
assert( msgData->length < MAX_URL_SIZE );
memcpy( sessionInfoPtr->serverName, msgData->data,
msgData->length );
sessionInfoPtr->serverName[ msgData->length ] = 0;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/* Handle a message sent to a session object */
static int sessionMessageFunction( const CRYPT_SESSION cryptSession,
const RESOURCE_MESSAGE_TYPE message,
void *messageDataPtr,
const int messageValue )
{
SESSION_INFO *sessionInfoPtr;
getCheckInternalResource( cryptSession, sessionInfoPtr, OBJECT_TYPE_SESSION );
/* Process destroy object messages */
if( message == RESOURCE_MESSAGE_DESTROY )
{
/* Shut down the session if required */
if( sessionInfoPtr->sessionOpen && \
sessionInfoPtr->shutdownFunction != NULL )
sessionInfoPtr->shutdownFunction( sessionInfoPtr );
/* Clear and free state information if necessary */
if( sessionInfoPtr->sendBuffer != NULL )
{
zeroise( sessionInfoPtr->sendBuffer,
sessionInfoPtr->sendBufSize );
free( sessionInfoPtr->sendBuffer );
}
if( sessionInfoPtr->receiveBuffer != NULL )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -