📄 cryptses.c
字号:
case CRYPT_SESSINFO_SERVER_PORT:
*valuePtr = sessionInfoPtr->serverPort;
return( CRYPT_OK );
case CRYPT_SESSINFO_CLIENT_PORT:
if( !sessionInfoPtr->clientPort )
return( exitErrorNotInited( sessionInfoPtr,
CRYPT_ERROR_NOTINITED ) );
*valuePtr = sessionInfoPtr->clientPort;
return( CRYPT_OK );
case CRYPT_SESSINFO_VERSION:
*valuePtr = sessionInfoPtr->version;
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttribute( SESSION_INFO *sessionInfoPtr,
void *messageDataPtr, const int messageValue )
{
const int value = *( int * ) messageDataPtr;
int status;
/* Handle the various information types */
switch( messageValue )
{
case CRYPT_OPTION_NET_CONNECTTIMEOUT:
sessionInfoPtr->connectTimeout = value;
return( CRYPT_OK );
case CRYPT_OPTION_NET_TIMEOUT:
sessionInfoPtr->timeout = value;
return( CRYPT_OK );
case CRYPT_ATTRIBUTE_BUFFERSIZE:
assert( !( sessionInfoPtr->flags & SESSION_ISOPEN ) );
sessionInfoPtr->receiveBufSize = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_ACTIVE:
/* Session state and persistent sessions are handled as follows:
The CRYPT_SESSINFO_ACTIVE attribute records the active state
of the session as a whole, and the
CRYPT_SESSINFO_CONNECTIONACTIVE attribute records the state of
the underlying comms session. Setting CRYPT_SESSINFO_ACTIVE
for the first time activates the comms session, and leaves it
active if the underlying mechanism (e.g. HTTP 1.1 persistent
connections) support it. The CRYPT_SESSINFO_ACTIVE attribute
is reset once the transaction completes, and further
transactions can be initiated as long as
CRYPT_SESSINFO_CONNECTIONACTIVE is set:
Obj.state _active _connactive
--------- ------- -----------
create 0 0 0
setattr 0 0 0
(clear out_param)
activate 1 0 -> 1 -> 0 1
(clear in_param)
setattr 1 0 1
(clear out_param)
activate 1 0 -> 1 -> 0 1
(clear in_param)
(peer closes conn) 1 0 0
setattr CRYPT_ERROR_COMPLETE */
if( value == FALSE )
return( CRYPT_OK ); /* No-op */
status = activateSession( sessionInfoPtr );
if( cryptArgError( status ) )
{
/* Catch leaked low-level status values. The session
management code does a large amount of work involving
other cryptlib objects, so it's quite possible that an
unexpected failure at some point will leak through an
inappropriate status value */
assert( NOTREACHED );
status = CRYPT_ERROR_FAILED;
}
return( status );
case CRYPT_SESSINFO_SERVER_PORT:
/* If there's already a transport session or network socket
specified, we can't set a port as well */
if( sessionInfoPtr->transportSession != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SESSION ) );
if( sessionInfoPtr->networkSocket != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_NETWORKSOCKET ) );
sessionInfoPtr->serverPort = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_VERSION:
if( value < sessionInfoPtr->protocolInfo->minVersion || \
value > sessionInfoPtr->protocolInfo->maxVersion )
return( CRYPT_ARGERROR_VALUE );
sessionInfoPtr->version = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_PRIVATEKEY:
{
const int requiredAttributeFlags = \
( sessionInfoPtr->flags & SESSION_ISSERVER ) ? \
sessionInfoPtr->serverReqAttrFlags : \
sessionInfoPtr->clientReqAttrFlags;
/* Make sure that it's a private key */
status = krnlSendMessage( value, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_PKC_PRIVATE );
if( cryptStatusError( status ) )
{
if( sessionInfoPtr->type != CRYPT_SESSION_SSL )
return( CRYPT_ARGERROR_NUM1 );
/* SSL can also do key-agreement-based key exchange, so we
fall back to this if key-transport-based exchange isn't
possible */
status = krnlSendMessage( value, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_PKC_KA_EXPORT );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
}
/* If we need a private key with certain capabilities, make sure
that it has these capabilities. This is a more specific check
than that allowed by the kernel */
if( requiredAttributeFlags & SESSION_NEEDS_PRIVKEYSIGN )
{
status = krnlSendMessage( value, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_PKC_SIGN );
if( cryptStatusError( status ) )
{
setErrorInfo( sessionInfoPtr, CRYPT_CERTINFO_KEYUSAGE,
CRYPT_ERRTYPE_ATTR_VALUE );
return( CRYPT_ARGERROR_NUM1 );
}
}
if( requiredAttributeFlags & SESSION_NEEDS_PRIVKEYCRYPT )
{
status = krnlSendMessage( value, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_PKC_DECRYPT );
if( cryptStatusError( status ) )
{
setErrorInfo( sessionInfoPtr, CRYPT_CERTINFO_KEYUSAGE,
CRYPT_ERRTYPE_ATTR_VALUE );
return( CRYPT_ARGERROR_NUM1 );
}
}
/* If we need a private key with a cert, make sure that the
appropriate type of initialised cert object is present. This
is a more specific check than that allowed by the kernel */
if( requiredAttributeFlags & SESSION_NEEDS_PRIVKEYCERT )
{
int attrValue;
status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE,
&attrValue, CRYPT_CERTINFO_IMMUTABLE );
if( cryptStatusError( status ) || !attrValue )
return( CRYPT_ARGERROR_NUM1 );
status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE,
&attrValue, CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) ||
( attrValue != CRYPT_CERTTYPE_CERTIFICATE && \
attrValue != CRYPT_CERTTYPE_CERTCHAIN ) )
return( CRYPT_ARGERROR_NUM1 );
}
if( ( requiredAttributeFlags & SESSION_NEEDS_PRIVKEYCACERT ) && \
cryptStatusError( \
krnlSendMessage( value, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_CA ) ) )
return( CRYPT_ARGERROR_NUM1 );
/* Make sure that 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->protocolInfo->requiredPrivateKeySize && \
( sessionInfoPtr->flags & SESSION_ISSERVER ) )
{
int length;
status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE,
&length, CRYPT_CTXINFO_KEYSIZE );
if( cryptStatusError( status ) || \
length < sessionInfoPtr->protocolInfo->requiredPrivateKeySize )
return( exitError( sessionInfoPtr,
CRYPT_SESSINFO_PRIVATEKEY,
CRYPT_ERRTYPE_ATTR_SIZE,
CRYPT_ARGERROR_NUM1 ) );
}
/* Perform any protocol-specific checks if necessary */
if( sessionInfoPtr->checkAttributeFunction != NULL )
{
status = sessionInfoPtr->checkAttributeFunction( sessionInfoPtr,
value, CRYPT_SESSINFO_PRIVATEKEY );
if( cryptStatusError( status ) )
return( status );
}
/* Add the private key and increment its reference count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->privateKey = value;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_KEYSET:
{
int type;
/* Make sure that it's a cert store (rather than just a generic
keyset) if required */
if( sessionInfoPtr->serverReqAttrFlags & SESSION_NEEDS_CERTSTORE )
{
status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE,
&type, CRYPT_IATTRIBUTE_SUBTYPE );
if( cryptStatusError( status ) || \
( type != SUBTYPE_KEYSET_DBMS_STORE ) )
return( CRYPT_ARGERROR_NUM1 );
}
/* Add the keyset and increment its reference count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->cryptKeyset = value;
return( CRYPT_OK );
}
case CRYPT_SESSINFO_SESSION:
/* If there's already a host or network socket specified, we
can't set a transport session as well */
if( sessionInfoPtr->serverName[ 0 ] )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_NAME ) );
if( sessionInfoPtr->networkSocket != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_NETWORKSOCKET ) );
/* Add the transport mechanism and increment its reference
count */
krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->transportSession = value;
return( CRYPT_OK );
case CRYPT_SESSINFO_NETWORKSOCKET:
{
NET_CONNECT_INFO connectInfo;
STREAM stream;
/* If there's already a host or session specified, we can't set
a network socket as well */
if( sessionInfoPtr->serverName[ 0 ] )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_NAME ) );
if( sessionInfoPtr->transportSession != CRYPT_ERROR )
return( exitErrorInited( sessionInfoPtr,
CRYPT_SESSINFO_SESSION ) );
/* Create a dummy network stream to make sure that the network
socket is OK */
initNetConnectInfo( &connectInfo, sessionInfoPtr->ownerHandle,
sessionInfoPtr->timeout,
sessionInfoPtr->connectTimeout,
NET_OPTION_NETWORKSOCKET_DUMMY );
connectInfo.networkSocket = value;
status = sNetConnect( &stream, STREAM_PROTOCOL_TCPIP,
&connectInfo, sessionInfoPtr->errorMessage,
&sessionInfoPtr->errorCode );
if( cryptStatusError( status ) )
return( status );
sNetDisconnect( &stream );
/* Add the network socket */
sessionInfoPtr->networkSocket = 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_OPTION_NET_SOCKS_SERVER:
case CRYPT_OPTION_NET_SOCKS_USERNAME:
case CRYPT_OPTION_NET_HTTP_PROXY:
/* These aren't implemented on a per-session level yet since
they're almost never user */
return( exitErrorNotFound( sessionInfoPtr,
messageValue ) );
case CRYPT_ATTRIBUTE_INT_ERRORMESSAGE:
if( !*sessionInfoPtr->errorMessage )
/* We don't set extended error information for this atribute
because it's usually read in response to an existing error,
which would overwrite the existing error information */
return( CRYPT_ERROR_NOTFOUND );
return( attributeCopy( msgData, sessionInfoPtr->errorMessage,
strlen( sessionInfoPtr->errorMessage ) ) );
case CRYPT_SESSINFO_USERNAME:
if( sessionInfoPtr->userNameLength <= 0 )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_USERNAME ) );
return( attributeCopy( msgData, sessionInfoPtr->userName,
sessionInfoPtr->userNameLength ) );
case CRYPT_SESSINFO_PASSWORD:
if( sessionInfoPtr->passwordLength <= 0 )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_PASSWORD ) );
return( attributeCopy( msgData, sessionInfoPtr->password,
sessionInfoPtr->passwordLength ) );
case CRYPT_SESSINFO_SERVER_NAME:
if( !strlen( sessionInfoPtr->serverName ) )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_NAME ) );
return( attributeCopy( msgData, sessionInfoPtr->serverName,
strlen( sessionInfoPtr->serverName ) ) );
case CRYPT_SESSINFO_SERVER_FINGERPRINT:
if( sessionInfoPtr->keyFingerprintSize <= 0 )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_SERVER_FINGERPRINT ) );
return( attributeCopy( msgData, sessionInfoPtr->keyFingerprint,
sessionInfoPtr->keyFingerprintSize ) );
case CRYPT_SESSINFO_CLIENT_NAME:
if( !strlen( sessionInfoPtr->clientName ) )
return( exitErrorNotFound( sessionInfoPtr,
CRYPT_SESSINFO_CLIENT_NAME ) );
return( attributeCopy( msgData, sessionInfoPtr->clientName,
strlen( sessionInfoPtr->clientName ) ) );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -