diff -r 000000000000 -r 164170e6151a pkiutilities/DeviceToken/Src/KeyStore/Server/DevCertKeyStoreConduit.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkiutilities/DeviceToken/Src/KeyStore/Server/DevCertKeyStoreConduit.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,1075 @@ +/* +* Copyright (c) 2006 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: Implementation of DevCertKeyStoreConduit +* +*/ + + + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif +#include "DevCertKeyStoreConduit.h" +#include "DevCertKeyStoreServer.h" +#include "DevCertKeyStoreSession.h" +#include "DevCertOpenedKeysSrv.h" +#include "DevTokenDataTypes.h" +#include "DevTokenMarshaller.h" +#include "DevTokenUtil.h" +#include +#include + + +// ======== MEMBER FUNCTIONS ======== + +// CDevCertKeyStoreConduit + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::NewL() +// --------------------------------------------------------------------------- +// +CDevCertKeyStoreConduit* CDevCertKeyStoreConduit::NewL(CDevCertKeyStoreServer& aServer) + { + CDevCertKeyStoreConduit* self = new (ELeave) CDevCertKeyStoreConduit(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::~CDevCertKeyStoreConduit() +// --------------------------------------------------------------------------- +// +CDevCertKeyStoreConduit::~CDevCertKeyStoreConduit() + { + Cancel(); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CDevCertKeyStoreConduit() +// --------------------------------------------------------------------------- +// +CDevCertKeyStoreConduit::CDevCertKeyStoreConduit(CDevCertKeyStoreServer& aServer) + : CActive(EPriorityHigh), iServer(aServer), iCurrentRequest(iStatus) + { + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ConstructL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ConstructL() + { + CActiveScheduler::Add(this); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ServiceRequestL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ServiceRequestL(const RMessage2& aMessage, CDevCertKeyStoreSession& aSession) + { + TDevTokenMessages request = static_cast(aMessage.Function()); + + if (iCurrentRequest.OutstandingRequest()!=EIdle) + { + // There is currently a request outstanding, only allow this one if it's a cancel + if ( (request!=ECancelCreateKey) && + (request!=ECancelImportKey) && + (request!=ECancelImportEncryptedKey) && + (request!=ECancelExportKey) && + (request!=ECancelRSASign) && + (request!=ECancelDSASign) && + (request!=ECancelDecrypt) ) + { + User::Leave(KErrServerBusy); + } + } + + switch (request) + { + case EListKeys: + ListL(aMessage); + break; + case EGetKeyInfo: + GetKeyInfoL(aMessage); + break; + case ECreateKey: + CreateKeyL(aMessage); + break; + case ECancelCreateKey: + CancelCreateKey(aMessage); + break; + case EImportKey: + case EImportEncryptedKey: + ImportKeyL(aMessage); + break; + case ECancelImportKey: + case ECancelImportEncryptedKey: + CancelImportKey(aMessage); + break; + case EExportKey: + ExportKeyL(aMessage); + break; + case ECancelExportKey: + CancelExportKey(aMessage); + break; + case EExportPublic: + ExportPublicL(aMessage); + break; + case EGetKeyLength: + GetKeyLengthL(aMessage); + break; + case EDeleteKey: + DeleteKeyL(aMessage); + break; + case ESetUsePolicy: + SetUsePolicyL(aMessage); + break; + case ESetManagementPolicy: + SetManagementPolicyL(aMessage); + break; + case EOpenKeyRepudiableRSASign: + OpenKeyL(aMessage, aSession, KRSARepudiableSignerUID); + break; + case EOpenKeyRepudiableDSASign: + OpenKeyL(aMessage, aSession, KDSARepudiableSignerUID); + break; + case EOpenKeyDecrypt: + OpenKeyL(aMessage, aSession, KPrivateDecryptorUID); + break; + case EOpenKeyAgree: + OpenKeyL(aMessage, aSession, KKeyAgreementUID); + break; + case ECloseObject: + CloseObjectL(aMessage, aSession); + break; + case ERepudiableDSASign: + RepudiableDSASignL(aMessage, aSession); + break; + case ECancelDSASign: + CancelDSASign(aMessage); + break; + case ERepudiableRSASign: + RepudiableRSASignL(aMessage, aSession); + break; + case ECancelRSASign: + CancelRSASign(aMessage); + break; + case EDecryptText: + DecryptL(aMessage, aSession); + break; + case ECancelDecrypt: + CancelDecrypt(aMessage); + break; + case EDHPublicKey: + DHPublicKeyL(aMessage, aSession); + break; + case EDHAgree: + DHAgreeL(aMessage, aSession); + break; + case ECancelDH: + CancelDH(aMessage); + break; + + default: // Should not reach here + __ASSERT_DEBUG(EFalse, PanicServer(EPanicInvalidRequest)); + User::Leave(KErrNotSupported); + } + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ListL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ListL(const RMessage2& aMessage) + { + // p[0] has the filter to use + RCPointerArray keyInfos; + CleanupClosePushL(keyInfos); + + TPckgBuf filter; + aMessage.ReadL(0, filter); + + iServer.ListL(filter(), keyInfos); + + TInt bufSize = User::LeaveIfError(aMessage.GetDesMaxLength(2)); + TInt reqdSize = DevTokenDataMarshaller::Size(keyInfos); + if (bufSize >= reqdSize) + { + HBufC8* buffer = HBufC8::NewMaxLC(reqdSize); + TPtr8 thePtr(buffer->Des()); + DevTokenDataMarshaller::Write(keyInfos, thePtr); + aMessage.WriteL(2, thePtr); + CleanupStack::PopAndDestroy(buffer); + } + else + { + TPckg sizePckg(reqdSize); + aMessage.WriteL(2, sizePckg); + User::Leave(KErrOverflow); + } + + CleanupStack::PopAndDestroy(&keyInfos); // keyInfos + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::GetKeyInfoL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::GetKeyInfoL(const RMessage2& aMessage) + { + // Token object to delete is in p[0] + TInt objectId = aMessage.Int0(); + CDevTokenKeyInfo* info = NULL; + iServer.GetKeyInfoL(objectId, info); + info->CleanupPushL(); + + TInt bufferSize = User::LeaveIfError(aMessage.GetDesMaxLength(2)); + TInt requiredSize = DevTokenDataMarshaller::Size(*info); + + if (bufferSize >= requiredSize) + { + HBufC8* buffer = HBufC8::NewMaxLC(requiredSize); + TPtr8 thePtr(buffer->Des()); + DevTokenDataMarshaller::Write(*info, thePtr); + aMessage.WriteL(2, thePtr); + CleanupStack::PopAndDestroy(buffer); + } + else + { + TPckg theSize(requiredSize); + aMessage.WriteL(2, theSize); + User::Leave(KErrOverflow); + } + + CleanupStack::PopAndDestroy(info); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::GetClientUidL() +// Work out the UID of the client process. +// --------------------------------------------------------------------------- +// +TUid CDevCertKeyStoreConduit::GetClientUidL(const RMessage2& aMessage) const + { + RThread clientThread; + User::LeaveIfError(aMessage.Client(clientThread)); + CleanupClosePushL(clientThread); + RProcess clientProcess; + User::LeaveIfError(clientThread.Process(clientProcess)); + CleanupClosePushL(clientProcess); + TUid uid = clientProcess.Type()[2]; + CleanupStack::PopAndDestroy(2); // clientProcess, clientThread + return uid; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CreateKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CreateKeyL(const RMessage2& aMessage) + { + ASSERT(!iKeyInfo); + // p[0] has the length of the buffer. Check our buffer is big + // enough, to cope with requests for keys with very long labels. + + TInt bufLength = User::LeaveIfError(aMessage.GetDesLength(1)); + HBufC8* keyInfoBuf = HBufC8::NewMaxLC(bufLength); + + // p[1] has the CDevTokenKeyInfo structure required to create a key + // Read it and convert from descriptor back to a CDevTokenKeyInfo + TPtr8 thePtr(keyInfoBuf->Des()); + thePtr.FillZ(); + + aMessage.ReadL(1, thePtr); + DevTokenDataMarshaller::ReadL(*keyInfoBuf, iKeyInfo); + CleanupStack::PopAndDestroy(keyInfoBuf); + + iCurrentRequest.Set(ECreateKey, aMessage); + iStatus = KRequestPending; + SetActive(); + iServer.CreateKey(*iKeyInfo, iStatus); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelCreateKey() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelCreateKey(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == ECreateKey) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ImportKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ImportKeyL(const RMessage2& aMessage) + { + ASSERT(!iImportKey); + ASSERT(!iKeyInfo); + + // p[0] has the descriptor containing the PKCS8 object (not be encrypted) + TInt keyLen = User::LeaveIfError(aMessage.GetDesLength(0)); + + HBufC8* importBuf = HBufC8::NewMaxLC(keyLen); + TPtr8 theKeyData(importBuf->Des()); + theKeyData.FillZ(); + aMessage.ReadL(0, theKeyData); + + TInt bufLen = User::LeaveIfError(aMessage.GetDesLength(1)); + HBufC8* keyInfoBuf = HBufC8::NewMaxLC(bufLen); + + // p[1] has the CDevTokenKeyInfo structure required to create a key + // Read it and convert from descriptor back to a CDevTokenKeyInfo + TPtr8 thePtr(keyInfoBuf->Des()); + thePtr.FillZ(); + aMessage.ReadL(1, thePtr); + + DevTokenDataMarshaller::ReadL(*keyInfoBuf, iKeyInfo); + CleanupStack::PopAndDestroy(keyInfoBuf); + + iImportKey = importBuf; + CleanupStack::Pop(importBuf); + + iCurrentRequest.Set(static_cast(aMessage.Function()), aMessage); + iStatus = KRequestPending; + SetActive(); + + TBool isEncrypted = (aMessage.Function() == EImportEncryptedKey); + iServer.ImportKey(*iImportKey, *iKeyInfo, isEncrypted, iStatus); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelImportKey() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelImportKey(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == EImportKey || + iCurrentRequest.OutstandingRequest() == EImportEncryptedKey) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::GetKeyLengthL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::GetKeyLengthL(const RMessage2& aMessage) + { + TInt length = iServer.GetKeyLengthL(aMessage.Int0()); + ASSERT(length > 0); + aMessage.Complete(length); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelExportKey() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelExportKey(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == EExportKey || + iCurrentRequest.OutstandingRequest() == EImportEncryptedKey) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ExportKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ExportKeyL(const RMessage2& aMessage) + { + ASSERT(!iExportBuf); + + TInt objectId = aMessage.Int0(); + TInt bufLen = User::LeaveIfError(aMessage.GetDesMaxLength(1)); // #1 IPC argument is the request Ptr + + HBufC8* exportBuf = HBufC8::NewMaxLC(bufLen); + TPtr8 temp(exportBuf->Des()); + temp.FillZ(); + + // No more leaves + iExportBuf = exportBuf; + CleanupStack::Pop(exportBuf); + + iCurrentRequest.Set(static_cast(aMessage.Function()), aMessage); + iStatus = KRequestPending; + SetActive(); + + if (aMessage.Function() == EExportKey) + { + iServer.ExportKey(objectId, temp, iStatus); + } + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ExportPublicL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::ExportPublicL(const RMessage2& aMessage) + { + TInt objectId = aMessage.Int0(); + TInt bufLen = User::LeaveIfError(aMessage.GetDesMaxLength(1)); + + HBufC8* exportBuf = HBufC8::NewMaxLC(bufLen); + TPtr8 ptr(exportBuf->Des()); + ptr.FillZ(); + iServer.ExportPublicL(objectId, ptr); + aMessage.WriteL(1, ptr); + + CleanupStack::PopAndDestroy(exportBuf); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DeleteKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DeleteKeyL(const RMessage2& aMessage) + { + TInt objectId = aMessage.Int0(); + iServer.DeleteKeyL(objectId); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::SetUsePolicyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::SetUsePolicyL(const RMessage2& aMessage) + { + TInt objectId = aMessage.Int0(); + TSecurityPolicyBuf policyBuf; + + aMessage.ReadL(1, policyBuf); + + iServer.SetUsePolicyL(objectId, policyBuf()); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::SetManagementPolicyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::SetManagementPolicyL(const RMessage2& aMessage) + { + TInt objectId = aMessage.Int0(); + TSecurityPolicyBuf policyBuf; + + aMessage.ReadL(1, policyBuf); + + iServer.SetManagementPolicyL(objectId, policyBuf()); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::OpenKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::OpenKeyL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession, + TUid aType) + { + CDevCertOpenedKeySrv* openedKey = iServer.OpenKeyL(aMessage.Int0(), aType); + CleanupStack::PushL(openedKey); + + const TDesC& label = openedKey->Label(); + + TInt writeBufLen = User::LeaveIfError(aMessage.GetDesMaxLength(3)); + TInt reqdLength = label.Length(); + if (writeBufLen < reqdLength) + { + // We're writing into a TDes16 so we can't use TPckg + TPtrC sizePtr(reinterpret_cast(&reqdLength), 2); + aMessage.WriteL(3, sizePtr); + User::Leave(KErrOverflow); + } + + aMessage.WriteL(3, label); + + TInt handle = aSession.AddOpenedKeyL(*openedKey); + + TPckg handlePckg(handle); + TRAPD(err, aMessage.WriteL(1, handlePckg)); + + if (err != KErrNone) + { + aSession.RemoveOpenedKeyL(handle); + User::Leave(err); + } + + CleanupStack::Pop(openedKey); // now owned by session + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::RepudiableRSASignL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::RepudiableRSASignL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession) + { + ASSERT( iOpenedKey == NULL ); + TPtr8 thePtr(0,0); + iOpenedKey = ProcessL(aMessage, aSession, KRSARepudiableSignerUID, ERepudiableRSASign, thePtr); + static_cast(iOpenedKey)->Sign(thePtr, iRSASignature, iStatus); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelRSASign() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelRSASign(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == ERepudiableRSASign) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::RepudiableDSASignL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::RepudiableDSASignL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession) + { + ASSERT( iOpenedKey == NULL ); + TPtr8 thePtr(0,0); + iOpenedKey = ProcessL(aMessage, aSession, KDSARepudiableSignerUID, ERepudiableDSASign, thePtr); + static_cast(iOpenedKey)->Sign(thePtr, iDSASignature, iStatus); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelDSASign() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelDSASign(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == ERepudiableDSASign) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DecryptL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DecryptL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession) + { + ASSERT( iOpenedKey == NULL ); + TPtr8 thePtr(0,0); + iOpenedKey = ProcessL(aMessage, aSession, KPrivateDecryptorUID, EDecryptText, thePtr); + static_cast(iOpenedKey)->Decrypt(thePtr, iPlaintext, iStatus); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelDecrypt() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelDecrypt(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == EDecryptText) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::ProcessL() +// --------------------------------------------------------------------------- +// +CDevCertOpenedKeySrv* CDevCertKeyStoreConduit::ProcessL( + const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession, + const TUid& aCKeyInfoID, + const TDevTokenMessages& aState, + TPtr8& aTextPtr) + { + CDevCertOpenedKeySrv* object = aSession.OpenedKey(aMessage.Int0()); + if (!object) + { + User::Leave(KErrNotFound); + } + + if (aCKeyInfoID != object->Type()) + { + User::Leave(KErrAccessDenied); + } + + TInt length = User::LeaveIfError(aMessage.GetDesLength(1)); + iText = HBufC8::NewL(length); + aTextPtr.Set(iText->Des()); + aMessage.ReadL(1, aTextPtr); + + iCurrentRequest.Set(aState, aMessage); + iStatus=KRequestPending; + SetActive(); + + return object; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DHPublicKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DHPublicKeyL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession) + { + // 0: Object id + // 1: DH paramters + + ASSERT(iDHParams == NULL ); + ASSERT(iOpenedKey == NULL ); + TRAPD(err, DoDHPublicKeyL(aMessage, aSession)); + if (err != KErrNone) + { + iOpenedKey = NULL; + delete iDHParams; + iDHParams = NULL; + User::Leave(err); + } + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DoDHPublicKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DoDHPublicKeyL(const RMessage2& aMessage, + CDevCertKeyStoreSession& aSession) + { + iOpenedKey = aSession.OpenedKey(aMessage.Int0()); + if (!iOpenedKey) + { + User::Leave(KErrNotFound); + } + + //Check that this is a DH object + if (KKeyAgreementUID != iOpenedKey->Type()) + { + iOpenedKey = NULL; + User::Leave(KErrAccessDenied); + } + + HBufC8* clientBuf = HBufC8::NewMaxLC(User::LeaveIfError(aMessage.GetDesLength(1))); + TPtr8 clientPtr = clientBuf->Des(); + aMessage.ReadL(1, clientPtr); + DevTokenDataMarshaller::ReadL(*clientBuf, iDHParams); + CleanupStack::PopAndDestroy(clientBuf); + + static_cast(iOpenedKey)->PublicKey(*iDHParams, iDHPublicKeyOut, iStatus); + + iCurrentRequest.Set(EDHPublicKey, aMessage); + iStatus=KRequestPending; + SetActive(); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::FinishDHPublicKeyL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::FinishDHPublicKeyL() + { + // Client buffer must be big enough for result because it had the DH + // parameters in it + TInt reqdSize = DevTokenDataMarshaller::Size(iDHPublicKeyOut); + ASSERT(reqdSize <= iCurrentRequest.Message().GetDesMaxLength(1)); + + HBufC8* clientBuf = HBufC8::NewMaxLC(reqdSize); + TPtr8 clientPtr = clientBuf->Des(); + DevTokenDataMarshaller::WriteL(iDHPublicKeyOut, clientPtr); + iCurrentRequest.Message().WriteL(1, clientPtr); + CleanupStack::PopAndDestroy(clientBuf); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DHAgreeL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DHAgreeL(const RMessage2& aMessage, CDevCertKeyStoreSession& aSession) + { + // 0: Object id + // 1: DH public key + + ASSERT( iOpenedKey == NULL ); + ASSERT( iDHPublicKey == NULL ); + TRAPD(err, DoDHAgreeL(aMessage, aSession)); + if (err != KErrNone) + { + iOpenedKey = NULL; + delete iDHPublicKey; + iDHPublicKey = NULL; + User::Leave(err); + } + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DoDHAgreeL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DoDHAgreeL(const RMessage2& aMessage, CDevCertKeyStoreSession& aSession) + { + CDevCertOpenedKeySrv* iOpenedKey = aSession.OpenedKey(aMessage.Int0()); + if (!iOpenedKey) + { + User::Leave(KErrNotFound); + } + + //Check that this is a DH object + if (KKeyAgreementUID != iOpenedKey->Type()) + { + iOpenedKey = NULL; + User::Leave(KErrAccessDenied); + } + + HBufC8* clientBuf = HBufC8::NewMaxLC(User::LeaveIfError(aMessage.GetDesLength(1))); + TPtr8 clientPtr = clientBuf->Des(); + aMessage.ReadL(1, clientPtr); + DevTokenDataMarshaller::ReadL(*clientBuf, iDHPublicKey); + CleanupStack::PopAndDestroy(clientBuf); + + static_cast(iOpenedKey)->Agree(*iDHPublicKey, iDHAgreedKeyOut, iStatus); + + iCurrentRequest.Set(EDHAgree, aMessage); + iStatus=KRequestPending; + SetActive(); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::FinishDHAgreeL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::FinishDHAgreeL() + { + // Client buffer must be big enough for result because it had the DH + // public key in it + ASSERT(iDHAgreedKeyOut->Length() <= iCurrentRequest.Message().GetDesMaxLength(1)); + + iCurrentRequest.Message().WriteL(1, *iDHAgreedKeyOut); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CancelDH() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CancelDH(const RMessage2& aMessage) + { + if (iCurrentRequest.OutstandingRequest() == EDHPublicKey || + iCurrentRequest.OutstandingRequest() == EDHAgree) + { + Cancel(); + } + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::CloseObjectL() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::CloseObjectL(const RMessage2& aMessage, CDevCertKeyStoreSession& aSession) + { + aSession.RemoveOpenedKeyL(aMessage.Int0()); + aMessage.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::DoCancel() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::DoCancel() + { + switch (iCurrentRequest.OutstandingRequest()) + { + case ECreateKey: + iServer.CancelCreateKey(); + break; + + case ERepudiableRSASign: + case ERepudiableDSASign: + case EDecryptText: + case EDHAgree: + case EDHPublicKey: + if (iOpenedKey) + { + iOpenedKey->Cancel(); + } + break; + + case EImportKey: + iServer.CancelImportKey(); + break; + + case EExportKey: + iServer.CancelExportKey(); + break; + + default: + // Nothing to do + break; + } + + Cleanup(); + iCurrentRequest.Cancel(); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::RunL() +// The token interface has completed the request - munge any return parameters +// and write back to client. +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::RunL() + { + // Handle errors from server + User::LeaveIfError(iStatus.Int()); + + switch (iCurrentRequest.OutstandingRequest()) + { + case ECreateKey: + case EImportKey: + case EImportEncryptedKey: + { + // Marshal TKeyUpdate to client - the client's buffer will be large + // enough as it passed us a CCTKeyInfo in the first place + ASSERT(iKeyInfo); + TDevTokenKeyUpdate update; + update.iReference = iKeyInfo->HandleID(); + update.iId = iKeyInfo->ID(); + update.iSize = iKeyInfo->Size(); + update.iAlgorithm = iKeyInfo->Algorithm(); + TPckg pckg(update); + iCurrentRequest.Message().WriteL(1, pckg); + break; + } + case EExportKey: + { + ASSERT(iExportBuf); + TPtr8 clientPtr(iExportBuf->Des()); + iCurrentRequest.Message().WriteL(1, clientPtr); + break; + } + case ERepudiableDSASign: + { + ASSERT(iDSASignature); + + TInt length = User::LeaveIfError(iCurrentRequest.Message().GetDesMaxLength(2)); + TInt reqdLength = DevTokenDataMarshaller::Size(*iDSASignature); + if (length < reqdLength) + { + User::Leave(KErrOverflow); + } + + HBufC8* clientBuffer = HBufC8::NewLC(reqdLength); + TPtr8 ptr(clientBuffer->Des()); + DevTokenDataMarshaller::WriteL(*iDSASignature, ptr); + iCurrentRequest.Message().WriteL(2, ptr); + CleanupStack::PopAndDestroy(clientBuffer); + break; + } + case ERepudiableRSASign: + { + ASSERT(iRSASignature); + TInt length = User::LeaveIfError(iCurrentRequest.Message().GetDesMaxLength(2)); + TInt reqdLength = DevTokenDataMarshaller::Size(*iRSASignature); + if (length < reqdLength) + { + User::Leave(KErrOverflow); + } + + HBufC8* clientBuffer = HBufC8::NewLC(reqdLength); + TPtr8 ptr(clientBuffer->Des()); + DevTokenDataMarshaller::WriteL(*iRSASignature, ptr); + iCurrentRequest.Message().WriteL(2, ptr); + CleanupStack::PopAndDestroy(clientBuffer); + break; + } + case EDecryptText: + { + ASSERT(iPlaintext); + TInt length = User::LeaveIfError(iCurrentRequest.Message().GetDesMaxLength(2)); + if (length < iPlaintext->Length()) + { + User::Leave(KErrOverflow); + } + iCurrentRequest.Message().WriteL(2, *iPlaintext); + break; + } + + case EDHPublicKey: + FinishDHPublicKeyL(); + break; + case EDHAgree: + FinishDHAgreeL(); + break; + + default: + __ASSERT_DEBUG(EFalse, PanicServer(EPanicInvalidRequest)); + User::Leave(KErrNotSupported); + } + + Cleanup(); + iCurrentRequest.Complete(KErrNone); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::Cleanup() +// Cleans up data members used in processing a client request. Called whenenver a +// request is completed, either from RunL, RunError or indirectly from DoCancel. +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::Cleanup() + { + delete iKeyInfo; iKeyInfo = NULL; + delete iImportKey; iImportKey = NULL; + delete iText; iText = NULL; + delete iDSASignature; iDSASignature = NULL; + delete iRSASignature; iRSASignature = NULL; + delete iExportBuf; iExportBuf = NULL; + delete iDHParams; iDHParams = NULL; + iDHPublicKeyOut.Close(); + delete iDHPublicKey; iDHPublicKey = NULL; + delete iDHAgreedKeyOut; iDHAgreedKeyOut = NULL; + delete iPlaintext; iPlaintext = NULL; + iOpenedKey = NULL; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::RunError() +// --------------------------------------------------------------------------- +// +TInt CDevCertKeyStoreConduit::RunError(TInt aError) + { + Cleanup(); + // Handle error by completing client appropriately + iCurrentRequest.Complete(aError); + return (KErrNone); + } + + +// CDevCertKeyStoreConduit::TAsyncRequest + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::TAsyncRequest::TAsyncRequest() +// --------------------------------------------------------------------------- +// +CDevCertKeyStoreConduit::TAsyncRequest::TAsyncRequest(TRequestStatus& aStatus) : + iOwnerStatus(aStatus) + { + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::TAsyncRequest::~TAsyncRequest() +// --------------------------------------------------------------------------- +// +CDevCertKeyStoreConduit::TAsyncRequest::~TAsyncRequest() + { + __ASSERT_DEBUG(EIdle==iRequest, PanicServer(EPanicRequestOutstanding)); + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::TAsyncRequest::Set() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::TAsyncRequest::Set(TDevTokenMessages aRequest, const RMessage2& aMessage) + { + __ASSERT_DEBUG(EIdle==iRequest, PanicServer(EPanicRequestOutstanding)); + + iOwnerStatus = KRequestPending; + iRequest = aRequest; + iMessage = aMessage; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::TAsyncRequest::Complete() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::TAsyncRequest::Complete(TInt aResult) + { + iMessage.Complete(aResult); + iRequest = EIdle; + } + + +// --------------------------------------------------------------------------- +// CDevCertKeyStoreConduit::TAsyncRequest::Cancel() +// --------------------------------------------------------------------------- +// +void CDevCertKeyStoreConduit::TAsyncRequest::Cancel() + {// Complete outstanding request with KErrCancel + iMessage.Complete(KErrCancel); + iRequest = EIdle; + } + +//EOF +