📄 user.c
字号:
assert( isReadPtr( password, passwordLength ) );
REQUIRES( passwordLength > 0 && passwordLength < MAX_INTLENGTH_SHORT );
/* Create the user index file and user file for the primary SO user */
status = openIndexKeyset( &iIndexKeyset, CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
return( status );
status = openUserKeyset( &iUserKeyset, 0, CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Update the index file */
memcpy( &userIndex, &userInfoPtr->userFileInfo,
sizeof( USER_FILE_INFO ) );
userIndex.fileRef = 0;
status = writeUserIndex( iIndexKeyset, &userIndex, MAX_USER_OBJECTS );
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
/* We couldn't update the index file, delete the newly-created user
keyset. Since we haven't written anything to it, it's zero-length
so it's deleted automatically on close */
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
return( status );
}
userInfoPtr->iKeyset = iUserKeyset;
/* Create the SO key and the user keyset file */
status = createSOKey( iUserKeyset, userInfoPtr, password,
passwordLength );
if( cryptStatusOK( status ) )
status = writeUserData( userData, USERDATA_BUFFERSIZE,
&userDataLength, userInfoPtr );
if( cryptStatusOK( status ) )
status = commitUserData( iUserKeyset, userInfoPtr, userData,
userDataLength );
if( cryptStatusError( status ) )
{
/* The primary SO create failed, return to the zeroised state.
Since we're already in an exception state here there's not
much that we can do if the zeroise fails */
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
( void ) zeroiseUsers( userInfoPtr );
return( status );
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*status = createCAKey( iUserKeyset, userInfoPtr, password, passwordLength );*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
return( status );
}
/****************************************************************************
* *
* User Management Functions *
* *
****************************************************************************/
/* Check whether a supplied password is the zeroise password */
BOOLEAN isZeroisePassword( IN_BUFFER( passwordLength ) const char *password,
IN_LENGTH_SHORT const int passwordLen )
{
assert( isReadPtr( password, passwordLen ) );
REQUIRES( passwordLen > 0 && passwordLen < MAX_INTLENGTH_SHORT );
if( passwordLen != PRIMARYSO_PASSWORD_LENGTH )
return( FALSE );
return( !memcmp( password, PRIMARYSO_PASSWORD,
PRIMARYSO_PASSWORD_LENGTH ) || \
!memcmp( password, PRIMARYSO_ALTPASSWORD,
PRIMARYSO_PASSWORD_LENGTH ) ? \
TRUE : FALSE );
}
/* Perform a zeroise */
int zeroiseUsers( INOUT USER_INFO *userInfoPtr )
{
USER_INDEX_INFO *userIndexInfo = userInfoPtr->userIndexPtr;
USER_FILE_INFO *userIndex = userIndexInfo->userIndex;
char userFilePath[ MAX_PATH_LENGTH + 1 + 8 ];
int userFilePathLen, i, iterationCount, status;
assert( isWritePtr( userInfoPtr, sizeof( USER_INFO ) ) );
/* Read the user index and step through each entry clearing the user
info for it */
for( i = 0, iterationCount = 0;
i < userIndexInfo->lastEntry && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
i++, iterationCount++ )
{
char userFileName[ 16 + 8 ];
/* Erase the given user keyset */
sprintf_s( userFileName, 16, "u%06x", userIndex[ i ].fileRef );
status = fileBuildCryptlibPath( userFilePath, MAX_PATH_LENGTH,
&userFilePathLen, userFileName,
strlen( userFileName ),
BUILDPATH_GETPATH );
if( cryptStatusOK( status ) )
{
userFilePath[ userFilePathLen ] = '\0';
fileErase( userFilePath );
}
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
/* Erase the index file */
status = fileBuildCryptlibPath( userFilePath, MAX_PATH_LENGTH,
&userFilePathLen, "index", 5,
BUILDPATH_GETPATH );
if( cryptStatusOK( status ) )
{
userFilePath[ userFilePathLen ] = '\0';
fileErase( userFilePath );
}
return( status );
}
/* Create a user keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int createUserKeyset( INOUT USER_INFO *defaultUserInfoPtr,
INOUT USER_INFO *newUserInfoPtr )
{
CRYPT_KEYSET iIndexKeyset, iUserKeyset;
USER_FILE_INFO *userFileInfo = &newUserInfoPtr->userFileInfo;
USER_FILE_INFO *userIndexPtr;
int status;
assert( isReadPtr( defaultUserInfoPtr, sizeof( USER_INFO ) ) );
assert( isReadPtr( newUserInfoPtr, sizeof( USER_INFO ) ) );
/* Try and open the index file */
status = openIndexKeyset( &iIndexKeyset, CRYPT_IKEYOPT_EXCLUSIVEACCESS );
if( cryptStatusError( status ) )
return( status );
/* Create the index entry for the new user */
status = createUserEntry( &userIndexPtr,
defaultUserInfoPtr->userIndexPtr,
MAX_USER_OBJECTS, userFileInfo );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Create the user keyset */
status = openUserKeyset( &iUserKeyset, userFileInfo->fileRef,
CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
return( status );
}
/* We've got the user keyset and info created, update the in-memory
index and index file */
memcpy( userIndexPtr, userFileInfo, sizeof( USER_FILE_INFO ) );
status = writeUserIndex( iIndexKeyset, defaultUserInfoPtr->userIndexPtr,
MAX_USER_OBJECTS );
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
/* We couldn't update the index file, delete the newly-created user
keyset (since we haven't written anything to it, it's zero-length
so it's deleted automatically on close) */
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
}
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
/* Clean up */
return( status );
}
/* Set/change the password for a user object */
int setUserPassword( USER_INFO *userInfoPtr,
IN_BUFFER( passwordLength ) const char *password,
IN_LENGTH_SHORT const int passwordLength )
{
CRYPT_KEYSET iUserKeyset;
USER_FILE_INFO *userFileInfo = &userInfoPtr->userFileInfo;
int status;
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
assert( isReadPtr( password, passwordLength ) );
REQUIRES( passwordLength > 0 && passwordLength < MAX_INTLENGTH_SHORT );
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*!!!!!! Dummy references to keep the compiler happy !!!!!*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
USER_FILE_INFO *userFileInfoPtr = NULL;
USER_INFO userInfo;
( void ) readUserData( userFileInfoPtr, "", 0 );
( void ) signUserData( 0, &userInfo, 0 );
( void ) sigCheckUserData();
( void ) createSOKey( 0, &userInfo, "", 0 );
( void ) createUserKeyset( &userInfo, &userInfo );
}
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* No-one can ever directly set the default SO password */
if( passwordLength == PRIMARYSO_PASSWORD_LENGTH && \
( !memcmp( password, PRIMARYSO_PASSWORD,
PRIMARYSO_PASSWORD_LENGTH ) || \
!memcmp( password, PRIMARYSO_ALTPASSWORD,
PRIMARYSO_PASSWORD_LENGTH ) ) )
return( CRYPT_ERROR_WRONGKEY );
/* If we're setting the password for the primary SO in the zeroised
state, create a new user keyset and SO authentication key and write
the details to the keyset */
if( userFileInfo->fileRef == -1 )
{
status = createPrimarySoUser( userInfoPtr, password,
passwordLength );
return( status );
}
/* Open an existing user keyset */
status = openUserKeyset( &iUserKeyset, userFileInfo->fileRef,
CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
return( status );
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* set state = USER_INITED */
/* write MAC( ??? ) to user file - needs PKCS #15 changes */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* Close the keyset and commit the changes */
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
/* The password has been set, we're now in the user inited state */
userFileInfo->state = USER_STATE_USERINITED;
return( CRYPT_OK );
}
/* Initialise the user index in the default user object from the index file,
and clean up after we're done with it */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initUserIndex( OUT_PTR void **userIndexPtrPtr )
{
CRYPT_KEYSET iIndexKeyset;
USER_INDEX_INFO *userIndexInfo;
char userFilePath[ MAX_PATH_LENGTH + 1 + 8 ];
int userFilePathLen, noEntries, status;
assert( isWritePtr( userIndexPtrPtr, sizeof( void * ) ) );
/* Clear return value */
*userIndexPtrPtr = NULL;
/* Open the index file and read the index entries from it. We open it
in exclusive mode since nothing else should be accessing it at this
point */
status = openIndexKeyset( &iIndexKeyset, CRYPT_IKEYOPT_EXCLUSIVEACCESS );
if( cryptStatusError( status ) )
{
/* If there's no index file present, we're already in the zeroised
state */
if( status == CRYPT_ERROR_NOTFOUND )
return( CRYPT_OK );
/* If there's something there but it's damaged, delete it so that we
can start again */
if( status == CRYPT_ERROR_BADDATA )
{
status = fileBuildCryptlibPath( userFilePath, MAX_PATH_LENGTH,
&userFilePathLen, "index", 5,
BUILDPATH_GETPATH );
if( cryptStatusOK( status ) )
{
userFilePath[ userFilePathLen ] = '\0';
fileErase( userFilePath );
}
return( CRYPT_OK );
}
return( status );
}
/* Allocate room for the user index and read it into the default user
object */
if( ( userIndexInfo = clAlloc( "initUserIndex", \
sizeof( USER_INDEX_INFO ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( userIndexInfo, 0, sizeof( USER_INDEX_INFO ) );
status = noEntries = readIndex( iIndexKeyset, userIndexInfo->userIndex,
MAX_USER_OBJECTS );
krnlSendNotifier( iIndexKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
clFree( "initUserIndex", userIndexInfo );
return( status );
}
userIndexInfo->lastEntry = noEntries;
*userIndexPtrPtr = userIndexInfo;
return( CRYPT_OK );
}
STDC_NONNULL_ARG( ( 1 ) ) \
void endUserIndex( INOUT void *userIndexPtr )
{
USER_INDEX_INFO *userIndexInfo = userIndexPtr;
assert( isWritePtr( userIndexInfo, sizeof( USER_INDEX_INFO ) ) );
zeroise( userIndexInfo, sizeof( USER_INDEX_INFO ) );
clFree( "endUserIndex", userIndexInfo );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -