pkiutilities/DeviceToken/Src/KeyStore/Server/DevCertKeyStoreConduit.cpp
changeset 0 164170e6151a
--- /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
+