pkiutilities/DeviceToken/Src/KeyStore/Server/DevCertCreateKey.cpp
changeset 0 164170e6151a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/DeviceToken/Src/KeyStore/Server/DevCertCreateKey.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,311 @@
+/*
+* 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 DevCertKeyDataManager
+*
+*/
+
+
+#include <bigint.h>
+#include "DevCertCreateKey.h"
+#include "DevTokenServerDebug.h"
+#include "SimpleDHKey.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CSimpleDHKey::NewL()
+// ---------------------------------------------------------------------------
+//
+CSimpleDHKey* CSimpleDHKey::NewL(TInt aSize)
+    {
+    CSimpleDHKey* me = new (ELeave) CSimpleDHKey();
+    CleanupStack::PushL(me);
+    me->ConstructL(aSize);
+    CleanupStack::Pop(me);
+    return (me);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSimpleDHKey::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CSimpleDHKey::ConstructL(TInt aSize)
+    {
+    iKey = RInteger::NewRandomL(aSize - 1);             
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSimpleDHKey::~CSimpleDHKey()
+// ---------------------------------------------------------------------------
+//
+CSimpleDHKey::~CSimpleDHKey()
+    {
+    iKey.Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::CDevCertKeyCreator()
+// ---------------------------------------------------------------------------
+//
+CDevCertKeyCreator::CDevCertKeyCreator()
+: CActive(EPriorityStandard), iAction(EIdle)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::~CDevCertKeyCreator()
+// ---------------------------------------------------------------------------
+//
+CDevCertKeyCreator::~CDevCertKeyCreator()
+    {
+    Cancel(); 
+    iCreatorThread.LogonCancel(iStatus);
+    iCreatorThread.Close();
+    delete iCreateData;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::DoCreateKeyAsyncL()
+//  Spin a thread to create an appropriate key, if successful, 
+// left on CleanupStack
+// ---------------------------------------------------------------------------
+//
+void CDevCertKeyCreator::DoCreateKeyAsyncL(CDevTokenKeyInfo::EKeyAlgorithm aAlgorithm, TInt aSize, TRequestStatus& aStatus)
+    {
+    if ( (aSize <= 0) ||
+    (aAlgorithm==CDevTokenKeyInfo::EInvalidAlgorithm) || 
+    ((aAlgorithm!=CDevTokenKeyInfo::ERSA) && (aAlgorithm!=CDevTokenKeyInfo::EDSA) && (aAlgorithm!=CDevTokenKeyInfo::EDH)) )
+    User::Leave(KErrArgument);
+
+    iClientStatus = &aStatus;
+    *iClientStatus = KRequestPending;
+
+    iCreateData = new (ELeave) CDevCertKeyCreatorData(aAlgorithm, aSize);
+
+    //  OK, ready to start the async operation...do it in RunL
+    iAction = EReadyToCreateKey;
+    iStatus = KRequestPending;
+    SetActive();
+    TRequestStatus* stat = &iStatus;
+    User::RequestComplete(stat, KErrNone);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::CreatorThreadEntryPoint()
+// HERE'S THE THREAD TO CREATE THE KEY
+// Code cannot leave in here, but not as many traps as it looks
+// ---------------------------------------------------------------------------
+//
+TInt CDevCertKeyCreator::CreatorThreadEntryPoint(TAny* aParameters)
+    {
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    if (!cleanup)
+    User::Exit(KErrNoMemory);
+
+    #ifdef _DEBUG
+    DevTokenServerDebug::PauseOOMTest();
+    #endif
+
+    ASSERT(aParameters);
+    TInt result = KErrNone;
+    CDevCertKeyCreatorData* createData = static_cast<CDevCertKeyCreatorData*>(aParameters);
+    switch (createData->iKeyAlgorithm)
+        {
+        case(CDevTokenKeyInfo::ERSA):
+            {// Currently, CRT signing is not supported, in case the key is to be used
+            //  for such, create a standard (private) key as part of the pair
+            TRAP(result, createData->iKey.iRSAKey = CRSAKeyPair::NewL(createData->iSize));
+            }
+        break;
+        case (CDevTokenKeyInfo::EDSA):
+            {
+            TRAP(result, createData->iKey.iDSAKey = CDSAKeyPair::NewL(createData->iSize));
+            }
+        break;
+        case (CDevTokenKeyInfo::EDH):
+            {// Generate a number that's less than N. The snag is that
+            //  we don't know what N is. We do know that it'll be of a
+            //  particular size, so we can safely generate any number
+            //  with less than iSize digits
+            TRAP(result, createData->iKey.iDHKey = CSimpleDHKey::NewL(createData->iSize));        
+            }
+        break;
+        default:
+        ASSERT(EFalse);
+        result = KErrArgument;
+        }
+
+    #ifdef _DEBUG
+    DevTokenServerDebug::ResumeOOMTest();
+    #endif
+
+    delete cleanup;
+    User::Exit(result);
+    return (KErrNone);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::GetCreatedRSAKey()
+// ---------------------------------------------------------------------------
+//
+CRSAKeyPair* CDevCertKeyCreator::GetCreatedRSAKey()
+    {// Check algorithm is as expected, return NULL if no key or wrong type
+    if ( (!iCreateData) || (CDevTokenKeyInfo::ERSA!=iCreateData->iKeyAlgorithm) )
+    return (NULL);
+    else
+    return (iCreateData->iKey.iRSAKey);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::GetCreatedDSAKey()
+// ---------------------------------------------------------------------------
+//
+CDSAKeyPair* CDevCertKeyCreator::GetCreatedDSAKey()
+    {// Check algorithm is as expected, return NULL if no key or wrong type
+    if ( (!iCreateData) || (CDevTokenKeyInfo::EDSA!=iCreateData->iKeyAlgorithm) )
+    return (NULL);
+    else
+    return (iCreateData->iKey.iDSAKey);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::GetCreatedDHKey()
+// ---------------------------------------------------------------------------
+//
+void CDevCertKeyCreator::GetCreatedDHKey(RInteger& aDHKey)
+    {
+    ASSERT(iCreateData);
+    ASSERT(CDevTokenKeyInfo::EDH==iCreateData->iKeyAlgorithm);    
+    aDHKey = iCreateData->iKey.iDHKey->DHKey();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::DoCancel()
+// ---------------------------------------------------------------------------
+//
+void CDevCertKeyCreator::DoCancel()
+    {// Only do the cancel if in the middle of creating a key.  Kill the thread.
+    if (iAction!=EIdle)
+        {
+        TExitType exitType = iCreatorThread.ExitType();
+        if (EExitPending==exitType) //  Still alive, so kill it
+        iCreatorThread.Kill(KErrCancel);
+
+        iAction = EIdle;
+        }
+
+    ASSERT(iClientStatus);
+    User::RequestComplete(iClientStatus, KErrCancel);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::RunL()
+// ---------------------------------------------------------------------------
+//
+void CDevCertKeyCreator::RunL()
+    {
+    ASSERT(iClientStatus);
+
+    switch (iAction)
+        {
+        case (EReadyToCreateKey):
+            {// Spin off the thread and pass it the parameter data, then stand by
+            User::LeaveIfError(iCreatorThread.Create(KCreateKeyName, CreatorThreadEntryPoint, KDefaultStackSize, NULL, (TAny*)iCreateData));
+            iStatus = KRequestPending;
+            iCreatorThread.Logon(iStatus);
+            iAction = ECreatedKey;
+            SetActive();
+            iCreatorThread.Resume();
+            }
+        break;
+        case (ECreatedKey):
+            {// Notify the caller
+            ASSERT(iClientStatus);
+
+            // May be OOM creating logon, in which case we should kill thread
+            if (iStatus.Int() == KErrNoMemory)
+                {
+                TExitType exitType = iCreatorThread.ExitType();
+                if (EExitPending==exitType) //  Still alive, so kill it
+                iCreatorThread.Kill(KErrNone);
+                }
+
+            User::RequestComplete(iClientStatus, iStatus.Int());
+            iAction = EIdle;
+            }
+        break;
+        default:
+        ASSERT(EFalse);
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::RunError()
+// ---------------------------------------------------------------------------
+//
+TInt CDevCertKeyCreator::RunError(TInt anError)
+    {
+    if (iClientStatus)
+        {
+        User::RequestComplete(iClientStatus, anError);
+        }
+    return (KErrNone);
+    }
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::CDevCertKeyCreatorData::CDevCertKeyCreatorData()
+// ---------------------------------------------------------------------------
+//
+CDevCertKeyCreator::CDevCertKeyCreatorData::CDevCertKeyCreatorData(CDevTokenKeyInfo::EKeyAlgorithm aAlgorithm, TInt aSize)
+: iSize(aSize), iKeyAlgorithm(aAlgorithm)
+    {}
+
+
+// ---------------------------------------------------------------------------
+// CDevCertKeyCreator::CDevCertKeyCreatorData::~CDevCertKeyCreatorData()
+// ---------------------------------------------------------------------------
+//
+CDevCertKeyCreator::CDevCertKeyCreatorData::~CDevCertKeyCreatorData()
+    {
+    if (iKeyAlgorithm==CDevTokenKeyInfo::ERSA)
+        {
+    	delete iKey.iRSAKey;
+        }
+    else if (iKeyAlgorithm==CDevTokenKeyInfo::EDSA)
+        {
+        delete iKey.iDSAKey;	
+        }
+    else if (iKeyAlgorithm==CDevTokenKeyInfo::EDH)
+        {
+    	delete iKey.iDHKey;
+        }
+    }
+    
+//EOF
+