📄 res_env.c
字号:
using a stronger hash algorithm must also be able to verify the
envelope using the stronger algorithm. This allows a transparent
upgrade to stronger hash algorithms as they become available */
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE,
&certHashAlgo, CRYPT_IATTRIBUTE_CERTHASHALGO );
if( cryptStatusOK( status ) && \
isStrongerHash( certHashAlgo, envelopeInfoPtr->defaultHash ) )
envelopeInfoPtr->defaultHash = certHashAlgo;
/* If there's no subject hash action available, create one so that we
can connect it to the signature action */
if( envelopeInfoPtr->actionList == NULL )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
/* Create a default hash action */
setMessageCreateObjectInfo( &createInfo, envelopeInfoPtr->defaultHash );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_CONTEXT );
if( cryptStatusError( status ) )
return( status );
/* Add the hash action to the list */
status = addActionEx( &hashActionPtr, &envelopeInfoPtr->actionList,
envelopeInfoPtr->memPoolState, ACTION_HASH,
createInfo.cryptHandle );
if( cryptStatusError( status ) )
{
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Remember that the action was added invisibly to the caller so that
we don't return an error if they add it explicitly later on */
hashActionPtr->flags |= ACTION_ADDEDAUTOMATICALLY;
}
else
{
/* Find the last hash action that was added */
hashActionPtr = findLastAction( envelopeInfoPtr->actionList,
ACTION_HASH );
if( hashActionPtr == NULL )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_HASH,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
}
/* Connect the signature action to the last hash action that was added
and remember that this action now has a controlling action */
actionListPtr->associatedAction = hashActionPtr;
hashActionPtr->flags &= ~ACTION_NEEDSCONTROLLER;
return( CRYPT_OK );
}
/****************************************************************************
* *
* Enveloping Information Management Functions *
* *
****************************************************************************/
/* Add enveloping information to an envelope */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int addEnvelopeInfo( INOUT ENVELOPE_INFO *envelopeInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE envInfo,
IN_INT_Z const int value )
{
CRYPT_HANDLE cryptHandle = ( CRYPT_HANDLE ) value;
ACTION_LIST *actionListPtr;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
REQUIRES( ( envInfo == CRYPT_IATTRIBUTE_INCLUDESIGCERT ) || \
( envInfo == CRYPT_IATTRIBUTE_ATTRONLY ) || \
( envInfo > CRYPT_ENVINFO_FIRST && \
envInfo < CRYPT_ENVINFO_LAST ) );
/* If it's a generic "add a context" action for a PGP envelope check
that everything is valid. This is necessary because the PGP format
doesn't support the full range of enveloping capabilities */
#ifdef USE_PGP
if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP && \
envInfo > CRYPT_ENVINFO_FIRST && \
envInfo < CRYPT_ENVINFO_LAST )
{
const int status = checkPgpUsage( envelopeInfoPtr, envInfo );
if( cryptStatusError( status ) )
{
setErrorInfo( envelopeInfoPtr, envInfo,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( status );
}
}
#endif /* USE_PGP */
/* If it's meta-information, remember the value */
switch( envInfo )
{
case CRYPT_IATTRIBUTE_INCLUDESIGCERT:
/* This is on by default so we should only be turning it off */
REQUIRES( value == FALSE );
envelopeInfoPtr->flags |= ENVELOPE_NOSIGNINGCERTS;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_ATTRONLY:
/* This is off by default so we should only be turning it on */
REQUIRES( value == TRUE );
/* Detached-signature and attribute-only messages are mutually
exclusive */
if( envelopeInfoPtr->flags & ENVELOPE_DETACHED_SIG )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_DETACHEDSIGNATURE,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
envelopeInfoPtr->flags |= ENVELOPE_ATTRONLY;
return( CRYPT_OK );
case CRYPT_ENVINFO_DATASIZE:
envelopeInfoPtr->payloadSize = value;
return( CRYPT_OK );
case CRYPT_ENVINFO_CONTENTTYPE:
envelopeInfoPtr->contentType = value;
return( CRYPT_OK );
case CRYPT_ENVINFO_DETACHEDSIGNATURE:
if( value )
{
/* Detached-signature and attribute-only messages are
mutually exclusive. Since the attribute-only message
attribute is internal we can't set extended error
information for this one */
if( envelopeInfoPtr->flags & ENVELOPE_ATTRONLY )
return( CRYPT_ERROR_INITED );
envelopeInfoPtr->flags |= ENVELOPE_DETACHED_SIG;
}
else
envelopeInfoPtr->flags &= ~ENVELOPE_DETACHED_SIG;
return( CRYPT_OK );
case CRYPT_ENVINFO_INTEGRITY:
switch( value )
{
case CRYPT_INTEGRITY_NONE:
return( CRYPT_OK );
case CRYPT_INTEGRITY_MACONLY:
envelopeInfoPtr->usage = ACTION_MAC;
return( CRYPT_OK );
case CRYPT_INTEGRITY_FULL:
envelopeInfoPtr->usage = ACTION_CRYPT;
envelopeInfoPtr->flags |= ENVELOPE_AUTHENC;
return( CRYPT_OK );
}
retIntError();
case CRYPT_ENVINFO_KEYSET_SIGCHECK:
case CRYPT_ENVINFO_KEYSET_ENCRYPT:
case CRYPT_ENVINFO_KEYSET_DECRYPT:
/* It's keyset information, just keep a record of it for later
use */
return( addKeysetInfo( envelopeInfoPtr, envInfo, cryptHandle ) );
case CRYPT_ENVINFO_SIGNATURE_EXTRADATA:
case CRYPT_ENVINFO_TIMESTAMP:
{
CRYPT_HANDLE *iCryptHandlePtr;
/* Find the last signature action that was added and make sure
that it doesn't already have an action of this type attached
to it */
actionListPtr = findLastAction( envelopeInfoPtr->postActionList,
ACTION_SIGN );
if( actionListPtr == NULL )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_SIGNATURE,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
iCryptHandlePtr = ( envInfo == CRYPT_ENVINFO_SIGNATURE_EXTRADATA ) ? \
&actionListPtr->iExtraData : \
&actionListPtr->iTspSession;
if( *iCryptHandlePtr != CRYPT_ERROR )
{
setErrorInfo( envelopeInfoPtr, envInfo,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
/* Increment its reference count and add it to the action */
krnlSendNotifier( cryptHandle, IMESSAGE_INCREFCOUNT );
*iCryptHandlePtr = cryptHandle;
return( CRYPT_OK );
}
case CRYPT_ENVINFO_ORIGINATOR:
#ifdef USE_FORTEZZA
/* If there's a session key present make sure that it's
consistent with the originator info */
if( envelopeInfoPtr->iCryptContext != CRYPT_ERROR )
{
int status;
status = checkFortezzaUsage( cryptHandle, envelopeInfoPtr,
CRYPT_ENVINFO_ORIGINATOR );
if( cryptStatusError( status ) )
return( status );
}
/* Increment its reference count and add it to the action */
krnlSendNotifier( cryptHandle, IMESSAGE_INCREFCOUNT );
envelopeInfoPtr->iExtraCertChain = cryptHandle;
/* Since we're using Fortezza key management we have to use
Skipjack as the data encryption algorithm */
envelopeInfoPtr->defaultAlgo = CRYPT_ALGO_SKIPJACK;
return( CRYPT_OK );
#else
return( CRYPT_ARGERROR_NUM1 );
#endif /* USE_FORTEZZA */
case CRYPT_ENVINFO_COMPRESSION:
#ifdef USE_COMPRESSION
/* Make sure that we don't try and initialise the compression
multiple times */
if( envelopeInfoPtr->flags & ENVELOPE_ZSTREAMINITED )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_COMPRESSION,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
/* Initialize the compression */
if( deflateInit( &envelopeInfoPtr->zStream, \
Z_DEFAULT_COMPRESSION ) != Z_OK )
return( CRYPT_ERROR_MEMORY );
envelopeInfoPtr->flags |= ENVELOPE_ZSTREAMINITED;
return( CRYPT_OK );
#else
return( CRYPT_ARGERROR_NUM1 );
#endif /* USE_COMPRESSION */
case CRYPT_ENVINFO_PUBLICKEY:
case CRYPT_ENVINFO_PRIVATEKEY:
return( addContextInfo( envelopeInfoPtr, cryptHandle,
&envelopeInfoPtr->preActionList,
ACTION_KEYEXCHANGE_PKC ) );
case CRYPT_ENVINFO_KEY:
/* PGP doesn't allow KEK-based encryption so if it's a PGP
envelope we drop through and treat it as a session key */
if( envelopeInfoPtr->type != CRYPT_FORMAT_PGP )
{
return( addContextInfo( envelopeInfoPtr, cryptHandle,
&envelopeInfoPtr->preActionList,
ACTION_KEYEXCHANGE ) );
}
/* Fall through */
case CRYPT_ENVINFO_SESSIONKEY:
/* We can't add more than one session key */
if( envelopeInfoPtr->actionList != NULL )
{
setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_SESSIONKEY,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
#ifdef USE_FORTEZZA
/* If there's originator info present make sure that it's
consistent with the new session key */
if( envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
{
int status;
status = checkFortezzaUsage( cryptHandle, envelopeInfoPtr,
CRYPT_ENVINFO_SESSIONKEY );
if( cryptStatusError( status ) )
return( status );
}
#endif /* USE_FORTEZZA */
return( addContextInfo( envelopeInfoPtr, cryptHandle,
&envelopeInfoPtr->actionList,
ACTION_CRYPT ) );
case CRYPT_ENVINFO_HASH:
return( addContextInfo( envelopeInfoPtr, cryptHandle,
&envelopeInfoPtr->actionList,
ACTION_HASH ) );
case CRYPT_ENVINFO_SIGNATURE:
return( addContextInfo( envelopeInfoPtr, cryptHandle,
&envelopeInfoPtr->postActionList,
ACTION_SIGN ) );
}
retIntError();
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int addEnvelopeInfoString( INOUT ENVELOPE_INFO *envelopeInfoPtr,
IN_RANGE( CRYPT_ENVINFO_PASSWORD, \
CRYPT_ENVINFO_PASSWORD ) \
const CRYPT_ATTRIBUTE_TYPE envInfo,
IN_BUFFER( valueLength ) const void *value,
IN_RANGE( 1, CRYPT_MAX_TEXTSIZE ) \
const int valueLength )
{
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
assert( isReadPtr( value, valueLength ) );
REQUIRES( envInfo == CRYPT_ENVINFO_PASSWORD );
REQUIRES( valueLength > 0 && valueLength <= CRYPT_MAX_TEXTSIZE );
#ifdef USE_PGP
if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP )
return( addPgpPasswordInfo( envelopeInfoPtr, value, valueLength ) );
#endif /* USE_PGP */
return( addPasswordInfo( envelopeInfoPtr, value, valueLength ) );
}
/****************************************************************************
* *
* Envelope Access Routines *
* *
****************************************************************************/
STDC_NONNULL_ARG( ( 1 ) ) \
void initEnvResourceHandling( INOUT ENVELOPE_INFO *envelopeInfoPtr )
{
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
REQUIRES_V( !( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) );
/* Set the access method pointers */
envelopeInfoPtr->addInfo = addEnvelopeInfo;
envelopeInfoPtr->addInfoString = addEnvelopeInfoString;
envelopeInfoPtr->checkMissingInfo = checkMissingInfo;
}
#endif /* USE_ENVELOPES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -