📄 user_rw.c
字号:
REQUIRES( isHandleRangeValid( iCryptKeyset ) );
/* Read each trusted cert from the keyset */
setMessageData( &msgData, buffer, CRYPT_MAX_PKCSIZE + 1536 );
status = krnlSendMessage( iCryptKeyset, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_TRUSTEDCERT );
for( iterationCount = 0;
cryptStatusOK( status ) && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
iterationCount++ )
{
/* Add the cert data as a trusted cert item and look for the next
one */
status = addTrustEntry( trustInfoPtr, CRYPT_UNUSED, msgData.data,
msgData.length, TRUE );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, buffer, CRYPT_MAX_PKCSIZE + 1536 );
status = krnlSendMessage( iCryptKeyset, IMESSAGE_GETATTRIBUTE_S,
&msgData,
CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT );
}
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
return( ( status == CRYPT_ERROR_NOTFOUND ) ? CRYPT_OK : status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
int readConfig( IN_HANDLE const CRYPT_USER iCryptUser,
IN_STRING const char *fileName, INOUT void *trustInfoPtr )
{
CRYPT_KEYSET iCryptKeyset;
MESSAGE_CREATEOBJECT_INFO createInfo;
STREAM stream;
DYNBUF configDB;
char configFilePath[ MAX_PATH_LENGTH + 8 ];
int configFilePathLen, iterationCount, status;
assert( fileName != NULL );
assert( trustInfoPtr != NULL );
REQUIRES( iCryptUser == DEFAULTUSER_OBJECT_HANDLE || \
isHandleRangeValid( iCryptUser ) );
/* Try and open the configuration file. If we can't open it it merely
means that the file doesn't exist, which isn't an error, we'll go
with the built-in defaults */
status = fileBuildCryptlibPath( configFilePath, MAX_PATH_LENGTH,
&configFilePathLen, fileName,
strlen( fileName ), BUILDPATH_GETPATH );
if( cryptStatusError( status ) )
return( CRYPT_OK ); /* Can't build configuration path */
setMessageCreateObjectInfo( &createInfo, CRYPT_KEYSET_FILE );
createInfo.arg2 = CRYPT_KEYOPT_READONLY;
createInfo.strArg1 = configFilePath;
createInfo.strArgLen1 = configFilePathLen;
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_KEYSET );
if( cryptStatusError( status ) )
return( CRYPT_OK ); /* No configuration data present */
iCryptKeyset = createInfo.cryptHandle;
/* Get the configuration info from the keyset */
status = dynCreate( &configDB, iCryptKeyset,
CRYPT_IATTRIBUTE_CONFIGDATA );
if( cryptStatusError( status ) )
{
/* If there were no configuration options present there may still be
trusted certs so we try and read those before exiting */
if( status == CRYPT_ERROR_NOTFOUND )
status = readTrustedCerts( iCryptKeyset, trustInfoPtr );
krnlSendNotifier( iCryptKeyset, IMESSAGE_DECREFCOUNT );
return( status );
}
status = readTrustedCerts( iCryptKeyset, trustInfoPtr );
krnlSendNotifier( iCryptKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
dynDestroy( &configDB );
return( status );
}
/* Read each configuration option */
sMemConnect( &stream, dynData( configDB ), dynLength( configDB ) );
for( iterationCount = 0;
cryptStatusOK( status ) && \
stell( &stream ) < dynLength( configDB ) && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
iterationCount++ )
{
status = readConfigOption( &stream, iCryptUser );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
sMemDisconnect( &stream );
/* Clean up */
dynDestroy( &configDB );
return( status );
}
/****************************************************************************
* *
* Write Configuration Options *
* *
****************************************************************************/
/* Write any user-defined configuration options. This is performed in two
phases, a first phase that encodes the configuration data and a second
phase that writes the data to disk. The reason for the split is that the
second phase doesn't require the use of the user object data any more
and can be a somewhat lengthy process due to disk accesses and other bits
and pieces, because of this the caller is expected to unlock the user
object between the two phases to ensure that the second phase doesn't
stall all other operations that require it */
CHECK_RETVAL_SPECIAL STDC_NONNULL_ARG( ( 1, 2, 3, 4, 5 ) ) \
int prepareConfigData( INOUT void *configOptions,
IN_STRING const char *fileName,
INOUT void *trustInfoPtr,
OUT_BUFFER_ALLOC( *dataLength ) void **dataPtrPtr,
OUT_LENGTH_Z int *dataLength )
{
STREAM stream;
const BOOLEAN trustedCertsPresent = \
cryptStatusOK( \
enumTrustedCerts( trustInfoPtr, CRYPT_UNUSED,
CRYPT_UNUSED ) ) ? \
TRUE : FALSE;
void *dataPtr;
int length, status;
assert( isReadPtr( configOptions,
sizeof( OPTION_INFO ) * \
( CRYPT_OPTION_LAST - CRYPT_OPTION_FIRST ) ) );
assert( fileName != NULL );
assert( trustInfoPtr != NULL );
assert( isWritePtr( dataPtrPtr, sizeof( void * ) ) );
assert( isWritePtr( dataLength, sizeof( int ) ) );
/* Clear return values */
*dataPtrPtr = NULL;
*dataLength = 0;
/* If neither the configuration options nor any cert trust settings have
changed, there's nothing to do */
if( !checkConfigChanged( configOptions ) && !trustedCertsPresent )
return( CRYPT_OK );
/* Determine the total encoded length of the configuration options */
status = sizeofConfigData( configOptions, &length );
if( cryptStatusError( status ) )
return( status );
/* If we've gone back to all default values from having non-default ones
stored, we either have to write only trusted certs or nothing at all */
if( length <= 0 )
{
char configFilePath[ MAX_PATH_LENGTH + 1 + 8 ];
int configFilePathLen;
/* There's no data to write, if there are trusted certs present
notify the caller */
if( trustedCertsPresent )
return( OK_SPECIAL );
/* There's nothing to write, delete the configuration file */
status = fileBuildCryptlibPath( configFilePath, MAX_PATH_LENGTH,
&configFilePathLen, fileName,
strlen( fileName ),
BUILDPATH_GETPATH );
if( cryptStatusOK( status ) )
{
configFilePath[ configFilePathLen ] = '\0';
fileErase( configFilePath );
}
return( CRYPT_OK );
}
ENSURES( length > 0 && length < MAX_INTLENGTH );
/* Allocate a buffer to hold the encoded values */
if( ( dataPtr = clAlloc( "prepareConfigData", length ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
/* Write the configuration options */
sMemOpen( &stream, dataPtr, length );
status = writeConfigData( &stream, configOptions );
if( cryptStatusOK( status ) )
length = stell( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
{
assert( DEBUG_WARN );
return( status );
}
/* We've written the configuration data to the memory buffer, let the
caller know that they can unlock it and commit it to permanent
storage */
*dataPtrPtr = dataPtr;
*dataLength = length;
return( OK_SPECIAL );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
int commitConfigData( IN_HANDLE const CRYPT_USER cryptUser,
IN_STRING const char *fileName,
IN_BUFFER_OPT( length ) const void *data,
IN_LENGTH_Z const int dataLength )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_DATA msgData;
char configFilePath[ MAX_PATH_LENGTH + 8 ];
int configFilePathLen, status;
assert( isHandleRangeValid( cryptUser ) );
assert( fileName != NULL );
assert( ( data == NULL && dataLength == 0 ) || \
isReadPtr( data, dataLength ) );
REQUIRES( ( data == NULL && dataLength == 0 ) || \
( dataLength > 0 && dataLength < MAX_INTLENGTH ) );
/* Build the path to the configuration file and try and create it */
status = fileBuildCryptlibPath( configFilePath, MAX_PATH_LENGTH,
&configFilePathLen, fileName,
strlen( fileName ),
BUILDPATH_CREATEPATH );
if( cryptStatusError( status ) )
{
/* Map the lower-level filesystem-specific error into a more
meaningful generic error */
return( CRYPT_ERROR_OPEN );
}
setMessageCreateObjectInfo( &createInfo, CRYPT_KEYSET_FILE );
createInfo.arg2 = CRYPT_KEYOPT_CREATE;
createInfo.strArg1 = configFilePath;
createInfo.strArgLen1 = configFilePathLen;
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_KEYSET );
if( cryptStatusError( status ) )
{
/* Map the lower-level keyset-specific error into a more meaningful
generic error */
return( CRYPT_ERROR_OPEN );
}
/* Send the configuration data (if there is any) and any trusted certs
to the keyset. dataLength can be zero if there are only trusted
certs to write */
if( dataLength > 0 )
{
setMessageData( &msgData, ( void * ) data, dataLength );
status = krnlSendMessage( createInfo.cryptHandle,
IMESSAGE_SETATTRIBUTE_S, &msgData,
CRYPT_IATTRIBUTE_CONFIGDATA );
}
if( cryptStatusOK( status ) )
{
status = krnlSendMessage( cryptUser, IMESSAGE_SETATTRIBUTE,
&createInfo.cryptHandle,
CRYPT_IATTRUBUTE_CERTKEYSET );
}
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
fileErase( configFilePath );
return( CRYPT_ERROR_WRITE );
}
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -