📄 user.c
字号:
break;
}
if( i >= MAX_USER_OBJECTS )
break;
}
ENSURES_N( newFileRef < MAX_USER_OBJECTS );
*fileRef = newFileRef;
return( userIndexPtr );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
static int createUserEntry( OUT_PTR USER_FILE_INFO **userIndexPtrPtr,
IN_ARRAY( noUserIndexEntries ) \
USER_FILE_INFO *userIndex,
IN_RANGE( 1, MAX_USER_OBJECTS ) \
const int noUserIndexEntries,
INOUT USER_FILE_INFO *userFileInfo )
{
USER_FILE_INFO *userIndexPtr;
int fileRef, iterationCount, status = CRYPT_OK;
assert( isWritePtr( userIndexPtrPtr, sizeof( USER_FILE_INFO * ) ) );
assert( isWritePtr( userIndex, \
sizeof( USER_FILE_INFO ) * noUserIndexEntries ) );
assert( isWritePtr( userFileInfo, sizeof( USER_FILE_INFO ) ) );
REQUIRES( noUserIndexEntries > 0 && \
noUserIndexEntries <= MAX_USER_OBJECTS );
/* Clear return value */
*userIndexPtrPtr = NULL;
/* Check whether this user is already present in the index */
if( findUser( userIndex, noUserIndexEntries, USERID_NAME,
userFileInfo->userName, userFileInfo->userNameLength ) != NULL )
return( CRYPT_ERROR_DUPLICATE );
/* Make sure that the userID that we're using is unique. This is a
pretty straightforward operation, we just keep generating new random
IDs until we get one that's not already present */
for( iterationCount = 0;
!cryptStatusError( status ) && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
iterationCount++ )
{
if( findUser( userIndex, noUserIndexEntries, USERID_USERID,
userFileInfo->userID, KEYID_SIZE ) != NULL )
{
MESSAGE_DATA msgData;
setMessageData( &msgData, ( void * ) userFileInfo->userID,
KEYID_SIZE );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_IATTRIBUTE_RANDOM_NONCE );
}
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
/* Locate a new unused entry that we can use */
userIndexPtr = findFreeEntry( userIndex, MAX_USER_OBJECTS, &fileRef );
if( userIndexPtr == NULL )
return( CRYPT_ERROR_OVERFLOW );
userFileInfo->fileRef = fileRef;
return( CRYPT_OK );
}
/* Read the user index file:
UserIndexEntry ::= SEQUENCE {
iD OCTET STRING SIZE(16), -- User ID
creatorID OCTET STRING SIZE(16), -- Creating SO's ID
name UTF8String, -- User name
fileReference INTEGER -- Reference to user file
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readIndexEntry( INOUT STREAM *stream,
INOUT USER_FILE_INFO *userIndexPtr )
{
USER_FILE_INFO userIndexEntry;
long value;
int length, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( userIndexPtr, sizeof( USER_FILE_INFO ) ) );
/* Clear return value */
memset( userIndexPtr, 0, sizeof( USER_FILE_INFO ) );
/* Read the user index data */
memset( &userIndexEntry, 0, sizeof( USER_FILE_INFO ) );
readSequence( stream, NULL );
readOctetString( stream, userIndexEntry.userID, &length, KEYID_SIZE,
KEYID_SIZE );
readOctetString( stream, userIndexEntry.creatorID, &length, KEYID_SIZE,
KEYID_SIZE );
readCharacterString( stream, userIndexEntry.userName,
CRYPT_MAX_TEXTSIZE, &userIndexEntry.userNameLength,
BER_STRING_UTF8 );
status = readShortInteger( stream, &value );
if( cryptStatusError( status ) )
return( status );
userIndexEntry.fileRef = value;
/* Return the result to the caller */
memcpy( userIndexPtr, &userIndexEntry, sizeof( USER_FILE_INFO ) );
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int readIndex( IN_HANDLE const CRYPT_KEYSET iIndexKeyset,
IN_ARRAY( maxUserObjects ) USER_FILE_INFO *userIndex,
IN_RANGE( 1, MAX_USER_OBJECTS ) const int maxUserObjects )
{
STREAM stream;
DYNBUF userIndexDB;
int i, iterationCount, status;
assert( isWritePtr( userIndex, \
maxUserObjects * sizeof( USER_FILE_INFO ) ) );
REQUIRES( isHandleRangeValid( iIndexKeyset ) );
REQUIRES( maxUserObjects > 0 && maxUserObjects <= MAX_USER_OBJECTS );
/* Read the user index file into memory */
status = dynCreate( &userIndexDB, iIndexKeyset,
CRYPT_IATTRIBUTE_USERINDEX );
if( cryptStatusError( status ) )
return( status );
sMemConnect( &stream, dynData( userIndexDB ), dynLength( userIndexDB ) );
for( i = 0, iterationCount = 0;
cryptStatusOK( status ) && \
stell( &stream ) < dynLength( userIndexDB ) && \
i < maxUserObjects && iterationCount < FAILSAFE_ITERATIONS_LARGE;
i++, iterationCount++ )
{
status = readIndexEntry( &stream, &userIndex[ i ] );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
sMemDisconnect( &stream );
dynDestroy( &userIndexDB );
if( cryptStatusError( status ) )
return( status );
if( i > maxUserObjects )
return( CRYPT_ERROR_OVERFLOW );
return( i );
}
/* Write the user index file */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeUserIndexEntry( INOUT STREAM *stream,
const USER_FILE_INFO *userIndexPtr )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( userIndexPtr, sizeof( USER_FILE_INFO ) ) );
writeSequence( stream, 2 * sizeofObject( KEYID_SIZE ) + \
sizeofObject( userIndexPtr->userNameLength ) + \
sizeofShortInteger( userIndexPtr->fileRef) );
writeOctetString( stream, userIndexPtr->userID, KEYID_SIZE, DEFAULT_TAG );
writeOctetString( stream, userIndexPtr->creatorID, KEYID_SIZE, DEFAULT_TAG );
writeCharacterString( stream, userIndexPtr->userName,
userIndexPtr->userNameLength, BER_STRING_UTF8 );
return( writeShortInteger( stream, userIndexPtr->fileRef, DEFAULT_TAG ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int writeUserIndex( IN_HANDLE const CRYPT_KEYSET iIndexKeyset,
IN_ARRAY( noUserIndexEntries ) \
USER_FILE_INFO *userIndex,
IN_RANGE( 1, MAX_USER_OBJECTS ) \
const int noUserIndexEntries )
{
STREAM stream;
MESSAGE_DATA msgData;
BYTE userIndexData[ MAX_USERINDEX_SIZE + 8 ];
int userIndexDataLength, i, iterationCount, status = CRYPT_OK;
assert( isWritePtr( userIndex, \
noUserIndexEntries * sizeof( USER_FILE_INFO ) ) );
REQUIRES( isHandleRangeValid( iIndexKeyset ) );
REQUIRES( noUserIndexEntries > 0 && \
noUserIndexEntries <= MAX_USER_OBJECTS );
/* Write the user index data to a buffer so that we can send it to the
index keyset */
sMemOpen( &stream, userIndexData, MAX_USERINDEX_SIZE );
for( i = 0, iterationCount = 0;
i < noUserIndexEntries && cryptStatusOK( status ) && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
i++, iterationCount++ )
{
if( userIndex[ i ].state != USER_STATE_NONE )
status = writeUserIndexEntry( &stream, &userIndex[ i ] );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
userIndexDataLength = stell( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
return( status );
/* Write the user index data to the keyset */
setMessageData( &msgData, userIndexData, userIndexDataLength );
return( krnlSendMessage( iIndexKeyset, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_USERINDEX ) );
}
/****************************************************************************
* *
* Read/Write User Data *
* *
****************************************************************************/
/* Read/write user data:
UserInfo ::= SEQUENCE {
role ENUMERATED, -- SO/user/CA
iD OCTET STRING SIZE(16), -- User ID
creatorID OCTET STRING SIZE(16), -- Creating SO's ID
name UTF8String, -- User name
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readUserData( INOUT USER_FILE_INFO *userFileInfoPtr,
IN_BUFFER( userDataLength ) const void *userData,
IN_LENGTH_SHORT const int userDataLength )
{
STREAM stream;
int enumValue, length, status;
assert( isWritePtr( userFileInfoPtr, sizeof( USER_FILE_INFO ) ) );
assert( isReadPtr( userData, userDataLength ) );
REQUIRES( userDataLength > 0 && userDataLength < MAX_INTLENGTH_SHORT );
/* Clear return value */
memset( userFileInfoPtr, 0, sizeof( userFileInfoPtr ) );
/* Read the user info */
sMemConnect( &stream, userData, userDataLength );
readSequence( &stream, NULL );
readEnumerated( &stream, &enumValue );
userFileInfoPtr->type = enumValue;
readOctetString( &stream, userFileInfoPtr->userID, &length,
KEYID_SIZE, KEYID_SIZE );
readOctetString( &stream, userFileInfoPtr->creatorID, &length,
KEYID_SIZE, KEYID_SIZE );
status = readCharacterString( &stream, userFileInfoPtr->userName,
CRYPT_MAX_TEXTSIZE,
&userFileInfoPtr->userNameLength,
BER_STRING_UTF8 );
sMemDisconnect( &stream );
return( status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
static int writeUserData( OUT_BUFFER( userDataMaxLength, \
*userDataLength ) void *userData,
IN_LENGTH_SHORT const int userDataMaxLength,
OUT_LENGTH_SHORT_Z int *userDataLength,
const USER_INFO *userInfoPtr )
{
const USER_FILE_INFO *userFileInfo = &userInfoPtr->userFileInfo;
STREAM stream;
int status;
assert( isWritePtr( userData, userDataMaxLength ) );
assert( isWritePtr( userDataLength, sizeof( int ) ) );
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
REQUIRES( userDataMaxLength > 0 && \
userDataMaxLength < MAX_INTLENGTH_SHORT );
/* Clear return values */
memset( userData, 0, min( 16, userDataMaxLength ) );
*userDataLength = 0;
/* Write the user information to a memory buffer */
sMemOpen( &stream, userData, userDataMaxLength );
writeSequence( &stream, sizeofShortInteger( userFileInfo->type ) + \
2 * sizeofObject( KEYID_SIZE ) + \
sizeofObject( userFileInfo->userNameLength ) );
writeEnumerated( &stream, userFileInfo->type, DEFAULT_TAG );
writeOctetString( &stream, userFileInfo->userID, KEYID_SIZE,
DEFAULT_TAG );
writeOctetString( &stream, userFileInfo->creatorID, KEYID_SIZE,
DEFAULT_TAG );
status = writeCharacterString( &stream, userFileInfo->userName,
userFileInfo->userNameLength,
BER_STRING_UTF8 );
if( cryptStatusOK( status ) )
*userDataLength = stell( &stream );
sMemDisconnect( &stream );
return( status );
}
/* Send user data to a user keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
static int commitUserData( IN_HANDLE const CRYPT_KEYSET iUserKeyset,
const USER_INFO *userInfoPtr,
IN_BUFFER( userDataLength ) const void *userData,
IN_LENGTH_SHORT const int userDataLength )
{
MESSAGE_DATA msgData;
int status;
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
assert( isReadPtr( userData, userDataLength ) );
REQUIRES( isHandleRangeValid( iUserKeyset ) );
REQUIRES( userDataLength > 0 && userDataLength < MAX_INTLENGTH_SHORT );
/* Add the user ID and SO-signed user info to the keyset */
setMessageData( &msgData, ( void * ) userData, userDataLength );
status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_USERINFO );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, ( void * ) userInfoPtr->userFileInfo.userID,
KEYID_SIZE );
status = krnlSendMessage( iUserKeyset, IMESSAGE_SETATTRIBUTE_S,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -