📄 cryptusr.c
字号:
{
memcpy( userInfoPtr->creatorID, userInfoPtr->userID,
KEYID_SIZE );
status = createSOKey( iUserKeyset, userInfoPtr,
password, passwordLength );
}
}
if( cryptStatusOK( status ) )
status = writeUserInfo( iUserKeyset, userInfoPtr,
userInfoPtr->iCryptContext );
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*status = createCAKey( iUserKeyset, userInfoPtr, password, passwordLength );*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
}
else
{
char userFileName[ 16 ];
/* Open an existing user keyset */
sPrintf( userFileName, "u%06x", userInfoPtr->fileRef );
status = openUserKeyset( &iUserKeyset, userFileName,
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 */
userInfoPtr->state = USER_STATE_USERINITED;
return( CRYPT_OK );
}
/****************************************************************************
* *
* General User Object Functions *
* *
****************************************************************************/
/* Handle a message sent to a user object */
static int userMessageFunction( const void *objectInfoPtr,
const MESSAGE_TYPE message,
void *messageDataPtr, const int messageValue )
{
USER_INFO *userInfoPtr = ( USER_INFO * ) objectInfoPtr;
/* Process destroy object messages */
if( message == MESSAGE_DESTROY )
{
/* Clean up any user-related crypto objects if necessary */
if( userInfoPtr->iCryptContext != CRYPT_ERROR )
krnlSendNotifier( userInfoPtr->iCryptContext,
IMESSAGE_DECREFCOUNT );
if( userInfoPtr->iKeyset != CRYPT_ERROR )
krnlSendNotifier( userInfoPtr->iKeyset, IMESSAGE_DECREFCOUNT );
/* Clean up the trust info and config options */
endTrustInfo( userInfoPtr->trustInfoPtr );
endOptions( userInfoPtr->configOptions );
return( CRYPT_OK );
}
/* Process attribute get/set/delete messages */
if( isAttributeMessage( message ) )
{
const CRYPT_USER cryptUser = userInfoPtr->objectHandle;
char userFileName[ 16 ];
void *data;
int length, status;
if( messageValue == CRYPT_USERINFO_PASSWORD )
{
RESOURCE_DATA *msgData = messageDataPtr;
return( setPassword( userInfoPtr, msgData->data,
msgData->length ) );
}
if( messageValue == CRYPT_USERINFO_CAKEY_CERTSIGN || \
messageValue == CRYPT_USERINFO_CAKEY_CRLSIGN || \
messageValue == CRYPT_USERINFO_CAKEY_OCSPSIGN )
{
const int objectHandle = *( int * ) messageDataPtr;
const int requiredKeyUsage = \
( messageValue == CRYPT_USERINFO_CAKEY_CERTSIGN ) ? \
CRYPT_KEYUSAGE_KEYCERTSIGN : \
( messageValue == CRYPT_USERINFO_CAKEY_CRLSIGN ) ? \
CRYPT_KEYUSAGE_CRLSIGN : \
( CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
CRYPT_KEYUSAGE_NONREPUDIATION );
int value;
/* Make sure that we've been given a signing key */
status = krnlSendMessage( objectHandle, IMESSAGE_CHECK,
NULL, MESSAGE_CHECK_PKC_SIGN );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
/* Make sure that the object has an initialised cert of the
correct type associated with it */
status = krnlSendMessage( objectHandle, IMESSAGE_GETATTRIBUTE,
&value, CRYPT_CERTINFO_IMMUTABLE );
if( cryptStatusError( status ) || !value )
return( CRYPT_ARGERROR_NUM1 );
status = krnlSendMessage( objectHandle, IMESSAGE_GETATTRIBUTE,
&value, CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) ||
( value != CRYPT_CERTTYPE_CERTIFICATE && \
value != CRYPT_CERTTYPE_CERTCHAIN ) )
return( CRYPT_ARGERROR_NUM1 );
/* Make sure that the key usage required for this action is
permitted. OCSP is a bit difficult since the key may or may
not have an OCSP extended usage (depending on whether the CA
bothers to set it or not, even if they do they may delegate
the functionality to a short-term generic signing key) and the
signing ability may be indicated by either a digital signature
flag or a nonrepudiation flag depending on whether the CA
considers an OCSP signature to be short or long-term, so we
just check for a generic signing ability */
status = krnlSendMessage( objectHandle, IMESSAGE_GETATTRIBUTE,
&value, CRYPT_CERTINFO_KEYUSAGE );
if( cryptStatusError( status ) || !( value & requiredKeyUsage ) )
return( CRYPT_ARGERROR_NUM1 );
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* Save this in the keyset at some point */
/* Handle get (gets public key) */
/* Handle delete (removes key) */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
return( status );
}
if( messageValue == CRYPT_IATTRUBUTE_CERTKEYSET )
{
int iCryptKeyset = *( ( int * ) messageDataPtr );
assert( message == MESSAGE_SETATTRIBUTE );
/* If it's a presence check, handle it specially */
if( iCryptKeyset == CRYPT_UNUSED )
return( enumTrustedCerts( userInfoPtr->trustInfoPtr,
CRYPT_UNUSED, CRYPT_UNUSED ) );
/* Send all trusted certs to the keyset */
return( enumTrustedCerts( userInfoPtr->trustInfoPtr,
CRYPT_UNUSED, iCryptKeyset ) );
}
if( messageValue == CRYPT_IATTRIBUTE_CTL )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
int *iCryptCtlPtr = ( int * ) messageDataPtr;
assert( message == MESSAGE_GETATTRIBUTE || \
message == MESSAGE_SETATTRIBUTE );
/* If we're setting trust info, add the certs via the trust
list */
if( message == MESSAGE_SETATTRIBUTE )
{
status = addTrustEntry( userInfoPtr->trustInfoPtr,
*iCryptCtlPtr, NULL, 0, FALSE );
if( cryptStatusOK( status ) )
userInfoPtr->trustInfoChanged = TRUE;
return( status );
}
/* Clear return value */
*iCryptCtlPtr = CRYPT_ERROR;
status = enumTrustedCerts( userInfoPtr->trustInfoPtr,
CRYPT_UNUSED, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( status );
/* Create a cert chain meta-object to hold the overall set of
certs */
setMessageCreateObjectInfo( &createInfo,
CRYPT_CERTTYPE_CERTCHAIN );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
status = enumTrustedCerts( userInfoPtr->trustInfoPtr,
createInfo.cryptHandle, CRYPT_UNUSED );
if( cryptStatusOK( status ) )
*iCryptCtlPtr = createInfo.cryptHandle;
else
krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
return( status );
}
if( messageValue == CRYPT_IATTRIBUTE_CERT_TRUSTED )
{
const CRYPT_CERTIFICATE cryptCert = \
*( ( CRYPT_CERTIFICATE * ) messageDataPtr );
assert( message == MESSAGE_SETATTRIBUTE );
/* Add the cert to the trust info */
status = addTrustEntry( userInfoPtr->trustInfoPtr, cryptCert,
NULL, 0, TRUE );
if( cryptStatusOK( status ) )
{
userInfoPtr->trustInfoChanged = TRUE;
setOption( userInfoPtr->configOptions,
CRYPT_OPTION_CONFIGCHANGED, TRUE );
}
return( status );
}
if( messageValue == CRYPT_IATTRIBUTE_CERT_UNTRUSTED )
{
const CRYPT_CERTIFICATE cryptCert = \
*( ( CRYPT_CERTIFICATE * ) messageDataPtr );
void *entryToDelete;
assert( message == MESSAGE_SETATTRIBUTE );
/* Find the entry to delete and remove it */
if( ( entryToDelete = findTrustEntry( userInfoPtr->trustInfoPtr,
cryptCert, FALSE ) ) == NULL )
return( CRYPT_ERROR_NOTFOUND );
deleteTrustEntry( userInfoPtr->trustInfoPtr, entryToDelete );
userInfoPtr->trustInfoChanged = TRUE;
setOption( userInfoPtr->configOptions,
CRYPT_OPTION_CONFIGCHANGED, TRUE );
return( CRYPT_OK );
}
if( messageValue == CRYPT_IATTRIBUTE_CERT_CHECKTRUST )
{
const CRYPT_CERTIFICATE cryptCert = \
*( ( CRYPT_CERTIFICATE * ) messageDataPtr );
int certType;
assert( message == MESSAGE_SETATTRIBUTE );
/* We can't perform this action as a MESSAGE_CHECK because these
are sent to the object being checked (the certificate in this
case) rather than the user object it's associated with, so we
have to do it as a pseudo-attribute-set action */
status = krnlSendMessage( cryptCert, IMESSAGE_GETATTRIBUTE,
&certType, CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) || \
( certType != CRYPT_CERTTYPE_CERTIFICATE && \
certType != CRYPT_CERTTYPE_CERTCHAIN ) )
/* A non-cert can never be implicitly trusted */
return( FALSE );
/* Check whether the cert is present in the trusted certs
collection */
return( ( findTrustEntry( userInfoPtr->trustInfoPtr, cryptCert,
FALSE ) != NULL ) ? \
CRYPT_OK : CRYPT_ERROR_INVALID );
}
if( messageValue == CRYPT_IATTRIBUTE_CERT_TRUSTEDISSUER )
{
const CRYPT_CERTIFICATE cryptCert = \
*( ( CRYPT_CERTIFICATE * ) messageDataPtr );
void *trustedIssuerInfo;
assert( message == MESSAGE_SETATTRIBUTE );
/* This is a highly nonstandard use of integer parameters that
passes in the user cert as its parameter and returns the
issuer cert in the same parameter, overwriting the user
cert value. This is the sole message that does this,
unfortunately there's no clean way to handle this without
implementing a new message type for this purpose. Since the
kernel is stateless it can only look at the parameter value
but not detect that it's changed during the call, so it works
for now, but it would be nicer to find some way to fix this */
trustedIssuerInfo = findTrustEntry( userInfoPtr->trustInfoPtr,
cryptCert, TRUE );
if( trustedIssuerInfo != NULL )
{
const int trustedCert = getTrustedCert( trustedIssuerInfo );
if( cryptStatusError( trustedCert ) )
return( trustedCert );
assert( trustedCert != cryptCert );
*( ( int * ) messageDataPtr ) = trustedCert;
return( CRYPT_OK );
}
return( CRYPT_ERROR_NOTFOUND );
}
if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
{
/* If it's an initialisation message, there's nothing to do (we
get these when creating the default user object, which doesn't
require an explicit logon to move it into the high state) */
assert( userInfoPtr->objectHandle == DEFAULTUSER_OBJECT_HANDLE );
return( CRYPT_OK );
}
/* Anything else has to be a config option */
assert( messageValue > CRYPT_OPTION_FIRST && \
messageValue < CRYPT_OPTION_LAST );
/* Delete attribute */
if( message == MESSAGE_DELETEATTRIBUTE )
/* Only string attributes can be deleted, so we can safely pass
all calls through to the set-string function */
return( setOptionString( userInfoPtr->configOptions,
messageValue, NULL, 0 ) );
/* Get/set string attributes */
if( message == MESSAGE_GETATTRIBUTE_S )
{
RESOURCE_DATA *msgData = messageDataPtr;
const char *retVal = getOptionString( userInfoPtr->configOptions,
messageValue );
if( retVal == NULL )
{
/* No value set, clear the return value in case the caller
isn't checking the return code */
if( msgData->data != NULL )
*( ( char * ) msgData->data ) = '\0';
msgData->length = 0;
return( CRYPT_ERROR_NOTFOUND );
}
return( attributeCopy( msgData, retVal, strlen( retVal ) ) );
}
if( message == MESSAGE_SETATTRIBUTE_S )
{
const RESOURCE_DATA *msgData = messageDataPtr;
return( setOptionString( userInfoPtr->configOptions,
messageValue, msgData->data,
msgData->length ) );
}
/* Get/set numeric attributes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -