📄 cms_envpre.c
字号:
return( CRYPT_OK );
}
/****************************************************************************
* *
* Signed Content Pre-processing *
* *
****************************************************************************/
/* Process signing certificates and match the content-type in the
authenticated attributes with the signed content type if it's anything
other than 'data' (the data content-type is added automatically) */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int processSigningCerts( INOUT ENVELOPE_INFO *envelopeInfoPtr,
INOUT ACTION_LIST *actionListPtr )
{
int value, status;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );
/* If we're including signing certificates and there are multiple
signing certificates present add the currently-selected one to the
overall certificate collection */
if( !( envelopeInfoPtr->flags & ENVELOPE_NOSIGNINGCERTS ) && \
envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
{
status = krnlSendMessage( envelopeInfoPtr->iExtraCertChain,
IMESSAGE_SETATTRIBUTE,
&actionListPtr->iCryptHandle,
CRYPT_IATTRIBUTE_CERTCOLLECTION );
if( cryptStatusError( status ) )
return( status );
}
/* If there's no content-type present and the signed content type isn't
'data' or it's an S/MIME envelope, create signing attributes to hold
the content-type and smimeCapabilities */
if( actionListPtr->iExtraData == CRYPT_ERROR && \
( envelopeInfoPtr->contentType != CRYPT_CONTENT_DATA || \
envelopeInfoPtr->type == CRYPT_FORMAT_SMIME ) )
{
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 );
actionListPtr->iExtraData = createInfo.cryptHandle;
}
/* If there are no signed attributes, we're done */
if( actionListPtr->iExtraData == CRYPT_ERROR )
return( CRYPT_OK );
/* Make sure that the content-type in the attributes matches the actual
content type by deleting any existing content-type if necessary and
adding our one (quietly fixing things is easier than trying to report
this error back to the caller) */
if( krnlSendMessage( actionListPtr->iExtraData, IMESSAGE_GETATTRIBUTE,
&value, CRYPT_CERTINFO_CMS_CONTENTTYPE ) != CRYPT_ERROR_NOTFOUND )
{
/* We ignore the return status from the deletion since the status
from the add that follows will be more meaningful to the caller */
( void ) krnlSendMessage( actionListPtr->iExtraData,
IMESSAGE_DELETEATTRIBUTE, NULL,
CRYPT_CERTINFO_CMS_CONTENTTYPE );
}
return( krnlSendMessage( actionListPtr->iExtraData,
IMESSAGE_SETATTRIBUTE,
&envelopeInfoPtr->contentType,
CRYPT_CERTINFO_CMS_CONTENTTYPE ) );
}
/* Pre-process information for signed enveloping */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int processSignatureAction( INOUT ENVELOPE_INFO *envelopeInfoPtr,
INOUT ACTION_LIST *actionListPtr )
{
CRYPT_ALGO_TYPE cryptAlgo = DUMMY_INIT;
int signatureSize, signingAttributes, status;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );
REQUIRES( actionListPtr->action == ACTION_SIGN && \
actionListPtr->associatedAction != NULL );
/* Process signing certificates and fix up the content-type in the
authenticated attributes if necessary */
if( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
envelopeInfoPtr->type == CRYPT_FORMAT_SMIME )
{
status = processSigningCerts( envelopeInfoPtr, actionListPtr );
if( cryptStatusError( status ) )
return( status );
}
/* Determine the type of signing attributes to use. If none are
specified (which can only happen if the signed content is data),
either get the signing code to add the default ones for us or use
none at all if the use of default attributes is disabled */
signingAttributes = actionListPtr->iExtraData;
if( signingAttributes == CRYPT_ERROR )
{
/* If it's a raw signature there are no signing attributes */
if( envelopeInfoPtr->type == CRYPT_FORMAT_CRYPTLIB )
signingAttributes = CRYPT_UNUSED;
else
{
int useDefaultAttributes;
/* It's a CMS/SMIME signature, use whatever the default is */
status = krnlSendMessage( envelopeInfoPtr->ownerHandle,
IMESSAGE_GETATTRIBUTE,
&useDefaultAttributes,
CRYPT_OPTION_CMS_DEFAULTATTRIBUTES );
if( cryptStatusError( status ) )
return( status );
signingAttributes = useDefaultAttributes ? \
CRYPT_USE_DEFAULT : CRYPT_UNUSED;
}
}
/* Evaluate the size of the exported action */
status = iCryptCreateSignature( NULL, 0, &signatureSize,
envelopeInfoPtr->type, actionListPtr->iCryptHandle,
actionListPtr->associatedAction->iCryptHandle,
signingAttributes,
( actionListPtr->iTspSession != CRYPT_ERROR ) ? \
actionListPtr->iTspSession : CRYPT_UNUSED );
if( cryptStatusOK( status ) )
{
status = krnlSendMessage( actionListPtr->iCryptHandle,
IMESSAGE_GETATTRIBUTE, &cryptAlgo,
CRYPT_CTXINFO_ALGO );
}
if( cryptStatusError( status ) )
return( status );
if( isDlpAlgo( cryptAlgo ) || actionListPtr->iTspSession != CRYPT_ERROR )
{
/* If there are any signature actions that will result in indefinite-
length encodings present we can't use a definite-length encoding
for the signature */
envelopeInfoPtr->dataFlags |= ENVDATA_HASINDEFTRAILER;
actionListPtr->encodedSize = CRYPT_UNUSED;
}
else
{
actionListPtr->encodedSize = signatureSize;
envelopeInfoPtr->signActionSize += signatureSize;
}
if( envelopeInfoPtr->dataFlags & ENVDATA_HASINDEFTRAILER )
envelopeInfoPtr->signActionSize = CRYPT_UNUSED;
ENSURES( ( envelopeInfoPtr->signActionSize == CRYPT_UNUSED ) || \
( envelopeInfoPtr->signActionSize > 0 && \
envelopeInfoPtr->signActionSize < MAX_INTLENGTH ) );
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int cmsPreEnvelopeSign( INOUT ENVELOPE_INFO *envelopeInfoPtr )
{
ACTION_LIST *actionListPtr = envelopeInfoPtr->postActionList;
int iterationCount, status;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
REQUIRES( envelopeInfoPtr->usage == ACTION_SIGN );
/* Make sure that there's at least one signing action present */
if( actionListPtr == NULL )
return( CRYPT_ERROR_NOTINITED );
assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );
REQUIRES( actionListPtr->associatedAction != NULL );
/* If we're generating a detached signature the content is supplied
externally and has zero size */
if( envelopeInfoPtr->flags & ENVELOPE_DETACHED_SIG )
envelopeInfoPtr->payloadSize = 0;
/* If it's an attributes-only message it must be zero-length CMS signed
data with signing attributes present */
if( envelopeInfoPtr->flags & ENVELOPE_ATTRONLY )
{
if( envelopeInfoPtr->type != CRYPT_FORMAT_CMS || \
actionListPtr->iExtraData == CRYPT_ERROR )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_SIGNATURE_EXTRADATA,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
if( envelopeInfoPtr->payloadSize > 0 )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_DATASIZE,
CRYPT_ERRTYPE_ATTR_VALUE );
return( CRYPT_ERROR_INITED );
}
}
/* If it's a CMS envelope we have to write the signing certificate chain
alongside the signatures as extra data unless it's explicitly
excluded so we record how large the info will be for later */
if( ( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
envelopeInfoPtr->type == CRYPT_FORMAT_SMIME ) && \
!( envelopeInfoPtr->flags & ENVELOPE_NOSIGNINGCERTS ) )
{
if( actionListPtr->next != NULL )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
/* There are multiple sets of signing certificates present,
create a signing-certificate meta-object to hold the overall
set of certificates */
setMessageCreateObjectInfo( &createInfo,
CRYPT_CERTTYPE_CERTCHAIN );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
envelopeInfoPtr->iExtraCertChain = createInfo.cryptHandle;
}
else
{
MESSAGE_DATA msgData;
/* There's a single signing certificate present, determine its
size */
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( actionListPtr->iCryptHandle,
IMESSAGE_CRT_EXPORT, &msgData,
CRYPT_ICERTFORMAT_CERTSET );
if( cryptStatusError( status ) )
return( status );
envelopeInfoPtr->extraDataSize = msgData.length;
}
}
/* Evaluate the size of each signature action */
for( actionListPtr = envelopeInfoPtr->postActionList, iterationCount = 0;
actionListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_MED;
actionListPtr = actionListPtr->next, iterationCount++ )
{
status = processSignatureAction( envelopeInfoPtr, actionListPtr );
if( cryptStatusError( status ) )
return( status );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
if( envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
{
MESSAGE_DATA msgData;
/* We're writing the signing certificate chain and there are
multiple signing certificates present, get the size of the
overall certificate collection */
setMessageData( &msgData, NULL, 0 );
status = krnlSendMessage( envelopeInfoPtr->iExtraCertChain,
IMESSAGE_CRT_EXPORT, &msgData,
CRYPT_ICERTFORMAT_CERTSET );
if( cryptStatusError( status ) )
return( status );
envelopeInfoPtr->extraDataSize = msgData.length;
}
ENSURES( envelopeInfoPtr->extraDataSize >= 0 && \
envelopeInfoPtr->extraDataSize < MAX_INTLENGTH );
/* Hashing is now active (you have no chance to survive make your
time) */
envelopeInfoPtr->dataFlags |= ENVDATA_HASHACTIONSACTIVE;
return( CRYPT_OK );
}
#endif /* USE_ENVELOPES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -