vpnengine/pkiservice/src/keyoperationqueue.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:   A task que to serialize the key operations among session.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "keyoperationqueue.h"
       
    21 #include "pkiserviceclientservercommon.h"
       
    22 #include "keyoperationprovider.h"
       
    23 #include "PKIMapper.h"
       
    24 #include "pkisession.h"
       
    25 #include "pkiserviceassert.h"
       
    26 
       
    27 #include "log_r6.h"
       
    28 
       
    29 CKeyOperationQueue::TKeyOperation::TKeyOperation(CPKISession& aOwner, 
       
    30                                                  const RMessage2& aMessage,
       
    31                                                  TInt aUsedKeyStore,
       
    32                                                  TPkiServiceStoreType aUsedCertStore)
       
    33 :iOwner(aOwner), iMessage(aMessage), iUsedKeyStore(aUsedKeyStore), iUsedCertStore(aUsedCertStore)
       
    34     {
       
    35     }
       
    36 
       
    37 
       
    38 
       
    39 CKeyOperationQueue* CKeyOperationQueue::NewL(CPKIMapper& aMapper)
       
    40     {
       
    41     CKeyOperationQueue* self = new (ELeave) CKeyOperationQueue(aMapper);
       
    42     CleanupStack::PushL(self);
       
    43     self->ConstructL();
       
    44     CleanupStack::Pop(self);
       
    45     
       
    46     return self;
       
    47     }
       
    48 
       
    49 
       
    50 CKeyOperationQueue::CKeyOperationQueue(CPKIMapper& aMapper)
       
    51 :iMapper(aMapper)
       
    52     {
       
    53     }
       
    54 
       
    55 
       
    56 void CKeyOperationQueue::ConstructL()
       
    57     {
       
    58     iKeyOperationProvider = CKeyPairOperationProvider::NewL(*this);
       
    59     }
       
    60 
       
    61 CKeyOperationQueue::~CKeyOperationQueue()
       
    62     {
       
    63     PKISERVICE_ASSERT(iOperationQue.Count() == 0);
       
    64     PKISERVICE_ASSERT(iCurrentOperation == NULL);
       
    65 
       
    66     delete iKeyOperationProvider;    
       
    67     iOperationQue.Close();
       
    68     }
       
    69 
       
    70 
       
    71 
       
    72 void CKeyOperationQueue::AddOperationL(CPKISession& aOwner, 
       
    73                                      const RMessage2& aMessage,
       
    74                                      TInt aUsedKeyStore,
       
    75                                      TPkiServiceStoreType aUsedCertStore)
       
    76     {
       
    77     TKeyOperation* operation = new (ELeave) TKeyOperation(aOwner, aMessage, 
       
    78                                                           aUsedKeyStore, aUsedCertStore);
       
    79     CleanupDeletePushL(operation);
       
    80     User::LeaveIfError(iOperationQue.Append(operation));
       
    81     CleanupStack::Pop(operation);
       
    82 
       
    83     if (iCurrentOperation == NULL)
       
    84         {
       
    85         PKISERVICE_ASSERT(iOperationQue.Count() == 1);
       
    86         //No operations in progress.
       
    87         //Handle the new one.
       
    88         StartNextOperation();
       
    89         }
       
    90     }
       
    91 
       
    92 
       
    93 
       
    94 
       
    95 void CKeyOperationQueue::StartNextOperation()
       
    96     {
       
    97     PKISERVICE_ASSERT(iOperationQue.Count() > 0);
       
    98     PKISERVICE_ASSERT(iCurrentOperation == NULL);
       
    99 
       
   100     iCurrentOperation = iOperationQue[0];
       
   101     iOperationQue.Remove(0);
       
   102     
       
   103     TRAPD(err, ServiceL(*iCurrentOperation));
       
   104     if (err != KErrNone)
       
   105         {
       
   106         iCurrentOperation->iMessage.Complete(err);
       
   107         iCurrentOperation = NULL;
       
   108         
       
   109         if (iOperationQue.Count() > 0)
       
   110             {
       
   111             StartNextOperation();
       
   112             }
       
   113         }
       
   114     }
       
   115 
       
   116 
       
   117 void CKeyOperationQueue::ServiceL(TKeyOperation& aOperation)
       
   118     {
       
   119     switch(aOperation.iMessage.Function())
       
   120         {        
       
   121         case PkiService::EInitialize:
       
   122             iKeyOperationProvider->Initialize();
       
   123             break;                                                           
       
   124         case PkiService::EKeyCount:    
       
   125             {                
       
   126             TPKIKeyIdentifier keyId;
       
   127             keyId.Zero();
       
   128                                             	
       
   129         	iKeyOperationProvider->GetKeyPairList(keyId, aOperation.iUsedKeyStore);
       
   130             }
       
   131             break;                        
       
   132     		
       
   133         case PkiService::EGetKeyDetails:
       
   134     		{            
       
   135     		TPKIKeyIdentifier keyId;
       
   136     		aOperation.iMessage.ReadL(1, keyId);
       
   137         
       
   138         	iKeyOperationProvider->GetKeyPairList(keyId, aOperation.iUsedKeyStore);    		    		    		    		    		
       
   139     		}
       
   140     		break;    		
       
   141         case PkiService::EDecrypt:
       
   142             {                        
       
   143             TPKIKeyIdentifier keyId;
       
   144             aOperation.iMessage.ReadL(0, keyId);
       
   145             
       
   146             if (keyId.Length() > 0)
       
   147                 {                                
       
   148                 HBufC8* encryptedData = HBufC8::NewLC(aOperation.iMessage.GetDesLength(1));
       
   149                 TPtr8 encryptedDataPtr = encryptedData->Des();
       
   150                 aOperation.iMessage.ReadL(1, encryptedDataPtr);
       
   151                 
       
   152                 CleanupStack::Pop(encryptedData);
       
   153                 //Transfer the ownership of the encryptedData
       
   154                 
       
   155                 TInt outputBufferMaxLength = aOperation.iMessage.GetDesMaxLength(2);
       
   156                 User::LeaveIfError(outputBufferMaxLength);
       
   157                 iKeyOperationProvider->Decrypt(keyId, aOperation.iUsedKeyStore, encryptedData,
       
   158                                                outputBufferMaxLength);                
       
   159                 }
       
   160             else
       
   161                 {
       
   162                 CompleteCurrentOperation(KPKIErrNotFound);
       
   163                 }
       
   164             }
       
   165             break;
       
   166         case PkiService::ESignWithKeyId:
       
   167             {         
       
   168             TPKIKeyIdentifier keyId;
       
   169             aOperation.iMessage.ReadL(0, keyId);
       
   170             
       
   171             if (keyId.Length() > 0)
       
   172                 {
       
   173                 HBufC8* dataIn = HBufC8::NewLC(aOperation.iMessage.GetDesLength(1));
       
   174                 TPtr8 dataInPtr = dataIn->Des();
       
   175                 aOperation.iMessage.ReadL(1, dataInPtr);                
       
   176                 
       
   177                 //transfers the dataIn buffer ownership  
       
   178                 CleanupStack::Pop(dataIn);              
       
   179                 iKeyOperationProvider->Sign(keyId, aOperation.iUsedKeyStore, dataIn);                
       
   180                 }
       
   181             else
       
   182                 {
       
   183                 CompleteCurrentOperation(KPKIErrNotFound);
       
   184                 }          
       
   185             }
       
   186             break;
       
   187         case PkiService::ESignWithCert:
       
   188             {
       
   189             TSecurityObjectDescriptor *securityObjectDesc = new (ELeave) TSecurityObjectDescriptor;
       
   190             CleanupDeletePushL(securityObjectDesc);
       
   191             
       
   192             TPckg<TSecurityObjectDescriptor> securityObjectDescPacketBuffer(*securityObjectDesc);            
       
   193             aOperation.iMessage.ReadL(0, securityObjectDescPacketBuffer);
       
   194             
       
   195             TPKIKeyIdentifier keyId;                        
       
   196             iMapper.GetCertificateKeyIdL(*securityObjectDesc, keyId,
       
   197                                          aOperation.iUsedCertStore);
       
   198             
       
   199             CleanupStack::PopAndDestroy(securityObjectDesc);            
       
   200             
       
   201            if (keyId.Length() > 0)
       
   202                 {
       
   203                 HBufC8* dataIn = HBufC8::NewLC(aOperation.iMessage.GetDesLength(1));
       
   204                 TPtr8 dataInPtr = dataIn->Des();
       
   205                 aOperation.iMessage.ReadL(1, dataInPtr);                
       
   206                 
       
   207                 //transfers the dataIn buffer ownership
       
   208                 CleanupStack::Pop(dataIn);
       
   209                 iKeyOperationProvider->Sign(keyId, aOperation.iUsedKeyStore, dataIn);
       
   210                 
       
   211                 }
       
   212             else
       
   213                 {
       
   214                 CompleteCurrentOperation(KPKIErrNotFound);
       
   215                 }            
       
   216             }
       
   217             break;            
       
   218         case PkiService::EReadPublicKey:
       
   219             {
       
   220             TPKIKeyIdentifier keyId;
       
   221             aOperation.iMessage.ReadL(0, keyId);
       
   222             
       
   223             if (keyId.Length() > 0)
       
   224                 {                
       
   225                 iKeyOperationProvider->GetPublicKey(keyId, aOperation.iUsedKeyStore);                
       
   226                 }
       
   227             else
       
   228                 {
       
   229                 CompleteCurrentOperation(KPKIErrNotFound);
       
   230                 }            
       
   231             }            
       
   232             break;
       
   233         case PkiService::ELogon:
       
   234             iKeyOperationProvider->Logon();
       
   235             break;
       
   236         case PkiService::ELogoff:
       
   237             iKeyOperationProvider->Logoff();
       
   238             break;         
       
   239         case PkiService::EChangePassword:
       
   240             iKeyOperationProvider->ChangePassword();
       
   241             break;
       
   242         case PkiService::ERemoveKeypair:
       
   243             {                
       
   244             TPKIKeyIdentifier keyId;
       
   245             aOperation.iMessage.ReadL(0, keyId);
       
   246             
       
   247             if (keyId.Length() > 0)
       
   248                 {                
       
   249                 iKeyOperationProvider->RemoveKeyPair(keyId, aOperation.iUsedKeyStore);                
       
   250                 }
       
   251             else
       
   252                 {
       
   253                 CompleteCurrentOperation(KPKIErrNotFound);
       
   254                 }                        
       
   255             }
       
   256             break;
       
   257         case PkiService::EGenerateKeypair:
       
   258             {
       
   259             TUint keySize = aOperation.iMessage.Int1();
       
   260             TPKIKeyAlgorithm keyAlgorithm = static_cast<TPKIKeyAlgorithm>(aOperation.iMessage.Int2());
       
   261             iKeyOperationProvider->GenerateKeyPair(keySize, keyAlgorithm, aOperation.iUsedKeyStore);   
       
   262             }            
       
   263             break;                   
       
   264         case PkiService::EStoreKeypair:
       
   265             {
       
   266             HBufC8* keyData = HBufC8::NewLC(aOperation.iMessage.GetDesLength(1));
       
   267             TPtr8 keyDataPtr = keyData->Des();
       
   268             aOperation.iMessage.ReadL(1, keyDataPtr);                        
       
   269             
       
   270             CleanupStack::Pop(keyData);
       
   271             iKeyOperationProvider->ImportKeyPair(keyData, aOperation.iUsedKeyStore);
       
   272             }
       
   273             break;  
       
   274         default:      
       
   275             PKISERVICE_INVARIANT();
       
   276             break;
       
   277         }
       
   278     
       
   279     }
       
   280 
       
   281 
       
   282 void CKeyOperationQueue::CompleteCurrentOperation(TInt aStatus)
       
   283     {
       
   284     TKeyOperation* operation = iCurrentOperation;
       
   285     iCurrentOperation = NULL;
       
   286     
       
   287     operation->iMessage.Complete(aStatus);
       
   288     delete operation;
       
   289     
       
   290     if (iOperationQue.Count() > 0)
       
   291         {
       
   292         StartNextOperation();
       
   293         }
       
   294     }
       
   295     
       
   296 
       
   297 void CKeyOperationQueue::KeyStoreInitComplete(TInt aStatus)
       
   298 	{			  
       
   299     PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   300     PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EInitialize);
       
   301 		
       
   302 	if (aStatus == KErrNone)
       
   303 		{
       
   304 		TRAPD(err, iCurrentOperation->iOwner.InitializeWrapperL(iCurrentOperation->iMessage));
       
   305 		if (err != KErrNone && iCurrentOperation->iMessage.Handle() != NULL)
       
   306 			{
       
   307 			CompleteCurrentOperation(err);
       
   308 			}
       
   309         else
       
   310             {
       
   311             delete iCurrentOperation;
       
   312             iCurrentOperation = NULL;
       
   313             if (iOperationQue.Count() > 0)
       
   314                 {
       
   315                 StartNextOperation();
       
   316                 }            
       
   317             }            
       
   318 		}
       
   319 	else
       
   320 		{
       
   321 		CompleteCurrentOperation(aStatus);
       
   322 		}
       
   323 	}
       
   324 
       
   325 
       
   326 void CKeyOperationQueue::KeyPairListComplete(TInt aStatus, CArrayFixFlat<TKeyListEntry>* aKeyList)
       
   327 	{	
       
   328 	
       
   329 	PKISERVICE_ASSERT((aStatus == KErrNone && aKeyList != NULL) ||
       
   330 	               (aStatus != KErrNone && aKeyList == NULL));	
       
   331 	
       
   332 	if (iCurrentOperation->iMessage.Function() == PkiService::EKeyCount)
       
   333     	{
       
   334     	//If we are getting key count, we save the 
       
   335     	//iKeyList, because the next call will be the list
       
   336     	//retrieve.    	
       
   337 
       
   338     	if (aStatus == KErrNone)
       
   339     		{
       
   340             iCurrentOperation->iOwner.SetKeyList(aKeyList);    		
       
   341     		CompleteCurrentOperation(aKeyList->Count());
       
   342     		}
       
   343     	else
       
   344     		{
       
   345     		CompleteCurrentOperation(aStatus);
       
   346     		}    
       
   347     	}
       
   348     else    
       
   349         {
       
   350         //If we are just retrieving a key details.
       
   351         //We can clean up the key list at the end.
       
   352         
       
   353         PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EGetKeyDetails);
       
   354     	if (aStatus == KErrNone)
       
   355     		{
       
   356     		if (aKeyList->Count() > 0)
       
   357         		{
       
   358         		const TKeyListEntry& entry = (*aKeyList)[0];        		
       
   359            		const TPckg<TKeyListEntry> listEntryBuf(entry);	                
       
   360                 TInt err = iCurrentOperation->iMessage.Write(0, listEntryBuf);
       
   361 
       
   362                 //We should newer get overflow, 
       
   363                 //because API knows the length of the result.
       
   364                 __ASSERT_DEBUG(err != KErrOverflow, User::Invariant());
       
   365                                     
       
   366                 CompleteCurrentOperation(err);
       
   367         		}
       
   368             else
       
   369                 {                                  
       
   370                 CompleteCurrentOperation(KPKIErrNotFound);    
       
   371                 }
       
   372     		}
       
   373     	else
       
   374     		{
       
   375     		CompleteCurrentOperation(aStatus);
       
   376     		}    
       
   377         delete aKeyList;    		    		
       
   378         }        
       
   379 	}
       
   380 
       
   381 
       
   382 void CKeyOperationQueue::DecryptComplete(TInt aStatus, HBufC8* aDecryptedData)
       
   383     {
       
   384 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   385 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EDecrypt);        
       
   386     
       
   387     
       
   388     PKISERVICE_ASSERT((aStatus == KErrNone && aDecryptedData != NULL) ||
       
   389                    (aStatus != KErrNone && aDecryptedData == NULL));                   
       
   390     
       
   391             
       
   392     if (aDecryptedData != NULL)
       
   393         {
       
   394         aStatus = iCurrentOperation->iMessage.Write(2, *aDecryptedData);
       
   395         if (aStatus == KErrOverflow)
       
   396             {
       
   397             iCurrentOperation->iOwner.SetRequiredBufferSize(aDecryptedData->Length());
       
   398             aStatus = KPKIErrBufferTooShort;
       
   399             }
       
   400         delete aDecryptedData;
       
   401         }
       
   402     CompleteCurrentOperation(aStatus);
       
   403     }
       
   404 
       
   405 
       
   406 void CKeyOperationQueue::SignComplete(TInt aStatus, HBufC8* aSignedData)
       
   407     {
       
   408 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   409 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::ESignWithKeyId ||
       
   410 	                iCurrentOperation->iMessage.Function() == PkiService::ESignWithCert);        
       
   411     
       
   412     PKISERVICE_ASSERT((aStatus == KErrNone && aSignedData != NULL) ||
       
   413                    (aStatus != KErrNone && aSignedData == NULL));                   
       
   414 
       
   415             
       
   416     if (aSignedData != NULL)
       
   417         {
       
   418         aStatus = iCurrentOperation->iMessage.Write(2, *aSignedData);
       
   419         if (aStatus == KErrOverflow)
       
   420             {
       
   421             iCurrentOperation->iOwner.SetRequiredBufferSize(aSignedData->Length());
       
   422             aStatus = KPKIErrBufferTooShort;
       
   423             }
       
   424         
       
   425         delete aSignedData;
       
   426         }
       
   427     CompleteCurrentOperation(aStatus);    
       
   428     }
       
   429 
       
   430 
       
   431 void CKeyOperationQueue::GetPublicKeyCompleted(TInt aStatus, HBufC8* aPublicKeyData)
       
   432     {
       
   433 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   434 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EReadPublicKey);        
       
   435     
       
   436     PKISERVICE_ASSERT((aStatus == KErrNone && aPublicKeyData != NULL) ||
       
   437                       (aStatus != KErrNone && aPublicKeyData == NULL));                   
       
   438 
       
   439     
       
   440     if (aPublicKeyData != NULL)
       
   441         {
       
   442         aStatus = iCurrentOperation->iMessage.Write(1, *aPublicKeyData);  
       
   443         if (aStatus == KErrOverflow)
       
   444             {
       
   445             iCurrentOperation->iOwner.SetRequiredBufferSize(aPublicKeyData->Length());
       
   446             aStatus = KPKIErrBufferTooShort;
       
   447             }
       
   448         delete aPublicKeyData;
       
   449         }
       
   450     CompleteCurrentOperation(aStatus);        
       
   451     }
       
   452 
       
   453 
       
   454 void CKeyOperationQueue::LogonCompleted(TInt aStatus)
       
   455     {
       
   456 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   457 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::ELogon);        
       
   458 	                
       
   459     CompleteCurrentOperation(aStatus);
       
   460     }
       
   461 
       
   462 
       
   463 void CKeyOperationQueue::LogoffCompleted(TInt aStatus)
       
   464     {
       
   465 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   466 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::ELogoff);        
       
   467 
       
   468     CompleteCurrentOperation(aStatus);
       
   469     }
       
   470 
       
   471 
       
   472 void CKeyOperationQueue::PasswordChangeCompleted(TInt aStatus)
       
   473     {
       
   474 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   475 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EChangePassword);        
       
   476     
       
   477     CompleteCurrentOperation(aStatus);        
       
   478     }
       
   479     
       
   480     
       
   481 void CKeyOperationQueue::KeyPairRemoveCompleted(TInt aStatus)
       
   482     {
       
   483 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   484 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::ERemoveKeypair);        
       
   485 
       
   486     CompleteCurrentOperation(aStatus);
       
   487     }
       
   488     
       
   489     
       
   490 void CKeyOperationQueue::KeyGenerationCompleted(TInt aStatus, TPKIKeyIdentifier& aKeyId)
       
   491     {
       
   492 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   493 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EGenerateKeypair);        
       
   494     
       
   495     if (aStatus == KErrNone)
       
   496         {
       
   497         aStatus = iCurrentOperation->iMessage.Write(0, aKeyId);
       
   498         if (aStatus == KErrOverflow)
       
   499             {
       
   500             iCurrentOperation->iOwner.SetRequiredBufferSize(aKeyId.Length());
       
   501             aStatus = KPKIErrBufferTooShort;
       
   502             }
       
   503 
       
   504         }
       
   505     CompleteCurrentOperation(aStatus);
       
   506     }
       
   507     
       
   508     
       
   509 void CKeyOperationQueue::StoreKeyPairCompleted(TInt aStatus, TPKIKeyIdentifier& aKeyId)
       
   510     {    
       
   511 	PKISERVICE_ASSERT(iCurrentOperation != NULL);
       
   512 	PKISERVICE_ASSERT(iCurrentOperation->iMessage.Function() == PkiService::EStoreKeypair);
       
   513 
       
   514     if (aStatus == KErrNone)
       
   515         {
       
   516         aStatus = iCurrentOperation->iMessage.Write(0, aKeyId);
       
   517         if (aStatus == KErrOverflow)
       
   518             {
       
   519             iCurrentOperation->iOwner.SetRequiredBufferSize(aKeyId.Length());
       
   520             aStatus = KPKIErrBufferTooShort;
       
   521             }        
       
   522         }
       
   523     CompleteCurrentOperation(aStatus);
       
   524     }
       
   525