javaextensions/satsa/pki/src.s60/cstssignatureservice.cpp
branchRCL_3
changeset 19 04becd199f91
child 50 023eef975703
child 60 6c158198356e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/satsa/pki/src.s60/cstssignatureservice.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1046 @@
+/*
+* Copyright (c) 2008 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:
+ *
+*/
+
+
+// INCLUDE FILES
+#include "cstssignatureservice.h"
+#include "tstsdistinguishednameconverter.h"
+#include "secdlg.h"
+#include <unifiedcertstore.h>
+#include <asn1enc.h>
+#include <x500dn.h>
+#include <charconv.h>
+#include <unifiedkeystore.h>
+#include <mctwritablecertstore.h>
+#include <signed.h>
+#include <asymmetric.h>
+#include <CCMSX509Certificate.h>
+#include <CCMSSignerInfo.h>
+#include <CCMSEncapsulatedContentInfo.h>
+#include <CCMSSignedData.h>
+#include <PKIDlg.h>
+#include "cstsseprompt.h"
+
+#include <hash.h>
+#include "fs_methodcall.h"
+#include <jutils.h>
+#include "satsajnitools.h"
+#include "logger.h"
+#include "jstringutils.h"
+
+// CONSTANTS
+const TInt KDefaultGranularity = 1;
+
+const TInt KOptionIncludeContent = 1;
+const TInt KOptionIncludeCertificate = 2;
+
+_LIT(KIdData, "1.2.840.113549.1.7.1");
+_LIT(KIdSignedData, "1.2.840.113549.1.7.2");
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSTSSignatureService* CSTSSignatureService::NewL()
+{
+    CSTSSignatureService* self = new(ELeave) CSTSSignatureService;
+    CallMethodL(self, &CSTSSignatureService::AddToScheduler, self);
+    CleanupStack::PushL(self);
+    CallMethodL(self, &CSTSSignatureService::ConstructL, self);
+    CleanupStack::Pop(self);
+    return self;
+}
+
+void CSTSSignatureService::AddToScheduler()
+{
+    CActiveScheduler::Add(this);
+}
+
+// Destructor
+CSTSSignatureService::~CSTSSignatureService()
+{
+    if (iDialog)
+    {
+        iDialog->Release(); // Release deletes the object
+    }
+    if (iPKIDialog)
+    {
+        iPKIDialog->Release();
+    }
+    iCertificateArray.Close();
+    iCertInfos.Close();
+    delete iFilter;
+    iDERNamesHBufC.ResetAndDestroy();
+    iDERNames.Close();
+    delete iTextToDisplay;
+    if (iCertificate)
+    {
+        iCertificate->Release();
+    }
+    delete iX509Certificate;
+    if (iRSASigner)
+    {
+        iRSASigner->Release();
+    }
+    if (iDSASigner)
+    {
+        iDSASigner->Release();
+    }
+    delete iCertStore;
+    delete iKeyStore;
+    iKeys.Close();
+    delete iRSASignature;
+    delete iDSASignature;
+    delete iSignature;
+    iFileServer.Close();
+    delete iWait;
+    delete iSecurityElementPrompt;
+    delete iSignerInfo;
+    delete iEncodedSignedAttributesHash;
+    delete iCMSCertificate;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::AuthenticateL
+// Authenticates given data
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSTSSignatureService::AuthenticateL(const TDesC8& abytesToAuthenticate,
+        TInt aOptions, const CDesCArray& aCaNames,
+        const TDesC& asecurityElementPrompt, TBool aShowData)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::AuthenticateL");
+    if (iState != EReady)
+    {
+        ELOG(ESATSA, "CSTSSignatureService::AuthenticateL: Not Ready");
+        User::Leave(KErrNotReady);
+    }
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::AuthenticateL:After convertions");
+    // First we need to convert the data to unicode, if we have to display it
+    HBufC* textToDisplay = NULL;
+    if (aShowData)
+    {
+        textToDisplay = ConvertUTF8ToUnicodeL(abytesToAuthenticate);
+        iAuthType = EAuthWithText;
+    }
+    else
+    {
+        textToDisplay = KNullDesC().AllocL();
+        iAuthType = EAuthWithoutText;
+    }
+
+    delete iTextToDisplay;
+    iTextToDisplay = textToDisplay;
+
+    iMessage.Set(abytesToAuthenticate);
+
+    iOptions = aOptions;
+
+    iShowNotes = EFalse;
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::AuthenticateL:Going to call CreateSignatureL");
+    // get handles to applicable certificates
+    HBufC8* retVal = CreateSignatureL(aCaNames, EX509UsageDigitalSignature,
+                                      asecurityElementPrompt);
+    LOG(ESATSA, EInfo, "CSTSSignatureService::AuthenticateL:After call to CreateSignatureL");
+
+    LOG(ESATSA, EInfo, "-- CSTSSignatureService::AuthenticateL");
+    return retVal;
+}
+
+TInt CSTSSignatureService::StaticAuthenticateL(JNIEnv* aJniEnv,
+        CSTSSignatureService* service, jbyteArray aByteArrayToAuthenticate,
+        jint aOptions, jobjectArray aCaNames, jstring aSecurityElementPrompt,
+        jboolean aShowData, HBufC8** aRetVal)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::StaticAuthenticateL");
+    const TInt byteArrayLength = aJniEnv->GetArrayLength(
+                                     aByteArrayToAuthenticate);
+    jbyte* bytesToAuthenticate = aJniEnv->GetByteArrayElements(
+                                     aByteArrayToAuthenticate, NULL);
+
+    if (!bytesToAuthenticate)
+    {
+        ELOG(ESATSA, "CSTSSignatureService::StaticAuthenticateL: No memory,return");
+        return NULL;
+    }
+
+    TPtrC8 desToAuthenticate(reinterpret_cast<TUint8*>(bytesToAuthenticate),
+                             byteArrayLength);
+
+    CDesCArrayFlat* nativeCaNames = STSCreateNativeStringArrayL(aJniEnv,
+                                    aCaNames);
+
+    LOG(ESATSA, EInfo,  "CSTSSignatureService::StaticAuthenticateL: prepare se prompt");
+    const JStringUtils securityElementPrompt(*aJniEnv, aSecurityElementPrompt);
+
+    LOG(ESATSA, EInfo,  "CSTSSignatureService::StaticAuthenticateL: start convertions to TInt");
+    TBool ShowData = static_cast<TBool>(aShowData);
+    const TDesC* sec = static_cast<const TDesC*>(&securityElementPrompt);
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::StaticAuthenticateL: After convertions,going to call CallMethodL");
+    TRAPD(err, CallMethodL(*aRetVal, service,
+                           &CSTSSignatureService::AuthenticateL, desToAuthenticate, aOptions,
+                           *nativeCaNames, *sec, ShowData, service));
+
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::StaticAuthenticateL:After CallmethodL");
+    LOG(ESATSA, EInfo, "-- return CSTSSignatureService::StaticAuthenticateL");
+    return err;
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::SignL
+
+// Signs given data
+// -----------------------------------------------------------------------------
+
+HBufC8* CSTSSignatureService::SignL(const TDesC8& aBytesToSign, TInt aOptions,
+                                    const CDesCArray& aCaNames, const TDesC& aSecurityElementPrompt)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::SignL");
+    if (iState != EReady)
+    {
+        ELOG(ESATSA, "CSTSSignatureService::SignL: Not Ready");
+        User::Leave(KErrNotReady);
+    }
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::SignL: start convertions!");
+    LOG(ESATSA, EInfo, "CSTSSignatureService::SignL: After convertions");
+    // convert text from UTF8
+    HBufC* textToDisplay = ConvertUTF8ToUnicodeL(aBytesToSign);
+    delete iTextToDisplay;
+    iTextToDisplay = textToDisplay;
+
+    iAuthType = ESignWithText;
+
+    iMessage.Set(aBytesToSign);
+
+    iOptions = aOptions;
+
+    iShowNotes = ETrue;
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::SignL: Before call to CreateSignatureL");
+    // get handles to applicable certificates
+    HBufC8* retVal = CreateSignatureL(aCaNames, EX509UsageNonRepudiation,
+                                      aSecurityElementPrompt);
+
+    LOG(ESATSA, EInfo, "-- return CSTSSignatureService::SignL");
+    return retVal;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::StaticSignL
+// Authenticates given data
+// -----------------------------------------------------------------------------
+//
+TInt CSTSSignatureService::StaticSignL(JNIEnv* aJniEnv,
+                                       CSTSSignatureService* service, jbyteArray aBytesToSign, jint aOptions,
+                                       jobjectArray aCaNames, jstring aSecurityElementPrompt, HBufC8** aRetVal)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::StaticSignL");
+    const TInt byteArrayLength = aJniEnv->GetArrayLength(aBytesToSign);
+    jbyte* bytesToSign = aJniEnv->GetByteArrayElements(aBytesToSign, NULL);
+
+    if (!bytesToSign)
+    {
+        LOG(ESATSA, EInfo, "CSTSSignatureService::StaticSignL: No memory");
+        return NULL;
+    }
+
+    TPtrC8 desToSign(reinterpret_cast<TUint8*>(bytesToSign), byteArrayLength);
+
+    CDesCArrayFlat* nativeCaNames = STSCreateNativeStringArrayL(aJniEnv,
+                                    aCaNames);
+
+    const JStringUtils securityElementPrompt(*aJniEnv, aSecurityElementPrompt);
+
+    LOG(ESATSA, EInfo, "CSTSSignatureService::StaticSignL: Start convertions");
+    LOG(ESATSA, EInfo, "CSTSSignatureService::StaticSignL: Before callmethodl");
+
+    const TDesC* sec = static_cast<const TDesC*>(&securityElementPrompt);
+
+    TRAPD(err, CallMethodL(*aRetVal, service, &CSTSSignatureService::SignL,
+                           desToSign, aOptions, *nativeCaNames, *sec, service));
+
+    LOG(ESATSA, EInfo, "-- ret CSTSSignatureService::StaticSignL");
+    return err;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::RunL
+// CActive callback
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::RunL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::RunL");
+    if (iStatus == KErrCancel)
+    {
+        LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: KErrCancel");
+        if (iShowNotes)
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: ShowNote");
+            iState = EFinalNote;
+            iStatus = KErrNone;
+            iPKIDialog->Note(MPKIDialog::ESigningCancelled, iStatus);
+            SetActive();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: Done ShowNote");
+        }
+        else
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: Complete");
+            Complete(KErrNone);
+        }
+    }
+    else if (iStatus != KErrNone)
+    {
+        LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: Error occured");
+        // Error has occured; inform java
+        Complete(iStatus.Int());
+    }
+    else
+    {
+        switch (iState)
+        {
+        case EInitialising:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EInitialising");
+            iState = EKeyStoreInit;
+            iKeyStore->Initialize(iStatus);
+            SetActive();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case EInitialising");
+            break;
+        }
+        case EKeyStoreInit:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EKeyStoreInit");
+            Complete(KErrNone);
+            break;
+        }
+        case EListing:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EListing");
+            HandlesFromCertInfosL();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case EListing");
+            break;
+        }
+        case EDialog:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EDialog");
+            iState = EGetCert;
+            if (iCertificate)
+            {
+                iCertificate->Release();
+                iCertificate = NULL;
+            }
+            // if there is only 1 handle, the dialog won't return it.
+            if (iCertificateArray.Count() == 1)
+            {
+                iCertificateHandle = iCertificateArray[0];
+            }
+
+            iCertStore->GetCert(iCertificate, iCertificateHandle, iStatus);
+            SetActive();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case EDialog");
+            break;
+        }
+        case EGetCert:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EGetCert");
+            if (iX509Certificate)
+            {
+                delete iX509Certificate;
+                iX509Certificate = NULL;
+            }
+            iState = ERetrieveCert;
+            iCertStore->Retrieve(*iCertificate, iX509Certificate, iStatus);
+            SetActive();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case EGetCert");
+            break;
+        }
+        case ERetrieveCert:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case ERetrieveCert");
+            FindKeyL();
+            break;
+        }
+        case EFindKey:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EFindKey");
+            OpenSignerL();
+            break;
+        }
+        case EOpenSigner:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EOpenSigner");
+            SignL();
+            break;
+        }
+        case ESign:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case ESign");
+            CreateSignedDataL();
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case ESign");
+            break;
+        }
+        case EFinalNote:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case EFinalNote");
+            Complete(KErrNone);
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: over case EFinalNote");
+            break;
+        }
+        default:
+        {
+            LOG(ESATSA, EInfo, "CSTSSignatureService::RunL: case default");
+            Complete(KErrGeneral);
+        }
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::RunError
+// CActive error callback
+// -----------------------------------------------------------------------------
+//
+TInt CSTSSignatureService::RunError(TInt aError)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::RunError");
+    Complete(aError);
+    return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::DoCancel
+// CActive cancellation callback
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::DoCancel()
+{
+    switch (iState)
+    {
+    case EInitialising:
+    {
+        iCertStore->CancelInitialize();
+        break;
+    }
+    case EKeyStoreInit:
+    {
+        iKeyStore->CancelInitialize();
+        break;
+    }
+    case EListing:
+    {
+        iCertStore->CancelList();
+        break;
+    }
+    case EDialog:
+    {
+        iDialog->Cancel();
+        break;
+    }
+    case EGetCert:
+    {
+        iCertStore->CancelGetCert();
+        break;
+    }
+    case ERetrieveCert:
+    {
+        iCertStore->CancelRetrieve();
+        break;
+    }
+    case EFindKey:
+    {
+        iKeyStore->CancelList();
+        break;
+    }
+    case EOpenSigner:
+    {
+        iKeyStore->CancelOpen();
+        break;
+    }
+    case ESign:
+    {
+        if (iRSASigner)
+        {
+            iRSASigner->CancelSign();
+        }
+        if (iDSASigner)
+        {
+            iDSASigner->CancelSign();
+        }
+        break;
+    }
+    default:
+    {
+        // nothing to cancel
+    }
+    }
+    iState = EERROR;
+    iError = KErrCancel;
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::CSTSSignatureService
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CSTSSignatureService::CSTSSignatureService() :
+        CActive(EPriorityStandard), java::util::FunctionServer("MySignatureServer"),
+        iState(EInitialising)
+{
+
+    createServerToNewThread();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::ConstructL()
+{
+    User::LeaveIfError(iFileServer.Connect());
+    iDialog = SecurityDialogFactory::CreateL();
+    iPKIDialog = PKIDialogFactory::CreateNoteL();
+
+    iFilter = CCertAttributeFilter::NewL();
+
+    iWait = new(ELeave) CActiveSchedulerWait;
+    iCertStore = CUnifiedCertStore::NewL(iFileServer, ETrue);
+    iKeyStore = CUnifiedKeyStore::NewL(iFileServer);
+    iCertStore->Initialize(iStatus);
+    WaitForCompletionL();
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::Complete
+// Completes the operation
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::Complete(TInt aError)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::Complete");
+    if (KErrNone == aError)
+    {
+        iState = EReady;
+    }
+    else
+    {
+        iState = EERROR;
+        iError = aError;
+    }
+    iWait->AsyncStop();
+    LOG(ESATSA, EInfo, "-- ret CSTSSignatureService::Complete");
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::WaitForCompletionL()
+// Wait for completion, leave on error
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::WaitForCompletionL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::WaitForCompletionL");
+    SetActive();
+    iWait->Start();
+    if (iState != EReady)
+    {
+        // we need to be ready for the next request
+        iState = EReady;
+
+        User::Leave(iError);
+    }
+    LOG(ESATSA, EInfo, "- ret CSTSSignatureService::WaitForCompletionL");
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::CreateSignatureL()
+// Creates the signature
+// -----------------------------------------------------------------------------
+//
+HBufC8* CSTSSignatureService::CreateSignatureL(const CDesCArray& aCaNames,
+        const TKeyUsageX509 aUsage, const TDesC& aSecurityElementPrompt)
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::CreateSignatureL");
+    HBufC* sePrompt = NULL;
+    if (aSecurityElementPrompt != KNullDesC())
+    {
+        sePrompt = aSecurityElementPrompt.AllocL();
+    }
+    delete iSecurityElementPrompt;
+    iSecurityElementPrompt = sePrompt;
+    LOG(ESATSA, EInfo, "CSTSSignatureService::CreateSignatureL: call findcertificates");
+    FindCertificatesL(aCaNames, aUsage);
+    LOG(ESATSA, EInfo, "CSTSSignatureService::CreateSignatureL: After call to findcertificates");
+    WaitForCompletionL();
+    LOG(ESATSA, EInfo, "CSTSSignatureService::CreateSignatureL: call WaitForCompletion");
+    HBufC8* retVal = iSignature;
+    iSignature = NULL;
+    LOG(ESATSA, EInfo, "-- ret CSTSSignatureService::CreateSignatureL");
+    return retVal;
+}
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::FindCertificatesL()
+// Find applicable certificates
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::FindCertificatesL(const CDesCArray& aCaNames,
+        const TKeyUsageX509 aUsage)
+{
+
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::FindCertificatesL");
+    iFilter->SetKeyUsage(aUsage);
+    iFilter->SetOwnerType(EUserCertificate);
+    iFilter->SetFormat(EX509Certificate);
+
+    iCertInfos.Close();
+
+    TInt caNameCount = aCaNames.Count();
+    if (0 == caNameCount)
+    {
+        // no caNames, so we may use any.
+        iState = EListing;
+        iCertStore->List(iCertInfos, *iFilter, iStatus);
+    }
+    else
+    {
+        // first we need to convert aCaNames to DER encoding
+        // make sure the array is empty
+        iDERNames.Reset();
+        iDERNamesHBufC.ResetAndDestroy();
+
+        TSTSDistinguishedNameConverter dnConverter;
+
+        for (TInt i = 0; i < caNameCount; i++)
+        {
+            CX500DistinguishedName* dName = dnConverter.CreateDNL(aCaNames[i]);
+            CleanupStack::PushL(dName);
+
+            CASN1EncSequence* dnEncoder = dName->EncodeASN1LC();
+            // encode the object in a DER encoding
+            HBufC8* der = HBufC8::NewMaxLC(dnEncoder->LengthDER());
+            TPtr8 pder(der->Des());
+            TUint pos = 0;
+            dnEncoder->WriteDERL(pder, pos);
+            User::LeaveIfError(iDERNamesHBufC.Append(der));
+            CleanupStack::Pop(der);
+            User::LeaveIfError(iDERNames.Append(der));
+            CleanupStack::PopAndDestroy(2); // dnEncoder, dName
+        }
+
+        iState = EListing;
+        iCertStore->List(iCertInfos, *iFilter, iDERNames, iStatus);
+    }
+    LOG(ESATSA, EInfo, "-- ret CSTSSignatureService::FindCertificatesL");
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::HandlesFromCertInfosL()
+// Fills iCertificateArray from iCertInfos.
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::HandlesFromCertInfosL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::HandlesFromCertInfosL");
+    TInt certificateCount = iCertInfos.Count();
+    if (certificateCount == 0)
+    {
+        ELOG(ESATSA, "CSTSSignatureService::HandlesFromCertInfosL, KErrNotFound");
+        User::Leave(KErrNotFound);
+    }
+
+    iCertificateArray.Reset();
+    for (TInt i = 0; i < certificateCount; i++)
+    {
+        LOG(ESATSA, EInfo, "+ CSTSSignatureService::HandlesFromCertInfosL: No Certificates");
+        User::LeaveIfError(iCertificateArray.Append(iCertInfos[i]->Handle()));
+    }
+
+    // next is a dialog shown depending on the authentication type
+    switch (iAuthType)
+    {
+    case EAuthWithoutText:
+    {
+        LOG(ESATSA, EInfo, "CSTSSignatureService::HandlesFromCertInfosL: case EAuthWithoutText");
+        iPKIDialog->UserAuthentication(iCertificateArray, iCertificateHandle,
+                                       iStatus);
+        LOG(ESATSA, EInfo, "CSTSSignatureService::HandlesFromCertInfosL: over case EAuthWithoutText");
+        break;
+    }
+    case EAuthWithText:
+    {
+        LOG(ESATSA, EInfo, "CSTSSignatureService::HandlesFromCertInfosL: case EAuthWithText");
+        iPKIDialog->UserAuthenticationText(*iTextToDisplay, iCertificateArray,
+                                           iCertificateHandle, iStatus);
+        LOG(ESATSA, EInfo, "CSTSSignatureService::HandlesFromCertInfosL: over case EAuthWithText");
+        break;
+    }
+    case ESignWithText:
+    {
+        iDialog->SignText(*iTextToDisplay, iCertificateArray,
+                          iCertificateHandle, iStatus);
+        break;
+    }
+    default:
+    {
+
+    }
+    }
+    iState = EDialog;
+    SetActive();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::FindKeyL()
+// Finds the key used in iCertificate.
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::FindKeyL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::FindKeyL");
+    iKeyFilter.iKeyAlgorithm = CKeyInfoBase::EInvalidAlgorithm;
+    iKeyFilter.iKeyId = iCertificate->SubjectKeyId();
+
+    iKeyFilter.iUsage = EPKCS15UsageAll;
+    iKeys.Close();
+    iState = EFindKey;
+    iKeyStore->List(iKeys, iKeyFilter, iStatus);
+    SetActive();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::OpenSignerL()
+// Opens a signer for the key in iKeys.
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::OpenSignerL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::OpenSignerL");
+    // if key is not found, display security element prompt and search again
+    if (iKeys.Count() == 0)
+    {
+        if (iSecurityElementPrompt)
+        {
+            CSTSSEPrompt* prompt = CSTSSEPrompt::NewLC();
+            prompt->DisplayPromptL(*iSecurityElementPrompt);
+            CleanupStack::PopAndDestroy(prompt);
+            // delete prompt so we only display it once.
+            delete iSecurityElementPrompt;
+            iSecurityElementPrompt = NULL;
+            FindKeyL();
+            return;
+        }
+        else
+        {
+            User::Leave(KErrNotFound);
+        }
+    }
+
+    CCTKeyInfo* keyInfo = iKeys[0];
+
+    if (iRSASigner)
+    {
+        iRSASigner->Release();
+        iRSASigner = NULL;
+    }
+    if (iDSASigner)
+    {
+        iDSASigner->Release();
+        iDSASigner = NULL;
+    }
+
+    iState = EOpenSigner;
+    switch (keyInfo->Algorithm())
+    {
+    case CCTKeyInfo::ERSA:
+    {
+        iKeyStore->Open(keyInfo->Handle(), iRSASigner, iStatus); // codescanner::open
+        break;
+    }
+    case CCTKeyInfo::EDSA:
+    {
+        iKeyStore->Open(keyInfo->Handle(), iDSASigner, iStatus); // codescanner::open
+        break;
+    }
+    default:
+    {
+        User::Leave(KErrNotSupported);
+    }
+    }
+    SetActive();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::SignL()
+// Signs the message
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::SignL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::SignL");
+
+    // first we create a digest of the message
+
+    CSHA1* sha = CSHA1::NewL();
+    CleanupStack::PushL(sha);
+    TPtrC8 hash = sha->Hash(iMessage);
+
+    CCMSX509Certificate* cmsCertificate = CCMSX509Certificate::NewL(
+                                              static_cast<CX509Certificate&>(*iX509Certificate));
+    delete iCMSCertificate;
+    iCMSCertificate = cmsCertificate;
+    CCMSSignerInfo* signerInfo = CCMSSignerInfo::NewL(*cmsCertificate, hash);
+    delete iSignerInfo;
+    iSignerInfo = signerInfo;
+
+    CleanupStack::PopAndDestroy(sha);
+
+    HBufC8* encodedSignedAttributes = iSignerInfo->SignedAttributesEncodedL();
+    CleanupStack::PushL(encodedSignedAttributes);
+
+    sha = CSHA1::NewL();
+    CleanupStack::PushL(sha);
+
+    TPtrC8 attributeHash = sha->Hash(*encodedSignedAttributes);
+
+    // create digest info
+    CASN1EncSequence* digestInfo = CASN1EncSequence::NewLC();
+    CASN1EncSequence* digestAlgId = CASN1EncSequence::NewLC();
+    CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KSHA1);
+    digestAlgId->AddAndPopChildL(oid);
+    CASN1EncNull* params = CASN1EncNull::NewLC();
+    digestAlgId->AddAndPopChildL(params);
+    digestInfo->AddAndPopChildL(digestAlgId);
+    CASN1EncOctetString* hashEncoder =
+        CASN1EncOctetString::NewLC(attributeHash);
+    digestInfo->AddAndPopChildL(hashEncoder);
+
+    HBufC8* encodedHash = HBufC8::NewMaxL(digestInfo->LengthDER());
+    delete iEncodedSignedAttributesHash;
+    iEncodedSignedAttributesHash = encodedHash;
+    iEncodedSignedAttributesHashPointer.Set(*encodedHash);
+    TPtr8 pder(encodedHash->Des());
+    TUint pos = 0;
+    digestInfo->WriteDERL(pder, pos);
+
+    CleanupStack::PopAndDestroy(digestInfo);
+    CleanupStack::PopAndDestroy(sha);
+    CleanupStack::PopAndDestroy(encodedSignedAttributes);
+
+    CCTKeyInfo* keyInfo = iKeys[0];
+
+    delete iRSASignature;
+    iRSASignature = NULL;
+    delete iDSASignature;
+    iDSASignature = NULL;
+
+    iState = ESign;
+    switch (keyInfo->Algorithm())
+    {
+    case CCTKeyInfo::ERSA:
+    {
+        iRSASigner->Sign(iEncodedSignedAttributesHashPointer, iRSASignature,
+                         iStatus);
+        break;
+    }
+    case CCTKeyInfo::EDSA:
+    {
+        iDSASigner->Sign(iEncodedSignedAttributesHashPointer, iDSASignature,
+                         iStatus);
+        break;
+    }
+    default:
+    {
+        User::Leave(KErrNotSupported);
+    }
+    }
+
+    SetActive();
+
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::CreateSignedDataL()
+// Creates signed data
+// -----------------------------------------------------------------------------
+//
+void CSTSSignatureService::CreateSignedDataL()
+{
+    LOG(ESATSA, EInfo, "+ CSTSSignatureService::CreateSignedDataL");
+    CCTKeyInfo* keyInfo = iKeys[0];
+
+    HBufC8* signature = NULL;
+    switch (keyInfo->Algorithm())
+    {
+    case CCTKeyInfo::ERSA:
+    {
+
+        signature = iRSASignature->S().BufferLC();
+        break;
+    }
+    case CCTKeyInfo::EDSA:
+    {
+
+        CASN1EncSequence* signatureEncoder = CASN1EncSequence::NewLC();
+        CASN1EncBigInt* rEncoder = CASN1EncBigInt::NewLC(iDSASignature->R());
+        signatureEncoder->AddAndPopChildL(rEncoder);
+        CASN1EncBigInt* sEncoder = CASN1EncBigInt::NewLC(iDSASignature->S());
+        signatureEncoder->AddAndPopChildL(sEncoder);
+        signature = HBufC8::NewMaxLC(signatureEncoder->LengthDER());
+        TPtr8 signatureDes = signature->Des();
+        TUint pos = 0;
+        signatureEncoder->WriteDERL(signatureDes, pos);
+        CleanupStack::Pop(signature);
+        CleanupStack::PopAndDestroy(signatureEncoder);
+        CleanupStack::PushL(signature);
+        break;
+    }
+    default:
+    {
+        User::Leave(KErrNotSupported);
+    }
+    }
+
+    iSignerInfo->SetSignatureValueL(*signature);
+    CArrayPtr<CCMSSignerInfo>* signerInfos = new(ELeave) CArrayPtrFlat<
+    CCMSSignerInfo> (KDefaultGranularity);
+    CleanupStack::PushL(signerInfos);
+    signerInfos->AppendL(iSignerInfo);
+
+    CArrayPtr<CCMSX509AlgorithmIdentifier>
+    * digestAlgorithmIdentifiers = new(ELeave) CArrayPtrFlat<
+    CCMSX509AlgorithmIdentifier> (KDefaultGranularity);
+    CleanupStack::PushL(digestAlgorithmIdentifiers);
+
+    CCMSX509AlgorithmIdentifier
+    * digestAlgorithm =
+        CCMSX509AlgorithmIdentifier::NewL(
+            iSignerInfo->DigestAlgorithmIdentifier().AlgorithmIdentifier());
+    CleanupStack::PushL(digestAlgorithm);
+
+    digestAlgorithmIdentifiers->AppendL(digestAlgorithm);
+
+    CCMSEncapsulatedContentInfo* contentInfo = NULL;
+    if ((iOptions & KOptionIncludeContent) != 0)
+    {
+        contentInfo = CCMSEncapsulatedContentInfo::NewLC(KIdData(), &iMessage);
+    }
+    else
+    {
+        contentInfo = CCMSEncapsulatedContentInfo::NewLC(KIdData(), NULL);
+    }
+
+    CCMSSignedData* signedData = CCMSSignedData::NewLC(
+                                     *digestAlgorithmIdentifiers, *contentInfo, *signerInfos);
+
+    if ((iOptions & KOptionIncludeCertificate) != 0)
+    {
+        CCMSCertificateChoices* choices = CCMSCertificateChoices::NewLC(
+                                              *iCMSCertificate);
+        CArrayPtr<CCMSCertificateChoices>* certificates =
+            new(ELeave) CArrayPtrFlat<CCMSCertificateChoices> (1);
+        CleanupStack::PushL(certificates);
+        certificates->AppendL(choices);
+        signedData->SetCertificatesL(certificates);
+        CleanupStack::PopAndDestroy(2); // certificates, choices
+    }
+
+    HBufC8* plainSignature = NULL;
+    signedData->EncodeL(plainSignature);
+    CleanupStack::PushL(plainSignature);
+
+    CCMSContentInfo* encapsulatedSignature = CCMSContentInfo::NewLC(
+                KIdSignedData(), *plainSignature);
+
+    delete iSignature;
+    iSignature = NULL;
+
+    encapsulatedSignature->EncodeL(iSignature);
+
+    CleanupStack::PopAndDestroy(8);
+    if (iShowNotes)
+    {
+        iState = EFinalNote;
+        iPKIDialog->Note(MPKIDialog::ESignatureDone, iStatus);
+        SetActive();
+    }
+    else
+    {
+        Complete(KErrNone);
+    }
+    LOG(ESATSA, EInfo, "-- ret CSTSSignatureService::CreateSignedDataL");
+}
+
+// -----------------------------------------------------------------------------
+// CSTSSignatureService::ConvertUTF8ToUnicodeLC()
+// Converts UTF8 data to Unicode
+// -----------------------------------------------------------------------------
+//
+HBufC* CSTSSignatureService::ConvertUTF8ToUnicodeL(const TDesC8& aUTF8String)
+{
+    CCnvCharacterSetConverter* converter = CCnvCharacterSetConverter::NewLC();
+
+    CCnvCharacterSetConverter::TAvailability charSetAvailable =
+        converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8,
+                                             iFileServer);
+
+    if (CCnvCharacterSetConverter::EAvailable != charSetAvailable)
+    {
+        User::Leave(KErrGeneral);
+    }
+
+    TInt state = CCnvCharacterSetConverter::KStateDefault;
+
+    HBufC* textToDisplay = HBufC::NewMaxLC(aUTF8String.Length());
+
+    TPtr16 textToDisplayDes = textToDisplay->Des();
+
+    TInt error = converter->ConvertToUnicode(textToDisplayDes, aUTF8String,
+                 state);
+    User::LeaveIfError(error);
+    CleanupStack::Pop(textToDisplay);
+    CleanupStack::PopAndDestroy(converter);
+    return textToDisplay;
+}
+
+//  End of File
+
+void CSTSSignatureService::vmAttached()
+{
+
+}
+
+void CSTSSignatureService::doServerSideInit()
+{
+
+    FunctionServer::doServerSideInit();
+
+}
+
+