📄 int_env.c
字号:
IN_HANDLE_OPT const CRYPT_CERTIFICATE iCmsAttributes )
{
CRYPT_ENVELOPE iCryptEnvelope;
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_DATA msgData;
const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength + 1024 );
int status;
assert( isReadPtr( inData, inDataLength ) );
assert( isWritePtr( outData, outDataMaxLength ) );
assert( isWritePtr( outDataLength, sizeof( int ) ) );
REQUIRES( ( inDataLength > 16 && inDataLength < MAX_INTLENGTH ) || \
( contentType == CRYPT_CONTENT_NONE && \
isHandleRangeValid( iCmsAttributes ) && \
inDataLength == 0 ) );
REQUIRES( outDataMaxLength > 16 && \
outDataMaxLength >= inDataLength + 512 && \
outDataMaxLength < MAX_INTLENGTH );
REQUIRES( contentType >= CRYPT_CONTENT_NONE && \
contentType < CRYPT_CONTENT_LAST );
REQUIRES( isHandleRangeValid( iSigKey ) );
REQUIRES( iCmsAttributes == CRYPT_UNUSED || \
isHandleRangeValid( iCmsAttributes ) );
/* Clear return values. Note that we can't clear the output buffer
at this point since this function is frequently used for in-place
processing, so we clear it after we've pushed the input data */
*outDataLength = 0;
/* Create an envelope to sign the data, add the signature key and
optional signing attributes, and pop the signed result */
setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_CMS );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_ENVELOPE );
if( cryptStatusError( status ) )
{
memset( outData, 0, min( 16, outDataMaxLength ) );
return( status );
}
iCryptEnvelope = createInfo.cryptHandle;
( void ) krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &minBufferSize,
CRYPT_ATTRIBUTE_BUFFERSIZE );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &inDataLength,
CRYPT_ENVINFO_DATASIZE );
if( cryptStatusOK( status ) && contentType != CRYPT_CONTENT_NONE )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &contentType,
CRYPT_ENVINFO_CONTENTTYPE );
if( cryptStatusOK( status ) )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &iSigKey,
CRYPT_ENVINFO_SIGNATURE );
if( cryptStatusOK( status ) && iCmsAttributes != CRYPT_UNUSED )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &iCmsAttributes,
CRYPT_ENVINFO_SIGNATURE_EXTRADATA );
if( cryptStatusOK( status ) )
{
/* If there's no data supplied it's an attributes-only message
containing only authenticated attributes */
if( inDataLength <= 0 )
{
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE,
CRYPT_IATTRIBUTE_ATTRONLY );
}
else
{
setMessageData( &msgData, ( void * ) inData, inDataLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
if( cryptStatusOK( status ) )
{
ENSURES( msgData.length >= inDataLength );
}
}
}
memset( outData, 0, min( 16, outDataMaxLength ) );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
}
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, outData, outDataMaxLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_POPDATA,
&msgData, 0 );
if( cryptStatusOK( status ) )
{
ENSURES( msgData.length > inDataLength && \
msgData.length < outDataMaxLength );
}
if( cryptStatusOK( status ) )
*outDataLength = msgData.length;
}
krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
assert( cryptStatusError( status ) || \
!cryptStatusError( checkObjectEncoding( outData, \
*outDataLength ) ) );
assert( !cryptArgError( status ) );
return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5, 7 ) ) \
int envelopeSigCheck( IN_BUFFER( inDataLength ) const void *inData,
IN_LENGTH_MIN( 16 ) const int inDataLength,
OUT_BUFFER( outDataMaxLength, \
*outDataLength ) void *outData,
IN_LENGTH_MIN( 16 ) const int outDataMaxLength,
OUT_LENGTH_Z int *outDataLength,
IN_HANDLE_OPT const CRYPT_CONTEXT iSigCheckKey,
OUT_RANGE( MAX_ERROR, CRYPT_OK ) int *sigResult,
OUT_OPT_HANDLE_OPT CRYPT_CERTIFICATE *iSigningCert,
OUT_OPT_HANDLE_OPT CRYPT_CERTIFICATE *iCmsAttributes )
{
CRYPT_ENVELOPE iCryptEnvelope;
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_DATA msgData = { DUMMY_INIT };
const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength );
int status;
assert( isReadPtr( inData, inDataLength ) );
assert( isWritePtr( outData, outDataMaxLength ) );
assert( isWritePtr( outDataLength, sizeof( int ) ) );
assert( isWritePtr( sigResult, sizeof( int ) ) );
assert( iSigningCert == NULL || \
isWritePtr( iSigningCert, sizeof( CRYPT_CERTIFICATE ) ) );
assert( iCmsAttributes == NULL || \
isWritePtr( iCmsAttributes, sizeof( CRYPT_CERTIFICATE ) ) );
REQUIRES( inDataLength > 16 && inDataLength < MAX_INTLENGTH );
REQUIRES( outDataMaxLength > 16 && \
outDataMaxLength >= inDataLength && \
outDataMaxLength < MAX_INTLENGTH );
REQUIRES( iSigCheckKey == CRYPT_UNUSED || \
isHandleRangeValid( iSigCheckKey ) );
/* Clear return values. Note that we can't clear the output buffer
at this point since this function is frequently used for in-place
processing, so we clear it after we've pushed the input data */
*outDataLength = 0;
*sigResult = CRYPT_ERROR;
if( iSigningCert != NULL )
*iSigningCert = CRYPT_ERROR;
if( iCmsAttributes != NULL )
*iCmsAttributes = CRYPT_ERROR;
/* Create an envelope to sig.check the data, push in the signed data and
sig.check key, and pop the result. We also speculatively set the
attributes-only flag to let the enveloping code know that a signed
message with no content is a zero-data-length message rather than a
detached signature, which is what this type of message would normally
be. In theory we could use checkASN1() here to perform a safety
check of the envelope data prior to processing, but this has already
been done by the calling code when the datagram containing the
enveloped data was read so we don't need to repeat the (rather
heavyweight) operation here */
setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_AUTO );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_ENVELOPE );
if( cryptStatusError( status ) )
{
memset( outData, 0, min( 16, outDataMaxLength ) );
return( status );
}
iCryptEnvelope = createInfo.cryptHandle;
( void ) krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &minBufferSize,
CRYPT_ATTRIBUTE_BUFFERSIZE );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE,
CRYPT_IATTRIBUTE_ATTRONLY );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, ( void * ) inData, inDataLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
}
if( cryptStatusOK( status ) )
{
ENSURES( msgData.length >= inDataLength );
}
memset( outData, 0, min( 16, outDataMaxLength ) );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
&msgData, 0 );
}
if( cryptStatusOK( status ) && iSigCheckKey != CRYPT_UNUSED )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
( void * ) &iSigCheckKey,
CRYPT_ENVINFO_SIGNATURE );
if( cryptStatusOK( status ) )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_GETATTRIBUTE,
sigResult, CRYPT_ENVINFO_SIGNATURE_RESULT );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, outData, outDataMaxLength );
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_POPDATA,
&msgData, 0 );
if( cryptStatusOK( status ) )
{
ENSURES( msgData.length < inDataLength && \
msgData.length < outDataMaxLength );
}
}
if( cryptStatusOK( status ) && iSigningCert != NULL )
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_GETATTRIBUTE,
iSigningCert,
CRYPT_ENVINFO_SIGNATURE );
if( cryptStatusOK( status ) && iCmsAttributes != NULL )
{
status = krnlSendMessage( iCryptEnvelope, IMESSAGE_GETATTRIBUTE,
iCmsAttributes,
CRYPT_ENVINFO_SIGNATURE_EXTRADATA );
if( cryptStatusError( status ) && iSigningCert != NULL )
{
krnlSendNotifier( *iSigningCert, IMESSAGE_DECREFCOUNT );
*iSigningCert = CRYPT_ERROR;
}
}
krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
if( cryptStatusOK( status ) )
*outDataLength = msgData.length;
assert( !cryptArgError( status ) );
return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -