diff -r 000000000000 -r bde4ae8d615e os/security/cryptomgmtlibs/cryptotokenfw/source/ctframework/SecurityDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/security/cryptomgmtlibs/cryptotokenfw/source/ctframework/SecurityDialog.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,618 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#include "CRefSecurityDialog.h" + +// ---------------------------------------------------------------------------- +// SecurityDialogFactory +// + +EXPORT_C MSecurityDialog* SecurityDialogFactory::CreateL() + { + return CRefSecurityDialog::NewL(); + } + + + +// ---------------------------------------------------------------------------- +// CRefSecurityDialog +// + + + +CRefSecurityDialog::~CRefSecurityDialog() + { + delete iRequester; + } + +void CRefSecurityDialog::Release() + { + delete this; + } + + +CRefSecurityDialog* CRefSecurityDialog::NewL() + { + CRefSecurityDialog* self = new (ELeave) CRefSecurityDialog(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + + +void CRefSecurityDialog::ConstructL() + { + iRequester = CDialogRequester::NewL( *this ); + } + + + +void CRefSecurityDialog::EnterPIN( const TPINParams& aPINParams, TBool aRetry, + TPINValue& aPINValue, TRequestStatus& aStatus ) + { + iClientPINValuePtr = &aPINValue; + DoBasicPINOperation( EEnterPIN, aPINParams, aRetry, iPINValueBuf, aStatus ); + } + + + +void CRefSecurityDialog::EnablePIN( const TPINParams& aPINParams, TBool aRetry, + TPINValue& aPINValue, TRequestStatus& aStatus ) + { + iClientPINValuePtr = &aPINValue; + DoBasicPINOperation( EEnablePIN, aPINParams, aRetry, iPINValueBuf, aStatus ); + } + + + +void CRefSecurityDialog::DisablePIN( const TPINParams& aPINParams, TBool aRetry, + TPINValue& aPINValue, TRequestStatus& aStatus ) + { + iClientPINValuePtr = &aPINValue; + DoBasicPINOperation( EDisablePIN, aPINParams, aRetry, iPINValueBuf, aStatus ); + } + + + +void CRefSecurityDialog::ChangePIN( const TPINParams& aPINParams, TBool aRetry, + TPINValue& aOldPINValue, TPINValue& aNewPINValue, + TRequestStatus& aStatus ) + { + iClientPINValuePtr = &aOldPINValue; + iClientSecondPINValuePtr = &aNewPINValue; + DoBasicPINOperation( EChangePIN, aPINParams, aRetry, iTwoPINOutputBuf, aStatus ); + } + + + +void CRefSecurityDialog::UnblockPIN( const TPINParams& aBlockedPINParams, + const TPINParams& aUnblockingPINParams, TBool aRetry, + TPINValue& aUnblockingPINValue, TPINValue& aNewPINValue, + TRequestStatus& aStatus ) + { + iCurrentOperation = EUnblockPIN; + InitClientStatus( aStatus ); + + TUnblockPINInput unblockPINInput; + unblockPINInput.iOperation = EUnblockPIN; + if ( aRetry ) + { + unblockPINInput.iOperation |= EPINValueIncorrect; + } + unblockPINInput.iPIN = aBlockedPINParams; + unblockPINInput.iUnblockPIN = aUnblockingPINParams; + TUnblockPINInputBuf unblockPINInputBuf( unblockPINInput ); + iUnblockPINInputBuf.Copy( unblockPINInputBuf ); + iClientPINValuePtr = &aUnblockingPINValue; + iClientSecondPINValuePtr = &aNewPINValue; + + iRequester->RequestDialog( iUnblockPINInputBuf, iTwoPINOutputBuf ); + } + +void CRefSecurityDialog::UnblockPINInClear( const TPINParams& aBlockedPINParams, + const TPINParams& aUnblockingPINParams, TBool aRetry, + TUnblockPINValue& aUnblockingPINValue, TPINValue& aNewPINValue, + TRequestStatus& aStatus ) + { + iCurrentOperation = EUnblockPINInClear; + InitClientStatus( aStatus ); + + TUnblockPINInput unblockPINInput; + unblockPINInput.iOperation = EUnblockPINInClear; + if ( aRetry ) + { + unblockPINInput.iOperation |= EPINValueIncorrect; + } + unblockPINInput.iPIN = aBlockedPINParams; + unblockPINInput.iUnblockPIN = aUnblockingPINParams; + TUnblockPINInputBuf unblockPINInputBuf( unblockPINInput ); + + iClientUnblockPINValuePtr = &aUnblockingPINValue; + iClientSecondPINValuePtr = &aNewPINValue; + iUnblockPINInputBuf.Copy( unblockPINInputBuf ); + iRequester->RequestDialog( iUnblockPINInputBuf, iUnblockPINInClearOutputBuf ); + } + +void CRefSecurityDialog::Cancel() + { + iRequester->Cancel(); + if (iClientStatus) + { + User::RequestComplete(iClientStatus, KErrCancel); + } + } + +void CRefSecurityDialog::PINBlocked( const TPINParams& aPINParams, + TRequestStatus& aStatus ) + { + iCurrentOperation = EPINBlocked; + TPckg pinValueBuf( KNullDesC() ); + DoBasicPINOperation( EPINBlocked, aPINParams, EFalse, pinValueBuf, aStatus ); + } + + +void CRefSecurityDialog::TotalBlocked( const TPINParams& aPINParams, + TRequestStatus& aStatus ) + { + iCurrentOperation = ETotalBlocked; + TPckg pinValueBuf( KNullDesC() ); + DoBasicPINOperation( ETotalBlocked, aPINParams, EFalse, pinValueBuf, aStatus ); + } + + + +void CRefSecurityDialog::EstablishSecureConnection( const TDesC8& aCertData, + const RArray& aCertHandleList, + MSecurityDialog::TConnectionType aConnectionType, + TBool& aDoClientAuthentication, TCTTokenObjectHandle& aCertHandle, + TRequestStatus& aStatus ) + { + iCurrentOperation = ESecureConnection; + InitClientStatus( aStatus ); + + TInt certDataSize = aCertData.Size(); + TSignInput signInput; + signInput.iOperation = ESecureConnection; + signInput.iVariableDataSize = certDataSize; + signInput.iCertHandleArrayTotal = aCertHandleList.Count(); + signInput.iDoClientAuthentication = aDoClientAuthentication; + signInput.iConnectionType = aConnectionType; + TPckgC signInputBufPtr( signInput ); + // iSignInputBuf is persistent because further input processing occurs in the AO before + // calling the notifier. + iSignInputBuf.Copy( signInputBufPtr ); + iVariableDataPtr.Set( aCertData ); + + iClientDoClientAuthenticationPtr = &aDoClientAuthentication; + iClientCertInfoHandlePtr = &aCertHandle; + + iRequester->RequestVariableBufferDialog( iSignInputBuf, iVariableDataPtr, + aCertHandleList, iCertInfoHandleBuf ); + } + + + +void CRefSecurityDialog::SignText( const TDesC& aTextToSign, + const RArray& aCertHandleList, + TCTTokenObjectHandle& aCertHandle, + TRequestStatus& aStatus ) + { + iCurrentOperation = ESignText; + InitClientStatus( aStatus ); + + TInt textSize = aTextToSign.Size(); + TSignInput signInput; + signInput.iOperation = ESignText; + signInput.iVariableDataSize = textSize; + signInput.iCertHandleArrayTotal = aCertHandleList.Count(); + TPckgC signInputBufPtr( signInput ); + // iSignInputBuf is persistent because further input processing occurs in the AO before + // calling the notifier. + iSignInputBuf.Copy( signInputBufPtr ); + const TUint8* textToSignPtr = reinterpret_cast( aTextToSign.Ptr() ); + iVariableDataPtr.Set( textToSignPtr, textSize ); + + iClientCertInfoHandlePtr = &aCertHandle; + + iRequester->RequestVariableBufferDialog( iSignInputBuf, iVariableDataPtr, + aCertHandleList, iCertInfoHandleBuf ); + } + +void CRefSecurityDialog::ServerAuthenticationFailure(const TDesC8& aServerName,const TValidationError& aFailureReason, const TDesC8& aEncodedCert,TRequestStatus& aStatus ) + { + iCurrentOperation = EServerAuthenticationFailure; + InitClientStatus( aStatus ); + + CServerAuthenticationFailureInput* serverAuthenticationFailureInput = NULL; + TRAPD(err, serverAuthenticationFailureInput = CServerAuthenticationFailureInput::NewL(aServerName, aFailureReason, aEncodedCert)); + + // Ownership of the inputBuffer will pass to the requester. + HBufC8* inputBuffer = NULL; + if (err == KErrNone) + TRAP(err, inputBuffer = serverAuthenticationFailureInput->PackBufferL()); + + delete serverAuthenticationFailureInput; + + if (err == KErrNone) + iRequester->RequestDialog(inputBuffer, iServerAuthenticationOutputBuf); + else + HandleResponse(err); + } + +void CRefSecurityDialog::DoBasicPINOperation( TSecurityDialogOperation aOperation, + const TPINParams& aPINParams, TBool aRetry, TDes8& aPINValue, + TRequestStatus& aStatus ) + { + iCurrentOperation = aOperation; + InitClientStatus( aStatus ); + TPINInput pinInput; + pinInput.iOperation = aOperation; + if ( aRetry ) + { + pinInput.iOperation |= EPINValueIncorrect; + } + pinInput.iPIN = aPINParams; + TPINInputBuf pinInputBuf( pinInput ); + iPINInputBuf.Copy( pinInputBuf ); + iRequester->RequestDialog( iPINInputBuf, aPINValue ); + } + + + +void CRefSecurityDialog::InitClientStatus( TRequestStatus& aStatus ) + { + iClientStatus = &aStatus; + *iClientStatus = KRequestPending; + } + + + +void CRefSecurityDialog::HandleResponse( TInt aResult ) + { + if ( aResult >= KErrNone ) + { + switch ( iCurrentOperation ) + { + case EServerAuthenticationFailure: + { + TServerAuthenticationFailureDialogResult serverAuthenticationOutput = iServerAuthenticationOutputBuf(); + + if(serverAuthenticationOutput == EContinue) + { + aResult = KErrNone; + } + else if(serverAuthenticationOutput == EStop) + { + aResult = KErrAbort; + } + } + break; + case ESecureConnection: + { + if ( aResult == KClientAuthenticationRequested ) + { + *iClientDoClientAuthenticationPtr = ETrue; + aResult = KErrNone; + } + else + { + *iClientDoClientAuthenticationPtr = EFalse; + } + *iClientCertInfoHandlePtr = iCertInfoHandleBuf(); + break; + } + case ESignText: + { + *iClientCertInfoHandlePtr = iCertInfoHandleBuf(); + break; + } + case EEnterPIN: + case EEnablePIN: + case EDisablePIN: + *iClientPINValuePtr = iPINValueBuf(); + break; + case EChangePIN: + case EUnblockPIN: + { + TTwoPINOutput& twoPINOutput = iTwoPINOutputBuf(); + *iClientPINValuePtr = twoPINOutput.iPINValueToCheck; + *iClientSecondPINValuePtr = twoPINOutput.iNewPINValue; + break; + } + + case EUnblockPINInClear: + { + TUnblockPINInClearOutput& unblockPINOutput = iUnblockPINInClearOutputBuf(); + *iClientUnblockPINValuePtr = unblockPINOutput.iPINValueToCheck; + *iClientSecondPINValuePtr = unblockPINOutput.iNewPINValue; + break; + } + + case EPINBlocked: + case ETotalBlocked: + // No data to return + break; + default: + __ASSERT_DEBUG( EFalse, _L( "Invalid operation" ) ); + } + } + + User::RequestComplete( iClientStatus, aResult ); + } + + + +// ---------------------------------------------------------------------------- +// CDialogRequester +// + +CDialogRequester::CDialogRequester( CRefSecurityDialog& aSecDialog ) + : CActive( EPriorityStandard ), iSecDialog( aSecDialog ) + { + CActiveScheduler::Add( this ); + } + + + +CDialogRequester::~CDialogRequester() + { + Cancel(); + iNotifier.Close(); + } + + + +CDialogRequester* CDialogRequester::NewL( CRefSecurityDialog& aSecDialog ) + { + CDialogRequester* self = new (ELeave) CDialogRequester( aSecDialog ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + + +void CDialogRequester::ConstructL() + { + User::LeaveIfError( iNotifier.Connect() ); + } + + + +void CDialogRequester::RequestDialog( const TDesC8& aData, TDes8& aResponse ) + { + iNotifier.StartNotifierAndGetResponse( iStatus, KUidSecurityDialogNotifier, + aData, aResponse ); + iState = KMakingRequest; + SetActive(); + } + + + +void CDialogRequester::DoCancel() + { + delete iInputBuffer; + iInputBuffer = NULL; + iNotifier.CancelNotifier( KUidSecurityDialogNotifier ); + } + + + +void CDialogRequester::RequestVariableBufferDialog( const TDesC8& aOperationData, + const TDesC8& aVariableData, + const RArray& aCertHandleList, + TDes8& aResponse ) + { + iOperationDataPtr = &aOperationData; + iVariableDataPtr = &aVariableData; + iCertHandleListPtr = &aCertHandleList; + iResponsePtr = &aResponse; + iState = KFillingVariableInputBuffer; + SetActive(); + // Complete the AO immediately so that buffer processing can occur in RunL(). + TRequestStatus* statusPtr = &iStatus; + User::RequestComplete( statusPtr, KErrNone ); + } + +void CDialogRequester::RequestDialog(HBufC8* aInputBuffer, TDes8& aResponse) +{ +iInputBuffer = aInputBuffer; +RequestDialog(*iInputBuffer, aResponse); +} + + +void CDialogRequester::RunL() + { + switch ( iState ) + { + case KFillingVariableInputBuffer: + { + TInt operationDataSize = iOperationDataPtr->Size(); + TInt variableDataSize = iVariableDataPtr->Size(); + TInt arraySize = sizeof( TCTTokenObjectHandle ) * iCertHandleListPtr->Count(); + TInt bufferSize = operationDataSize + variableDataSize + arraySize; + iInputBuffer = HBufC8::NewL( bufferSize ); + TPtr8 inputBufferPtr( iInputBuffer->Des() ); + inputBufferPtr.Append( *iOperationDataPtr ); + for ( TInt h = 0, total = iCertHandleListPtr->Count(); h < total; ++h ) + { + const TCTTokenObjectHandle& certHandle = (*iCertHandleListPtr)[h]; + TPckgC certHandleBuf( certHandle ); + inputBufferPtr.Append( certHandleBuf ); + } + inputBufferPtr.Append( *iVariableDataPtr ); + RequestDialog( *iInputBuffer, *iResponsePtr ); + break; + } + case KMakingRequest: + { + delete iInputBuffer; + iInputBuffer = NULL; + iSecDialog.HandleResponse( iStatus.Int() ); + break; + } + default: + __ASSERT_DEBUG( EFalse, _L( "Invalid state" ) ); + } + } + + + +/** + * RunError should only be called if the buffer allocation fails, in which case + * let client handle it. + */ +TInt CDialogRequester::RunError( TInt aError ) + { + iSecDialog.HandleResponse( aError ); + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CServerAuthenticationFailureInput +// + +CServerAuthenticationFailureInput::CServerAuthenticationFailureInput() + { + } + + +CServerAuthenticationFailureInput::~CServerAuthenticationFailureInput() + { + if(iServerName) + delete iServerName; + if(iEncodedCert) + delete iEncodedCert; + } + +CServerAuthenticationFailureInput* CServerAuthenticationFailureInput::NewL(const TDesC8& aServerName,const TValidationError& aFailureReason, const TDesC8& aEncodedCert, const TBool aCreateOwnBuffers) + { + CServerAuthenticationFailureInput* self = CServerAuthenticationFailureInput::NewLC(aServerName, aFailureReason, aEncodedCert, aCreateOwnBuffers); + CleanupStack::Pop(self); + return self; + } + +CServerAuthenticationFailureInput* CServerAuthenticationFailureInput::NewLC(const TDesC8& aServerName,const TValidationError& aFailureReason, const TDesC8& aEncodedCert, const TBool aCreateOwnBuffers) + { + CServerAuthenticationFailureInput* self = new(ELeave) CServerAuthenticationFailureInput(); + CleanupStack::PushL(self); + self->ConstructL(aServerName, aFailureReason, aEncodedCert, aCreateOwnBuffers); + return self; + } + +EXPORT_C CServerAuthenticationFailureInput* CServerAuthenticationFailureInput::NewL(const TDesC8& aBuffer, const TBool aCreateOwnBuffers) + { + CServerAuthenticationFailureInput* self = CServerAuthenticationFailureInput::NewLC(aBuffer, aCreateOwnBuffers); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C CServerAuthenticationFailureInput* CServerAuthenticationFailureInput::NewLC(const TDesC8& aBuffer, const TBool aCreateOwnBuffers) + { + CServerAuthenticationFailureInput* self = new(ELeave) CServerAuthenticationFailureInput(); + CleanupStack::PushL(self); + self->ConstructL(aBuffer, aCreateOwnBuffers); + return self; + } + +void CServerAuthenticationFailureInput::ConstructL(const TDesC8& aServerName,const TValidationError& aFailureReason, const TDesC8& aEncodedCert, const TBool aCreateOwnBuffers) + { + iFailureReason = aFailureReason; + + if (aCreateOwnBuffers) + { + iServerName = aServerName.AllocL(); + iServerNamePtr.Set(iServerName->Des()); + iEncodedCert = aEncodedCert.AllocL(); + iEncodedCertPtr.Set(iEncodedCert->Des()); + } + else + { + iServerNamePtr.Set(aServerName); + iEncodedCertPtr.Set(aEncodedCert); + } + } + + +void CServerAuthenticationFailureInput::ConstructL(const TDesC8& aBuffer, const TBool aCreateOwnBuffers) + { + const TServerAuthenticationFailureInput* srvAuthFail = + reinterpret_cast + ( aBuffer.Ptr() ); + + const TUint8* binaryDataPtr = aBuffer.Ptr() + sizeof(TServerAuthenticationFailureInput); + + iFailureReason = srvAuthFail->iFailureReason; + + if(aCreateOwnBuffers) + { + TPtrC8 dataPtr(binaryDataPtr, srvAuthFail->iServerNameLength); + iServerName = dataPtr.AllocL(); + iServerNamePtr.Set(iServerName->Des()); + + dataPtr.Set(binaryDataPtr + srvAuthFail->iServerNameLength, srvAuthFail->iEncodedCertLength); + iEncodedCert = dataPtr.AllocL(); + iEncodedCertPtr.Set(iEncodedCert->Des()); + } + else + { + iServerNamePtr.Set(binaryDataPtr, srvAuthFail->iServerNameLength); + iEncodedCertPtr.Set(binaryDataPtr + srvAuthFail->iServerNameLength, srvAuthFail->iEncodedCertLength); + } + + } + +EXPORT_C TValidationError CServerAuthenticationFailureInput::FailureReason() + { + return iFailureReason; + } + +EXPORT_C void CServerAuthenticationFailureInput::GetServerName(TPtrC8& aServerNamePtr) + { + aServerNamePtr.Set(iServerNamePtr); + } + +EXPORT_C void CServerAuthenticationFailureInput::GetEncodedCert(TPtrC8& aEncodedCertPtr) + { + aEncodedCertPtr.Set(iEncodedCertPtr); + } + +EXPORT_C HBufC8* CServerAuthenticationFailureInput::PackBufferL() const + { + TServerAuthenticationFailureInput serverAuthenticationInput; + serverAuthenticationInput.iOperation = EServerAuthenticationFailure; + serverAuthenticationInput.iFailureReason = iFailureReason; + serverAuthenticationInput.iServerNameLength = iServerNamePtr.Length(); + serverAuthenticationInput.iEncodedCertLength = iEncodedCertPtr.Length(); + + TServerAuthenticationFailureInputBuf serverAuthenticationInputBuf(serverAuthenticationInput); + + TInt bufferSize = sizeof(serverAuthenticationInputBuf) + iServerNamePtr.Length() + iEncodedCertPtr.Length(); + HBufC8* packedBuffer = HBufC8::NewL(bufferSize); + TPtr8 packedBufferPtr(packedBuffer->Des()); + + packedBufferPtr.Append(serverAuthenticationInputBuf); + packedBufferPtr.Append(iServerNamePtr); + packedBufferPtr.Append(iEncodedCertPtr); + + return packedBuffer; + } +