diff -r 675a964f4eb5 -r 35751d3474b7 cryptomgmtlibs/cryptotokenfw/tsecdlg/Tsecdlg.cpp --- a/cryptomgmtlibs/cryptotokenfw/tsecdlg/Tsecdlg.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/cryptomgmtlibs/cryptotokenfw/tsecdlg/Tsecdlg.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,449 +1,449 @@ -/* -* 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: -* secdlgImpl.cpp -* -*/ - - -#include "Tsecdlg.h" -#include -#include -#include - - -// These are not really allocated to us, but this is only for finding errors -// while debugging, so it doesn't really matter -const TInt KErrTooManyDialogs = -12000; -const TInt KErrLabelMismatch = -12001; -const TInt KErrOperationMismatch = -12002; -const TInt KErrOperationNotSupported = -12003; - -_LIT(KpinValue,"pinkcloud"); -_LIT(KYes,"Yes"); - -// ---------------------------------------------------------------------------- -// Lib main entry point. -// This can leave and should leave (if failure occurs) despite the lack of trailing L. -// - -#ifdef _T_SECDLG_TEXTSHELL -EXPORT_C CArrayPtr* NotifierArray() -#else -CArrayPtr* NotifierArray() -#endif - { - //The notifierArray function CAN leave, despite no trailing L - CArrayPtrFlat* subjects = new (ELeave) CArrayPtrFlat( 1 ); - CleanupStack::PushL(subjects); - CTestSecDlgNotifier* notifier = CTestSecDlgNotifier::NewL(); - CleanupStack::PushL( notifier ); - subjects->AppendL( notifier ); - CleanupStack::Pop( 2,subjects); //notifier, subjects - return subjects; - } - -// ---------------------------------------------------------------------------- -// Ecom plugin implementation for UI notifier -// - -#ifndef _T_SECDLG_TEXTSHELL - -const TImplementationProxy ImplementationTable[] = - { - IMPLEMENTATION_PROXY_ENTRY(KTSecDlgNotiferUid, NotifierArray) - }; - -EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) - { - aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); - return (ImplementationTable); - } - -#endif - -// ---------------------------------------------------------------------------- -// CInputSpec -// - -CInputSpec::CInputSpec(TSecurityDialogOperation aOp, HBufC* aLabelSpec, HBufC* aResponse1, HBufC* aResponse2) : - iOp(aOp), iLabelSpec(aLabelSpec), iResponse1(aResponse1), iResponse2(aResponse2) - { - } - -CInputSpec::~CInputSpec() - { - delete iLabelSpec; - delete iResponse1; - delete iResponse2; - } - - -// ---------------------------------------------------------------------------- -// CTestSecDlgNotifier -// - -_LIT(KInputFile, "\\t_secdlg_in.dat"); -_LIT(KOutputFile, "\\t_secdlg_out.dat"); - -CTestSecDlgNotifier* CTestSecDlgNotifier::NewL() - { - CTestSecDlgNotifier* self=new (ELeave) CTestSecDlgNotifier(); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -CTestSecDlgNotifier::CTestSecDlgNotifier() - { - iInfo.iUid = KUidSecurityDialogNotifier; - iInfo.iChannel = TUid::Uid(0x00001234); // dummy - iInfo.iPriority = ENotifierPriorityHigh; - } - -void CTestSecDlgNotifier::ConstructL() - { - User::LeaveIfError(iFs.Connect()); - } - - -TInt CTestSecDlgNotifier::GetInputIndexL() - { - RFileReadStream stream; - TDriveUnit sysDrive (RFs::GetSystemDrive()); - TDriveName driveName(sysDrive.Name()); - TBuf<128> outputFile (driveName); - outputFile.Append(KOutputFile); - - TInt err = stream.Open(iFs, outputFile, EFileRead | EFileShareExclusive); - // If the file doesn't exist yet just return zero - if (err == KErrNotFound) - { - return 0; - } - User::LeaveIfError(err); - stream.PushL(); - TInt index = stream.ReadInt32L(); - CleanupStack::PopAndDestroy(); // stream - return index; - } - -void CTestSecDlgNotifier::WriteDialogCountL(TInt aCount) - { - RFileWriteStream stream; - TDriveUnit sysDrive (RFs::GetSystemDrive()); - TDriveName driveName(sysDrive.Name()); - TBuf<128> outputFile (driveName); - outputFile.Append(KOutputFile); - - TInt err = stream.Replace(iFs, outputFile, EFileWrite | EFileShareExclusive); - if (err == KErrNotFound) - { - err = stream.Create(iFs, outputFile, EFileWrite | EFileShareExclusive); - } - User::LeaveIfError(err); - stream.PushL(); - stream.WriteInt32L(aCount); - stream.CommitL(); - CleanupStack::PopAndDestroy(); // stream - } - -CInputSpec* CTestSecDlgNotifier::ReadInputSpecL(TInt aIndex) - { - RFileReadStream stream; - TDriveUnit sysDrive (RFs::GetSystemDrive()); - TDriveName driveName(sysDrive.Name()); - TBuf<128> inputFile (driveName); - inputFile.Append(KInputFile); - User::LeaveIfError(stream.Open(iFs, inputFile, EFileRead | EFileShareExclusive)); - stream.PushL(); - - // Update dialog count here so test code can see how many dialogs were - // requested if there were more than expected - WriteDialogCountL(aIndex + 1); - - MStreamBuf* streamBuf = stream.Source(); - TInt labelSize, response1Size, response2Size; - - // Skip records until we reach the one we want - for (TInt i = 0 ; i < aIndex ; ++i) - { - stream.ReadInt32L(); - labelSize = stream.ReadInt32L(); - streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, labelSize * 2); - response1Size = stream.ReadInt32L(); - streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, response1Size * 2); - response2Size = stream.ReadInt32L(); - streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, response2Size * 2); - } - - TSecurityDialogOperation op = static_cast(stream.ReadInt32L()); - - labelSize = stream.ReadInt32L(); - HBufC* labelSpec = HBufC::NewMaxLC(labelSize); - TPtr labelPtr(labelSpec->Des()); - stream.ReadL(labelPtr, labelSize); - - response1Size = stream.ReadInt32L(); - HBufC* response1 = HBufC::NewMaxLC(response1Size); - TPtr response1Ptr(response1->Des()); - stream.ReadL(response1Ptr, response1Size); - - response2Size = stream.ReadInt32L(); - HBufC* response2 = HBufC::NewMaxLC(response2Size); - TPtr response2Ptr(response2->Des()); - stream.ReadL(response2Ptr, response2Size); - - CInputSpec* inputSpec = new (ELeave) CInputSpec(op, labelSpec, response1, response2); - CleanupStack::Pop(3, labelSpec); - CleanupStack::PopAndDestroy(); // stream - - return inputSpec; - } - - -void CTestSecDlgNotifier::DoEnterPINL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) - { - const TPINInput& pinInput = reinterpret_cast(*aBuffer.Ptr()); - - if (pinInput.iPIN.iPINLabel.Find(aSpec.LabelSpec()) == KErrNotFound) - { - User::Leave(KErrLabelMismatch); - } - - TPINValue pinValue = aSpec.Response1(); - TPckg pinValueBufPtr(pinValue); - aMessage.WriteL(aReplySlot, pinValueBufPtr); - } - -void CTestSecDlgNotifier::DoChangePINL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) - { - const TPINInput& input = reinterpret_cast(*aBuffer.Ptr()); - - if (input.iPIN.iPINLabel.Find(aSpec.LabelSpec()) == KErrNotFound) - { - User::Leave(KErrLabelMismatch); - } - - TTwoPINOutput output; - output.iPINValueToCheck = aSpec.Response1(); - output.iNewPINValue = aSpec.Response2(); - TPckg outputPckg(output); - aMessage.WriteL(aReplySlot, outputPckg); - } - - -void CTestSecDlgNotifier::Release() - { - delete this; - } - - - -CTestSecDlgNotifier::TNotifierInfo CTestSecDlgNotifier::RegisterL() - { - return iInfo; - } - - - -CTestSecDlgNotifier::TNotifierInfo CTestSecDlgNotifier::Info() const - { - return iInfo; - } - - - -void CTestSecDlgNotifier::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) - { - TRAPD(err, DoStartL(aBuffer, aReplySlot, aMessage)); - aMessage.Complete(err); - } - - -void CTestSecDlgNotifier::DoStartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) - { - // Minimum length is 4 - __ASSERT_DEBUG( aBuffer.Length() >= 4, User::Panic(_L("CTestSecDlgNotifier"), 0)); - - TUint operation = *reinterpret_cast(aBuffer.Ptr()) & KSecurityDialogOperationMask; - - TInt index = GetInputIndexL(); - CInputSpec* spec = NULL; - - TRAPD(err, spec = ReadInputSpecL(index)); - - // If the input file doesn't exist then we will answer PIN requests with the - // "pinkcloud" passphrase - this is so the certstore tests work independantly - // from keystore - if (err == KErrNotFound) - { - switch(operation) - { - case EEnterPIN: - { - TPINValue pinValue(KpinValue); - TPckg pinValueBufPtr(pinValue); - aMessage.WriteL(aReplySlot, pinValueBufPtr); - break; - } - case EServerAuthenticationFailure: - { - TServerAuthenticationFailureDialogResult output; - output = EStop; - TServerAuthenticationFailureOutputBuf outputPckg(output); - aMessage.WriteL(aReplySlot, outputPckg); - break; - } - default: - { - User::Leave(KErrOperationMismatch); - break; - } - } - return; - } - - if (err == KErrEof) - { - User::Leave(KErrTooManyDialogs); - } - - User::LeaveIfError(err); - - CleanupStack::PushL(spec); - - if (operation != spec->Operation()) - { - User::Leave(KErrOperationMismatch); - } - - switch (operation) - { - case EEnterPIN: - DoEnterPINL(*spec, aBuffer, aReplySlot, aMessage); - break; - - case EChangePIN: - DoChangePINL(*spec, aBuffer, aReplySlot, aMessage); - break; - - case ESecureConnection: - DoSecureConnectionL(*spec, aBuffer, aReplySlot, aMessage); - break; - - case ESignText: - case EEnablePIN: - case EDisablePIN: - case EUnblockPIN: - case EUnblockPINInClear: - case EPINBlocked: - // these operations are not yet implemented in this test harness - User::Leave(KErrOperationNotSupported); - break; - - case EServerAuthenticationFailure: - DoServerAuthenticationFailureL(*spec, aBuffer, aReplySlot, aMessage); - break; - - default: - User::Panic(_L("CTestSecDlgNotifier"), 0); - } - CleanupStack::PopAndDestroy(spec); - } - -void CTestSecDlgNotifier::DoServerAuthenticationFailureL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) - { - // Test for valid packing of dialog data by extracting the encoded certificate - // and attempting to construct an X509 certificate from it. - CServerAuthenticationFailureInput* srvAuthFail = CServerAuthenticationFailureInput::NewLC(aBuffer); - TPtrC8 encodedCert; - srvAuthFail->GetEncodedCert(encodedCert); - - // If CX509Certificate::NewL leaves the encoded cert buffer must not be valid. - const CX509Certificate* cert = CX509Certificate::NewL(encodedCert); - - // There is no further need for the cert, so it can be deleted immediately. - delete cert; - - CleanupStack::PopAndDestroy(srvAuthFail); - - TServerAuthenticationFailureDialogResult output; - output = EStop; - if( (aSpec.Response1()).CompareF(KYes) == KErrNone ) - { - output = EContinue; - } - TServerAuthenticationFailureOutputBuf outputPckg(output); - aMessage.WriteL(aReplySlot, outputPckg); - } - -void CTestSecDlgNotifier::DoSecureConnectionL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) - { - // If the client does not want to continue - if( (aSpec.Response1()).CompareF(KYes) != KErrNone ) - { - User::Leave(KErrCancel); - } - else - { - const TSignInput* secureConnectionInput = - reinterpret_cast( aBuffer.Ptr() ); - // if the client certificate is requested - if (secureConnectionInput->iDoClientAuthentication) - { - TLex lexi(aSpec.Response2()); - TInt32 selectionId=0; - TInt err=lexi.Val(selectionId); - - TInt certHandleTotal = secureConnectionInput->iCertHandleArrayTotal; - if (selectionId>certHandleTotal) - { - User::Leave(KErrNotFound); - } - - // Get index at start of list of TCTTokenObjectHandle objects - TInt bufferIndex = sizeof( TSignInput ); - TInt certHandleSize = sizeof( TCTTokenObjectHandle ); - TPckgBuf certHandleBuf; - TPtrC8 certHandleData( aBuffer.Mid( bufferIndex+(selectionId-1)*certHandleSize, certHandleSize ) ); - certHandleBuf.Copy( certHandleData ); - aMessage.WriteL( aReplySlot, certHandleBuf ); - } - } - } - - -TPtrC8 CTestSecDlgNotifier::StartL( const TDesC8& /*aBuffer*/ ) - { - User::Panic(_L("CTestSecDlgNotifier"), 0); - return TPtrC8(KNullDesC8); - } - - -void CTestSecDlgNotifier::Cancel() - { - // Don't think there is much we can do here. If a client deletes the - // client-side security dialog instance, after calling a method that - // displays a dialog, this will not get called until the user dismisses - // the dialog. We can't do anything then. - } - - -TPtrC8 CTestSecDlgNotifier::UpdateL( const TDesC8& /*aBuffer*/ ) - { - User::Panic(_L("CTestSecDlgNotifier"), 0); - return NULL; - } +/* +* 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: +* secdlgImpl.cpp +* +*/ + + +#include "Tsecdlg.h" +#include +#include +#include + + +// These are not really allocated to us, but this is only for finding errors +// while debugging, so it doesn't really matter +const TInt KErrTooManyDialogs = -12000; +const TInt KErrLabelMismatch = -12001; +const TInt KErrOperationMismatch = -12002; +const TInt KErrOperationNotSupported = -12003; + +_LIT(KpinValue,"pinkcloud"); +_LIT(KYes,"Yes"); + +// ---------------------------------------------------------------------------- +// Lib main entry point. +// This can leave and should leave (if failure occurs) despite the lack of trailing L. +// + +#ifdef _T_SECDLG_TEXTSHELL +EXPORT_C CArrayPtr* NotifierArray() +#else +CArrayPtr* NotifierArray() +#endif + { + //The notifierArray function CAN leave, despite no trailing L + CArrayPtrFlat* subjects = new (ELeave) CArrayPtrFlat( 1 ); + CleanupStack::PushL(subjects); + CTestSecDlgNotifier* notifier = CTestSecDlgNotifier::NewL(); + CleanupStack::PushL( notifier ); + subjects->AppendL( notifier ); + CleanupStack::Pop( 2,subjects); //notifier, subjects + return subjects; + } + +// ---------------------------------------------------------------------------- +// Ecom plugin implementation for UI notifier +// + +#ifndef _T_SECDLG_TEXTSHELL + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KTSecDlgNotiferUid, NotifierArray) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return (ImplementationTable); + } + +#endif + +// ---------------------------------------------------------------------------- +// CInputSpec +// + +CInputSpec::CInputSpec(TSecurityDialogOperation aOp, HBufC* aLabelSpec, HBufC* aResponse1, HBufC* aResponse2) : + iOp(aOp), iLabelSpec(aLabelSpec), iResponse1(aResponse1), iResponse2(aResponse2) + { + } + +CInputSpec::~CInputSpec() + { + delete iLabelSpec; + delete iResponse1; + delete iResponse2; + } + + +// ---------------------------------------------------------------------------- +// CTestSecDlgNotifier +// + +_LIT(KInputFile, "\\t_secdlg_in.dat"); +_LIT(KOutputFile, "\\t_secdlg_out.dat"); + +CTestSecDlgNotifier* CTestSecDlgNotifier::NewL() + { + CTestSecDlgNotifier* self=new (ELeave) CTestSecDlgNotifier(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CTestSecDlgNotifier::CTestSecDlgNotifier() + { + iInfo.iUid = KUidSecurityDialogNotifier; + iInfo.iChannel = TUid::Uid(0x00001234); // dummy + iInfo.iPriority = ENotifierPriorityHigh; + } + +void CTestSecDlgNotifier::ConstructL() + { + User::LeaveIfError(iFs.Connect()); + } + + +TInt CTestSecDlgNotifier::GetInputIndexL() + { + RFileReadStream stream; + TDriveUnit sysDrive (RFs::GetSystemDrive()); + TDriveName driveName(sysDrive.Name()); + TBuf<128> outputFile (driveName); + outputFile.Append(KOutputFile); + + TInt err = stream.Open(iFs, outputFile, EFileRead | EFileShareExclusive); + // If the file doesn't exist yet just return zero + if (err == KErrNotFound) + { + return 0; + } + User::LeaveIfError(err); + stream.PushL(); + TInt index = stream.ReadInt32L(); + CleanupStack::PopAndDestroy(); // stream + return index; + } + +void CTestSecDlgNotifier::WriteDialogCountL(TInt aCount) + { + RFileWriteStream stream; + TDriveUnit sysDrive (RFs::GetSystemDrive()); + TDriveName driveName(sysDrive.Name()); + TBuf<128> outputFile (driveName); + outputFile.Append(KOutputFile); + + TInt err = stream.Replace(iFs, outputFile, EFileWrite | EFileShareExclusive); + if (err == KErrNotFound) + { + err = stream.Create(iFs, outputFile, EFileWrite | EFileShareExclusive); + } + User::LeaveIfError(err); + stream.PushL(); + stream.WriteInt32L(aCount); + stream.CommitL(); + CleanupStack::PopAndDestroy(); // stream + } + +CInputSpec* CTestSecDlgNotifier::ReadInputSpecL(TInt aIndex) + { + RFileReadStream stream; + TDriveUnit sysDrive (RFs::GetSystemDrive()); + TDriveName driveName(sysDrive.Name()); + TBuf<128> inputFile (driveName); + inputFile.Append(KInputFile); + User::LeaveIfError(stream.Open(iFs, inputFile, EFileRead | EFileShareExclusive)); + stream.PushL(); + + // Update dialog count here so test code can see how many dialogs were + // requested if there were more than expected + WriteDialogCountL(aIndex + 1); + + MStreamBuf* streamBuf = stream.Source(); + TInt labelSize, response1Size, response2Size; + + // Skip records until we reach the one we want + for (TInt i = 0 ; i < aIndex ; ++i) + { + stream.ReadInt32L(); + labelSize = stream.ReadInt32L(); + streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, labelSize * 2); + response1Size = stream.ReadInt32L(); + streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, response1Size * 2); + response2Size = stream.ReadInt32L(); + streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, response2Size * 2); + } + + TSecurityDialogOperation op = static_cast(stream.ReadInt32L()); + + labelSize = stream.ReadInt32L(); + HBufC* labelSpec = HBufC::NewMaxLC(labelSize); + TPtr labelPtr(labelSpec->Des()); + stream.ReadL(labelPtr, labelSize); + + response1Size = stream.ReadInt32L(); + HBufC* response1 = HBufC::NewMaxLC(response1Size); + TPtr response1Ptr(response1->Des()); + stream.ReadL(response1Ptr, response1Size); + + response2Size = stream.ReadInt32L(); + HBufC* response2 = HBufC::NewMaxLC(response2Size); + TPtr response2Ptr(response2->Des()); + stream.ReadL(response2Ptr, response2Size); + + CInputSpec* inputSpec = new (ELeave) CInputSpec(op, labelSpec, response1, response2); + CleanupStack::Pop(3, labelSpec); + CleanupStack::PopAndDestroy(); // stream + + return inputSpec; + } + + +void CTestSecDlgNotifier::DoEnterPINL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) + { + const TPINInput& pinInput = reinterpret_cast(*aBuffer.Ptr()); + + if (pinInput.iPIN.iPINLabel.Find(aSpec.LabelSpec()) == KErrNotFound) + { + User::Leave(KErrLabelMismatch); + } + + TPINValue pinValue = aSpec.Response1(); + TPckg pinValueBufPtr(pinValue); + aMessage.WriteL(aReplySlot, pinValueBufPtr); + } + +void CTestSecDlgNotifier::DoChangePINL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) + { + const TPINInput& input = reinterpret_cast(*aBuffer.Ptr()); + + if (input.iPIN.iPINLabel.Find(aSpec.LabelSpec()) == KErrNotFound) + { + User::Leave(KErrLabelMismatch); + } + + TTwoPINOutput output; + output.iPINValueToCheck = aSpec.Response1(); + output.iNewPINValue = aSpec.Response2(); + TPckg outputPckg(output); + aMessage.WriteL(aReplySlot, outputPckg); + } + + +void CTestSecDlgNotifier::Release() + { + delete this; + } + + + +CTestSecDlgNotifier::TNotifierInfo CTestSecDlgNotifier::RegisterL() + { + return iInfo; + } + + + +CTestSecDlgNotifier::TNotifierInfo CTestSecDlgNotifier::Info() const + { + return iInfo; + } + + + +void CTestSecDlgNotifier::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) + { + TRAPD(err, DoStartL(aBuffer, aReplySlot, aMessage)); + aMessage.Complete(err); + } + + +void CTestSecDlgNotifier::DoStartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage) + { + // Minimum length is 4 + __ASSERT_DEBUG( aBuffer.Length() >= 4, User::Panic(_L("CTestSecDlgNotifier"), 0)); + + TUint operation = *reinterpret_cast(aBuffer.Ptr()) & KSecurityDialogOperationMask; + + TInt index = GetInputIndexL(); + CInputSpec* spec = NULL; + + TRAPD(err, spec = ReadInputSpecL(index)); + + // If the input file doesn't exist then we will answer PIN requests with the + // "pinkcloud" passphrase - this is so the certstore tests work independantly + // from keystore + if (err == KErrNotFound) + { + switch(operation) + { + case EEnterPIN: + { + TPINValue pinValue(KpinValue); + TPckg pinValueBufPtr(pinValue); + aMessage.WriteL(aReplySlot, pinValueBufPtr); + break; + } + case EServerAuthenticationFailure: + { + TServerAuthenticationFailureDialogResult output; + output = EStop; + TServerAuthenticationFailureOutputBuf outputPckg(output); + aMessage.WriteL(aReplySlot, outputPckg); + break; + } + default: + { + User::Leave(KErrOperationMismatch); + break; + } + } + return; + } + + if (err == KErrEof) + { + User::Leave(KErrTooManyDialogs); + } + + User::LeaveIfError(err); + + CleanupStack::PushL(spec); + + if (operation != spec->Operation()) + { + User::Leave(KErrOperationMismatch); + } + + switch (operation) + { + case EEnterPIN: + DoEnterPINL(*spec, aBuffer, aReplySlot, aMessage); + break; + + case EChangePIN: + DoChangePINL(*spec, aBuffer, aReplySlot, aMessage); + break; + + case ESecureConnection: + DoSecureConnectionL(*spec, aBuffer, aReplySlot, aMessage); + break; + + case ESignText: + case EEnablePIN: + case EDisablePIN: + case EUnblockPIN: + case EUnblockPINInClear: + case EPINBlocked: + // these operations are not yet implemented in this test harness + User::Leave(KErrOperationNotSupported); + break; + + case EServerAuthenticationFailure: + DoServerAuthenticationFailureL(*spec, aBuffer, aReplySlot, aMessage); + break; + + default: + User::Panic(_L("CTestSecDlgNotifier"), 0); + } + CleanupStack::PopAndDestroy(spec); + } + +void CTestSecDlgNotifier::DoServerAuthenticationFailureL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) + { + // Test for valid packing of dialog data by extracting the encoded certificate + // and attempting to construct an X509 certificate from it. + CServerAuthenticationFailureInput* srvAuthFail = CServerAuthenticationFailureInput::NewLC(aBuffer); + TPtrC8 encodedCert; + srvAuthFail->GetEncodedCert(encodedCert); + + // If CX509Certificate::NewL leaves the encoded cert buffer must not be valid. + const CX509Certificate* cert = CX509Certificate::NewL(encodedCert); + + // There is no further need for the cert, so it can be deleted immediately. + delete cert; + + CleanupStack::PopAndDestroy(srvAuthFail); + + TServerAuthenticationFailureDialogResult output; + output = EStop; + if( (aSpec.Response1()).CompareF(KYes) == KErrNone ) + { + output = EContinue; + } + TServerAuthenticationFailureOutputBuf outputPckg(output); + aMessage.WriteL(aReplySlot, outputPckg); + } + +void CTestSecDlgNotifier::DoSecureConnectionL(const CInputSpec& aSpec, const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) + { + // If the client does not want to continue + if( (aSpec.Response1()).CompareF(KYes) != KErrNone ) + { + User::Leave(KErrCancel); + } + else + { + const TSignInput* secureConnectionInput = + reinterpret_cast( aBuffer.Ptr() ); + // if the client certificate is requested + if (secureConnectionInput->iDoClientAuthentication) + { + TLex lexi(aSpec.Response2()); + TInt32 selectionId=0; + TInt err=lexi.Val(selectionId); + + TInt certHandleTotal = secureConnectionInput->iCertHandleArrayTotal; + if (selectionId>certHandleTotal) + { + User::Leave(KErrNotFound); + } + + // Get index at start of list of TCTTokenObjectHandle objects + TInt bufferIndex = sizeof( TSignInput ); + TInt certHandleSize = sizeof( TCTTokenObjectHandle ); + TPckgBuf certHandleBuf; + TPtrC8 certHandleData( aBuffer.Mid( bufferIndex+(selectionId-1)*certHandleSize, certHandleSize ) ); + certHandleBuf.Copy( certHandleData ); + aMessage.WriteL( aReplySlot, certHandleBuf ); + } + } + } + + +TPtrC8 CTestSecDlgNotifier::StartL( const TDesC8& /*aBuffer*/ ) + { + User::Panic(_L("CTestSecDlgNotifier"), 0); + return TPtrC8(KNullDesC8); + } + + +void CTestSecDlgNotifier::Cancel() + { + // Don't think there is much we can do here. If a client deletes the + // client-side security dialog instance, after calling a method that + // displays a dialog, this will not get called until the user dismisses + // the dialog. We can't do anything then. + } + + +TPtrC8 CTestSecDlgNotifier::UpdateL( const TDesC8& /*aBuffer*/ ) + { + User::Panic(_L("CTestSecDlgNotifier"), 0); + return NULL; + }