📄 env_attr.c
字号:
case CRYPT_ENVINFO_KEYSET_ENCRYPT:
*checkType = MESSAGE_CHECK_PKC_ENCRYPT_AVAIL;
if( envelopeInfoPtr->iEncryptionKeyset != CRYPT_ERROR )
return( exitErrorInited( envelopeInfoPtr,
CRYPT_ENVINFO_KEYSET_ENCRYPT ) );
return( CRYPT_OK );
case CRYPT_ENVINFO_KEYSET_DECRYPT:
*checkType = MESSAGE_CHECK_PKC_DECRYPT_AVAIL;
if( envelopeInfoPtr->iDecryptionKeyset != CRYPT_ERROR )
return( exitErrorInited( envelopeInfoPtr,
CRYPT_ENVINFO_KEYSET_DECRYPT ) );
return( CRYPT_OK );
case CRYPT_ENVINFO_KEYSET_SIGCHECK:
*checkType = MESSAGE_CHECK_PKC_SIGCHECK_AVAIL;
if( envelopeInfoPtr->iSigCheckKeyset != CRYPT_ERROR )
return( exitErrorInited( envelopeInfoPtr,
CRYPT_ENVINFO_KEYSET_SIGCHECK ) );
return( CRYPT_OK );
}
retIntError();
}
/****************************************************************************
* *
* Get Attributes *
* *
****************************************************************************/
/* Get a numeric/boolean attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int getEnvelopeAttribute( INOUT ENVELOPE_INFO *envelopeInfoPtr,
OUT_INT_Z int *valuePtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
assert( isWritePtr( valuePtr, sizeof( int ) ) );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
/* Clear return value */
*valuePtr = 0;
/* Generic attributes are valid for all envelope types */
if( attribute == CRYPT_ATTRIBUTE_BUFFERSIZE )
{
*valuePtr = envelopeInfoPtr->bufSize;
return( CRYPT_OK );
}
if( attribute == CRYPT_ATTRIBUTE_ERRORTYPE )
{
*valuePtr = envelopeInfoPtr->errorType;
return( CRYPT_OK );
}
if( attribute == CRYPT_ATTRIBUTE_ERRORLOCUS )
{
*valuePtr = envelopeInfoPtr->errorLocus;
return( CRYPT_OK );
}
/* If we're de-enveloping PGP data, make sure that the attribute is valid
for PGP envelopes. We can't perform this check via the ACLs because
the data type isn't known at envelope creation time so there's a
single generic de-envelope type for which the ACLs allow the union of
all de-enveloping attribute types. The following check weeds out the
ones that don't work for PGP */
if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP && \
attribute == CRYPT_ENVINFO_SIGNATURE_EXTRADATA )
return( CRYPT_ARGERROR_VALUE );
/* Make sure that the attribute is valid for this envelope type and state */
switch( attribute )
{
case CRYPT_OPTION_ENCR_ALGO:
case CRYPT_OPTION_ENCR_HASH:
case CRYPT_OPTION_ENCR_MAC:
/* Algorithm types are valid only for enveloping */
if( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE )
return( CRYPT_ARGERROR_OBJECT );
break;
case CRYPT_ATTRIBUTE_CURRENT_GROUP:
case CRYPT_ATTRIBUTE_CURRENT:
case CRYPT_ENVINFO_SIGNATURE_RESULT:
case CRYPT_ENVINFO_SIGNATURE:
case CRYPT_ENVINFO_SIGNATURE_EXTRADATA:
case CRYPT_ENVINFO_TIMESTAMP:
/* The following checks aren't strictly necessary since we can
get some information as soon as it's available, but it leads
to less confusion (for example without this check we can get
signer info long before we can get the signature results,
which could be misinterpreted to mean that the signature is
bad) and forces the caller to do things cleanly */
if( envelopeInfoPtr->usage == ACTION_SIGN && \
envelopeInfoPtr->state != STATE_FINISHED )
return( CRYPT_ERROR_INCOMPLETE );
if( envelopeInfoPtr->usage == ACTION_MAC && \
attribute == CRYPT_ENVINFO_SIGNATURE_RESULT )
{
if( envelopeInfoPtr->state != STATE_FINISHED )
return( CRYPT_ERROR_INCOMPLETE );
/* If it's a MACd envelope then the signature result isn't
held in a content list as for the other signatures since
the "signature" is just a MAC tag appended to the data,
so there's no need to check for the presence of a content
list */
break;
}
/* We're querying something that resides in the content list,
make sure that there's a content list present. If it's
present but nothing is selected, select the first entry */
if( envelopeInfoPtr->contentListCurrent == NULL )
{
if( envelopeInfoPtr->contentList == NULL )
return( exitErrorNotFound( envelopeInfoPtr,
attribute ) );
envelopeInfoPtr->contentListCurrent = envelopeInfoPtr->contentList;
resetVirtualCursor( envelopeInfoPtr->contentListCurrent );
}
break;
default:
REQUIRES( attribute == CRYPT_ENVINFO_COMPRESSION || \
attribute == CRYPT_ENVINFO_CONTENTTYPE || \
attribute == CRYPT_ENVINFO_INTEGRITY || \
attribute == CRYPT_ENVINFO_DETACHEDSIGNATURE || \
attribute == CRYPT_IATTRIBUTE_ATTRONLY );
}
/* Handle the various information types */
switch( attribute )
{
case CRYPT_ATTRIBUTE_CURRENT_GROUP:
case CRYPT_ATTRIBUTE_CURRENT:
return( getCurrentAttributeInfo( envelopeInfoPtr, valuePtr ) );
case CRYPT_OPTION_ENCR_ALGO:
if( envelopeInfoPtr->defaultAlgo == CRYPT_ALGO_NONE )
return( exitErrorNotInited( envelopeInfoPtr,
CRYPT_OPTION_ENCR_ALGO ) );
*valuePtr = envelopeInfoPtr->defaultAlgo;
return( CRYPT_OK );
case CRYPT_OPTION_ENCR_HASH:
if( envelopeInfoPtr->defaultHash == CRYPT_ALGO_NONE )
return( exitErrorNotInited( envelopeInfoPtr,
CRYPT_OPTION_ENCR_HASH ) );
*valuePtr = envelopeInfoPtr->defaultHash;
return( CRYPT_OK );
case CRYPT_OPTION_ENCR_MAC:
if( envelopeInfoPtr->defaultMAC == CRYPT_ALGO_NONE )
return( exitErrorNotInited( envelopeInfoPtr,
CRYPT_OPTION_ENCR_MAC ) );
*valuePtr = envelopeInfoPtr->defaultMAC;
return( CRYPT_OK );
case CRYPT_ENVINFO_COMPRESSION:
if( envelopeInfoPtr->usage == ACTION_NONE )
return( exitErrorNotInited( envelopeInfoPtr,
CRYPT_ENVINFO_COMPRESSION ) );
*valuePtr = ( envelopeInfoPtr->usage == ACTION_COMPRESS ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_ENVINFO_CONTENTTYPE:
if( envelopeInfoPtr->contentType == CRYPT_CONTENT_NONE )
return( exitErrorNotFound( envelopeInfoPtr,
CRYPT_ENVINFO_CONTENTTYPE ) );
*valuePtr = envelopeInfoPtr->contentType;
return( CRYPT_OK );
case CRYPT_ENVINFO_DETACHEDSIGNATURE:
/* If this isn't signed data or we haven't sorted out the
content details yet we don't know whether it's a detached
signature or not. We have to make an exception for PGP
signed data because the PGP format doesn't record whether a
signature is a detached signature or not. To resolve this,
the lower-level de-enveloping code takes a guess based on
whether the user has manually added a hash for signed-data
processing or not. Because of this the detached-signature
status can change from (apparently-)false before adding the
hash to (apparently-)true after adding it, but there's not
much that we can do about this */
if( envelopeInfoPtr->usage != ACTION_SIGN || \
( envelopeInfoPtr->type != CRYPT_FORMAT_PGP && \
envelopeInfoPtr->contentType == CRYPT_CONTENT_NONE ) )
return( exitErrorNotFound( envelopeInfoPtr,
CRYPT_ENVINFO_DETACHEDSIGNATURE ) );
*valuePtr = ( envelopeInfoPtr->flags & ENVELOPE_DETACHED_SIG ) ? \
TRUE : FALSE;
return( CRYPT_OK );
case CRYPT_ENVINFO_SIGNATURE_RESULT:
return( getSignatureResult( envelopeInfoPtr, valuePtr ) );
case CRYPT_ENVINFO_INTEGRITY:
*valuePtr = ( envelopeInfoPtr->usage == ACTION_MAC ) ? \
CRYPT_INTEGRITY_MACONLY : CRYPT_INTEGRITY_NONE;
return( CRYPT_OK );
case CRYPT_ENVINFO_SIGNATURE:
return( getSignatureKey( envelopeInfoPtr, valuePtr ) );
case CRYPT_ENVINFO_SIGNATURE_EXTRADATA:
case CRYPT_ENVINFO_TIMESTAMP:
{
CRYPT_HANDLE iCryptHandle;
CONTENT_LIST *contentListItem = \
envelopeInfoPtr->contentListCurrent;
assert( contentListItem != NULL );
/* Make sure that there's extra data present */
iCryptHandle = \
( attribute == CRYPT_ENVINFO_SIGNATURE_EXTRADATA ) ? \
contentListItem->clSigInfo.iExtraData : \
contentListItem->clSigInfo.iTimestamp;
if( iCryptHandle == CRYPT_ERROR )
return( exitErrorNotFound( envelopeInfoPtr, attribute ) );
/* Return it to the caller */
krnlSendNotifier( iCryptHandle, IMESSAGE_INCREFCOUNT );
*valuePtr = iCryptHandle;
return( CRYPT_OK );
}
case CRYPT_IATTRIBUTE_ATTRONLY:
/* If this isn't signed data we don't know whether it's an
attributes-only message or not */
if( envelopeInfoPtr->usage != ACTION_SIGN )
return( exitErrorNotFound( envelopeInfoPtr,
CRYPT_IATTRIBUTE_ATTRONLY ) );
*valuePtr = ( envelopeInfoPtr->flags & ENVELOPE_ATTRONLY ) ? \
TRUE : FALSE;
return( CRYPT_OK );
}
retIntError();
}
/* Get a string attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int getEnvelopeAttributeS( INOUT ENVELOPE_INFO *envelopeInfoPtr,
INOUT MESSAGE_DATA *msgData,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
CONTENT_LIST *contentListItem;
int status;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
assert( isWritePtr( msgData, sizeof( MESSAGE_DATA ) ) );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
/* If we're querying something that resides in the content list make
sure that there's a content list present. If it's present but
nothing is selected, select the first entry */
if( attribute == CRYPT_ENVINFO_PRIVATEKEY_LABEL && \
envelopeInfoPtr->contentListCurrent == NULL )
{
if( envelopeInfoPtr->contentList == NULL )
return( exitErrorNotFound( envelopeInfoPtr,
CRYPT_ENVINFO_PRIVATEKEY_LABEL ) );
envelopeInfoPtr->contentListCurrent = envelopeInfoPtr->contentList;
resetVirtualCursor( envelopeInfoPtr->contentListCurrent );
}
/* Generic attributes are valid for all envelope types */
if( attribute == CRYPT_ENVINFO_PRIVATEKEY_LABEL )
{
MESSAGE_KEYMGMT_INFO getkeyInfo;
char label[ CRYPT_MAX_TEXTSIZE + 8 ];
/* Make sure that the current required resource is a private key and
that there's a keyset available to pull the key from */
contentListItem = envelopeInfoPtr->contentListCurrent;
if( contentListItem->envInfo != CRYPT_ENVINFO_PRIVATEKEY )
return( exitErrorNotFound( envelopeInfoPtr,
CRYPT_ENVINFO_PRIVATEKEY_LABEL ) );
if( envelopeInfoPtr->iDecryptionKeyset == CRYPT_ERROR )
return( exitErrorNotInited( envelopeInfoPtr,
CRYPT_ENVINFO_KEYSET_DECRYPT ) );
/* Try and get the key label information. Since we're accessing the
key by (unique) key ID there's no real need to specify a
preference for encryption keys */
if( contentListItem->issuerAndSerialNumber == NULL )
{
setMessageKeymgmtInfo( &getkeyInfo,
( contentListItem->formatType == CRYPT_FORMAT_PGP ) ? \
CRYPT_IKEYID_PGPKEYID : CRYPT_IKEYID_KEYID,
contentListItem->keyID,
contentListItem->keyIDsize,
label, CRYPT_MAX_TEXTSIZE,
KEYMGMT_FLAG_LABEL_ONLY );
}
else
{
setMessageKeymgmtInfo( &getkeyInfo,
CRYPT_IKEYID_ISSUERANDSERIALNUMBER,
contentListItem->issuerAndSerialNumber,
contentListItem->issuerAndSerialNumberSize,
label, CRYPT_MAX_TEXTSIZE,
KEYMGMT_FLAG_LABEL_ONLY );
}
status = krnlSendMessage( envelopeInfoPtr->iDecryptionKeyset,
IMESSAGE_KEY_GETKEY, &getkeyInfo,
KEYMGMT_ITEM_PRIVATEKEY );
if( cryptStatusOK( status ) )
return( attributeCopy( msgData, getkeyInfo.auxInfo,
getkeyInfo.auxInfoLength ) );
return( status );
}
retIntError();
}
/****************************************************************************
* *
* Set Attributes *
* *
****************************************************************************/
/* Set a numeric/boolean attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setEnvelopeAttribute( INOUT ENVELOPE_INFO *envelopeInfoPtr,
IN_INT_Z const int value,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
MESSAGE_CHECK_TYPE checkType = MESSAGE_CHECK_NONE;
ACTION_TYPE usage = ACTION_NONE;
typedef struct {
const CRYPT_ATTRIBUTE_TYPE type; /* Attribute type */
const ACTION_TYPE usage; /* Corresponding usage type */
const MESSAGE_CHECK_TYPE checkType; /* and check type */
} CHECK_INFO;
static const CHECK_INFO checkTable[] = {
/* The following checks are fairly stereotyped and can be selected
via a lookup table. Envelope attributes that require more
specialised checking are handled via custom code in a case
statement */
#ifdef USE_COMPRESSION
{ CRYPT_ENVINFO_COMPRESSION, ACTION_COMPRESS, MESSAGE_CHECK_NONE },
#endif /* USE_COMPRESSION */
{ CRYPT_ENVINFO_KEY, ACTION_CRYPT, MESSAGE_CHECK_CRYPT },
{ CRYPT_ENVINFO_PUBLICKEY, ACTION_CRYPT, MESSAGE_CHECK_PKC_ENCRYPT },
{ CRYPT_ENVINFO_PRIVATEKEY, ACTION_CRYPT, MESSAGE_CHECK_PKC_DECRYPT },
{ CRYPT_ENVINFO_SESSIONKEY, ACTION_CRYPT, MESSAGE_CHECK_CRYPT },
{ CRYPT_ENVINFO_HASH, ACTION_SIGN, MESSAGE_CHECK_HASH },
{ CRYPT_ENVINFO_TIMESTAMP, ACTION_SIGN, MESSAGE_CHECK_NONE },
{ CRYPT_ENVINFO_DETACHEDSIGNATURE, ACTION_SIGN, MESSAGE_CHECK_NONE },
{ CRYPT_IATTRIBUTE_INCLUDESIGCERT, ACTION_SIGN, MESSAGE_CHECK_NONE },
{ CRYPT_IATTRIBUTE_ATTRONLY, ACTION_SIGN, MESSAGE_CHECK_NONE },
{ CRYPT_ATTRIBUTE_NONE, ACTION_NONE }, { CRYPT_ATTRIBUTE_NONE, ACTION_NONE }
};
int i, status;
assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
REQUIRES( ( attribute == CRYPT_ENVINFO_COMPRESSION || \
attribute == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -