📄 cmp_wr.c
字号:
sessionInfoPtr->protocolFlags & CMP_PFLAG_MACINFOSENT );
else
writeContextAlgoID( &nullStream, protocolInfo->authContext,
protocolInfo->hashAlgo,
ALGOID_FLAG_ALGOID_ONLY );
protInfoLength = stell( &nullStream );
sMemClose( &nullStream );
if( !( sessionInfoPtr->protocolFlags & CMP_PFLAG_CLIBIDSENT ) )
{
attributeLength += sizeofObject( \
sizeofOID( OID_CRYPTLIB_PRESENCECHECK ) + \
sizeofObject( 0 ) );
sendClibID = TRUE;
}
if( !( sessionInfoPtr->protocolFlags & CMP_PFLAG_CERTIDSENT ) && \
( ( ( sessionInfoPtr->flags & SESSION_ISSERVER ) && \
protocolInfo->operation == CTAG_PB_GENM ) || \
!protocolInfo->useMACsend ) )
{
attributeLength += writeCertID( NULL, protocolInfo->authContext );
sendCertID = TRUE;
}
totalLength = sizeofShortInteger( CMP_VERSION ) + \
objSize( senderNameLength ) + objSize( recipNameLength ) + \
objSize( protInfoLength );
if( protocolInfo->transIDsize > 0 )
totalLength += objSize( sizeofObject( protocolInfo->transIDsize ) );
if( useFullHeader || \
!( sessionInfoPtr->protocolFlags & CMP_PFLAG_USERIDSENT ) )
totalLength += objSize( sizeofObject( protocolInfo->userIDsize ) );
if( useFullHeader )
totalLength += ( protocolInfo->senderNonceSize > 0 ? \
objSize( sizeofObject( protocolInfo->senderNonceSize ) ) : 0 ) + \
( protocolInfo->recipNonceSize > 0 ? \
objSize( sizeofObject( protocolInfo->recipNonceSize ) ) : 0 );
if( attributeLength > 0 )
totalLength += objSize( objSize( attributeLength ) );
if( sizeofObject( totalLength ) > sMemDataLeft( stream ) )
return( CRYPT_ERROR_OVERFLOW );
/* Write the PKI header wrapper, version info, and sender and recipient
names if there's name information present */
writeSequence( stream, totalLength );
writeShortInteger( stream, CMP_VERSION, DEFAULT_TAG );
if( useFullHeader )
{
writeConstructed( stream, senderNameLength, 4 );
if( senderNameObject != CRYPT_ERROR )
{
status = exportAttributeToStream( stream, senderNameObject,
CRYPT_IATTRIBUTE_SUBJECT,
CRYPT_USE_DEFAULT );
if( cryptStatusError( status ) )
return( status );
}
else
writeSequence( stream, 0 );
writeConstructed( stream, recipNameLength, 4 );
if( recipNameObject != CRYPT_ERROR )
{
status = exportAttributeToStream( stream, recipNameObject,
CRYPT_IATTRIBUTE_SUBJECT,
CRYPT_USE_DEFAULT );
if( cryptStatusError( status ) )
return( status );
}
else
writeSequence( stream, 0 );
}
else
{
/* This is one of the portions of CMP where an optional field is
marked as mandatory, to balance out the mandatory fields that are
marked as optional. To work around this, we write the names as
zero-length DNs */
writeConstructed( stream, 0, 4 );
writeConstructed( stream, 0, 4 );
}
/* Write the protection info, assorted nonces and IDs, and extra
information that the other side may be able to make use of */
writeConstructed( stream, protInfoLength, CTAG_PH_PROTECTIONALGO );
if( protocolInfo->useMACsend )
{
writeMacInfo( stream, protocolInfo,
sessionInfoPtr->protocolFlags & CMP_PFLAG_MACINFOSENT );
sessionInfoPtr->protocolFlags |= CMP_PFLAG_MACINFOSENT;
}
else
writeContextAlgoID( stream, protocolInfo->authContext,
protocolInfo->hashAlgo,
ALGOID_FLAG_ALGOID_ONLY );
if( useFullHeader || \
!( sessionInfoPtr->protocolFlags & CMP_PFLAG_USERIDSENT ) )
{
/* We're using full headers or we're the client sending our first
message, identify the sender key */
writeConstructed( stream, objSize( protocolInfo->userIDsize ),
CTAG_PH_SENDERKID );
writeOctetString( stream, protocolInfo->userID,
protocolInfo->userIDsize, DEFAULT_TAG );
sessionInfoPtr->protocolFlags |= CMP_PFLAG_USERIDSENT;
}
if( protocolInfo->transIDsize > 0 )
{
/* If we're sending an error response to an initial message that we
couldn't even start to parse, the transaction ID won't be present
yet so we only send this if it's present */
writeConstructed( stream, objSize( protocolInfo->transIDsize ),
CTAG_PH_TRANSACTIONID );
status = writeOctetString( stream, protocolInfo->transID,
protocolInfo->transIDsize, DEFAULT_TAG );
}
if( useFullHeader )
{
if( protocolInfo->senderNonceSize > 0 )
{
writeConstructed( stream,
objSize( protocolInfo->senderNonceSize ),
CTAG_PH_SENDERNONCE );
status = writeOctetString( stream, protocolInfo->senderNonce,
protocolInfo->senderNonceSize,
DEFAULT_TAG );
}
if( protocolInfo->recipNonceSize > 0 )
{
writeConstructed( stream,
objSize( protocolInfo->recipNonceSize ),
CTAG_PH_RECIPNONCE );
status = writeOctetString( stream, protocolInfo->recipNonce,
protocolInfo->recipNonceSize,
DEFAULT_TAG );
}
}
if( attributeLength > 0 )
{
assert( sendClibID || sendCertID );
/* We haven't sent any messages yet, let the other side know that
we're running cryptlib and identify our signing cert */
writeConstructed( stream, objSize( attributeLength ),
CTAG_PH_GENERALINFO );
status = writeSequence( stream, attributeLength );
if( sendClibID )
{
writeSequence( stream, sizeofOID( OID_CRYPTLIB_PRESENCECHECK ) + \
sizeofObject( 0 ) );
writeOID( stream, OID_CRYPTLIB_PRESENCECHECK );
status = writeSet( stream, 0 );
sessionInfoPtr->protocolFlags |= CMP_PFLAG_CLIBIDSENT;
}
if( sendCertID )
{
status = writeCertID( stream, protocolInfo->authContext );
sessionInfoPtr->protocolFlags |= CMP_PFLAG_CERTIDSENT;
}
}
return( status );
}
/****************************************************************************
* *
* Write a PKI Message *
* *
****************************************************************************/
/* Write a PKI message:
PkiMessage ::= SEQUENCE {
header PKIHeader,
body CHOICE { [0]... [24]... },
protection [0] BIT STRING
} */
int writePkiMessage( SESSION_INFO *sessionInfoPtr,
CMP_PROTOCOL_INFO *protocolInfo,
const CMPBODY_TYPE bodyType )
{
BYTE protInfo[ 64 + MAX_PKCENCRYPTED_SIZE ], headerBuffer[ 8 ];
STREAM stream;
int headerSize, protInfoSize, status;
/* Write the header and payload so that we can MAC/sign it */
sMemOpen( &stream, sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufSize );
status = writePkiHeader( &stream, sessionInfoPtr, protocolInfo );
if( cryptStatusOK( status ) )
{
switch( bodyType )
{
case CMPBODY_NORMAL:
if( sessionInfoPtr->flags & SESSION_ISSERVER )
status = writeResponseBody( &stream, sessionInfoPtr,
protocolInfo );
else
status = writeRequestBody( &stream, sessionInfoPtr,
protocolInfo );
break;
case CMPBODY_CONFIRMATION:
status = writeConfBody( &stream, sessionInfoPtr,
protocolInfo );
break;
case CMPBODY_ACK:
writeConstructed( &stream, objSize( sizeofNull() ),
CTAG_PB_PKICONF );
writeSequence( &stream, sizeofNull() );
status = writeNull( &stream, DEFAULT_TAG );
break;
case CMPBODY_GENMSG:
if( sessionInfoPtr->flags & SESSION_ISSERVER )
status = writeGenMsgBody( &stream, sessionInfoPtr,
protocolInfo );
else
{
writeConstructed( &stream,
objSize( objSize( sizeofOID( OID_PKIBOOT ) ) ),
CTAG_PB_GENM );
writeSequence( &stream,
objSize( sizeofOID( OID_PKIBOOT ) ) );
writeSequence( &stream, sizeofOID( OID_PKIBOOT ) );
status = writeOID( &stream, OID_PKIBOOT );
}
break;
case CMPBODY_ERROR:
status = writeErrorBody( &stream, protocolInfo );
break;
default:
assert( NOTREACHED );
}
}
if( cryptStatusError( status ) )
{
sMemClose( &stream );
return( status );
}
/* Generate the MAC or signature as appropriate */
if( protocolInfo->useMACsend )
{
BYTE macValue[ CRYPT_MAX_HASHSIZE ];
status = hashMessageContents( protocolInfo->iMacContext,
sessionInfoPtr->receiveBuffer, stell( &stream ) );
if( cryptStatusOK( status ) )
{
RESOURCE_DATA msgData;
setMessageData( &msgData, macValue, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( protocolInfo->iMacContext,
IMESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_CTXINFO_HASHVALUE );
protInfoSize = msgData.length;
}
if( cryptStatusOK( status ) )
{
STREAM macStream;
/* Write the MAC value with BIT STRING encapsulation */
sMemOpen( &macStream, protInfo, 64 + MAX_PKCENCRYPTED_SIZE );
writeBitStringHole( &macStream, protInfoSize, DEFAULT_TAG );
swrite( &macStream, macValue, protInfoSize );
protInfoSize = stell( &macStream );
sMemDisconnect( &macStream );
}
}
else
{
MESSAGE_CREATEOBJECT_INFO createInfo;
/* Hash the data and create the signature */
setMessageCreateObjectInfo( &createInfo, protocolInfo->hashAlgo );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_CONTEXT );
if( cryptStatusOK( status ) )
{
status = hashMessageContents( createInfo.cryptHandle,
sessionInfoPtr->receiveBuffer, stell( &stream ) );
if( cryptStatusOK( status ) )
status = createRawSignature( protInfo, &protInfoSize,
sizeof( protInfo ),
protocolInfo->authContext,
createInfo.cryptHandle );
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
}
}
if( cryptStatusError( status ) )
{
sMemClose( &stream );
return( status );
}
/* Attach the MAC/signature to the payload */
writeConstructed( &stream, protInfoSize, CTAG_PM_PROTECTION );
status = swrite( &stream, protInfo, protInfoSize );
sessionInfoPtr->receiveBufEnd = stell( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
return( status );
/* Write the wrapper and move it onto the front of the message */
sMemOpen( &stream, headerBuffer, 8 );
writeSequence( &stream, sessionInfoPtr->receiveBufEnd );
headerSize = stell( &stream );
sMemDisconnect( &stream );
memmove( sessionInfoPtr->receiveBuffer + headerSize,
sessionInfoPtr->receiveBuffer,
sessionInfoPtr->receiveBufEnd );
memcpy( sessionInfoPtr->receiveBuffer, headerBuffer, headerSize );
sessionInfoPtr->receiveBufEnd += headerSize;
return( CRYPT_OK );
}
#endif /* USE_CMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -