📄 user.c
字号:
&msgData, CRYPT_IATTRIBUTE_USERID );
}
return( status );
}
/* Read a user's info from a user keyset and verify it using the creating
SO's key */
#if 0 /*!!!!!!!!!!!!!!! Needs a serious overhaul !!!!!!!!!!!!!!!!!!!!!*/
/*!!!!!!!!!!!!! Should also do recursive walk !!!!!!!!!!!!!!!!!!*/
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int getCheckUserInfo( INOUT USER_FILE_INFO *userFileInfoPtr,
IN_INT_SHORT_Z const int fileRef )
{
CRYPT_ALGO_TYPE hashAlgo;
CRYPT_CONTEXT iHashContext;
CRYPT_KEYSET iUserKeyset;
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_KEYMGMT_INFO getkeyInfo;
STREAM stream;
DYNBUF userDataDB;
void *hashDataPtr, *signaturePtr;
int soFileRef, hashDataLength, signatureLength, status;
assert( isWritePtr( userFileInfoPtr, sizeof( USER_FILE_INFO ) ) );
REQUIRES( fileRef >= 0 && fileRef < MAX_INTLENGTH_SHORT );
/* Clear return values */
memset( userFileInfoPtr, 0, sizeof( USER_FILE_INFO ) );
/* Open the user keyset and read the user data from it */
status = openUserKeyset( &iUserKeyset, fileRef, CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
return( status );
status = dynCreate( &userDataDB, iUserKeyset,
CRYPT_IATTRIBUTE_USERINFO );
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
return( status );
/* Burrow into the user info to get the information we need. We do it
this way rather than using envelopes because we don't need the full
generality of the enveloping process (we know exactly what data to
expect) and to avoid the overhead of de-enveloping data every time a
user logs in */
sMemConnect( &stream, dynData( userDataDB ), dynLength( userDataDB ) );
readSequence( &stream, NULL ); /* Outer wrapper */
readUniversal( &stream ); /* ContentType OID */
readConstructed( &stream, NULL, 0 ); /* Content */
readSequence( &stream, NULL );
readUniversal( &stream ); /* Version */
readSet( &stream, NULL ); /* DigestAlgorithms */
readAlgoID( &stream, &hashAlgo );
readSequence( &stream, NULL ); /* EncapContentInfo */
readUniversal( &stream ); /* ContentType OID */
readConstructed( &stream, NULL, 0 ); /* Content type wrapper */
status = readGenericHole( &stream, &hashDataLength, 16, DEFAULT_TAG );
if( cryptStatusError( status ) )
{
sMemDisconnect( &stream );
dynDestroy( &userDataDB );
return( status );
}
hashDataPtr = sMemBufPtr( &stream );
/* Read the user info */
status = readUserData( userFileInfoPtr, hashDataPtr, hashDataLength );
if( cryptStatusError( status ) )
{
sMemDisconnect( &stream );
dynDestroy( &userDataDB );
return( status );
}
/* Hash the signed data and verify the signature using the SO key */
setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_SHA );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT, &createInfo,
OBJECT_TYPE_CONTEXT );
if( cryptStatusError( status ) )
{
dynDestroy( &userDataDB );
sMemDisconnect( &stream );
return( status );
}
iHashContext = createInfo.cryptHandle;
krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, hashDataPtr,
hashDataLength );
status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 );
dynDestroy( &userDataDB );
if( cryptStatusError( status ) )
{
sMemDisconnect( &stream );
return( status );
}
/* Read the signature */
status = readSet( &stream, &signatureLength );
signaturePtr = sMemBufPtr( &stream );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Open the SO keyset and read the SO public key from it */
status = soFileRef = \
findUserIndexEntry( USERID_USERID, userFileInfoPtr->creatorID,
KEYID_SIZE );
if( cryptStatusOK( status ) )
status = openUserKeyset( &iUserKeyset, soFileRef,
CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
return( status );
}
setMessageKeymgmtInfo( &getkeyInfo, CRYPT_IKEYID_KEYID,
userFileInfoPtr->creatorID, KEYID_SIZE, NULL, 0,
KEYMGMT_FLAG_NONE );
status = krnlSendMessage( iUserKeyset, IMESSAGE_KEY_GETKEY,
&getkeyInfo, KEYMGMT_ITEM_PUBLICKEY );
krnlSendNotifier( iUserKeyset, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Verify the signature using the SO key */
status = iCryptCheckSignatureEx( signaturePtr, signatureLength,
CRYPT_FORMAT_CRYPTLIB,
getkeyInfo.cryptHandle, iHashContext,
NULL );
krnlSendNotifier( iHashContext, IMESSAGE_DECREFCOUNT );
krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
return( status );
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* MAC (???) using password - needs PKCS #15 changes */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
return( status );
}
#endif /*!!!!!!!!!!!!!!! Needs a serious overhaul !!!!!!!!!!!!!!!!!!!!!*/
/****************************************************************************
* *
* SO Management Functions *
* *
****************************************************************************/
/* Return the primary SO user info. This is used as a template to create
the primary SO user after a zeroise */
const USER_FILE_INFO *getPrimarySoUserInfo( void )
{
return( &primarySOInfo );
}
/* Sign the user info and write it to the user keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int signUserData( IN_HANDLE const CRYPT_KEYSET iUserKeyset,
const USER_INFO *userInfoPtr,
IN_HANDLE const CRYPT_CONTEXT iSignContext )
{
BYTE userInfoBuffer[ USERDATA_BUFFERSIZE + 8 ];
int userInfoLength, status;
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
REQUIRES( isHandleRangeValid( iUserKeyset ) );
REQUIRES( isHandleRangeValid( iSignContext ) );
/* Sign the data via an envelope. This is kind of heavyweight, but it's
OK because we rarely create new users and it saves having to hand-
assemble the data like the PKCS #15 code does */
status = envelopeSign( userInfoBuffer, userInfoLength,
userInfoBuffer, USERDATA_BUFFERSIZE,
&userInfoLength, CRYPT_CONTENT_DATA,
iSignContext, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( status );
return( CRYPT_ERROR_SIGNATURE );
}
CHECK_RETVAL \
static int sigCheckUserData( void )
{
return( CRYPT_ERROR_SIGNATURE );
}
/* Create an SO private key and write it to the user keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
static int createSOKey( IN_HANDLE const CRYPT_KEYSET iUserKeyset,
INOUT USER_INFO *userInfoPtr,
IN_BUFFER( passwordLength ) const char *password,
IN_LENGTH_SHORT const int passwordLength )
{
const USER_FILE_INFO *userFileInfo = &userInfoPtr->userFileInfo;
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_DATA msgData;
const int actionPerms = MK_ACTION_PERM( MESSAGE_CTX_SIGN,
ACTION_PERM_NONE_EXTERNAL ) | \
MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK,
ACTION_PERM_NONE_EXTERNAL );
int status;
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
assert( isReadPtr( password, passwordLength ) );
REQUIRES( isHandleRangeValid( iUserKeyset ) );
REQUIRES( passwordLength > 0 && passwordLength < MAX_INTLENGTH_SHORT );
/* Create the SO private key, making it internal and signature-only */
setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_RSA );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CONTEXT );
if( cryptStatusError( status ) )
return( status );
setMessageData( &msgData, ( void * ) userFileInfo->userName,
min( userFileInfo->userNameLength, CRYPT_MAX_TEXTSIZE ) );
krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_LABEL );
status = krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_CTX_GENKEY );
if( cryptStatusOK( status ) )
status = krnlSendMessage( createInfo.cryptHandle,
IMESSAGE_SETATTRIBUTE,
( int * ) &actionPerms,
CRYPT_IATTRIBUTE_ACTIONPERMS );
if( cryptStatusError( status ) )
{
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Add the SO private key to the keyset */
status = addKey( iUserKeyset, createInfo.cryptHandle,
userFileInfo->userID, KEYID_SIZE, password,
passwordLength, TRUE );
if( cryptStatusError( status ) )
{
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
userInfoPtr->iCryptContext = createInfo.cryptHandle;
return( CRYPT_OK );
}
#if 0 /* Currently unused, for future use for CA users */
/* Create a CA secret key and write it to the user keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
static int createCAKey( IN_HANDLE const CRYPT_KEYSET iUserKeyset,
INOUT USER_INFO *userInfoPtr,
IN_BUFFER( passwordLength ) const char *password,
IN_LENGTH_SHORT const int passwordLength )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
MESSAGE_DATA msgData;
const int actionPerms = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT,
ACTION_PERM_NONE_EXTERNAL ) | \
MK_ACTION_PERM( MESSAGE_CTX_DECRYPT,
ACTION_PERM_NONE_EXTERNAL );
int status;
assert( isReadPtr( userInfoPtr, sizeof( USER_INFO ) ) );
assert( isReadPtr( password, passwordLength ) );
REQUIRES( isHandleRangeValid( iUserKeyset ) );
REQUIRES( passwordLength > 0 && passwordLength < MAX_INTLENGTH_SHORT );
/* Create the CA secret key, making it internal-only */
setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_3DES );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CONTEXT );
if( cryptStatusError( status ) )
return( status );
setMessageData( &msgData, userInfoPtr->userID, KEYID_SIZE );
krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_LABEL );
status = krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_CTX_GENKEY );
if( cryptStatusOK( status ) )
status = krnlSendMessage( createInfo.cryptHandle,
IMESSAGE_SETATTRIBUTE,
( int * ) &actionPerms,
CRYPT_IATTRIBUTE_ACTIONPERMS );
if( cryptStatusError( status ) )
{
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Add the CA secret key to the keyset */
status = addKey( iUserKeyset, createInfo.cryptHandle,
userInfoPtr->userID, KEYID_SIZE, password,
passwordLength, FALSE );
if( cryptStatusError( status ) )
{
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
return( CRYPT_OK );
}
#endif /* 0 */
/* Create a primary SO user. This can only occur when we're in the zeroised
state */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int createPrimarySoUser( INOUT USER_INFO *userInfoPtr,
IN_BUFFER( passwordLength ) const char *password,
IN_LENGTH_SHORT const int passwordLength )
{
CRYPT_KEYSET iIndexKeyset, iUserKeyset;
USER_FILE_INFO userIndex;
BYTE userData[ USERDATA_BUFFERSIZE + 8 ];
int userDataLength = DUMMY_INIT, status;
assert( isWritePtr( userInfoPtr, sizeof( USER_INFO ) ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -