📄 ctx_attr.c
字号:
case CRYPT_CTXINFO_HASHVALUE:
REQUIRES( contextType == CONTEXT_HASH || \
contextType == CONTEXT_MAC );
if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
return( CRYPT_ERROR_NOTINITED );
if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_DONE ) )
return( CRYPT_ERROR_INCOMPLETE );
return( attributeCopy( msgData, ( contextType == CONTEXT_HASH ) ? \
contextInfoPtr->ctxHash->hash : \
contextInfoPtr->ctxMAC->mac,
capabilityInfoPtr->blockSize ) );
case CRYPT_CTXINFO_LABEL:
if( contextInfoPtr->labelSize <= 0 )
return( exitErrorNotInited( contextInfoPtr,
CRYPT_CTXINFO_LABEL ) );
return( attributeCopy( msgData, contextInfoPtr->label,
contextInfoPtr->labelSize ) );
case CRYPT_IATTRIBUTE_KEYID:
REQUIRES( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->keyID,
KEYID_SIZE ) );
case CRYPT_IATTRIBUTE_KEYID_PGP2:
REQUIRES( contextType == CONTEXT_PKC );
if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
return( CRYPT_ERROR_NOTFOUND );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->pgp2KeyID,
PGP_KEYID_SIZE ) );
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 );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->openPgpKeyID,
PGP_KEYID_SIZE ) );
#ifdef USE_KEA
case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
REQUIRES( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->domainParamPtr,
contextInfoPtr->ctxPKC->domainParamSize ) );
case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
REQUIRES( contextType == CONTEXT_PKC );
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicValuePtr,
contextInfoPtr->ctxPKC->publicValueSize ) );
#else
case CRYPT_IATTRIBUTE_KEY_KEADOMAINPARAMS:
case CRYPT_IATTRIBUTE_KEY_KEAPUBLICVALUE:
return( CRYPT_ERROR_NOTFOUND );
#endif /* USE_KEA */
case CRYPT_IATTRIBUTE_KEY_SPKI:
REQUIRES( contextType == CONTEXT_PKC && \
( contextInfoPtr->flags & CONTEXT_FLAG_KEY_SET ) );
if( contextInfoPtr->ctxPKC->publicKeyInfo != NULL )
{
/* If the data is available in pre-encoded form, copy it
out */
return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicKeyInfo,
contextInfoPtr->ctxPKC->publicKeyInfoSize ) );
}
/* Drop through */
case CRYPT_IATTRIBUTE_KEY_SSH:
case CRYPT_IATTRIBUTE_KEY_SSH1:
case CRYPT_IATTRIBUTE_KEY_SSL:
{
STREAM stream;
KEYFORMAT_TYPE formatType;
REQUIRES( contextType == CONTEXT_PKC && \
( contextInfoPtr->flags & CONTEXT_FLAG_KEY_SET ) );
/* Write the appropriately-formatted key data from the context */
status = attributeToFormatType( attribute, &formatType );
if( cryptStatusError( status ) )
return( status );
sMemOpenOpt( &stream, msgData->data, msgData->length );
status = contextInfoPtr->ctxPKC->writePublicKeyFunction( &stream,
contextInfoPtr, formatType,
"public_key", 10 );
if( cryptStatusOK( status ) )
msgData->length = stell( &stream );
sMemDisconnect( &stream );
return( status );
}
case CRYPT_IATTRIBUTE_PGPVALIDITY:
REQUIRES( contextType == CONTEXT_PKC );
*( ( time_t * ) msgData->data ) = \
contextInfoPtr->ctxPKC->pgpCreationTime;
return( CRYPT_OK );
}
retIntError();
}
/****************************************************************************
* *
* Set Attributes *
* *
****************************************************************************/
/* Set a numeric/boolean attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
IN_INT_Z const int value,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
const CONTEXT_TYPE contextType = contextInfoPtr->type;
int *valuePtr, status;
assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
REQUIRES( value >= 0 && value < MAX_INTLENGTH );
REQUIRES( isAttribute( attribute ) || \
isInternalAttribute( attribute ) );
switch( attribute )
{
case CRYPT_OPTION_MISC_SIDECHANNELPROTECTION:
if( value > 0 )
contextInfoPtr->flags |= CONTEXT_FLAG_SIDECHANNELPROTECTION;
else
contextInfoPtr->flags &= ~CONTEXT_FLAG_SIDECHANNELPROTECTION;
return( CRYPT_OK );
case CRYPT_CTXINFO_MODE:
REQUIRES( contextType == CONTEXT_CONV );
/* If the mode for the context isn't set to the initial default
value, it's already been explicitly set and we can't change
it again */
if( contextInfoPtr->ctxConv->mode != \
( isStreamCipher( capabilityInfoPtr->cryptAlgo ) ? \
CRYPT_MODE_OFB : CRYPT_MODE_CBC ) )
return( exitErrorInited( contextInfoPtr, CRYPT_CTXINFO_MODE ) );
/* Set the en/decryption mode */
return( capabilityInfoPtr->initKeyParamsFunction( contextInfoPtr,
KEYPARAM_MODE, NULL, value ) );
case CRYPT_CTXINFO_KEYSIZE:
{
int keySize;
switch( contextType )
{
case CONTEXT_CONV:
valuePtr = &contextInfoPtr->ctxConv->userKeyLength;
break;
case CONTEXT_PKC:
valuePtr = &contextInfoPtr->ctxPKC->keySizeBits;
break;
case CONTEXT_MAC:
valuePtr = &contextInfoPtr->ctxMAC->userKeyLength;
break;
default:
retIntError();
}
if( *valuePtr != 0 )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYSIZE ) );
/* Trim the user-supplied value to the correct shape, taking
into account various issues such as limitations with the
underlying crypto code/hardware and interop problems with
algorithms that allow excessively long keys */
status = adjustUserKeySize( contextInfoPtr, value, &keySize );
if( cryptStatusError( status ) )
return( status );
*valuePtr = ( contextType == CONTEXT_PKC ) ? \
bytesToBits( keySize ) : keySize;
return( CRYPT_OK );
}
case CRYPT_CTXINFO_KEYING_ALGO:
case CRYPT_OPTION_KEYING_ALGO:
{
CRYPT_ALGO_TYPE *algoValuePtr;
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
algoValuePtr = ( contextType == CONTEXT_CONV ) ? \
&contextInfoPtr->ctxConv->keySetupAlgorithm : \
&contextInfoPtr->ctxMAC->keySetupAlgorithm;
if( *algoValuePtr != CRYPT_ALGO_NONE )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ALGO ) );
*algoValuePtr = value;
return( CRYPT_OK );
}
case CRYPT_CTXINFO_KEYING_ITERATIONS:
case CRYPT_OPTION_KEYING_ITERATIONS:
REQUIRES( contextType == CONTEXT_CONV || \
contextType == CONTEXT_MAC );
valuePtr = ( contextType == CONTEXT_CONV ) ? \
&contextInfoPtr->ctxConv->keySetupIterations : \
&contextInfoPtr->ctxMAC->keySetupIterations;
if( *valuePtr )
return( exitErrorInited( contextInfoPtr,
CRYPT_CTXINFO_KEYING_ITERATIONS ) );
*valuePtr = value;
return( CRYPT_OK );
case CRYPT_CTXINFO_PERSISTENT:
/* The is-object-persistent attribute functions as follows:
| Software | Hardware
-----+----------+-------------------
PKC | R/O (1) | R/O (2)
-----+----------+-------------------
Conv | R/O (1) | R/W low state (3)
| | R/O high state
(1) = Set if stored to or read from a keyset.
(2) = Always set. Private-key objects are automatically
created as persistent objects, public-key objects
are (transparently) created as software objects since
the operation is much faster on the host system than
by going via the device.
(3) = Can be set in the low state, if set then the object
is created as a persistent object in the device.
Most of these checks are enforced by the kernel, the one
thing that the ACL language can't specify is the requirement
that a persistent conventional-encryption object be tied to
a device, which we do explicitly here */
if( ( value != 0 ) && \
!( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
return( CRYPT_ERROR_PERMISSION );
/* Set or clear the persistent flag as required */
if( value != 0 )
contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
else
contextInfoPtr->flags &= ~CONTEXT_FLAG_PERSISTENT;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_KEYSIZE:
/* If it's a private key context or a persistent context we need
to have a key label set before we can continue */
if( ( ( contextInfoPtr->type == CONTEXT_PKC ) || \
( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ) && \
contextInfoPtr->labelSize <= 0 )
retIntError();
/* If the key is held outside the context (e.g. in a device) we
need to manually supply the key-related information needed by
the context, which in this case is the key size. Once this
is set there is (effectively) a key loaded, although the
actual keying values are held anderswhere */
switch( contextType )
{
case CONTEXT_CONV:
contextInfoPtr->ctxConv->userKeyLength = value;
break;
case CONTEXT_PKC:
contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( value );
break;
case CONTEXT_MAC:
contextInfoPtr->ctxMAC->userKeyLength = value;
break;
default:
retIntError();
}
contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
return( CRYPT_OK );
case CRYPT_IATTRIBUTE_DEVICEOBJECT:
#ifdef USE_DEVICES
contextInfoPtr->deviceObject = value;
#endif /* USE_DEVICES */
return( CRYPT_OK );
}
retIntError();
}
/* Set a string attribute */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int setContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
IN_BUFFER( dataLength ) const void *data,
IN_LENGTH const int dataLength,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
{
const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
const CONTEXT_TYPE contextType = contextInfoPtr->type;
int status;
assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
assert( isReadPtr( data, dataLength ) );
REQUIRES( dataLength > 0 && dataLength < MAX_INTLENGTH );
REQUIRES( isAttribute( attribute ) || \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -