diff -r 000000000000 -r 164170e6151a wim/WimClient/src/WimKeyDetails.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wim/WimClient/src/WimKeyDetails.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,648 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Gets keydetails from WIM -card +* +*/ + + + +#include "WimCertMgmt.h" +#include "WimKeyDetails.h" +#include "WimTrace.h" + + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::CWimKeyDetails() +// Default constructor +// ----------------------------------------------------------------------------- +CWimKeyDetails::CWimKeyDetails( MCTToken& aToken ): +CActive( EPriorityStandard ), iToken( aToken ), iPckg( iKeyNumber ) + { + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::NewL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +EXPORT_C CWimKeyDetails* CWimKeyDetails::NewL( MCTToken& aToken ) + { + _WIMTRACE ( _L( "CWimKeyDetails::NewL()" ) ); + CWimKeyDetails* self = new( ELeave ) CWimKeyDetails( aToken ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); //self + return self; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::ConstructL() +// Second phase +// ----------------------------------------------------------------------------- +void CWimKeyDetails::ConstructL() + { + _WIMTRACE ( _L( "CWimKeyDetails::ConstructL()" ) ); + CActiveScheduler::Add( this ); + iConnectionHandle = RWimCertMgmt::ClientSessionL(); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::~CWimKeyDetails() +// Allocated memory is released. +// ----------------------------------------------------------------------------- +EXPORT_C CWimKeyDetails::~CWimKeyDetails() + { + _WIMTRACE ( _L( "CWimKeyDetails::~CWimKeyDetails()" ) ); + Cancel(); + iConnectionHandle->Close(); + delete iConnectionHandle; + iKeyReferences.Close(); + DeallocMemoryFromSign(); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::GetKeyList() +// Starts to list all keys found from WIM -card +// ----------------------------------------------------------------------------- +EXPORT_C void CWimKeyDetails::GetKeyList( RPointerArray& aKeys, + CArrayFixFlat& aKeyNumbers, + TRequestStatus& aStatus ) + { + _WIMTRACE ( _L( "CWimKeyDetails::GetKeyList()" ) ); + iClientStatus = &aStatus; + aStatus = KRequestPending; + iKeys = &aKeys; + iKeyNumberArray = &aKeyNumbers; + iPhase = EGetKeyList; + SignalOwnStatusAndComplete(); + iFetchedKeyInfos = 0; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::CancelList() +// Cancels listing operation. +// ----------------------------------------------------------------------------- +EXPORT_C void CWimKeyDetails::CancelList() + { + _WIMTRACE ( _L( "CWimKeyDetails::CancelList()" ) ); + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::Sign() +// Sign some data. Authentication is handled by server. +// ----------------------------------------------------------------------------- + +EXPORT_C void CWimKeyDetails::Sign( const TDesC8& aData, + TDesC8& aKeyId, + HBufC8*& aSignature, + TRequestStatus& aStatus ) + { + _WIMTRACE ( _L( "CWimKeyDetails::Sign()" ) ); + + aStatus = KRequestPending; + iClientStatus = &aStatus; + + if ( aKeyId.Length() ) + { + //Check that the data is not too long + if ( aData.Length() > KMaxRSADigestSize ) + { + User::RequestComplete( iClientStatus, KErrOverflow ); + } + else + { + iSignature = aSignature; + TRAPD( err, AllocMemoryForSignL( aData, aKeyId ) ); + if ( err ) + { + User::RequestComplete( iClientStatus, err ); + } + else + { + iPhase = ESign; + SignalOwnStatusAndComplete(); + } + } + } + else + { + User::RequestComplete( iClientStatus, KErrArgument ); + } + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::CancelSign() +// Cancels outgoing signing operation +// ----------------------------------------------------------------------------- +EXPORT_C void CWimKeyDetails::CancelSign() + { + _WIMTRACE ( _L( "CWimKeyDetails::CancelSign()" ) ); + Cancel(); + } + + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::ExportPublicKeyL() +// Export public key +// ----------------------------------------------------------------------------- +EXPORT_C void CWimKeyDetails::ExportPublicKeyL( TDesC8& aKeyId, + HBufC8*& aPublicKey, + TRequestStatus& aStatus ) + { + _WIMTRACE ( _L( "CWimKeyDetails::ExportPublicKeyL()" ) ); + + iClientStatus = &aStatus; + aStatus = KRequestPending; + + if ( aKeyId.Length() ) + { + //KeyId from Plugin + iKeyId = aKeyId.AllocL(); + iKeyIdPtr = new( ELeave ) TPtr8( iKeyId->Des() ); + iExportPublicKey.iKeyId.Copy( iKeyIdPtr->Ptr(), iKeyIdPtr->Length() ); + + //Exported key from Server + iPublicKey = aPublicKey; + iPublicKeyPtr = new( ELeave ) TPtr8( iPublicKey->Des() ); + iExportPublicKey.iPublicKey = iPublicKeyPtr; + + //Request to Server + iConnectionHandle->ExportPublicKeyL( iExportPublicKey, + iStatus ); + iPhase = EExportPublicKey; + SetActive(); + } + else + { + User::RequestComplete( iClientStatus, KErrArgument ); + } + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::CancelExport() +// Cancel public key export +// ----------------------------------------------------------------------------- +EXPORT_C void CWimKeyDetails::CancelExport() + { + _WIMTRACE ( _L( "CWimKeyDetails::CancelExport()" ) ); + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::AllocMemoryForSignL() +// Allocates memory for signing operation +// ----------------------------------------------------------------------------- +void CWimKeyDetails::AllocMemoryForSignL( const TDesC8& aData, + const TDesC8& aKeyId ) + { + _WIMTRACE ( _L( "CWimKeyDetails::AllocMemoryForSignL()" ) ); + + iSigningData = aData.AllocL(); //Data to be signed + iSigningDataPtr = new( ELeave ) TPtr8( iSigningData->Des() ); + + iKeyId = aKeyId.AllocL(); //KeyId used to match correct signing key + iKeyIdPtr = new( ELeave ) TPtr8( iKeyId->Des() ); + + //Alloc pointer for signature buffer, which is owned by keystore + iSignaturePtr = new( ELeave ) TPtr8( iSignature->Des() ); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::DeallocMemoryFromSign() +// Deallocates memory after signing operation +// ----------------------------------------------------------------------------- +void CWimKeyDetails::DeallocMemoryFromSign() + { + _WIMTRACE ( _L( "CWimKeyDetails::DeallocMemoryFromSign()" ) ); + + delete iSigningData; + delete iSigningDataPtr; + delete iSignaturePtr; + delete iKeyId; + delete iKeyIdPtr; + iSigningData = NULL; + iSigningDataPtr = NULL; + iSignaturePtr = NULL; + iKeyId = NULL; + iKeyIdPtr = NULL; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::SignalOwnStatusAndComplete() +// Sets own iStatus to KRequestPending, and signals it +// with User::RequestComplete() -request. This gives chance +// active scheduler to run other active objects. After a quick +// visit in active scheduler, signal returns to RunL() and starts next +// phase of operation. +// @return void +// ----------------------------------------------------------------------------- +void CWimKeyDetails::SignalOwnStatusAndComplete() + { + _WIMTRACE ( _L( "CWimKeyDetails::SignalOwnStatusAndComplete()" ) ); + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::RunL() +// EGetKeyList: Get the number of keys key and references to each key. +// EConvertParams: Gets key references from string and puts them to RArray +// EGetKeyInfo: Fetches a single keyinfo. According to received values, a new +// CCTKeyInfo -object is created and inserted to an Array. Received +// parameters requires a little bit conversion. +// ESign: Sends signing request with data to be signed to server. +// ESignCompleted: Sign is done +// EExportPublicKey: Sends Export public key request to server. Receives +// exported public key. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::RunL() + { + //Check for error + if ( iStatus.Int() != KErrNone ) + { + if ( iPhase == EConvertParams ) + { + DeallocMemoryFromKeyList(); + } + else if ( iPhase == ESignCompleted ) + { + iConnectionHandle->DeallocKeySignPckgBuf(); + DeallocMemoryFromSign(); + } + else if ( iPhase == EExportPublicKey ) + { + iConnectionHandle->DeallocExportPublicKeyPckgBuf(); + DeallocMemoryFromKeyInfo(); + delete iPublicKeyPtr; + iPublicKey = NULL; // no delete, ownership moved to caller + iPublicKeyPtr = NULL; + } + User::RequestComplete( iClientStatus, iStatus.Int() ); + } + else + { + switch ( iPhase ) + { + case EGetKeyList: + { + AllocMemoryForKeyListL(); + iConnectionHandle->KeyList( *iKeyListPtr, + iPckg, + iStatus ); + iPhase = EConvertParams; + SetActive(); + _WIMTRACE ( _L( "CWimKeyDetails::RunL(),\ + case:EGetKeyList" ) ); + break; + } + case EConvertParams: //Convert previously fetched parameters + { //and put them to an RArray. + ConvertKeyListL(); + DeallocMemoryFromKeyList(); //We don't need keylist anymore + iPhase = EGetKeyInfo; + SignalOwnStatusAndComplete(); + _WIMTRACE ( _L( "CWimKeyDetails::RunL(),EConvertParams" ) ); + break; + } + case EGetKeyInfo: //Now we can fetch details for every key. + { + //Are all keyinfo -objects fetched? + if ( iFetchedKeyInfos < iKeyReferences.Count() ) + { //No, get next keyinfo.. + TKeyInfo keyInfo; + AllocMemoryForKeyInfoL( keyInfo ); + TInt ret = iConnectionHandle->GetKeyInfo( + iKeyReferences.operator[]( iFetchedKeyInfos ), + keyInfo ); + + if ( ret != KErrNone )//Something went wrong + { + DeallocMemoryFromKeyInfo(); + User::RequestComplete( iClientStatus, ret ); + } + else + { + TKeyUsagePKCS15 keyUsage; + keyUsage = ConvertKeyUsage( keyInfo.iUsage ); + + //Convert key type to support only RSA signing or + //invalidAlgorithm + if ( keyInfo.iType != CKeyInfoBase::ERSA ) + { + keyInfo.iType = + ( TUint8 )CKeyInfoBase::EInvalidAlgorithm; + } + //Create new KeyInfo -object and put it into array. + CCTKeyInfo* cctKeyInfo = NULL; + + // Create a 16 bit heap-based buffer descriptor and a + // pointer to it + HBufC16* label16 = HBufC16::NewLC( KLabelLen ); + // 16 bit modifiable pointer descriptor to object + // above in order to manipulate data + TPtr16 labelPtr16 = label16->Des(); + + labelPtr16.Copy( keyInfo.iLabel.Left( + keyInfo.iLabel.Length() ) ); + + TTime nullTime( _L( "00000000:" ) ); +#ifdef __SECURITY_PLATSEC_ARCH__ + TSecurityPolicy usePolicy; + TSecurityPolicy managementPolicy; + + cctKeyInfo = CCTKeyInfo::NewL( + keyInfo.iKeyId, //Key ID + keyUsage, //Key usage + keyInfo.iLength, //Key length + NULL, //protector + label16, //Key label + iToken, //token + keyInfo.iKeyNumber, //Key number + usePolicy, // + managementPolicy, // + ( CKeyInfoBase::EKeyAlgorithm )keyInfo.iType, + CKeyInfoBase::EInvalidAccess, //bitf. access + ETrue, //Always Native + nullTime, //NULL time + nullTime ); //NULL time +#else + RArray array; + + cctKeyInfo = CCTKeyInfo::NewL( + keyInfo.iKeyId, //Key ID + keyUsage, //Key usage + keyInfo.iLength, //Key length + NULL, //protector + label16, //Key label + iToken, //token + keyInfo.iKeyNumber, //Key number + KWimServerUid, //WimServer owns all keys + array, //Null array + ( CKeyInfoBase::EKeyAlgorithm )keyInfo.iType, + CKeyInfoBase::EInvalidAccess, //bitf. access + ETrue, //Always Native + nullTime, //NULL time + nullTime ); //NULL time +#endif + + _WIMTRACE ( _L( "CWimKeyDetails::RunL(),EGetKeyInfo | CCTKeyInfo is initialized " ) ); + + ret = iKeys->Append( cctKeyInfo ); + + if ( ret != KErrNone ) + { + CleanupStack::Pop( label16 ); + cctKeyInfo->Release(); + User::Leave( ret ); + } + + //Append corresponding pinnumber to array. + iKeyNumberArray->AppendL( keyInfo.iPinNumber ); + + //We must not destroy label16, because CCTKeyInfo + //-object takes ownership. + CleanupStack::Pop( label16 ); + //Increase counter, we have successfully fetched + //infos for single key and corresponding CCTKeyInfo + //is created + iFetchedKeyInfos++; + //Cleanup label and keyid modifiers. + DeallocMemoryFromKeyInfo(); + iPhase = EGetKeyInfo; + SignalOwnStatusAndComplete(); + _WIMTRACE ( _L( "CWimKeyDetails::RunL(),\ + case:EGetKeyInfo" ) ); + } + } + else//Yep, All done. + { + iFetchedKeyInfos = 0; + //Don't need key references anymore + iKeyReferences.Close(); + User::RequestComplete( iClientStatus, iStatus.Int() ); + } + break; + } + case ESign: + { + iPhase = ESignCompleted; + iKeySignParameters.iSigningData = iSigningDataPtr; + iKeySignParameters.iSignature = iSignaturePtr; + iKeySignParameters.iKeyId.Copy( iKeyIdPtr->Ptr(), iKeyIdPtr->Length() ); + iConnectionHandle->SignL( iKeySignParameters, iStatus ); + SetActive(); + break; + } + case ESignCompleted: + { + //signature data is copied by now to plugins memory. + iConnectionHandle->DeallocKeySignPckgBuf(); + DeallocMemoryFromSign(); + User::RequestComplete( iClientStatus, iStatus.Int() ); + break; + } + case EExportPublicKey: + { + iConnectionHandle->DeallocExportPublicKeyPckgBuf(); + DeallocMemoryFromKeyInfo(); + delete iPublicKeyPtr; + iPublicKeyPtr = NULL; + User::RequestComplete( iClientStatus, iStatus.Int() ); + break; + } + default: + { + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::ConvertKeyUsage() +// Converts keyUsage to new form. All keyUsages loaded from WIM are treated +// as private keys. +// ----------------------------------------------------------------------------- +TKeyUsagePKCS15 CWimKeyDetails::ConvertKeyUsage( TUint16 aKeyUsage ) + { + _WIMTRACE ( _L( "CWimKeyDetails::ConvertKeyUsage()" ) ); + + TKeyUsagePKCS15 usage = EPKCS15UsageNone; + switch ( aKeyUsage ) + { + case KPkcs15KeyUsageFlagsDecrypt: + { + usage = EPKCS15UsageDecrypt; + break; + } + case KPkcs15KeyUsageFlagsSign: + { + usage = EPKCS15UsageSign; + break; + } + case KPkcs15KeyUsageFlagsSignRecover: + { + usage = EPKCS15UsageSignRecover; + break; + } + case KPkcs15KeyUsageFlagsUnwrap: + { + usage = EPKCS15UsageUnwrap; + break; + } + case KPkcs15KeyUsageFlagsDerive: + { + usage = EPKCS15UsageDerive; + break; + } + case KPkcs15KeyUsageFlagsNonRepudiation: + { + usage = EPKCS15UsageNonRepudiation; + break; + } + default: + { + break; + } + } + return usage; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::AllocMemoryForKeyListL() +// Allocates memory for Array which is filled by server. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::AllocMemoryForKeyListL() + { + _WIMTRACE ( _L( "CWimKeyDetails::AllocMemoryForKeyListL()" ) ); + + iKeyList = HBufC8::NewL( KLabelLen ); + iKeyListPtr = new( ELeave ) TPtr8( iKeyList->Des() ); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::DeallocMemoryFromKeyList() +// Deallocates memory from Array which was filled by server. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::DeallocMemoryFromKeyList() + { + _WIMTRACE ( _L( "CWimKeyDetails::DeallocMemoryFromKeyList()" ) ); + + delete iKeyList; + delete iKeyListPtr; + iKeyList = NULL; + iKeyListPtr = NULL; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::ConvertKeyListL() +// Converts keylist parameters. Extracts data out from keylist & keynumber. +// Extracted data is inserted to RArray. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::ConvertKeyListL() + { + _WIMTRACE ( _L( "CWimKeyDetails::ConvertKeyListL()" ) ); + + TInt32 output = 0; + + TLex8 lex8( iKeyListPtr->Ptr() ); + for ( TInt i = 0; i < iKeyNumber; i++ ) //Put keyreferences to array. + { + lex8.SkipSpaceAndMark(); + lex8.Val( output ); + User::LeaveIfError( iKeyReferences.Append( output ) ); + } + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::AllocMemoryForKeyInfoL() +// Allocates memory for label and keyid. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::AllocMemoryForKeyInfoL( TKeyInfo& aKeyInfo ) + { + _WIMTRACE ( _L( "CWimKeyDetails::AllocMemoryForKeyInfoL()" ) ); + + iLabel = HBufC8::NewL( KLabelLen ); //Label + iLabelPtr = new( ELeave ) TPtr8( iLabel->Des() ); + aKeyInfo.iLabel.Copy( iLabelPtr->Ptr(), iLabelPtr->Length() ); + + iKeyId = HBufC8::NewL( KKeyIdLen ); //KeyId + iKeyIdPtr = new( ELeave ) TPtr8( iKeyId->Des() ); + aKeyInfo.iKeyId.Copy( iKeyIdPtr->Ptr(), iKeyIdPtr->Length() ); + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::DeallocMemoryFromKeyInfo() +// Deallocates memory from label and keyid. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::DeallocMemoryFromKeyInfo() + { + _WIMTRACE ( _L( "CWimKeyDetails::DeallocMemoryFromKeyInfo()" ) ); + + delete iLabel; + delete iLabelPtr; + delete iKeyId; + delete iKeyIdPtr; + iLabel = NULL; + iLabelPtr = NULL; + iKeyId = NULL; + iKeyIdPtr = NULL; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::RunError() +// The active scheduler calls this function if this active object's RunL() +// function leaves. This gives this active object the opportunity to perform +// any necessary cleanup. +// After array's cleanup, complete request with received error code. +// ----------------------------------------------------------------------------- +TInt CWimKeyDetails::RunError( TInt aError ) + { + _WIMTRACE ( _L( "CWimKeyDetails::RunError()" ) ); + DeallocMemoryFromKeyInfo(); + DeallocMemoryFromKeyList(); + User::RequestComplete( iClientStatus, aError ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CWimKeyDetails::DoCancel() +// Deallocates member variables and completes client status with +// KErrCancel error code. +// ----------------------------------------------------------------------------- +void CWimKeyDetails::DoCancel() + { + _WIMTRACE ( _L( "CWimKeyDetails::DoCancel()" ) ); + + if ( iConnectionHandle && iPhase == ESignCompleted ) + { + iConnectionHandle->DeallocKeySignPckgBuf(); + } + else if ( iConnectionHandle && iPhase == EExportPublicKey ) + { + delete iPublicKeyPtr; + iPublicKey = NULL; + iPublicKeyPtr = NULL; + iConnectionHandle->DeallocExportPublicKeyPckgBuf(); + } + DeallocMemoryFromKeyList(); + DeallocMemoryFromKeyInfo(); + DeallocMemoryFromSign(); + iKeyReferences.Close(); + User::RequestComplete( iClientStatus, KErrCancel ); + } + +// End of File