📄 rtcs.c
字号:
retExt( sessionInfoPtr, status,
"Unexpected RTCS encapsulation type %d", actionType );
status = envelopeUnwrap( sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufEnd,
sessionInfoPtr->receiveBuffer, &dataLength,
sessionInfoPtr->receiveBufSize, CRYPT_UNUSED );
if( cryptStatusError( status ) )
retExt( sessionInfoPtr, status,
"Invalid RTCS request data (CMS enveloped data)" );
/* Create an RTCS response. We always create this since an empty
response is sent to indicate an error condition */
setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_RTCS_RESPONSE );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
sessionInfoPtr->iCertResponse = createInfo.cryptHandle;
/* Import the request as a cryptlib object and try and read the nonce
from it */
setMessageCreateObjectIndirectInfo( &createInfo,
sessionInfoPtr->receiveBuffer, dataLength,
CRYPT_CERTTYPE_RTCS_REQUEST );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
retExt( sessionInfoPtr, status, "Invalid RTCS request contents" );
setMessageData( &msgData, protocolInfo->nonce, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( createInfo.cryptHandle,
IMESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_CERTINFO_CMS_NONCE );
if( cryptStatusOK( status ) )
protocolInfo->nonceSize = msgData.length;
/* Create an RTCS response and add the request information to it */
status = krnlSendMessage( sessionInfoPtr->iCertResponse,
IMESSAGE_SETATTRIBUTE,
&createInfo.cryptHandle,
CRYPT_IATTRIBUTE_RTCSREQUEST );
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
retExt( sessionInfoPtr, status,
"Couldn't create RTCS response from request" );
return( CRYPT_OK );
}
/* Return a response to an RTCS client */
static int sendServerResponse( SESSION_INFO *sessionInfoPtr,
RTCS_PROTOCOL_INFO *protocolInfo )
{
CRYPT_CERTIFICATE iCmsAttributes = CRYPT_UNUSED;
RESOURCE_DATA msgData;
int status;
/* Check the entries from the request against the cert store and sign
the resulting status information ("Love, ken"). Note that
CRYPT_ERROR_INVALID is a valid return status for the sigcheck call
since it indicates that one (or more) of the certs was revoked */
status = krnlSendMessage( sessionInfoPtr->iCertResponse,
IMESSAGE_CRT_SIGCHECK, NULL,
sessionInfoPtr->cryptKeyset );
if( cryptStatusError( status ) && status != CRYPT_ERROR_INVALID )
retExt( sessionInfoPtr, status,
"Couldn't check RTCS request against certificate store" );
/* If there's a nonce present, create CMS attributes to contain it */
if( protocolInfo->nonceSize > 0 )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
setMessageCreateObjectInfo( &createInfo,
CRYPT_CERTTYPE_CMS_ATTRIBUTES );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
iCmsAttributes = createInfo.cryptHandle;
setMessageData( &msgData, protocolInfo->nonce,
protocolInfo->nonceSize );
status = krnlSendMessage( iCmsAttributes, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_CMS_NONCE );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
return( status );
}
}
/* Sign the response data using the responder's key and send it to the
client */
setMessageData( &msgData, sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufSize );
status = krnlSendMessage( sessionInfoPtr->iCertResponse,
IMESSAGE_CRT_EXPORT, &msgData,
CRYPT_ICERTFORMAT_DATA );
if( cryptStatusOK( status ) )
status = envelopeSign( sessionInfoPtr->receiveBuffer, msgData.length,
sessionInfoPtr->receiveBuffer,
&sessionInfoPtr->receiveBufEnd,
sessionInfoPtr->receiveBufSize,
CRYPT_CONTENT_RTCSRESPONSE,
sessionInfoPtr->privateKey, iCmsAttributes );
if( iCmsAttributes != CRYPT_UNUSED )
krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
retExt( sessionInfoPtr, status,
"Couldn't create RTCS response (CMS enveloped data)" );
DEBUG_DUMP( "rtcs_sresp", sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufEnd );
return( writePkiDatagram( sessionInfoPtr ) );
}
/****************************************************************************
* *
* Init/Shutdown Functions *
* *
****************************************************************************/
/* Exchange data with an RTCS client/server */
static int clientTransact( SESSION_INFO *sessionInfoPtr )
{
int status;
/* Get cert status information from the server */
status = sendClientRequest( sessionInfoPtr );
if( cryptStatusOK( status ) )
status = readServerResponse( sessionInfoPtr );
return( status );
}
static int serverTransact( SESSION_INFO *sessionInfoPtr )
{
RTCS_PROTOCOL_INFO protocolInfo;
int status;
/* Send cert status information to the client */
memset( &protocolInfo, 0, sizeof( RTCS_PROTOCOL_INFO ) );
status = readClientRequest( sessionInfoPtr, &protocolInfo );
if( cryptStatusOK( status ) )
status = sendServerResponse( sessionInfoPtr, &protocolInfo );
return( status );
}
/****************************************************************************
* *
* Control Information Management Functions *
* *
****************************************************************************/
static int setAttributeFunction( SESSION_INFO *sessionInfoPtr,
const void *data,
const CRYPT_ATTRIBUTE_TYPE type )
{
const CRYPT_CERTIFICATE rtcsRequest = *( ( CRYPT_CERTIFICATE * ) data );
RESOURCE_DATA msgData = { NULL, 0 };
int status;
assert( type == CRYPT_SESSINFO_REQUEST );
/* Make sure that everything is set up ready to go. Since RTCS requests
aren't signed like normal cert objects, we can't just check the
immutable attribute but have to perform a dummy export for which the
cert export code will return an error status if there's a problem
with the request. If not, it pseudo-signs the request (if it hasn't
already done so) and prepares it for use */
status = krnlSendMessage( rtcsRequest, IMESSAGE_CRT_EXPORT, &msgData,
CRYPT_ICERTFORMAT_DATA );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
/* If we haven't already got a server name explicitly set, try and get
it from the request */
if( findSessionAttribute( sessionInfoPtr->attributeList,
CRYPT_SESSINFO_SERVER_NAME ) == NULL )
{
char buffer[ MAX_URL_SIZE ];
setMessageData( &msgData, buffer, MAX_URL_SIZE );
status = krnlSendMessage( rtcsRequest, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_RESPONDERURL );
if( cryptStatusOK( status ) )
krnlSendMessage( sessionInfoPtr->objectHandle,
IMESSAGE_SETATTRIBUTE_S, &msgData,
CRYPT_SESSINFO_SERVER_NAME );
}
/* Add the request and increment its usage count */
krnlSendNotifier( rtcsRequest, IMESSAGE_INCREFCOUNT );
sessionInfoPtr->iCertRequest = rtcsRequest;
return( CRYPT_OK );
}
/****************************************************************************
* *
* Session Access Routines *
* *
****************************************************************************/
/* Open/close an RTCS session */
int setAccessMethodRTCS( SESSION_INFO *sessionInfoPtr )
{
static const PROTOCOL_INFO protocolInfo = {
/* General session information */
TRUE, /* Request-response protocol */
SESSION_ISHTTPTRANSPORT, /* Flags */
80, /* HTTP port */
SESSION_NEEDS_REQUEST, /* Client flags */
SESSION_NEEDS_PRIVATEKEY | /* Server flags */
SESSION_NEEDS_PRIVKEYSIGN | \
SESSION_NEEDS_PRIVKEYCERT | \
SESSION_NEEDS_KEYSET,
1, 1, 1, /* Version 1 */
"application/rtcs-request", /* Client content-type */
"application/rtcs-response",/* Server content-type */
/* Protocol-specific information */
};
/* Set the access method pointers */
sessionInfoPtr->protocolInfo = &protocolInfo;
if( sessionInfoPtr->flags & SESSION_ISSERVER )
sessionInfoPtr->transactFunction = serverTransact;
else
sessionInfoPtr->transactFunction = clientTransact;
sessionInfoPtr->setAttributeFunction = setAttributeFunction;
return( CRYPT_OK );
}
#endif /* USE_RTCS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -