vpnengine/pkiservice/src/keyoperationprovider.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Class, which provides keypair operations.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <asymmetric.h>
       
    20 
       
    21 #include "keyoperationprovider.h"
       
    22 #include "pkiservicesigner.h"
       
    23 #include "pkiservicedecryptor.h"
       
    24 #include "pkisession.h"
       
    25 #include "pkidefs.h"
       
    26 #include "logonservices.h"
       
    27 #include "keymanager.h"
       
    28 #include "pkiserviceassert.h"
       
    29 #include "keyoperationqueue.h"
       
    30 
       
    31 static const TInt KTimeoutNever = -1;
       
    32 
       
    33 CKeyPairOperationProvider* CKeyPairOperationProvider::NewL(CKeyOperationQueue& aKeyOperationQueue)
       
    34     {
       
    35     CKeyPairOperationProvider* self = new (ELeave)CKeyPairOperationProvider(aKeyOperationQueue);
       
    36     CleanupStack::PushL(self);
       
    37     self->ConstructL();
       
    38     CleanupStack::Pop(self);
       
    39     
       
    40     return self;
       
    41     }
       
    42 
       
    43 
       
    44 CKeyPairOperationProvider::CKeyPairOperationProvider(CKeyOperationQueue& aKeyOperationQueue) 
       
    45 :CActive(EPriorityStandard), iKeyOperationQueue(aKeyOperationQueue), iOutputDataPtr(NULL, 0)
       
    46     {
       
    47     CActiveScheduler::Add(this);
       
    48     }
       
    49 
       
    50 
       
    51 void CKeyPairOperationProvider::ConstructL()
       
    52     {    
       
    53     User::LeaveIfError(iFileServer.Connect());
       
    54     iUnifiedKeyStore = CUnifiedKeyStore::NewL(iFileServer);        
       
    55     iLogonService = CLogonServices::NewL(*iUnifiedKeyStore);
       
    56     iKeyManager = CKeyManager::NewL(*iLogonService);
       
    57     iPkiSigner = CPkiServiceSigner::NewL(*iLogonService);
       
    58     iPkiDecryptor = CPkiServiceDecryptor::NewL(*iLogonService);
       
    59     }
       
    60 
       
    61 
       
    62 CKeyPairOperationProvider::~CKeyPairOperationProvider()
       
    63     {
       
    64     Cancel();
       
    65     
       
    66     delete iPkiDecryptor;
       
    67     delete iPkiSigner;
       
    68     delete iKeyManager;
       
    69     delete iLogonService;
       
    70     delete iUnifiedKeyStore;
       
    71     iFileServer.Close();
       
    72     }
       
    73 
       
    74 
       
    75 void CKeyPairOperationProvider::Initialize()
       
    76 	{	
       
    77 	PKISERVICE_ASSERT(!IsActive());
       
    78 	PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);
       
    79 	
       
    80 	iKeyOperation = EKeyOperationInitialize;
       
    81 	if (!iIsInitialized)
       
    82     	{	    	    
       
    83     	iUnifiedKeyStore->Initialize(iStatus);
       
    84     	SetActive();
       
    85     	}
       
    86     else
       
    87         {
       
    88         TRequestStatus* ownStatus = &iStatus;
       
    89         *ownStatus = KRequestPending;        
       
    90         SetActive();
       
    91         User::RequestComplete(ownStatus, KErrNone);
       
    92         }
       
    93 	}
       
    94 
       
    95 
       
    96 void CKeyPairOperationProvider::GetKeyPairList(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore)
       
    97 	{
       
    98 	PKISERVICE_ASSERT(iIsInitialized);
       
    99     PKISERVICE_ASSERT(!IsActive());	
       
   100 	PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   101 	
       
   102 	iKeyOperation = EKeyOperationGetKeyList;
       
   103 	iUsedKeyStore = aUsedKeyStore;
       
   104 	
       
   105     TCTKeyAttributeFilter filter;    
       
   106     if (aKeyId.Length() > 0)
       
   107         {        
       
   108         filter.iKeyId = aKeyId;
       
   109         }
       
   110     
       
   111 	iUnifiedKeyStore->List(iKeysList, filter, iStatus);
       
   112 	SetActive();
       
   113 	}
       
   114 
       
   115 
       
   116 void CKeyPairOperationProvider::Decrypt(const TPKIKeyIdentifier& aKeyId,
       
   117                                         TInt aUsedKeyStore,
       
   118                                         HBufC8* aEncryptedData,
       
   119                                         TInt aOutputLength)
       
   120     {
       
   121     PKISERVICE_ASSERT(iIsInitialized);
       
   122     PKISERVICE_ASSERT(!IsActive());    
       
   123 	PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);
       
   124     PKISERVICE_ASSERT(aKeyId.Length() > 0);
       
   125         
       
   126     iKeyOperation = EKeyOperationDecrypting;
       
   127     TRAPD(err, DecryptL(aKeyId, aUsedKeyStore, aEncryptedData, aOutputLength));
       
   128     if (err != KErrNone)
       
   129         {
       
   130         iStatus = KRequestPending;
       
   131         TRequestStatus* ownStatus = &iStatus;
       
   132         SetActive();
       
   133         
       
   134         User::RequestComplete(ownStatus, err);
       
   135         }   
       
   136     }
       
   137 
       
   138 
       
   139 void CKeyPairOperationProvider::DecryptL(const TPKIKeyIdentifier& aKeyId,
       
   140                                          TInt aUsedKeyStore,
       
   141                                          HBufC8* aEncryptedData,
       
   142                                          TInt aOutputLength)
       
   143     {
       
   144     PKISERVICE_ASSERT(iKeysList.Count() == 0);
       
   145     PKISERVICE_ASSERT(iInputData == NULL);
       
   146     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationDecrypting);        
       
   147           
       
   148     iInputData = aEncryptedData;
       
   149     iOutputData = HBufC8::NewL(aOutputLength);
       
   150     iOutputDataPtr.Set(iOutputData->Des());
       
   151     
       
   152     iPkiDecryptor->Decrypt(aKeyId,
       
   153                            *iInputData,
       
   154                            iOutputDataPtr,
       
   155                            *iUnifiedKeyStore,
       
   156                            aUsedKeyStore,
       
   157                            iStatus);
       
   158                             
       
   159     SetActive();                                
       
   160     }
       
   161 
       
   162 
       
   163 void CKeyPairOperationProvider::Sign(const TPKIKeyIdentifier& aKeyId,
       
   164                                      TInt aUsedKeyStore,
       
   165                                      HBufC8* aDataToBeSigned)
       
   166     {
       
   167     PKISERVICE_ASSERT(iIsInitialized);
       
   168     PKISERVICE_ASSERT(!IsActive());    
       
   169 	PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);
       
   170     PKISERVICE_ASSERT(aKeyId.Length() > 0);    
       
   171     PKISERVICE_ASSERT(iKeysList.Count() == 0);
       
   172     PKISERVICE_ASSERT(iInputData == NULL);
       
   173     
       
   174     
       
   175     iKeyOperation = EKeyOperationSigning;
       
   176     iInputData = aDataToBeSigned;
       
   177     
       
   178     iPkiSigner->Sign(aKeyId,
       
   179                      *iInputData,
       
   180                      iOutputData,
       
   181                      *iUnifiedKeyStore,
       
   182                      aUsedKeyStore,
       
   183                      iStatus);
       
   184     SetActive();                  
       
   185     }
       
   186 
       
   187 
       
   188 void CKeyPairOperationProvider::Logon()
       
   189     {
       
   190     PKISERVICE_ASSERT(iIsInitialized);
       
   191     PKISERVICE_ASSERT(!IsActive()); 
       
   192     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);           
       
   193     
       
   194     iKeyOperation = EKeyOperationLogon;
       
   195     iLogonService->Logon(iStatus);
       
   196     SetActive();		
       
   197     }
       
   198 
       
   199 
       
   200 void CKeyPairOperationProvider::Logoff()
       
   201     {
       
   202     PKISERVICE_ASSERT(iIsInitialized);
       
   203     PKISERVICE_ASSERT(!IsActive());    
       
   204     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   205    
       
   206     iKeyOperation = EKeyOperationLogoff;
       
   207     iLogonService->Logoff(iStatus);
       
   208     SetActive();		        
       
   209     }
       
   210 
       
   211 
       
   212 void CKeyPairOperationProvider::ChangePassword()
       
   213     {
       
   214     PKISERVICE_ASSERT(iIsInitialized);
       
   215     PKISERVICE_ASSERT(!IsActive());    
       
   216     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   217    
       
   218     if (iLogonService->LogonCompleted())
       
   219         {
       
   220         iKeyOperation = EKeyOperationChangingPassword;
       
   221         iLogonService->ChangePassword(iStatus);
       
   222         }
       
   223     else
       
   224         {
       
   225         iKeyOperation = EKeyOperationLogonForChangePassword;
       
   226         iLogonService->Logon(iStatus);
       
   227         }    
       
   228         
       
   229     SetActive();        
       
   230     }
       
   231 
       
   232 
       
   233 void CKeyPairOperationProvider::RemoveKeyPair(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore)
       
   234     {
       
   235     PKISERVICE_ASSERT(iIsInitialized);
       
   236     PKISERVICE_ASSERT(!IsActive());    
       
   237     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   238 
       
   239     iKeyOperation = EKeyOperationRemoveKeyPair;
       
   240     
       
   241     iKeyManager->RemoveKeyPair(aKeyId, *iUnifiedKeyStore, aUsedKeyStore, iStatus);
       
   242     SetActive();
       
   243     }
       
   244 
       
   245 
       
   246 void CKeyPairOperationProvider::GenerateKeyPair(const TUint aKeySize, 
       
   247                                                 TPKIKeyAlgorithm aKeyAlgorithm,
       
   248                                                 TInt aUsedKeyStore)
       
   249     {
       
   250     PKISERVICE_ASSERT(iIsInitialized);
       
   251     PKISERVICE_ASSERT(!IsActive());    
       
   252     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   253 
       
   254     iKeyOperation = EKeyOperationGeneratingKeyPair;
       
   255     
       
   256     iKeyManager->GenerateKeyPair(*iUnifiedKeyStore, aUsedKeyStore, aKeySize, 
       
   257                                  aKeyAlgorithm, iKeyId, iStatus);
       
   258     SetActive();   
       
   259     }
       
   260 
       
   261 
       
   262 void CKeyPairOperationProvider::ImportKeyPair(HBufC8* aKeyData, TInt aUsedKeyStore)
       
   263     {
       
   264     PKISERVICE_ASSERT(iIsInitialized);
       
   265     PKISERVICE_ASSERT(!IsActive());    
       
   266     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   267 
       
   268     iKeyOperation = EKeyOperationImportingKeyPair;
       
   269     iInputData = aKeyData;    
       
   270     
       
   271     iKeyManager->ImportKeyPair(*iUnifiedKeyStore, aUsedKeyStore, *iInputData, iKeyId, iStatus);
       
   272     SetActive();       
       
   273     }
       
   274 
       
   275 
       
   276 void CKeyPairOperationProvider::GetPublicKey(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore)
       
   277     {	
       
   278     PKISERVICE_ASSERT(iIsInitialized);
       
   279     PKISERVICE_ASSERT(!IsActive());    
       
   280     PKISERVICE_ASSERT(iKeyOperation == EKeyOperationIdle);    
       
   281 
       
   282     iKeyOperation = EKeyOperationPublicKeyExport;
       
   283     
       
   284     iKeyManager->ExportPublicKey(*iUnifiedKeyStore, aUsedKeyStore, aKeyId, iOutputData, iStatus);
       
   285     SetActive();       	
       
   286     }
       
   287 
       
   288 
       
   289 
       
   290 void CKeyPairOperationProvider::RunL()
       
   291 	{
       
   292 	switch(iKeyOperation)
       
   293 		{
       
   294 		case EKeyOperationInitialize:
       
   295 		    {		        
       
   296 			iKeyOperation = EKeyOperationIdle;	
       
   297 			TInt err = iStatus.Int();		
       
   298 			if (err == KErrNone)
       
   299 				{
       
   300 				if (!iIsInitialized)
       
   301     				{				    
       
   302     				iKeyOperation = EKeyOperationSetPassPhraseTimeout;
       
   303     			    iUnifiedKeyStore->SetPassphraseTimeout(KTimeoutNever, iStatus);	
       
   304     			    SetActive();
       
   305     				}
       
   306                 else
       
   307                     {//keystore is already initialized
       
   308                     iKeyOperationQueue.KeyStoreInitComplete(err);
       
   309                     }
       
   310 				}          
       
   311             else
       
   312                 {                    				  				
       
   313 			    iKeyOperationQueue.KeyStoreInitComplete(err);
       
   314                 }
       
   315 		    }
       
   316 			break;
       
   317         case EKeyOperationSetPassPhraseTimeout:
       
   318             iKeyOperation = EKeyOperationIdle;
       
   319             if (iStatus.Int() == KErrNone)
       
   320                 {
       
   321                 iIsInitialized = ETrue;
       
   322                 }
       
   323             iKeyOperationQueue.KeyStoreInitComplete(iStatus.Int());
       
   324             break;			
       
   325 		case EKeyOperationGetKeyList:
       
   326 		    {		        
       
   327 			PKISERVICE_ASSERT(iIsInitialized);
       
   328 			iKeyOperation = EKeyOperationIdle;
       
   329 			
       
   330 			CArrayFixFlat<TKeyListEntry>* list = NULL;
       
   331 			TInt err = iStatus.Int();
       
   332 			if (err == KErrNone)
       
   333     			{			    
       
   334     			TRAP(err, list = MakeKeyEntryListL(iKeysList, iUsedKeyStore));
       
   335     			}
       
   336             CleanupCryptoOperation();   			
       
   337 			iKeyOperationQueue.KeyPairListComplete(err, list);
       
   338 		    }
       
   339 			break;
       
   340         case EKeyOperationDecrypting:
       
   341             {                
       
   342             PKISERVICE_ASSERT(iIsInitialized);            
       
   343             iKeyOperation = EKeyOperationIdle;                       
       
   344             HBufC8* plainTextData = NULL;
       
   345             if (iStatus.Int() == KErrNone)
       
   346                 {       
       
   347                 plainTextData = iOutputData;
       
   348                 iOutputData = NULL;                
       
   349                 }                
       
   350             CleanupCryptoOperation();
       
   351             iKeyOperationQueue.DecryptComplete(iStatus.Int(), plainTextData);
       
   352             }
       
   353             break;     
       
   354         case EKeyOperationSigning:
       
   355             {                
       
   356             PKISERVICE_ASSERT(iIsInitialized);                       
       
   357             iKeyOperation = EKeyOperationIdle;
       
   358             HBufC8* data = iOutputData;
       
   359             iOutputData = NULL;
       
   360             CleanupCryptoOperation(); 
       
   361             iKeyOperationQueue.SignComplete(iStatus.Int(), data);                             
       
   362             }
       
   363             break; 
       
   364         case EKeyOperationPublicKeyExport:
       
   365             {
       
   366             PKISERVICE_ASSERT(iIsInitialized);            
       
   367             iKeyOperation = EKeyOperationIdle;     
       
   368                         
       
   369             PKISERVICE_ASSERT((iStatus.Int() == KErrNone && iOutputData != NULL) ||
       
   370                            (iStatus.Int() != KErrNone && iOutputData == NULL));
       
   371                                                       
       
   372             HBufC8* publicKeyData = iOutputData;
       
   373             iOutputData = NULL;
       
   374             CleanupCryptoOperation();                 
       
   375             iKeyOperationQueue.GetPublicKeyCompleted(iStatus.Int(), publicKeyData);                                      
       
   376             }
       
   377             break;
       
   378 		case EKeyOperationLogon:
       
   379 		    iKeyOperation = EKeyOperationIdle;     
       
   380             iKeyOperationQueue.LogonCompleted(iStatus.Int());
       
   381 		    break;
       
   382 		case EKeyOperationLogoff:
       
   383 		    iKeyOperation = EKeyOperationIdle;     
       
   384 		    iKeyOperationQueue.LogoffCompleted(iStatus.Int());
       
   385             break;
       
   386 		case EKeyOperationLogonForChangePassword:
       
   387 		    iKeyOperation = EKeyOperationIdle;     
       
   388 		    if (iStatus.Int() == KErrNone)
       
   389     		    {
       
   390     		    iKeyOperation = EKeyOperationChangingPassword;  
       
   391     		    iLogonService->ChangePassword(iStatus);
       
   392     		    SetActive();
       
   393     		    }
       
   394 		    else
       
   395 		        {
       
   396 		        iKeyOperationQueue.PasswordChangeCompleted(iStatus.Int());
       
   397 		        }
       
   398 		    break;
       
   399 		case EKeyOperationChangingPassword: 
       
   400 		    iKeyOperation = EKeyOperationIdle;     
       
   401 		    iKeyOperationQueue.PasswordChangeCompleted(iStatus.Int());
       
   402             break;
       
   403 		case EKeyOperationRemoveKeyPair:
       
   404 		    iKeyOperation = EKeyOperationIdle;     
       
   405 		    iKeyOperationQueue.KeyPairRemoveCompleted(iStatus.Int());
       
   406 		    break;
       
   407         case EKeyOperationGeneratingKeyPair:
       
   408             {                
       
   409             iKeyOperation = EKeyOperationIdle;
       
   410             TPKIKeyIdentifier keyId = iKeyId;
       
   411             iKeyId.Zero();
       
   412             iKeyOperationQueue.KeyGenerationCompleted(iStatus.Int(), keyId);        		                
       
   413             }
       
   414             break;
       
   415         case EKeyOperationImportingKeyPair:
       
   416             {
       
   417             delete iInputData;
       
   418             iInputData = NULL;
       
   419             iKeyOperation = EKeyOperationIdle;
       
   420             TPKIKeyIdentifier keyId = iKeyId;
       
   421             iKeyId.Zero();
       
   422             iKeyOperationQueue.StoreKeyPairCompleted(iStatus.Int(), keyId);        		                            
       
   423             }
       
   424             break;
       
   425 		default:
       
   426 			PKISERVICE_INVARIANT();
       
   427 		}
       
   428 	}
       
   429 
       
   430 
       
   431 void CKeyPairOperationProvider::DoCancel()
       
   432 	{		
       
   433 	switch(iKeyOperation)
       
   434 		{
       
   435 		case EKeyOperationInitialize:
       
   436 			PKISERVICE_ASSERT(!iIsInitialized);
       
   437 			iUnifiedKeyStore->CancelInitialize();
       
   438 			break;
       
   439         case EKeyOperationSetPassPhraseTimeout:
       
   440             iUnifiedKeyStore->CancelSetPassphraseTimeout();
       
   441             break;
       
   442 		case EKeyOperationGetKeyList:
       
   443 			PKISERVICE_ASSERT(iIsInitialized);
       
   444 			iUnifiedKeyStore->CancelList();
       
   445 			break;
       
   446 		case EKeyOperationDecrypting:		    
       
   447 		    //Deletes and cancels the decryptor also
       
   448             CleanupCryptoOperation();            		    
       
   449             break;		        
       
   450         case EKeyOperationSigning:
       
   451             //Deletes and cancels the signer also.
       
   452             CleanupCryptoOperation();
       
   453             break;
       
   454 		case EKeyOperationLogon: //falls through
       
   455 		case EKeyOperationLogoff: //falls through
       
   456 		case EKeyOperationLogonForChangePassword: //falls through
       
   457 		case EKeyOperationChangingPassword: 
       
   458 		    iLogonService->Cancel();
       
   459 		    break;
       
   460 		case EKeyOperationRemoveKeyPair: //falls through
       
   461 		case EKeyOperationGeneratingKeyPair://falls through
       
   462         case EKeyOperationImportingKeyPair://falls through
       
   463         case EKeyOperationPublicKeyExport:        
       
   464 		    iKeyManager->Cancel();
       
   465 		    break;
       
   466 		default:
       
   467 			PKISERVICE_INVARIANT();
       
   468 		}
       
   469     iKeyOperation = EKeyOperationIdle;		
       
   470 	}
       
   471 
       
   472 
       
   473 TInt CKeyPairOperationProvider::RunError(TInt aError)
       
   474 	{
       
   475 	//This is not be called, because the RunL doesn't
       
   476 	//leave.
       
   477 	PKISERVICE_INVARIANT();
       
   478 	return aError;
       
   479 	}
       
   480 
       
   481 
       
   482 CArrayFixFlat<TKeyListEntry>* CKeyPairOperationProvider::MakeKeyEntryListL(RMPointerArray<CCTKeyInfo> aKeysList,
       
   483                                                                            TInt aUsedKeyStore) const
       
   484     {
       
   485     CArrayFixFlat<TKeyListEntry>* list = new (ELeave) CArrayFixFlat<TKeyListEntry>(2);
       
   486     CleanupStack::PushL(list);
       
   487         
       
   488     for (TInt i = 0; i < aKeysList.Count(); ++i)
       
   489         {
       
   490         const CCTKeyInfo* info = aKeysList[i];
       
   491         if (aUsedKeyStore == 0 ||
       
   492             aUsedKeyStore == aKeysList[i]->Token().TokenType().Type().iUid)
       
   493             {
       
   494             TKeyListEntry keyInfo;	        
       
   495             keyInfo.iObjectName = info->Label();
       
   496             keyInfo.iSubjectKeyId = info->ID();
       
   497             keyInfo.iKeySize = info->Size();                  // Key size                            
       
   498             switch(info->Algorithm())
       
   499                 {
       
   500                 case CCTKeyInfo::ERSA:
       
   501                 	keyInfo.iKeyAlgorithm = EPKIRSA;
       
   502                 	break;
       
   503                 case CCTKeyInfo::EDSA:
       
   504                 	keyInfo.iKeyAlgorithm = EPKIDSA;
       
   505                 	break;
       
   506                 case CCTKeyInfo::EDH:
       
   507                 	keyInfo.iKeyAlgorithm = EPKIDH;
       
   508                 	break;
       
   509                 default:	         
       
   510                 	keyInfo.iKeyAlgorithm = EPKIInvalidAlgorithm;
       
   511                 	break;
       
   512                 }            
       
   513             list->AppendL(keyInfo);
       
   514             }        
       
   515         }    
       
   516     CleanupStack::Pop(list);    
       
   517     return list;
       
   518     }
       
   519 
       
   520 
       
   521 
       
   522 void CKeyPairOperationProvider::CleanupCryptoOperation()
       
   523     {                
       
   524     delete iInputData;
       
   525     iInputData = NULL;
       
   526     
       
   527     delete iOutputData;
       
   528     iOutputData = NULL;
       
   529     iKeysList.Close();            		        
       
   530     }
       
   531 
       
   532