📄 ctx_attr.c
字号:
isInternalAttribute( attribute ) );
switch( attribute )
{
case CRYPT_CTXINFO_KEYING_SALT:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_HASHSIZE );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->saltLength > 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
memcpy( contextInfoPtr->ctxConv->salt, data, dataLength );
contextInfoPtr->ctxConv->saltLength = dataLength;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->saltLength > 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
memcpy( contextInfoPtr->ctxMAC->salt, data, dataLength );
contextInfoPtr->ctxMAC->saltLength = dataLength;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_VALUE:
return( deriveKey( contextInfoPtr, data, dataLength ) );
case CRYPT_CTXINFO_KEY:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
REQUIRES( needsKey( contextInfoPtr ) );
/* If it's a persistent context we need to have a key label set
before we can continue */
if( ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) && \
contextInfoPtr->labelSize <= 0 )
return( exitErrorNotInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
/* The kernel performs a general check on the size of this
attribute but doesn't know about context subtype-specific
limits so we perform a context-specific check here */
if( dataLength < capabilityInfoPtr->minKeySize || \
dataLength > capabilityInfoPtr->maxKeySize )
return( CRYPT_ARGERROR_NUM1 );
/* Load the key into the context */
status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
data, dataLength );
if( cryptStatusOK( status ) )
contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
return( status );
#ifndef USE_FIPS140
case CRYPT_CTXINFO_KEY_COMPONENTS:
return( setKeyComponents( contextInfoPtr, data, dataLength ) );
#endif /* !USE_FIPS140 */
case CRYPT_CTXINFO_IV:
REQUIRES( contextType == CONTEXT_CONV );
/* If it's a mode that doesn't use an IV then the load IV
operation is meaningless */
if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
return( CRYPT_ERROR_NOTAVAIL );
/* Make sure that the data size is valid */
if( dataLength != capabilityInfoPtr->blockSize )
return( CRYPT_ARGERROR_NUM1 );
/* Load the IV */
return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
KEYPARAM_IV, data, dataLength ) );
case CRYPT_CTXINFO_LABEL:
{
CRYPT_HANDLE iCryptHandle;
if( contextInfoPtr->labelSize > 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
/* Check any device object that the context is associated with
to ensure that nothing with that label already exists in the
device. For keysets the check for duplicates is performed
when the context is explicitly added to the keyset but with
devices the context will be implicitly created within the
device at some future point (at context creation, on key
load/generation, or at some other point) that depends on the
device. Because of this we perform a preemptive check for
duplicates to avoid a potentially confusing error condition
at some indeterminate point in the future.
Since objects are typed, we have to check for the three
possible { label, type } combinations. In theory we could
require that labels are only unique per object type but this
can lead to problems with underlying devices or keysets that
only support a check by label and not by { label, type }
combination. In addition we can't send the message to the
context because the kernel won't forward this message type
(sending a get-key message to a context doesn't make sense)
so we have to explicitly get the dependent device and then
send the get-key directly to it */
status = krnlSendMessage( contextInfoPtr->objectHandle,
IMESSAGE_GETDEPENDENT, &iCryptHandle,
OBJECT_TYPE_DEVICE );
if( cryptStatusOK( status ) && \
( iCryptHandle != SYSTEM_OBJECT_HANDLE ) )
{
MESSAGE_KEYMGMT_INFO getkeyInfo;
setMessageKeymgmtInfo( &getkeyInfo, CRYPT_KEYID_NAME,
data, dataLength, NULL, 0,
KEYMGMT_FLAG_CHECK_ONLY );
status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
&getkeyInfo, KEYMGMT_ITEM_SECRETKEY );
if( cryptStatusError( status ) )
status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
&getkeyInfo,
KEYMGMT_ITEM_PUBLICKEY );
if( cryptStatusError( status ) )
status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
&getkeyInfo,
KEYMGMT_ITEM_PRIVATEKEY );
if( cryptStatusOK( status ) )
{
/* We've found something with this label already
present, we can't use it again */
return( CRYPT_ERROR_DUPLICATE );
}
assert( !cryptArgError( status ) );
}
/* Fall through */
}
case CRYPT_IATTRIBUTE_EXISTINGLABEL:
REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
/* The difference between CRYPT_CTXINFO_LABEL and
CRYPT_IATTRIBUTE_EXISTINGLABEL is that the latter is used to
set a label for a context that's being instantiated from a
persistent object in a device. We can't perform the
duplicate-label check in this case because we'll always get a
match for the device object's label */
if( contextInfoPtr->labelSize > 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
/* Set the label */
memcpy( contextInfoPtr->label, data, dataLength );
contextInfoPtr->labelSize = dataLength;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
REQUIRES( contextType == CONTEXT_PKC );
REQUIRES( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );
REQUIRES( dataLength == PGP_KEYID_SIZE );
memcpy( contextInfoPtr->ctxPKC->openPgpKeyID, data, dataLength );
contextInfoPtr->ctxPKC->openPgpKeyIDSet = TRUE;
/* If it's a non-PGP 2.x key type, set the PGP 2.x keyID to the
OpenPGP keyID. This is necessary because non-PGP 2.x keys can
be used with PGP 2.x message formats which would imply the use
of a PGP 2.x keyID except that it's not defined for this key
type */
if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
memcpy( contextInfoPtr->ctxPKC->pgp2KeyID,
contextInfoPtr->ctxPKC->openPgpKeyID, PGP_KEYID_SIZE );
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_KEY_SPKI:
case CRYPT_IATTRIBUTE_KEY_PGP:
case CRYPT_IATTRIBUTE_KEY_SSH:
case CRYPT_IATTRIBUTE_KEY_SSH1:
case CRYPT_IATTRIBUTE_KEY_SSL:
case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
case CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL:
REQUIRES( contextType == CONTEXT_PKC );
return( setEncodedKey( contextInfoPtr, attribute, data,
dataLength ) );
case CRYPT_IATTRIBUTE_PGPVALIDITY:
REQUIRES( contextType == CONTEXT_PKC );
contextInfoPtr->ctxPKC->pgpCreationTime = *( ( time_t * ) data );
return( CRYPT_OK );
}
retIntError();
}
/****************************************************************************
* *
* Delete Attributes *
* *
****************************************************************************/
/* Delete an attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int deleteContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
const CONTEXT_TYPE contextType = contextInfoPtr->type;
assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
switch( attribute )
{
case CRYPT_CTXINFO_KEYING_ALGO:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->keySetupAlgorithm == CRYPT_ALGO_NONE )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_NONE;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->keySetupAlgorithm == CRYPT_ALGO_NONE )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
contextInfoPtr->ctxMAC->keySetupAlgorithm = CRYPT_ALGO_NONE;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_ITERATIONS:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->keySetupIterations == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
contextInfoPtr->ctxConv->keySetupIterations = 0;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->keySetupIterations == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
contextInfoPtr->ctxMAC->keySetupIterations = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_KEYING_SALT:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
if( contextType == CONTEXT_CONV )
{
if( contextInfoPtr->ctxConv->saltLength == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
zeroise( contextInfoPtr->ctxConv->salt, CRYPT_MAX_HASHSIZE );
contextInfoPtr->ctxConv->saltLength = 0;
return( CRYPT_OK );
}
if( contextInfoPtr->ctxMAC->saltLength == 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_KEYING_SALT ) );
zeroise( contextInfoPtr->ctxMAC->salt, CRYPT_MAX_HASHSIZE );
contextInfoPtr->ctxMAC->saltLength = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_IV:
REQUIRES( contextType == CONTEXT_CONV );
if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_IV ) );
contextInfoPtr->ctxConv->ivLength = \
contextInfoPtr->ctxConv->ivCount = 0;
contextInfoPtr->flags &= ~CONTEXT_FLAG_IV_SET;
return( CRYPT_OK );
case CRYPT_CTXINFO_LABEL:
if( contextInfoPtr->labelSize <= 0 )
return( exitErrorNotFound( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
zeroise( contextInfoPtr->label, contextInfoPtr->labelSize );
contextInfoPtr->labelSize = 0;
return( CRYPT_OK );
case CRYPT_CTXINFO_HASHVALUE:
switch( contextType )
{
case CONTEXT_HASH:
zeroise( contextInfoPtr->ctxHash->hash, CRYPT_MAX_HASHSIZE );
break;
case CONTEXT_MAC:
zeroise( contextInfoPtr->ctxMAC->mac, CRYPT_MAX_HASHSIZE );
break;
default:
retIntError();
}
contextInfoPtr->flags &= ~( CONTEXT_FLAG_HASH_INITED | \
CONTEXT_FLAG_HASH_DONE );
return( CRYPT_OK );
}
retIntError();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -