📄 user_rw.c
字号:
/****************************************************************************
* *
* cryptlib Configuration Read/Write Routines *
* Copyright Peter Gutmann 1994-2008 *
* *
****************************************************************************/
#include "crypt.h"
#ifdef INC_ALL
#include "trustmgr.h"
#include "asn1.h"
#include "user_int.h"
#include "user.h"
#else
#include "cert/trustmgr.h"
#include "misc/asn1.h"
#include "misc/user_int.h"
#include "misc/user.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* Utility Functions *
* *
****************************************************************************/
/* Read an individual configuration option */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int readConfigOption( INOUT STREAM *stream,
IN_HANDLE CRYPT_USER iCryptUser )
{
CRYPT_ATTRIBUTE_TYPE attributeType;
const BUILTIN_OPTION_INFO *builtinOptionInfoPtr;
MESSAGE_DATA msgData;
void *dataPtr = DUMMY_INIT_PTR;
long optionCode;
int value, tag, length, status;
/* Read the wrapper and option index and map it to the actual option.
If we find an unknown index or one that shouldn't be writeable to
persistent storage, we skip it and continue. This is done to handle
new options that may have been added after this version of cryptlib
was built (for unknown indices) and because the stored configuration
options are an untrusted source so we have to check for attempts to
feed in bogus values (for non-writeable options) */
readSequence( stream, NULL );
status = readShortInteger( stream, &optionCode );
if( cryptStatusError( status ) )
return( status );
if( optionCode < 0 || optionCode > LAST_STORED_OPTION )
{
/* Unknown option, ignore it */
return( readUniversal( stream ) );
}
builtinOptionInfoPtr = getBuiltinOptionInfoByCode( optionCode );
if( builtinOptionInfoPtr == NULL || \
builtinOptionInfoPtr->index < 0 || \
builtinOptionInfoPtr->index > LAST_STORED_OPTION || \
builtinOptionInfoPtr->index == CRYPT_UNUSED )
{
/* Unknown option, ignore it */
return( readUniversal( stream ) );
}
attributeType = builtinOptionInfoPtr->option;
/* Read the option value and set the option. We don't treat a failure
to set the option as a problem since the user probably doesn't want
the entire system to fail because of a bad configuration option, and
in any case we'll fall back to a safe default value */
tag = peekTag( stream );
if( cryptStatusError( tag ) )
return( tag );
if( tag == BER_BOOLEAN || tag == BER_INTEGER )
{
/* It's a numeric value, read the appropriate type and try and set
the option */
if( tag == BER_BOOLEAN )
status = readBoolean( stream, &value );
else
{
long integer;
status = readShortInteger( stream, &integer );
if( cryptStatusOK( status ) )
value = ( int ) integer;
}
if( cryptStatusError( status ) )
return( status );
( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE,
&value, attributeType );
return( CRYPT_OK );
}
/* It's a string value, set the option straight from the encoded data */
status = readGenericHole( stream, &length, 1, BER_STRING_UTF8 );
if( cryptStatusOK( status ) )
status = sMemGetDataBlock( stream, &dataPtr, length );
if( cryptStatusOK( status ) )
status = sSkip( stream, length );
if( cryptStatusError( status ) )
return( status );
setMessageData( &msgData, dataPtr, length );
( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE_S,
&msgData, attributeType );
return( CRYPT_OK );
}
/* Rumble through the configuration options to determine the total encoded
length of the ones that don't match the default setting. We can't just
check the isDirty flag because if a value is reset to its default setting
the encoded size will be zero even though the isDirty flag is set */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int sizeofConfigData( IN_ARRAY( CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST ) \
const OPTION_INFO *optionList,
OUT_LENGTH_Z int *length )
{
int dataLength = 0, i;
assert( isReadPtr( optionList,
sizeof( OPTION_INFO ) * \
( CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST ) ) );
assert( isWritePtr( length, sizeof( int ) ) );
/* Clear return value */
*length = 0;
/* Check each option to see whether it needs to be written to disk. If
it does, determine its length */
for( i = 0;
optionList[ i ].builtinOptionInfo->option <= LAST_STORED_OPTION && \
i < FAILSAFE_ITERATIONS_MED; i++ )
{
const BUILTIN_OPTION_INFO *builtinOptionInfoPtr = \
optionList[ i ].builtinOptionInfo;
const OPTION_INFO *optionInfoPtr = &optionList[ i ];
int lengthValue;
/* If it's an option that can't be written to disk, skip it */
if( builtinOptionInfoPtr->index == CRYPT_UNUSED )
continue;
if( builtinOptionInfoPtr->type == OPTION_STRING )
{
/* If the string value is the same as the default, there's
nothing to do */
if( optionInfoPtr->strValue == NULL || \
optionInfoPtr->strValue == builtinOptionInfoPtr->strDefault )
continue;
lengthValue = ( int ) \
sizeofObject( \
sizeofShortInteger( builtinOptionInfoPtr->index ) + \
sizeofObject( optionInfoPtr->intValue ) );
}
else
{
/* If the integer/boolean value that's currently set isn't the
default setting, update it */
if( optionInfoPtr->intValue == builtinOptionInfoPtr->intDefault )
continue;
lengthValue = ( int ) \
sizeofObject( \
sizeofShortInteger( builtinOptionInfoPtr->index ) + \
( builtinOptionInfoPtr->type == OPTION_NUMERIC ? \
sizeofShortInteger( optionInfoPtr->intValue ) : \
sizeofBoolean() ) );
}
ENSURES( lengthValue > 0 && lengthValue < MAX_INTLENGTH_SHORT );
dataLength += lengthValue;
}
ENSURES( i < FAILSAFE_ITERATIONS_MED );
ENSURES( dataLength >= 0 && dataLength < MAX_INTLENGTH );
*length = dataLength;
return( CRYPT_OK );
}
/* Write the configuration data to a stream */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeConfigData( INOUT STREAM *stream,
IN_ARRAY( CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST ) \
const OPTION_INFO *optionList )
{
int i, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( optionList,
sizeof( OPTION_INFO ) * \
( CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST ) ) );
/* Write each option that needs to be written to the stream */
for( i = 0;
optionList[ i ].builtinOptionInfo->option <= LAST_STORED_OPTION && \
i < FAILSAFE_ITERATIONS_MED; i++ )
{
const BUILTIN_OPTION_INFO *builtinOptionInfoPtr = \
optionList[ i ].builtinOptionInfo;
const OPTION_INFO *optionInfoPtr = &optionList[ i ];
/* If it's an option that can't be written to disk, skip it */
if( builtinOptionInfoPtr->index == CRYPT_UNUSED )
continue;
if( builtinOptionInfoPtr->type == OPTION_STRING )
{
if( optionInfoPtr->strValue == NULL || \
optionInfoPtr->strValue == builtinOptionInfoPtr->strDefault )
continue;
writeSequence( stream,
sizeofShortInteger( builtinOptionInfoPtr->index ) + \
sizeofObject( strlen( optionInfoPtr->strValue ) ) );
writeShortInteger( stream, builtinOptionInfoPtr->index,
DEFAULT_TAG );
status = writeCharacterString( stream, optionInfoPtr->strValue,
strlen( optionInfoPtr->strValue ),
BER_STRING_UTF8 );
if( cryptStatusError( status ) )
return( status );
continue;
}
if( optionInfoPtr->intValue == builtinOptionInfoPtr->intDefault )
continue;
if( builtinOptionInfoPtr->type == OPTION_NUMERIC )
{
writeSequence( stream,
sizeofShortInteger( builtinOptionInfoPtr->index ) + \
sizeofShortInteger( optionInfoPtr->intValue ) );
writeShortInteger( stream, builtinOptionInfoPtr->index,
DEFAULT_TAG );
status = writeShortInteger( stream, optionInfoPtr->intValue,
DEFAULT_TAG );
}
else
{
writeSequence( stream,
sizeofShortInteger( builtinOptionInfoPtr->index ) + \
sizeofBoolean() );
writeShortInteger( stream, builtinOptionInfoPtr->index,
DEFAULT_TAG );
status = writeBoolean( stream, optionInfoPtr->intValue,
DEFAULT_TAG );
}
if( cryptStatusError( status ) )
return( status );
}
ENSURES( i < FAILSAFE_ITERATIONS_MED );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Read Configuration Options *
* *
****************************************************************************/
/* Read any user-defined configuration options. Since the configuration
file is an untrusted source we set the values in it via external messages
rather than manipulating the configuration info directly, which means
that everything read is subject to the usual ACL checks */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int readTrustedCerts( IN_HANDLE const CRYPT_KEYSET iCryptKeyset,
INOUT void *trustInfoPtr )
{
MESSAGE_DATA msgData;
BYTE buffer[ CRYPT_MAX_PKCSIZE + 1536 + 8 ];
int iterationCount, status;
assert( trustInfoPtr != NULL );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -