--- /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 <mctkeystoreuids.h>
+#endif
+#include "DevCertKeyStoreConduit.h"
+#include "DevCertKeyStoreServer.h"
+#include "DevCertKeyStoreSession.h"
+#include "DevCertOpenedKeysSrv.h"
+#include "DevTokenDataTypes.h"
+#include "DevTokenMarshaller.h"
+#include "DevTokenUtil.h"
+#include <asymmetric.h>
+#include <mctkeystoremanager.h>
+
+
+// ======== 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<TDevTokenMessages>(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<CDevTokenKeyInfo> keyInfos;
+ CleanupClosePushL(keyInfos);
+
+ TPckgBuf<TCTKeyAttributeFilter> 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<TInt> 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<TInt> 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<TDevTokenMessages>(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<TDevTokenMessages>(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<TInt>
+ TPtrC sizePtr(reinterpret_cast<TUint16*>(&reqdLength), 2);
+ aMessage.WriteL(3, sizePtr);
+ User::Leave(KErrOverflow);
+ }
+
+ aMessage.WriteL(3, label);
+
+ TInt handle = aSession.AddOpenedKeyL(*openedKey);
+
+ TPckg<TInt> 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<CDevCertRSARepudiableSignerSrv*>(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<CDevCertDSARepudiableSignerSrv*>(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<CDevCertRSADecryptorSrv*>(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<CDevCertDHAgreementSrv*>(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<CDevCertDHAgreementSrv*>(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<TDevTokenKeyUpdate> 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
+