pkiutilities/PKCS12/CrPkcs12/Src/crpkcs12.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2004 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:   This file contains the implementation of CCrPKCS12 class. 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //  INCLUDE FILES
       
    21 #include "crpkcs12.h"
       
    22 #include <crdefs.h>      // CCrDefines
       
    23 #include <e32std.h>
       
    24 #include <x509certext.h>
       
    25 
       
    26 const TInt KX509Version3 = 3;
       
    27 
       
    28 // -----------------------------------------------------------------------------
       
    29 // CPKCS12SyncWrapper
       
    30 // Constructor
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CCrPKCS12::CPKCS12SyncWrapper::CPKCS12SyncWrapper(): CActive( EPriorityStandard )
       
    34     {
       
    35     CActiveScheduler::Add( this );
       
    36     }
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CPKCS12SyncWrapper
       
    40 // Destructor
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CCrPKCS12::CPKCS12SyncWrapper::~CPKCS12SyncWrapper()
       
    44     {
       
    45     if (iSecDlg)
       
    46         {
       
    47 		iSecDlg->Release();
       
    48         }
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CPKCS12SyncWrapper
       
    53 // EnterPassword wrapper function.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 TInt CCrPKCS12::CPKCS12SyncWrapper::EnterPasswordL(const TPINParams& aPINParams, TBool aRetry, TPINValue& aPINValue)
       
    57     {
       
    58     iSecDlg = SecurityDialogFactory::CreateL();
       
    59     iSecDlg->EnterPIN(aPINParams, aRetry, aPINValue, iStatus);
       
    60     return SetActiveAndWait();
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CPKCS12SyncWrapper::SetActiveAndWait
       
    65 // 
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 TInt CCrPKCS12::CPKCS12SyncWrapper::SetActiveAndWait()
       
    69     {
       
    70     SetActive();
       
    71     iWait.Start();
       
    72     return iStatus.Int();
       
    73     }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CPKCS12SyncWrapper::DoCancel
       
    77 // 
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 void CCrPKCS12::CPKCS12SyncWrapper::DoCancel()
       
    81     {
       
    82     }
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CPKCS12SyncWrapper::RunL
       
    86 // 
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 void CCrPKCS12::CPKCS12SyncWrapper::RunL()
       
    90     {
       
    91     iWait.AsyncStop();
       
    92     }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CCrPKCS12
       
    96 // Constructor
       
    97 // This function constructs CCrPKCS12 object
       
    98 // Return Values:  None
       
    99 // -----------------------------------------------------------------------------
       
   100 CCrPKCS12::CCrPKCS12():iIter(1), iPrivateKeyIdArray(1), iSafeBagsCount(0)
       
   101     {
       
   102     // Default iteration count is 1.
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CCrPKCS12::ConstructL
       
   107 // This function initializes CCrPKCS12 object's member objects.
       
   108 // Parameters:     None
       
   109 // Return Values:  None
       
   110 // -----------------------------------------------------------------------------
       
   111 void CCrPKCS12::ConstructL()
       
   112     {
       
   113   	iberSet = CCrBerSet::NewL( 1 );
       
   114     iUserCertificates = CX509CertificateSet::NewL( 1 );
       
   115     iCACertificates = CX509CertificateSet::NewL( 1 );
       
   116     iUserCertificateBuffer = new (ELeave) CArrayPtrFlat<TDesC8>(1);
       
   117     iCACertificateBuffer = new (ELeave) CArrayPtrFlat<TDesC8>(1);
       
   118     iPKCS8PrivateKeyArray = new (ELeave) CArrayPtrFlat<HBufC8>(1);
       
   119     }
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CCrPKCS12
       
   123 // Destructor
       
   124 // This function destructs CCrPKCS12 object
       
   125 // Return Values:  None
       
   126 // -----------------------------------------------------------------------------
       
   127 CCrPKCS12::~CCrPKCS12()
       
   128     {    
       
   129     delete iberSet;
       
   130     delete iUserCertificates;
       
   131     delete iCACertificates;
       
   132     
       
   133     if (iUserCertificateBuffer)
       
   134         {
       
   135         iUserCertificateBuffer->ResetAndDestroy();
       
   136         delete iUserCertificateBuffer;
       
   137         }
       
   138     if (iCACertificateBuffer)
       
   139         {
       
   140         iCACertificateBuffer->ResetAndDestroy();
       
   141         delete iCACertificateBuffer;
       
   142         }
       
   143     delete iMac;
       
   144     delete iSalt;
       
   145     delete iPassWord;    
       
   146     delete iContentInfo;
       
   147     delete iBags;    
       
   148     delete iDecryptionKey;
       
   149         
       
   150     if (iPKCS8PrivateKeyArray)
       
   151         {        
       
   152         iPKCS8PrivateKeyArray->ResetAndDestroy();    
       
   153         delete iPKCS8PrivateKeyArray;
       
   154         }
       
   155     iPrivateKeyIdArray.ResetAndDestroy();
       
   156     }
       
   157 
       
   158 // -----------------------------------------------------------------------------
       
   159 // CCrPKCS12::NewLC
       
   160 // This function implements the two-phase construction of CCrPKCS12
       
   161 // class. The function uses standard constructor to reserve memory
       
   162 // for pkcs12-object, stores a pointer to the object into clean up
       
   163 // stack, and returns the pointer to the object.
       
   164 // Parameters:     None.
       
   165 // Return Values:  CCrPKCS12*     Pointer to the CCrPKCS12 object.
       
   166 // -----------------------------------------------------------------------------
       
   167 CCrPKCS12* CCrPKCS12::NewLC()
       
   168     {
       
   169     CCrPKCS12* self = new ( ELeave ) CCrPKCS12();
       
   170     CleanupStack::PushL( self );
       
   171 
       
   172     self->ConstructL();
       
   173 
       
   174     return self; 
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CCrPKCS12::NewL
       
   179 // This function implements the two-phase construction of CCrPKCS12
       
   180 // class. The function reserves memory for pkcs12-object and
       
   181 // returns pointer to that object. This function uses NewLC to create
       
   182 // the object and store it to cleanup stack. Finally the object is popped
       
   183 // from clean up stack.
       
   184 // Parameters:     None.
       
   185 // Return Values:  CCrPKCS12*    Pointer to the CCrPKCS12 object.
       
   186 // -----------------------------------------------------------------------------
       
   187 CCrPKCS12* CCrPKCS12::NewL()
       
   188     {
       
   189     CCrPKCS12* self = NewLC();
       
   190     CleanupStack::Pop();
       
   191 
       
   192     return self; 
       
   193     }
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 // CCrPKCS12::Open
       
   197 // Opens pkcs12-file from location given in parameter afilePath,
       
   198 // then it makes a CCrBer::berSet from it. Then it starts testing
       
   199 // berObjects from berSet. When it comes long enough, needed
       
   200 // information can be get and stored to CCrPKCS12-Class' members.
       
   201 // Parameters: CCrData& aPkcs12File    PKCS #12 file.
       
   202 //             TBuf<48> aPassWord      password.
       
   203 // Returns:    TCrStatus               Value of error.
       
   204 // -----------------------------------------------------------------------------
       
   205 TCrStatus CCrPKCS12::OpenL(CCrData&       aPkcs12File, 
       
   206                           const TDesC16& aPassword)
       
   207     {
       
   208     TCrStatus status = KCrOK;
       
   209     TInt errData = KErrNone;
       
   210    
       
   211     if (!iberSet)
       
   212         {
       
   213         User::Leave(KErrGeneral);
       
   214         }
       
   215 
       
   216     // Number of extracted BER objects.
       
   217     TInt numberOfBerObjects = 0;
       
   218     // make berSet, set of berObjects
       
   219     TRAP( errData,numberOfBerObjects = iberSet->OpenL( &aPkcs12File,KOpenAllLevels ));        
       
   220     if ( errData < KErrNone )
       
   221         {
       
   222         return KCrPkcs12 | KCrBerLibraryError;
       
   223         }
       
   224     // number of ber objects must be > 0.
       
   225     if (numberOfBerObjects < 1)
       
   226         {
       
   227         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   228         }
       
   229  
       
   230     iObjectNum = KFirstObject;
       
   231 
       
   232     // Now we have the first object
       
   233     iberObject = iberSet->At( iObjectNum );
       
   234            
       
   235     // File opened successfully, let's start testing berObjects.
       
   236 
       
   237     // 1. Test, is berObject Sequence?
       
   238 	if ( !iberObject->IsSeqOrSet( iberObject->Type() ) )			
       
   239 	    {
       
   240 		return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   241         }
       
   242 
       
   243     iObjectNum++;
       
   244     if (numberOfBerObjects < iObjectNum)
       
   245         {
       
   246         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   247         }
       
   248     iberObject = iberSet->At(iObjectNum );
       
   249                 
       
   250     // 2. Test, is an integer?
       
   251     if ( iberObject->Type() != KBerInteger )					
       
   252         {
       
   253         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   254         }
       
   255     
       
   256     TInt version = 0;
       
   257     TRAP( errData,version = iberObject->GetIntegerL() );       
       
   258     if ( errData < KErrNone )
       
   259         {
       
   260         return KCrPkcs12 | KCrBerLibraryError;
       
   261         }
       
   262 
       
   263     // 3. Test, is version 3?
       
   264     if ( version != KVersion3 )				
       
   265         {
       
   266         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   267         }
       
   268 
       
   269     // Is there still ber objects?
       
   270     iObjectNum++;
       
   271     if (numberOfBerObjects < iObjectNum)
       
   272         {
       
   273         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   274         }
       
   275     iberObject = iberSet->At(iObjectNum );
       
   276     
       
   277     // 4. Test, is Seq?
       
   278     if ( !iberObject->IsSeqOrSet( iberObject->Type() ) )			
       
   279         {
       
   280         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   281         }
       
   282 
       
   283     // Remember where we are.
       
   284     TInt place = iObjectNum;
       
   285 
       
   286     // Is there still ber objects?
       
   287     iObjectNum++;
       
   288     if (numberOfBerObjects < iObjectNum)
       
   289         {
       
   290         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   291         }
       
   292 
       
   293     iberObject = iberSet->At(iObjectNum );
       
   294     
       
   295     CCrData* contentInfo = NULL;
       
   296     TRAP (errData, contentInfo = CCrData::NewL(EFalse));
       
   297     if (errData < KErrNone)
       
   298         {
       
   299         delete contentInfo;
       
   300         contentInfo = NULL;
       
   301         return KCrPkcs12 | KCrNoMemory; 
       
   302         }
       
   303         
       
   304     if ( !ReadContentInfo(*contentInfo ) )
       
   305         {
       
   306         delete contentInfo;
       
   307         contentInfo = NULL;
       
   308         return KCrPkcs12 | KCrNotPasswordBasedEncryption;
       
   309         }
       
   310 
       
   311     iberObject = iberSet->At( place );
       
   312 
       
   313     iObjectNum += JumpNextObjectAtSameLevel();
       
   314 
       
   315     iObjectNum++;
       
   316     if (numberOfBerObjects < iObjectNum)
       
   317         {
       
   318         delete contentInfo;
       
   319         contentInfo = NULL;
       
   320         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   321         }
       
   322     iberObject = iberSet->At( iObjectNum );
       
   323     
       
   324     // 5. Test, is Seq?
       
   325     if ( !iberObject->IsSeqOrSet( iberObject->Type() ) )			
       
   326         {
       
   327         delete contentInfo;
       
   328         contentInfo = NULL;
       
   329         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   330         }
       
   331     
       
   332     iObjectNum++;
       
   333     if (numberOfBerObjects < iObjectNum)
       
   334         {
       
   335         delete contentInfo;
       
   336         contentInfo = NULL;
       
   337         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   338         }
       
   339     iberObject = iberSet->At(iObjectNum );
       
   340              
       
   341     // 6. Test, is Seq?
       
   342     if ( !iberObject->IsSeqOrSet( iberObject->Type() ) )			
       
   343         {
       
   344         delete contentInfo;
       
   345         contentInfo = NULL;
       
   346         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   347         }
       
   348 
       
   349     iObjectNum++;
       
   350     if (numberOfBerObjects < iObjectNum)
       
   351         {
       
   352         delete contentInfo;
       
   353         contentInfo = NULL;
       
   354         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   355         }
       
   356     iberObject = iberSet->At(iObjectNum ); 
       
   357 
       
   358      // 6. Test, is Seq?
       
   359     if ( iberObject->IsSeqOrSet( iberObject->Type() ) )
       
   360         {
       
   361         iObjectNum++;
       
   362         if (numberOfBerObjects < iObjectNum)
       
   363             {
       
   364             delete contentInfo;
       
   365             contentInfo = NULL;
       
   366             return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   367             }
       
   368          iberObject = iberSet->At(iObjectNum );
       
   369         }
       
   370 
       
   371     // 7. Test, is OID?
       
   372     if ( iberObject->Type() != KBerOid)			
       
   373         {
       
   374         delete contentInfo;
       
   375         contentInfo = NULL;
       
   376         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   377         }
       
   378  
       
   379     HBufC* oid = NULL;
       
   380 
       
   381     TRAP(errData, oid = iberObject->GetOidL() );
       
   382         
       
   383     if ( errData < KErrNone )
       
   384         {
       
   385         delete contentInfo;
       
   386         contentInfo = NULL;
       
   387         return KCrPkcs12 | KCrBerLibraryError;
       
   388         }
       
   389 
       
   390     // 8. What is used HMAC-algorithm??
       
   391     if ( *oid == KCrSha1 )										
       
   392         {  
       
   393         iHMACalgorithm = ECrSHA1; 
       
   394         }
       
   395     else if ( *oid == KCrMD5 )
       
   396         {
       
   397         iHMACalgorithm = ECrMD5;
       
   398         }   
       
   399     else
       
   400         {
       
   401         delete oid;
       
   402         oid = NULL;
       
   403         delete contentInfo;
       
   404         contentInfo = NULL;
       
   405         return KCrPkcs12 | KCrNotSupportedHMACalgorithm;
       
   406         }
       
   407 
       
   408     delete oid;
       
   409     oid = NULL;
       
   410 
       
   411     iObjectNum++;
       
   412     if (numberOfBerObjects < iObjectNum)
       
   413         {
       
   414         delete contentInfo;
       
   415         contentInfo = NULL;
       
   416         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   417         }
       
   418  
       
   419     iberObject = iberSet->At(iObjectNum);
       
   420     
       
   421     // If Octet String, read mac // Case in Outlook
       
   422     if (iberObject->Type() == KBerOctetString)
       
   423         {
       
   424         }
       
   425     else
       
   426         {
       
   427         // 9. Test, is Null Tag?
       
   428         if ( iberObject->Type() != KBerNull )
       
   429             {
       
   430             delete contentInfo;
       
   431             contentInfo = NULL;
       
   432             return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   433             }
       
   434         
       
   435         iObjectNum++;
       
   436         if (numberOfBerObjects < iObjectNum)
       
   437             {
       
   438             delete contentInfo;
       
   439             contentInfo = NULL;
       
   440             return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   441             }
       
   442         iberObject = iberSet->At(iObjectNum);
       
   443 
       
   444         // If Octet String, read mac
       
   445         if ( iberObject->Type() != KBerOctetString )
       
   446             {
       
   447             delete contentInfo;
       
   448             contentInfo = NULL;
       
   449             return EFalse;
       
   450             }
       
   451         } 
       
   452         
       
   453     // This is where needed data can be get
       
   454     TRAP( errData,iMac = iberObject->GetOctetStringL() );
       
   455         
       
   456     if ( errData < KErrNone )
       
   457         {
       
   458         delete contentInfo;
       
   459         contentInfo = NULL;
       
   460         return KCrPkcs12 | KCrBerLibraryError;
       
   461         }
       
   462     
       
   463     iObjectNum++;
       
   464     if (numberOfBerObjects < iObjectNum)
       
   465         {
       
   466         delete contentInfo;
       
   467         contentInfo = NULL;
       
   468         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   469         }
       
   470     iberObject = iberSet->At(iObjectNum );
       
   471 
       
   472     // If Octet String, read salt, if OctetString can be found,
       
   473     // validate of this file is OK.
       
   474     if ( iberObject->Type() != KBerOctetString )
       
   475         {
       
   476         delete contentInfo;
       
   477         contentInfo = NULL;
       
   478         return KCrPkcs12 | KCrNotValidPkcs12Object;
       
   479         }
       
   480 
       
   481     TRAP( errData,iSalt = iberObject->GetOctetStringL() );        
       
   482     if ( errData < KErrNone )
       
   483         {
       
   484         delete contentInfo;
       
   485         contentInfo = NULL;
       
   486         return KCrPkcs12 | KCrBerLibraryError;
       
   487         }
       
   488 
       
   489     // Here's optional integer value
       
   490     if ( iberSet->Count() > ++iObjectNum )
       
   491         {
       
   492         iberObject = iberSet->At( iObjectNum );
       
   493 
       
   494         // If here is an integer, then read the number of iterations,
       
   495         // otherwise leave DEFAULT value ( = 1, given in constructor).
       
   496         if ( iberObject->Type() == KBerInteger )	
       
   497             {
       
   498             TRAP( errData,iIter = iberObject->GetIntegerL() );
       
   499             
       
   500             if ( errData < KErrNone )
       
   501                 {
       
   502                 delete contentInfo;
       
   503                 contentInfo = NULL;
       
   504                 return KCrPkcs12 | KCrBerLibraryError;
       
   505                 }
       
   506             }
       
   507         }
       
   508     
       
   509     
       
   510     // Verify Mac.
       
   511     TBool result = EFalse;
       
   512     TRAP(errData, result = VerifyMacL(aPassword));
       
   513     if ( errData < KErrNone )
       
   514         {
       
   515         delete contentInfo;
       
   516         contentInfo = NULL;
       
   517         return KCrPkcs12 | KCrWrongPassWordOrCorruptedFile;
       
   518         }
       
   519     if ( result)
       
   520         {
       
   521        // If password was OK, open ContentInfo
       
   522         if ( !UnpackContentInfo(*contentInfo))
       
   523             {
       
   524             delete contentInfo;
       
   525             contentInfo = NULL;
       
   526             return KCrPkcs12 | KCrNotPasswordBasedEncryption;
       
   527             } 
       
   528         
       
   529         delete contentInfo;
       
   530         contentInfo = NULL;
       
   531 
       
   532         iSafeBagsCount = DecodeSafeBagsL();
       
   533 
       
   534         if ( !iSafeBagsCount )
       
   535             {
       
   536             return KCrPkcs12 | KCrNotPasswordBasedEncryption;
       
   537             } 
       
   538         }
       
   539     // If macs weren't the same, password was wrong
       
   540     else
       
   541         {
       
   542         delete contentInfo;
       
   543         contentInfo = NULL;
       
   544         return KCrPkcs12 | KCrWrongPassWordOrCorruptedFile;
       
   545         }
       
   546 
       
   547     return status;    
       
   548     }
       
   549 
       
   550 // -----------------------------------------------------------------------------
       
   551 // CCrPKCS12::ReadContentInfo
       
   552 // Reads ContentInfo.
       
   553 // Parameters:     
       
   554 // Return Values:  
       
   555 // -----------------------------------------------------------------------------
       
   556 TBool CCrPKCS12::ReadContentInfo( CCrData& aContentInfo )
       
   557     {
       
   558     // If this object isn't OID, or if it isn't type pkcs7Data, return EFalse
       
   559     if ( iberObject->Type() != KBerOid )
       
   560         {
       
   561         return EFalse;
       
   562         }
       
   563 
       
   564     HBufC* oid = NULL;
       
   565     TInt errData = KErrNone;
       
   566     
       
   567     TRAP( errData,oid = iberObject->GetOidL());
       
   568     if ( errData < KErrNone )
       
   569         {
       
   570         delete oid;
       
   571         oid = NULL;
       
   572         return EFalse;
       
   573         }
       
   574 
       
   575     if ( *oid != Kpkcs7Data )
       
   576         {
       
   577         delete oid;
       
   578         oid = NULL;
       
   579         return EFalse;
       
   580         }
       
   581 
       
   582     delete oid;
       
   583     oid = NULL;
       
   584 
       
   585     iberObject = iberSet->At( ++iObjectNum );
       
   586 
       
   587     if ( iberObject->Type() != KBerImplicitConstructed )
       
   588         {
       
   589         return EFalse;
       
   590         }
       
   591 
       
   592     // Now, let's open Constructed data.
       
   593     iberObject = iberSet->At( ++iObjectNum );
       
   594 
       
   595     // Outlook or Netscape
       
   596     if (iberObject->Type() == KBerConstructedBit + KBerOctetString ||
       
   597         iberObject->Type() == KBerOctetString)
       
   598         { 
       
   599         // Outlook
       
   600         if (iberObject->Type() == KBerOctetString )
       
   601             {
       
   602             TRAP (errData, iberObject->GetOctetStringL(aContentInfo));
       
   603             if (errData < KErrNone)
       
   604                 {
       
   605                 return EFalse;
       
   606                 }
       
   607             }
       
   608         // Netscape
       
   609         else  // iberObject->Type() == KBerConstructedBit + KBerOctetString
       
   610             {
       
   611             TRAP(errData,iberObject->OpenConstructedEncodingL(aContentInfo));
       
   612             if ( errData < KErrNone )
       
   613                 {
       
   614                 return EFalse;
       
   615                 }
       
   616             }
       
   617 
       
   618         // Size of contentData
       
   619         TInt size = 0;
       
   620         aContentInfo.Seek( ESeekCurrent,size );
       
   621 
       
   622         // ContentInfo's size -> Buffer's allocated size
       
   623         TRAP( errData,iContentInfo = HBufC8::NewL( size ) );
       
   624         if ( errData < KErrNone )
       
   625             {
       
   626             return EFalse;
       
   627             }
       
   628 
       
   629         // Make pointer to iContentInfo
       
   630         TPtr8 pContentInfo = iContentInfo->Des();
       
   631 
       
   632         // Copy readed ContentInfo to aContentInfo (parameter)
       
   633         aContentInfo.Read( pContentInfo );
       
   634        
       
   635         // Go back to start
       
   636         size = 0;
       
   637         aContentInfo.Seek( ESeekStart,size );
       
   638         return ETrue;
       
   639         }
       
   640     else
       
   641         {
       
   642         return EFalse;
       
   643         }    
       
   644     }
       
   645 
       
   646 // -----------------------------------------------------------------------------
       
   647 // CCrPKCS12::UnpackContentInfo
       
   648 // This function unpacks ContentInfo. First, it tests from what level
       
   649 // SafeContents begin and after that it goes through ContentData.
       
   650 // All sequences, that begin at that level, are tested (via OID) and
       
   651 // Unpacked.
       
   652 // Parameters: CCrData& aContentData. CCrData containing ContentInfo.             
       
   653 // Return Values:  TBool   If OK, returns ETrue and if not, EFalse
       
   654 // -----------------------------------------------------------------------------
       
   655 TBool CCrPKCS12::UnpackContentInfo( CCrData& aContentData )
       
   656     {
       
   657     TInt objectNum = KFirstObject;
       
   658     TInt count     = 0;
       
   659     TInt errData   = KErrNone;
       
   660     HBufC* oid = NULL;
       
   661 
       
   662     CCrBerSet* set = NULL;
       
   663 
       
   664     TRAP( errData,set = CCrBerSet::NewL( 1 ) );
       
   665 
       
   666     if ( errData < KErrNone )
       
   667         {
       
   668         delete set;
       
   669         set = NULL;
       
   670         return EFalse;
       
   671         }
       
   672 
       
   673     // make berSet, set of berObjects
       
   674     TRAP( errData,set->OpenL( &aContentData,KOpenAllLevels ) );
       
   675 
       
   676     if ( errData < KErrNone )
       
   677         {
       
   678         delete set;
       
   679         set = NULL;
       
   680         return EFalse;
       
   681         }
       
   682 
       
   683     count = set->Count();
       
   684     
       
   685     CCrBer* object = set->At( objectNum );
       
   686         
       
   687     // 1. Test, is seq?
       
   688     if ( !object->IsSeqOrSet( object->Type() ) )
       
   689 	    {
       
   690         delete set;
       
   691         set = NULL;
       
   692 		return EFalse;
       
   693         }
       
   694 
       
   695     object = set->At( ++objectNum );
       
   696     
       
   697 	TInt i(0);
       
   698     for (i = objectNum ; i < count ; i++)
       
   699         {
       
   700         // If there exists object, then check
       
   701         //this object
       
   702         if ( i < count )
       
   703             {
       
   704             object = set->At( i );
       
   705             }
       
   706 
       
   707         // Next check type of SafeContent
       
   708         if ( object->Type() == KBerOid )
       
   709             {
       
   710             // Get object identifier
       
   711             TRAP( errData, oid = object->GetOidL() );
       
   712 
       
   713             if( errData < KErrNone )
       
   714                 {
       
   715                 delete set;
       
   716                 set = NULL;
       
   717                 return EFalse;
       
   718                 }
       
   719 
       
   720             if ( *oid == Kpkcs7Data )
       
   721                 {
       
   722                 // Unpack PKCS #7 data
       
   723                 object = set->At( ++i );
       
   724                 
       
   725                 // Case it's just an octetstring
       
   726                 // NOT TESTED!
       
   727                 if ( object->Type() != KBerImplicitConstructed &&
       
   728                      object->Type() == KBerOctetString )
       
   729                     {
       
   730                     HBufC8* pkcs7Data = NULL;
       
   731 
       
   732                     TRAP( errData, pkcs7Data = object->GetOctetStringL() );
       
   733                     if ( errData < KErrNone )
       
   734                         {
       
   735                         delete oid;
       
   736                         oid = NULL;
       
   737                         delete set;
       
   738                         set = NULL;
       
   739                         return EFalse;
       
   740                         }
       
   741                     // Riddance from warnings
       
   742                     if ( pkcs7Data == NULL ) { delete pkcs7Data; }
       
   743                     
       
   744                     }
       
   745                 else
       
   746                     {
       
   747                     object = set->At( ++i );
       
   748                     
       
   749                     if ( (object->Type() ==
       
   750                             (KBerConstructedBit + KBerOctetString)) ||  
       
   751                          (object->Type() == KBerOctetString))
       
   752                         {
       
   753                         CCrData* pkcs7Data = NULL;
       
   754                         TRAP (errData, pkcs7Data = CCrData::NewL(EFalse));
       
   755                         if (errData < KErrNone)
       
   756                             {
       
   757                             delete pkcs7Data;
       
   758                             pkcs7Data = NULL;
       
   759                             delete oid;
       
   760                             oid = NULL;
       
   761                             delete set;
       
   762                             set = NULL;
       
   763                             return EFalse; 
       
   764                             }
       
   765 
       
   766                         // Netscape
       
   767                         if (object->Type() ==
       
   768                                 (KBerConstructedBit + KBerOctetString))
       
   769                             {
       
   770 
       
   771                             TRAP( errData,
       
   772                                  object->OpenConstructedEncodingL(*pkcs7Data));                            
       
   773                             if ( errData < KErrNone )
       
   774                                 {
       
   775                                 delete pkcs7Data;
       
   776                                 pkcs7Data = NULL;
       
   777                                 delete oid;
       
   778                                 oid = NULL;
       
   779                                 delete set;
       
   780                                 set = NULL;
       
   781                                 return EFalse;
       
   782                                 }
       
   783                             }
       
   784                         // Outlook
       
   785                         else if (object->Type() == KBerOctetString)
       
   786                             {
       
   787                             TRAP (errData, object->GetOctetStringL(*pkcs7Data));
       
   788                             if ( errData < KErrNone )
       
   789                                 {
       
   790                                 delete pkcs7Data;
       
   791                                 pkcs7Data = NULL;
       
   792                                 delete oid;
       
   793                                 oid = NULL;
       
   794                                 delete set;
       
   795                                 set = NULL;
       
   796                                 return EFalse;
       
   797                                 }
       
   798                             }
       
   799              
       
   800                         else
       
   801                             {
       
   802                             delete pkcs7Data;
       
   803                             pkcs7Data = NULL;
       
   804                             delete oid;
       
   805                             oid = NULL;
       
   806                             delete set;
       
   807                             set = NULL;
       
   808                             return EFalse;
       
   809                             }
       
   810 
       
   811                         TBool result = EFalse;
       
   812                         TRAP (errData, result = UnpackPkcs7DataL(*pkcs7Data));
       
   813                         if ( !result || errData < KErrNone )
       
   814                             {
       
   815                             delete pkcs7Data;
       
   816                             pkcs7Data = NULL;
       
   817                             delete oid;
       
   818                             oid = NULL;
       
   819                             delete set;
       
   820                             set = NULL;
       
   821                             return EFalse;
       
   822                             }
       
   823                         delete pkcs7Data;
       
   824                         pkcs7Data = NULL;
       
   825                         }
       
   826                     }
       
   827                 }
       
   828             else if ( *oid == Kpkcs7EncryptedData )
       
   829                 {
       
   830                 TInt currentPlace = 0;
       
   831                 // Mark, where we are now
       
   832                 aContentData.Seek( ESeekCurrent,currentPlace );
       
   833 
       
   834                 // Unpack PKCS #7 encrypted Data
       
   835                 TBool result = EFalse;
       
   836                 TRAP(errData, result = UnpackPkcs7EncryptedDataL( aContentData ) );
       
   837                 if (!result || errData < KErrNone)
       
   838                     {
       
   839                     delete oid;
       
   840                     oid = NULL;
       
   841                     delete set;
       
   842                     set = NULL;
       
   843                     return EFalse;
       
   844                     }
       
   845                                   
       
   846                 // Go back where we were and continue
       
   847                 aContentData.Seek( ESeekStart,currentPlace );
       
   848                 }
       
   849             delete oid;
       
   850             oid = NULL;
       
   851             }
       
   852         }
       
   853     if( i < count )
       
   854         {
       
   855         object = set->At( i );
       
   856         }
       
   857 
       
   858     delete set;
       
   859     set = NULL;
       
   860     // Now iBags contains all SafeBags.
       
   861     return ETrue;
       
   862     }
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // CCrPKCS12::UnpackPkcs7DataL
       
   866 // Unpacks Pkcs7Data.
       
   867 // Parameters: CCrData& aPkcs7Data     
       
   868 // Return Values:  TBool   If OK, returns ETrue and if not, EFalse
       
   869 // -----------------------------------------------------------------------------
       
   870 TBool CCrPKCS12::UnpackPkcs7DataL( CCrData& aPkcs7Data )
       
   871     {
       
   872     TInt size = 0;
       
   873 
       
   874     // Size fo aPkcs7Data
       
   875     aPkcs7Data.Seek( ESeekCurrent,size );
       
   876     // Add this bag to iBags
       
   877 
       
   878     // Allocate needed amount of memory for iBags
       
   879     // If iBags-buffer is NULL
       
   880     if ( iBags == NULL)
       
   881         {
       
   882         iBags = HBufC8::NewL( size );
       
   883         }
       
   884     // If iBags isn't NULL
       
   885     else
       
   886         {
       
   887         // Re-allocated space for iBags is
       
   888         // size of the current iBags buffer + size of aPkcs7Dat
       
   889         iBags = iBags->ReAllocL(iBags->Size() + size);
       
   890         }
       
   891     // Append aPkcs7Data to iBags
       
   892     TPtr8 pBags = iBags->Des();
       
   893     HBufC8* tempBuf = HBufC8::NewLC(size);
       
   894     TPtr8 tempPtr = tempBuf->Des();
       
   895     aPkcs7Data.Read(tempPtr);
       
   896     pBags.Append(tempPtr);
       
   897     CleanupStack::PopAndDestroy(); // tempBuf
       
   898 
       
   899     return ETrue;
       
   900     }
       
   901 
       
   902 // -----------------------------------------------------------------------------
       
   903 // CCrPKCS12::UnpackPkcs7EncryptedDataL
       
   904 // Unpacks Pkcs7EncryptedData.
       
   905 // Parameters: CCrData& aPkcs7EncryptedData     
       
   906 // Return Values:  TBool   If OK, returns ETrue and if not, EFalse
       
   907 // -----------------------------------------------------------------------------  
       
   908 TBool CCrPKCS12::UnpackPkcs7EncryptedDataL( CCrData& aPkcs7EncryptedData )
       
   909     {
       
   910     TInt objectNum = KFirstObject;
       
   911     //TInt count     = 0;
       
   912     HBufC* oid = NULL;
       
   913     HBufC8* pkcs7EncryptedDataBuf = NULL;
       
   914     CCrBerSet* set = NULL;
       
   915     CCrBer* object;
       
   916 
       
   917     TInt numberOfItemsInCStack = 0;
       
   918 
       
   919     set = CCrBerSet::NewL(1);
       
   920     CleanupStack::PushL(set);
       
   921     numberOfItemsInCStack++;
       
   922 
       
   923     // make berSet, set of berObjects
       
   924     set->OpenL( &aPkcs7EncryptedData,KOpenAllLevels );
       
   925 
       
   926     //count = set->Count();    
       
   927 
       
   928     // Now we should have a sequence here
       
   929     object = set->At( ++objectNum );
       
   930         
       
   931     // 1. Test, is seq?
       
   932     if ( !object->IsSeqOrSet( object->Type() ) )			
       
   933 	    {
       
   934         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   935         numberOfItemsInCStack = 0;
       
   936         return EFalse;
       
   937         }
       
   938     
       
   939     object = set->At( ++objectNum );
       
   940     
       
   941     // 2. Test, is integer?
       
   942     if ( object->Type() != KBerInteger )
       
   943         {
       
   944         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   945         numberOfItemsInCStack = 0;
       
   946         return EFalse;
       
   947         }
       
   948 
       
   949     // 3. Test, is version 1?
       
   950     if ( object->GetIntegerL() != KEdVer0 )
       
   951         {
       
   952         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   953         numberOfItemsInCStack = 0;
       
   954         return EFalse;
       
   955         }
       
   956 
       
   957     object = set->At( ++objectNum );
       
   958         
       
   959     // 4. Test, is seq?
       
   960     if ( !object->IsSeqOrSet( object->Type() ) )			
       
   961 	    {
       
   962         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   963         numberOfItemsInCStack = 0;
       
   964 		return EFalse;
       
   965         }
       
   966 
       
   967     object = set->At( ++objectNum );
       
   968         
       
   969     // 5. Test, is OID?
       
   970     if ( object->Type() != KBerOid )
       
   971         {
       
   972         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   973         numberOfItemsInCStack = 0;
       
   974         return EFalse;
       
   975         }
       
   976 
       
   977     // Get OID.
       
   978     oid = object->GetOidL();
       
   979     CleanupStack::PushL(oid);
       
   980     numberOfItemsInCStack++; // 2 set + oid
       
   981     // Is it pkcs7Data?
       
   982     if ( *oid != Kpkcs7Data )
       
   983         {
       
   984         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set + oid
       
   985         numberOfItemsInCStack = 0;
       
   986         return EFalse;
       
   987         }
       
   988 
       
   989     CleanupStack::PopAndDestroy(); // oid
       
   990     numberOfItemsInCStack--; // 1
       
   991 
       
   992     object = set->At( ++objectNum );
       
   993         
       
   994     // 6. Test, is seq?
       
   995     if ( !object->IsSeqOrSet( object->Type() ) )
       
   996 	    {
       
   997         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
   998         numberOfItemsInCStack = 0;
       
   999 		return EFalse;
       
  1000         }
       
  1001 
       
  1002     object = set->At( ++objectNum );
       
  1003 
       
  1004     // Here should be encryption algorithm
       
  1005     if ( object->Type() != KBerOid )
       
  1006         {
       
  1007         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
  1008         numberOfItemsInCStack = 0;
       
  1009         return EFalse;
       
  1010         }
       
  1011 
       
  1012     // Get used encryption algorithm
       
  1013     TInt algorithm = 0;
       
  1014 
       
  1015     oid = object->GetOidL();
       
  1016     CleanupStack::PushL(oid);
       
  1017     numberOfItemsInCStack++; // 2 set + oid
       
  1018 
       
  1019     algorithm = GetAlgorithmL( oid );
       
  1020     CleanupStack::PopAndDestroy(); // oid
       
  1021     numberOfItemsInCStack--; // 1
       
  1022 
       
  1023     object = set->At( ++objectNum );
       
  1024         
       
  1025     // 7. Test, is seq?
       
  1026     if ( !object->IsSeqOrSet(object->Type()))			
       
  1027 	    {
       
  1028         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
  1029         numberOfItemsInCStack = 0;
       
  1030 		return EFalse;
       
  1031         }
       
  1032     
       
  1033     object = set->At( ++objectNum );
       
  1034 
       
  1035     // Here should be salt
       
  1036     if ( object->Type() != KBerOctetString )
       
  1037         {
       
  1038         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set
       
  1039         numberOfItemsInCStack = 0;
       
  1040         return EFalse;
       
  1041         }
       
  1042 
       
  1043     HBufC8* salt = NULL;    
       
  1044     salt = object->GetOctetStringL();
       
  1045     CleanupStack::PushL(salt);
       
  1046     numberOfItemsInCStack++; // 2 set + salt
       
  1047 
       
  1048     object = set->At( ++objectNum );
       
  1049     
       
  1050     // Here should be an iteration count
       
  1051     if ( object->Type() != KBerInteger)
       
  1052         {
       
  1053         CleanupStack::PopAndDestroy(numberOfItemsInCStack); // set + salt
       
  1054         numberOfItemsInCStack = 0;
       
  1055         return EFalse;
       
  1056         }
       
  1057 
       
  1058     // By default, iteration count is set to 1
       
  1059     TInt iter = 1;
       
  1060     iter = object->GetIntegerL();
       
  1061 
       
  1062     // Next we have encrypted data
       
  1063 
       
  1064     object = set->At( ++objectNum );
       
  1065     
       
  1066     // If it's an octet string, read it.
       
  1067     if (object->Type() == KBerOctetString)
       
  1068         {
       
  1069         pkcs7EncryptedDataBuf = object->GetOctetStringL();
       
  1070         }
       
  1071 
       
  1072     // If it's an Outlook's KBerImplicit, read it.
       
  1073     if (object->Type() == KBerImplicit)
       
  1074         {
       
  1075         pkcs7EncryptedDataBuf = object->GetContentStringLC();
       
  1076         numberOfItemsInCStack++;
       
  1077         }
       
  1078 
       
  1079     TBool stop = EFalse;
       
  1080 
       
  1081     if (object->Type() == KBerImplicitConstructed )
       
  1082         {
       
  1083         object = set->At( ++objectNum );
       
  1084         
       
  1085         for (TInt i = objectNum ; i < set->Count() && !stop ; i++)
       
  1086             {
       
  1087             if ( object->Type() == KBerOctetString )
       
  1088                 {
       
  1089                 // First octet string into buffer...
       
  1090                 if ( i == objectNum )
       
  1091                     {
       
  1092                     pkcs7EncryptedDataBuf = object->GetOctetStringL();
       
  1093                     CleanupStack::PushL(pkcs7EncryptedDataBuf);
       
  1094                     numberOfItemsInCStack++;
       
  1095                     }
       
  1096                 // ...and rest of octet strings. 
       
  1097                 // New object's content is added to the
       
  1098                 // pkcs7EncryptedDataBuf 
       
  1099                 else
       
  1100                     {
       
  1101                     object = set->At( i );                    
       
  1102                     
       
  1103                     // Re-allocate buffer
       
  1104                     __ASSERT_DEBUG(pkcs7EncryptedDataBuf, User::Invariant());
       
  1105                     TInt currentSize = pkcs7EncryptedDataBuf->Size();
       
  1106                     CleanupStack::Pop(); // pkcs7EncryptedDataBuf
       
  1107                     numberOfItemsInCStack--;
       
  1108                   
       
  1109                     pkcs7EncryptedDataBuf = pkcs7EncryptedDataBuf->ReAllocL(currentSize + object->ContentLen());
       
  1110                     CleanupStack::PushL(pkcs7EncryptedDataBuf);
       
  1111                     numberOfItemsInCStack++;
       
  1112                 
       
  1113                     // Get new OctetString
       
  1114                     HBufC8* octetString = NULL;
       
  1115                     octetString = object->GetOctetStringL();
       
  1116                     TPtr8 pOctetString = octetString->Des();
       
  1117 
       
  1118                     // Copy it into buffer
       
  1119                     TPtr8 pPkcs7EncryptedData = pkcs7EncryptedDataBuf->Des();
       
  1120                     pPkcs7EncryptedData.Append( pOctetString );
       
  1121 
       
  1122                     // Delete OctetString
       
  1123                      delete octetString;
       
  1124                      octetString = NULL;                    
       
  1125                     }
       
  1126                 }
       
  1127             else if ( object->Type() == KBerEndOfContent )
       
  1128                 {
       
  1129                 stop = ETrue;
       
  1130                 }
       
  1131             }
       
  1132         }
       
  1133     // OK, now we have buffer to be decrypted, used algorithm, salt and
       
  1134     // an iteration count. Next we decrypt buffer and append it to iBags.
       
  1135 	
       
  1136 	DecryptPkcs7EncryptedDataL( pkcs7EncryptedDataBuf,salt,iter,algorithm );
       
  1137 
       
  1138     CleanupStack::PopAndDestroy(numberOfItemsInCStack);
       
  1139     numberOfItemsInCStack = 0;
       
  1140 
       
  1141     return ETrue;
       
  1142     }
       
  1143 
       
  1144 // -----------------------------------------------------------------------------
       
  1145 // CCrPKCS12::DecryptPkcs7EncryptedDataL
       
  1146 // Decrypts Pkcs7EncryptedData and adds it to iBags.
       
  1147 // Parameters:     
       
  1148 // Return Values:  TBool   If OK, returns ETrue and if not, EFalse
       
  1149 // -----------------------------------------------------------------------------
       
  1150 TBool CCrPKCS12::DecryptPkcs7EncryptedDataL( HBufC8* aPkcs7EncryptedData,
       
  1151                                              HBufC8* aSalt,
       
  1152                                              TInt aIter,
       
  1153                                              TInt aAlgorithm)
       
  1154     {
       
  1155     HBufC8* certificates = HBufC8::NewLC(aPkcs7EncryptedData->Length());    
       
  1156     TPtr8 ptrCertificates = certificates->Des();    
       
  1157     DecryptDataL(*aPkcs7EncryptedData, *aSalt, aIter, aAlgorithm, ptrCertificates);
       
  1158   
       
  1159     if (iBags)
       
  1160         {
       
  1161         iBags = iBags->ReAllocL(iBags->Size() + ptrCertificates.Size());
       
  1162         }
       
  1163     else
       
  1164         {
       
  1165         iBags = HBufC8::NewL(ptrCertificates.Size());
       
  1166         }
       
  1167 
       
  1168     TPtr8 pIBag = iBags->Des();
       
  1169     pIBag.Append(ptrCertificates);
       
  1170          
       
  1171     CleanupStack::PopAndDestroy(certificates);    
       
  1172     return ETrue;
       
  1173     }
       
  1174 // -----------------------------------------------------------------------------
       
  1175 // CCrPKCS12::DecodeSafeBagsL
       
  1176 // Decodes SafeBags and if needed, also decrypts them.
       
  1177 // Parameters:
       
  1178 // Return Values:  TBool       If OK, returns ETrue and if not, EFalse
       
  1179 // -----------------------------------------------------------------------------
       
  1180 TInt CCrPKCS12::DecodeSafeBagsL()
       
  1181     {
       
  1182     TInt numberOfItemsInCStack = 0;
       
  1183     TInt bagCount = 0;
       
  1184 
       
  1185     CCrData* safeBags = CCrData::NewLC(EFalse);
       
  1186     ++numberOfItemsInCStack;
       
  1187     
       
  1188     TPtr8 piBags = iBags->Des();
       
  1189     safeBags->Write( piBags );
       
  1190 
       
  1191     // Go back to start
       
  1192     TInt start = 0;
       
  1193     safeBags->Seek( ESeekStart,start );
       
  1194 
       
  1195     CCrBerSet* set = NULL;
       
  1196     CCrBer* object = NULL;
       
  1197     
       
  1198     set = CCrBerSet::NewLC( 1 );
       
  1199     ++numberOfItemsInCStack;
       
  1200     
       
  1201     set->OpenL( safeBags,KOpenAllLevels );    
       
  1202 
       
  1203     TInt count = set->Count();
       
  1204 
       
  1205     // We have to check first only for a private key, because we need
       
  1206     // it's LocalKeyId, so we can identify a corresponding certificate.
       
  1207 	TInt i(0); 
       
  1208     for (i = 0 ; i < count ; i++)
       
  1209         {
       
  1210         object = set->At( i );
       
  1211 
       
  1212         if ( object->Type() == KBerOid )
       
  1213             {
       
  1214             
       
  1215             HBufC* oid = object->GetOidL();
       
  1216             CleanupStack::PushL(oid);
       
  1217 
       
  1218             if ( *oid == Kpkcs8ShroudedKeyBag )
       
  1219                 {
       
  1220                 bagCount++;
       
  1221                 DecryptShroudedKeybagL( * safeBags );                    
       
  1222                 }
       
  1223                 
       
  1224             if ( *oid == KkeyBag )
       
  1225                 {
       
  1226                 bagCount++;
       
  1227                 
       
  1228                 ExtractKeybagL( * safeBags );
       
  1229                 } 
       
  1230             
       
  1231             CleanupStack::PopAndDestroy(oid);            
       
  1232             oid = NULL;
       
  1233             }
       
  1234         }
       
  1235 
       
  1236     // And now for certificates.
       
  1237     for (i = 0 ; i < count ; i++)
       
  1238         {
       
  1239         object = set->At( i );
       
  1240 
       
  1241         if ( object->Type() == KBerOid )
       
  1242             {            
       
  1243             HBufC* oid = object->GetOidL();
       
  1244             CleanupStack::PushL(oid);
       
  1245                         
       
  1246             if ( *oid == KcertBag )
       
  1247                 {
       
  1248                 bagCount++;
       
  1249                 DecodeCertBagL( * safeBags );
       
  1250                 }
       
  1251 
       
  1252             CleanupStack::PopAndDestroy(oid);            
       
  1253             oid = NULL;
       
  1254             }
       
  1255         }
       
  1256 
       
  1257     CleanupStack::PopAndDestroy(numberOfItemsInCStack, safeBags);
       
  1258 
       
  1259     // Return amount fo safebags
       
  1260     return bagCount;
       
  1261     }
       
  1262 
       
  1263 // -----------------------------------------------------------------------------
       
  1264 // CCrPKCS12::ExtractKeybagL
       
  1265 // Extract Keybag.
       
  1266 // Parameters:     
       
  1267 // Return Values:
       
  1268 // -----------------------------------------------------------------------------
       
  1269 void CCrPKCS12::ExtractKeybagL( CCrData& aSafeBag )
       
  1270     {
       
  1271     TInt numberOfItemsinCStack = 0;
       
  1272     CCrBerSet* set = NULL;
       
  1273 
       
  1274     set = CCrBerSet::NewLC( 1 );
       
  1275     ++numberOfItemsinCStack;
       
  1276     
       
  1277     CCrBer* object = NULL;
       
  1278     TInt objectNum = KFirstObject;
       
  1279 
       
  1280     set->OpenL( &aSafeBag,KOpenAllLevels );
       
  1281     
       
  1282     object = set->At( objectNum );
       
  1283 
       
  1284    if ( object->Type() != KBerImplicitConstructed )
       
  1285         {
       
  1286         User::Leave( KErrArgument );
       
  1287         }
       
  1288 
       
  1289     HBufC8* PKCS8PrivateKey = object->GetOctetStringL();
       
  1290     iPKCS8PrivateKeyArray->AppendL( PKCS8PrivateKey );
       
  1291 
       
  1292     if ( ++objectNum < set->Count() )
       
  1293         {
       
  1294         object = set->At( objectNum );        
       
  1295         iPrivateKeyIdArray.Append( GetLocalKeyId( aSafeBag ) );
       
  1296         }
       
  1297 
       
  1298     CleanupStack::PopAndDestroy( numberOfItemsinCStack, set );
       
  1299     
       
  1300     }
       
  1301 
       
  1302 // -----------------------------------------------------------------------------
       
  1303 // CCrPKCS12::DecryptShroudedKeybagL
       
  1304 // DecryptShroudedKeybag.
       
  1305 // Parameters:     
       
  1306 // Return Values:
       
  1307 // -----------------------------------------------------------------------------
       
  1308 void CCrPKCS12::DecryptShroudedKeybagL( CCrData& aSafeBag )
       
  1309     {
       
  1310     TInt numberOfItemsinCStack = 0;
       
  1311     CCrBerSet* set = NULL;
       
  1312     TInt errData = KErrNone;
       
  1313 
       
  1314     set = CCrBerSet::NewLC( 1 );
       
  1315     ++numberOfItemsinCStack;
       
  1316     
       
  1317     CCrBer* object = NULL;
       
  1318     TInt objectNum = KFirstObject;
       
  1319 
       
  1320     set->OpenL( &aSafeBag,KOpenAllLevels );
       
  1321     
       
  1322     object = set->At( objectNum );
       
  1323 
       
  1324     // This one needs first to be decrypted, first we open SafeBag and
       
  1325     // then we decrypt encyrpted PrivateKey
       
  1326 
       
  1327     // Decryption Starts
       
  1328     // -----------------
       
  1329     if ( object->Type() != KBerImplicitConstructed )
       
  1330         {
       
  1331         User::Leave(KErrArgument);
       
  1332         }
       
  1333 
       
  1334     object = set->At( ++objectNum );
       
  1335 
       
  1336     if ( !object->IsSeqOrSet( object->Type() ) )
       
  1337         {
       
  1338         User::Leave(KErrArgument);
       
  1339         }
       
  1340 
       
  1341     object = set->At( ++objectNum );
       
  1342 
       
  1343     if ( !object->IsSeqOrSet( object->Type() ) )
       
  1344         {
       
  1345         User::Leave(KErrArgument);
       
  1346         }
       
  1347 
       
  1348     object = set->At( ++objectNum );
       
  1349 
       
  1350     if ( object->Type() != KBerOid)
       
  1351         {
       
  1352         User::Leave(KErrArgument);
       
  1353         }
       
  1354 
       
  1355     // Algorithm
       
  1356     HBufC* oid = object->GetOidL();   
       
  1357     CleanupStack::PushL(oid);
       
  1358 
       
  1359     TInt algorithm = GetAlgorithmL( oid );
       
  1360     
       
  1361     CleanupStack::PopAndDestroy(oid);
       
  1362     oid = NULL;
       
  1363 
       
  1364     object = set->At( ++objectNum );
       
  1365 
       
  1366     if (!object->IsSeqOrSet(object->Type()))
       
  1367         {
       
  1368         User::Leave(KErrArgument);
       
  1369         }
       
  1370 
       
  1371     object = set->At( ++objectNum );
       
  1372 
       
  1373     if ( object->Type() != KBerOctetString )
       
  1374         {
       
  1375         User::Leave(KErrArgument);
       
  1376         }
       
  1377 
       
  1378     // Salt
       
  1379     HBufC8* salt = object->GetOctetStringL();
       
  1380     CleanupStack::PushL(salt);
       
  1381     ++numberOfItemsinCStack;
       
  1382     
       
  1383     object = set->At( ++objectNum );
       
  1384 
       
  1385     if ( object->Type() != KBerInteger)
       
  1386         {
       
  1387         User::Leave(KErrArgument);
       
  1388         }
       
  1389 
       
  1390     // Iterations
       
  1391     TInt iter = 1;
       
  1392     iter = object->GetIntegerL();
       
  1393 
       
  1394     object = set->At( ++objectNum );
       
  1395 
       
  1396     if ( object->Type() != KBerOctetString )
       
  1397         {
       
  1398         User::Leave(KErrArgument);
       
  1399         }
       
  1400 
       
  1401     // EncryptedData
       
  1402     HBufC8* encryptedPrivateKeyInfo = object->GetOctetStringL();
       
  1403     CleanupStack::PushL(encryptedPrivateKeyInfo);
       
  1404     ++numberOfItemsinCStack;
       
  1405     
       
  1406     if ( errData < KErrNone )
       
  1407         {
       
  1408         User::Leave(KErrArgument);
       
  1409         }
       
  1410 
       
  1411     // Decrypt
       
  1412     if ( !DecryptPrivateKeyL( encryptedPrivateKeyInfo,
       
  1413                                                  salt,
       
  1414                                                  iter,
       
  1415                                                  algorithm ) )
       
  1416         {
       
  1417         User::Leave(KErrArgument);
       
  1418         }
       
  1419 
       
  1420     // Decryption Ends
       
  1421     // ---------------
       
  1422     
       
  1423     if ( ++objectNum < set->Count() )
       
  1424         {
       
  1425         object = set->At( objectNum );        
       
  1426         iPrivateKeyIdArray.Append(GetLocalKeyId( aSafeBag ));
       
  1427         }
       
  1428 
       
  1429     CleanupStack::PopAndDestroy(numberOfItemsinCStack, set);
       
  1430     }
       
  1431 
       
  1432 // -----------------------------------------------------------------------------
       
  1433 // CCrPKCS12::GetLocalKeyId
       
  1434 // Gets pkcs12-SafeBag-attribute LocalKeyId
       
  1435 // Parameters:     CCrData& aBagData       SafeBag
       
  1436 // Return Values:  TBool
       
  1437 // -----------------------------------------------------------------------------    
       
  1438 HBufC8* CCrPKCS12::GetLocalKeyId( CCrData& aBagData )
       
  1439     {
       
  1440     CCrBerSet* set = NULL;
       
  1441     CCrBer* object;
       
  1442     TInt errData = KErrNone;
       
  1443 
       
  1444     TRAP( errData,set = CCrBerSet::NewL( 1 ) );
       
  1445 
       
  1446     if ( errData < KErrNone )
       
  1447         {
       
  1448         return NULL;
       
  1449         }
       
  1450 
       
  1451     TInt objectNum = KFirstObject;
       
  1452 
       
  1453     TRAP( errData,set->OpenL( &aBagData,KOpenAllLevels ) );
       
  1454 
       
  1455     if ( errData < KErrNone )
       
  1456         {
       
  1457         delete set;
       
  1458         set = NULL;
       
  1459         return NULL;
       
  1460         }
       
  1461 
       
  1462     TInt count = set->Count();
       
  1463 
       
  1464     // If there are attributes,
       
  1465     if( count > 0 )
       
  1466         {
       
  1467         // continue,
       
  1468         object = set->At( KFirstObject );
       
  1469         }
       
  1470     else
       
  1471         {
       
  1472         // otherwise go away.
       
  1473         delete set;
       
  1474         set = NULL;
       
  1475         return NULL;
       
  1476         }
       
  1477 
       
  1478     // Attributes begin
       
  1479     if ( !object->IsSeqOrSet( object->Type() ) )
       
  1480         {
       
  1481         delete set;
       
  1482         set = NULL;
       
  1483         return NULL;
       
  1484         }
       
  1485 
       
  1486     // Some applications seem to put an empty set in the
       
  1487     // place of LocalKeyId. If so, give up.
       
  1488     if (object->ContentLen() == 0)
       
  1489         {
       
  1490         delete set;
       
  1491         set = NULL;
       
  1492         return NULL;
       
  1493         }
       
  1494 
       
  1495     // If there are more ber-objects left,
       
  1496     if ( count > ++objectNum )
       
  1497         {
       
  1498         // get next,
       
  1499         object = set->At( objectNum );
       
  1500         }
       
  1501     else
       
  1502         {
       
  1503         // otherwise give up.
       
  1504         delete set;
       
  1505         set = NULL;
       
  1506         return NULL;
       
  1507         }
       
  1508 
       
  1509     // First attribute
       
  1510     if ( !object->IsSeqOrSet( object->Type() ) )
       
  1511         {
       
  1512         delete set;
       
  1513         set = NULL;
       
  1514         return NULL;
       
  1515         }
       
  1516 
       
  1517     // Remember, at what level we are
       
  1518     TUint level = object->Level();
       
  1519     TBool stop = EFalse;
       
  1520 
       
  1521     object = set->At( ++objectNum );
       
  1522 
       
  1523     for( TInt i = objectNum ; i < count && !stop; i++ )
       
  1524         {
       
  1525         object = set->At( i );
       
  1526 
       
  1527         if ( object->Level() < level )
       
  1528             {
       
  1529             stop = ETrue;
       
  1530             }
       
  1531                
       
  1532         // What is it?
       
  1533         if ( object->Type() == KBerOid )
       
  1534             {
       
  1535             HBufC* oid = NULL;
       
  1536 
       
  1537             TRAP( errData,oid = object->GetOidL() );
       
  1538 
       
  1539             if ( errData < KErrNone )
       
  1540                 {
       
  1541                 delete set;
       
  1542                 set = NULL;
       
  1543                 return NULL;
       
  1544                 }
       
  1545 
       
  1546             if ( *oid == Kpkcs9LocalKeyId )
       
  1547                 {
       
  1548 				/// BEGIN OF WORKAROUND ///
       
  1549 				/* There is a major error in this library which causes that in certain 
       
  1550 				situations the localKeyId attribute is found for certificate even though
       
  1551 				it is not specified in the file. This happens when for example private key buffer
       
  1552 				is right after CA certificate buffer in bag data. After the CA certificate is parsed then
       
  1553 				the module starts searching for localKeyId and it founds it from the private key buffer. 
       
  1554 				This buffer contains localKeyId and thus CA certificate is wrongly identified to be 
       
  1555 				user certificate. A proper solution would be somehow limit the searching to correct ASN.1 sets
       
  1556 				but there's no time for that now. This is a ugly quick fix for this problem:
       
  1557 				Zero the localKeyId oid so that it is used only once. */	
       
  1558 								
       
  1559 				CCrData* data = object->Data();
       
  1560 				TInt start = object->ContentBegin();
       
  1561 				TInt len = object->ContentLen();
       
  1562 				data->Zero(start, len);
       
  1563 				
       
  1564 				// END OF WORKAROUND ///
       
  1565                 i += 2;
       
  1566 
       
  1567                 if ( count > i )
       
  1568                     {
       
  1569                     object = set->At( i );
       
  1570                     HBufC8* buf = NULL;
       
  1571 
       
  1572                     // Now we can read LocalKeyId
       
  1573                     TRAP( errData,buf = object->GetOctetStringL() );
       
  1574 
       
  1575                     if ( errData < KErrNone )
       
  1576                         {
       
  1577                         delete set;
       
  1578                         set = NULL;
       
  1579                         return NULL;
       
  1580                     }
       
  1581 
       
  1582                     stop = ETrue;
       
  1583                     delete set;
       
  1584                     set = NULL;
       
  1585                     delete oid;
       
  1586                     oid = NULL;
       
  1587                     return buf;
       
  1588                     }
       
  1589                 }
       
  1590             delete oid;
       
  1591             oid = NULL;
       
  1592             }
       
  1593         }
       
  1594 
       
  1595     delete set;
       
  1596     set = NULL;
       
  1597     return NULL;
       
  1598     }
       
  1599 
       
  1600 // -----------------------------------------------------------------------------
       
  1601 // CCrPKCS12::DecodeCertBagL
       
  1602 // DecodeCertBag.
       
  1603 // Parameters:     
       
  1604 // Return Values: TBool
       
  1605 // -----------------------------------------------------------------------------    
       
  1606 void CCrPKCS12::DecodeCertBagL( CCrData& aSafeBags )
       
  1607     {
       
  1608     TInt numberOfItemsinCStack = 0;
       
  1609     CCrBerSet* set = NULL;
       
  1610     
       
  1611     set = CCrBerSet::NewLC( 1 );
       
  1612     ++numberOfItemsinCStack;
       
  1613     
       
  1614 
       
  1615     CCrBer* object;
       
  1616     TInt objectNum = KFirstObject;
       
  1617 
       
  1618     set->OpenL( &aSafeBags,KOpenAllLevels );   
       
  1619 
       
  1620     object = set->At( objectNum );
       
  1621 
       
  1622     // CertificateBags are decrypted at this phase and they just need
       
  1623     // to be decoded from a certificate bag and added to certificate set.
       
  1624     // LocalKeyId is used to check if certificate is user's.
       
  1625 
       
  1626     // Decoding starts
       
  1627     // -----------------
       
  1628     if ( object->Type() != KBerImplicitConstructed )
       
  1629         {
       
  1630         User::Leave(KErrArgument);
       
  1631         }
       
  1632 
       
  1633     object = set->At( ++objectNum );
       
  1634 
       
  1635     if ( !object->IsSeqOrSet( object->Type() ) )
       
  1636         {
       
  1637         User::Leave(KErrArgument);
       
  1638         }
       
  1639 
       
  1640     object = set->At( ++objectNum );
       
  1641 
       
  1642     if ( object->Type() != KBerOid )
       
  1643         {
       
  1644         User::Leave(KErrArgument);
       
  1645         }
       
  1646 
       
  1647     // Algorithm
       
  1648     HBufC* oid = NULL;
       
  1649 
       
  1650     oid = object->GetOidL();
       
  1651     CleanupStack::PushL(oid);
       
  1652         
       
  1653     if ( *oid != Kx509certificate )
       
  1654         {
       
  1655         User::Leave(KErrNotSupported);
       
  1656         }
       
  1657     
       
  1658     CleanupStack::PopAndDestroy(oid);
       
  1659     oid = NULL;
       
  1660 
       
  1661     object = set->At( ++objectNum );
       
  1662 
       
  1663     if ( object->Type() != KBerImplicitConstructed )
       
  1664         {
       
  1665         User::Leave(KErrArgument);
       
  1666         }
       
  1667 
       
  1668     object = set->At( ++objectNum );
       
  1669 
       
  1670     if ( object->Type() != KBerOctetString )
       
  1671         {
       
  1672         User::Leave(KErrArgument);
       
  1673         }
       
  1674 
       
  1675     HBufC8* x509certificate = object->GetOctetStringL();   
       
  1676     CleanupStack::PushL(x509certificate);
       
  1677     ++numberOfItemsinCStack;
       
  1678 
       
  1679     // For identifying certificate's type.
       
  1680     HBufC8* localKeyId = NULL;
       
  1681     
       
  1682     if ( ++objectNum < set->Count() )
       
  1683         {
       
  1684         object = set->At( objectNum );
       
  1685         localKeyId = GetLocalKeyId( aSafeBags );
       
  1686         }
       
  1687     TBool isCA = EFalse;
       
  1688     CX509Certificate* cert  =  CX509Certificate::NewLC( *x509certificate );
       
  1689    
       
  1690 
       
  1691     // Check certificate version
       
  1692     if ( cert->Version() != KX509Version3 )
       
  1693           {
       
  1694           isCA = cert->IsSelfSignedL();
       
  1695           }
       
  1696       else
       
  1697           {
       
  1698           // X509 v3 certificate. Check basicConstrains
       
  1699           const CX509CertExtension* certExt = cert->Extension( KBasicConstraints );
       
  1700           if ( certExt )
       
  1701               {
       
  1702               CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC( certExt->Data() );
       
  1703               isCA = basic->IsCA();
       
  1704               CleanupStack::PopAndDestroy( basic ); //basic
       
  1705               }
       
  1706           else
       
  1707               {
       
  1708               isCA = cert->IsSelfSignedL();
       
  1709               }
       
  1710           }
       
  1711      
       
  1712      
       
  1713     CleanupStack::PopAndDestroy( cert );
       
  1714     
       
  1715     if( localKeyId == NULL || isCA )
       
  1716         {
       
  1717         if ( localKeyId )
       
  1718         	{
       
  1719             delete localKeyId;
       
  1720             localKeyId = NULL;
       
  1721         	}
       
  1722         // Add to CAcertificates;
       
  1723         PutCertsIntoSetL( iCACertificates, iCACertificateBuffer, x509certificate );
       
  1724         // Do not delete x509certificate in this case 
       
  1725         CleanupStack::Pop(x509certificate);
       
  1726         --numberOfItemsinCStack;
       
  1727         }    
       
  1728     else
       
  1729         {        
       
  1730         CleanupStack::PushL(localKeyId);
       
  1731         ++numberOfItemsinCStack;
       
  1732         for (TInt i = 0; i < iPrivateKeyIdArray.Count(); ++i)
       
  1733             {
       
  1734             if (*localKeyId == *(iPrivateKeyIdArray[i]))
       
  1735                 {
       
  1736                 PutCertsIntoSetL( iUserCertificates,iUserCertificateBuffer, x509certificate );
       
  1737                 CleanupStack::PopAndDestroy(localKeyId);
       
  1738                 --numberOfItemsinCStack;
       
  1739                 // Do not delete x509certificate in this case 
       
  1740                 CleanupStack::Pop(x509certificate);
       
  1741                 --numberOfItemsinCStack;
       
  1742                 break;
       
  1743                 }                
       
  1744             }                       
       
  1745         }
       
  1746     /*else
       
  1747         {
       
  1748         delete x509certificate;
       
  1749         x509certificate = NULL; 
       
  1750         }
       
  1751 */
       
  1752     
       
  1753     CleanupStack::PopAndDestroy(numberOfItemsinCStack, set);
       
  1754     }
       
  1755 
       
  1756 // -----------------------------------------------------------------------------
       
  1757 // CCrPKCS12::DecryptDataL
       
  1758 // -----------------------------------------------------------------------------        
       
  1759 void CCrPKCS12::DecryptDataL( const TDesC8& aEncryptedData,
       
  1760                               const TDesC8& aSalt,
       
  1761                               TInt aIter,
       
  1762                               TInt aAlgorithm,
       
  1763                               TDes8& aDecryptedData )
       
  1764     {
       
  1765     HBufC8* keyBuf = NULL; 
       
  1766     TBuf8<8>   iv;
       
  1767     TInt keySize = 0;
       
  1768     TInt numberOfItemsinCStack = 0;
       
  1769             
       
  1770     CCrCrypto* crypto = CCrCrypto::NewLC();
       
  1771     ++numberOfItemsinCStack;
       
  1772         
       
  1773     switch(aAlgorithm)
       
  1774         {
       
  1775         case ECrKpbeWithSHAAnd128BitRC2_CBC:
       
  1776             {
       
  1777             keySize = K128BitRC2KeySize;
       
  1778             break;
       
  1779             }
       
  1780         case ECrKpbeWithSHAAnd40BitRC2_CBC:
       
  1781             {                      
       
  1782             keySize = K40BitRC2KeySize;
       
  1783             break;
       
  1784             }
       
  1785         case ECrpbeWithSHAAnd3_KeyTripleDES_CBC:
       
  1786             {
       
  1787             // We need 3 keys for triple DES.
       
  1788             keySize = 3 * KDesKeySize; 
       
  1789             break;
       
  1790             }
       
  1791         case ECrpbeWithSHAAnd2_KeyTripleDES_CBC:
       
  1792             {
       
  1793             keySize = 2 * KDesKeySize;             
       
  1794             break;
       
  1795             }
       
  1796         default:
       
  1797             {
       
  1798             User::Leave(KErrNotSupported);
       
  1799             }
       
  1800         }
       
  1801     keyBuf = HBufC8::NewLC(keySize);
       
  1802     ++numberOfItemsinCStack;
       
  1803     TPtr8 keyPtr = keyBuf->Des();
       
  1804     // Get key.
       
  1805     crypto->DeriveKeyPKCS12L(*iPassWord,
       
  1806                              aSalt,
       
  1807                              aIter,
       
  1808                              ECrSHA1,
       
  1809                              KId1,
       
  1810                              keySize,
       
  1811                              keyPtr);
       
  1812     
       
  1813     // Get IV
       
  1814     crypto->DeriveKeyPKCS12L(*iPassWord,
       
  1815                              aSalt,
       
  1816                              aIter,
       
  1817                              ECrSHA1,
       
  1818                              KId2,
       
  1819                              iv.MaxSize(),
       
  1820                              iv);
       
  1821 
       
  1822            
       
  1823     switch(aAlgorithm)
       
  1824         {
       
  1825         case ECrKpbeWithSHAAnd128BitRC2_CBC:            
       
  1826             {
       
  1827             crypto->InitCryptRC2L(*keyBuf, iv, EFalse, 8*K128BitRC2KeySize);    
       
  1828             break;
       
  1829             }
       
  1830         case ECrKpbeWithSHAAnd40BitRC2_CBC:
       
  1831             {            
       
  1832             crypto->InitCryptRC2L(*keyBuf, iv, EFalse, 40);    
       
  1833             break;
       
  1834             }
       
  1835         case ECrpbeWithSHAAnd3_KeyTripleDES_CBC:
       
  1836             {
       
  1837             crypto->InitCrypt3DESL(
       
  1838                 keyPtr.Left(KDesKeySize), keyPtr.Mid(KDesKeySize, KDesKeySize), 
       
  1839                 keyPtr.Right(KDesKeySize), iv, EFalse); 
       
  1840             break;
       
  1841             }
       
  1842         case ECrpbeWithSHAAnd2_KeyTripleDES_CBC:
       
  1843             {
       
  1844             crypto->InitCrypt3DESL(
       
  1845                 keyPtr.Left(KDesKeySize), keyPtr.Right(KDesKeySize), 
       
  1846                 keyPtr.Left(KDesKeySize), iv, EFalse); 
       
  1847             break;
       
  1848             }
       
  1849         default:
       
  1850             {
       
  1851             User::Leave(KErrNotSupported);
       
  1852             }
       
  1853         }
       
  1854     crypto->ProcessL(aEncryptedData, aDecryptedData);        
       
  1855     crypto->FinalCryptL(aDecryptedData);                       
       
  1856     CleanupStack::PopAndDestroy(numberOfItemsinCStack, crypto);
       
  1857     }
       
  1858     
       
  1859 // -----------------------------------------------------------------------------
       
  1860 // CCrPKCS12::DecryptPrivateKey
       
  1861 // DecryptPrivateKey.
       
  1862 // Parameters:     
       
  1863 // Return Values:
       
  1864 // -----------------------------------------------------------------------------
       
  1865 
       
  1866 TBool CCrPKCS12::DecryptPrivateKeyL( HBufC8* aEncryptedPrivateKey,
       
  1867                                     HBufC8* aSalt,
       
  1868                                     TInt aIter,
       
  1869                                     TInt aAlgorithm )
       
  1870     {    
       
  1871     TBool   returnValue = ETrue;    
       
  1872     HBufC8* privateKey = HBufC8::NewLC(aEncryptedPrivateKey->Length());    
       
  1873     TPtr8 privateKeyPtr = privateKey->Des();
       
  1874     TPtr8   paEncryptedPrivateKey = aEncryptedPrivateKey->Des();
       
  1875     TPtr8   paSalt = aSalt->Des();
       
  1876 
       
  1877     DecryptDataL(*aEncryptedPrivateKey, *aSalt, aIter, aAlgorithm, privateKeyPtr);
       
  1878    
       
  1879     HBufC8* PKCS8PrivateKey = HBufC8::NewL(privateKey->Length());
       
  1880     PKCS8PrivateKey->Des().Copy(*privateKey);
       
  1881     iPKCS8PrivateKeyArray->AppendL(PKCS8PrivateKey);
       
  1882                     
       
  1883     CleanupStack::PopAndDestroy(privateKey);
       
  1884     return returnValue;
       
  1885     }
       
  1886 
       
  1887 // -----------------------------------------------------------------------------
       
  1888 // CCrPKCS12::VerifyMacFromEightBytePassword
       
  1889 // This function generates double byte pasword from given eight byte
       
  1890 // password and calls VerifyMac.
       
  1891 // Parameters:     aPassWord   password given to open function
       
  1892 // Return Values:  TBool       If OK, returns ETrue and if not, EFalse
       
  1893 // -----------------------------------------------------------------------------
       
  1894 TBool CCrPKCS12::VerifyMacFromEightBytePassword(const TDesC8& aPassWord)
       
  1895     {
       
  1896     TInt errData = KErrNone;
       
  1897 
       
  1898     // Alloc Space for password in pkcs12-format. Needed space is
       
  1899     // 2 * aPassWord + 2
       
  1900     if (iPassWord == NULL)
       
  1901         {
       
  1902         TRAP( errData,iPassWord = HBufC8::NewL( (2 * aPassWord.Length()) + 2) );
       
  1903         
       
  1904         if ( errData < KErrNone )
       
  1905             {
       
  1906             return EFalse;
       
  1907             }
       
  1908         }
       
  1909 
       
  1910     // Pointer to allocated pkcs12PassWord
       
  1911     TPtr8 aPkcs12PassWord = iPassWord->Des();
       
  1912 
       
  1913     // Make sure password is empty.
       
  1914     aPkcs12PassWord = _L8("");
       
  1915 
       
  1916     // Append 0x00 between characters
       
  1917     for( TInt i = 0 ; i < aPassWord.Length() ; i++ )
       
  1918         {
       
  1919         aPkcs12PassWord.Append(0x00);
       
  1920         aPkcs12PassWord.Append(aPassWord[i]);
       
  1921         }
       
  1922 
       
  1923     // Append last 0x00 0x00
       
  1924     aPkcs12PassWord.Append(0x00);
       
  1925     aPkcs12PassWord.Append(0x00);
       
  1926     
       
  1927     TBool result = EFalse;
       
  1928     TRAP(errData, result = VerifyMacL(aPkcs12PassWord));
       
  1929     if ( errData < KErrNone )
       
  1930         {
       
  1931         return EFalse;
       
  1932         }
       
  1933     return result;
       
  1934     }
       
  1935 // -----------------------------------------------------------------------------
       
  1936 // CCrPKCS12::VerifyMacL
       
  1937 // Verifies Mac. This function generates mac with password given to
       
  1938 // open function above, salt and iteration count, It uses crypto-
       
  1939 // library to do that. Generated mac is compared with iMac (mac within
       
  1940 // pkcs12 file) and if they are the same, password was OK and if they
       
  1941 // weren't the same, password was wrong, or file is corrupted.
       
  1942 // Parameters:     aPassWord   password given to open function
       
  1943 // Return Values:  TBool       If OK, returns ETrue and if not, EFalse
       
  1944 // -----------------------------------------------------------------------------  
       
  1945 TBool CCrPKCS12::VerifyMacL(const TDesC8& aPassWord)
       
  1946     { 
       
  1947     TPtr8 pContentInfo = iContentInfo->Des();
       
  1948     
       
  1949     // Key to be derivated
       
  1950     iDecryptionKey = HBufC8::NewL( iMac->Length() );
       
  1951     TPtr8 pDecryptionKey = iDecryptionKey->Des();
       
  1952 
       
  1953     TInt numberOfItemsInCStack = 0;
       
  1954     // Mac to be calculated
       
  1955     HBufC8* mac = HBufC8::NewLC( iMac->Length() );
       
  1956     numberOfItemsInCStack++;        
       
  1957     TPtr8 pMac = mac->Des();
       
  1958 
       
  1959     CCrCrypto* crypto = CCrCrypto::NewLC();
       
  1960     numberOfItemsInCStack++;
       
  1961 
       
  1962     if ( iHMACalgorithm == ECrSHA1 )
       
  1963         {
       
  1964         crypto->DeriveKeyPKCS12L(aPassWord,
       
  1965                                  *iSalt,
       
  1966                                  iIter,
       
  1967                                  ECrSHA1,
       
  1968                                  KId3,
       
  1969                                  iMac->Length(),
       
  1970                                  pDecryptionKey);
       
  1971         
       
  1972         // Initialize HMAC SHA-1 algorithm
       
  1973         crypto->InitDigestHMACL( pDecryptionKey,ECrSHA1 );        
       
  1974         }
       
  1975     else
       
  1976         {
       
  1977         CleanupStack::PopAndDestroy(numberOfItemsInCStack);
       
  1978         return EFalse;
       
  1979         }
       
  1980 
       
  1981     // Process data (filedata)
       
  1982     crypto->ProcessL( pContentInfo, pMac);
       
  1983     
       
  1984     // Final digest algorithm
       
  1985     crypto->FinalDigest( pMac );
       
  1986 
       
  1987     if ( pMac == *iMac )
       
  1988         {
       
  1989         CleanupStack::PopAndDestroy(numberOfItemsInCStack); 
       
  1990         return ETrue;
       
  1991         }
       
  1992     else
       
  1993         {
       
  1994         CleanupStack::PopAndDestroy(numberOfItemsInCStack);
       
  1995         return EFalse;
       
  1996         }
       
  1997     }
       
  1998 
       
  1999 TBool CCrPKCS12::VerifyMacL(const TDesC16& aPassWord)
       
  2000     {
       
  2001     TUint8  halfCharacter;
       
  2002     TUint16 character;
       
  2003 
       
  2004     // Alloc Space for password in pkcs12-format. Needed space is
       
  2005     // 2 * aPassWord + 2
       
  2006     if (iPassWord == NULL)
       
  2007         {
       
  2008         iPassWord = HBufC8::NewL( (2 * aPassWord.Length()) + 2);
       
  2009         }
       
  2010 
       
  2011     // Pointer to allocated pkcs12PassWord
       
  2012     TPtr8 pPkcs12PassWord = iPassWord->Des();
       
  2013 
       
  2014     // Make sure password is empty.
       
  2015     pPkcs12PassWord = _L8("");
       
  2016 
       
  2017     // Divide characters into bytes and append them.
       
  2018     for (TInt i = 0; i < aPassWord.Length(); i++)
       
  2019         {
       
  2020         character = aPassWord[i];
       
  2021 
       
  2022         halfCharacter = (TUint8) (character >> 8);
       
  2023         pPkcs12PassWord.Append(halfCharacter);
       
  2024 
       
  2025         halfCharacter = (TUint8) (character & 0xFF);
       
  2026         pPkcs12PassWord.Append(halfCharacter);
       
  2027         }
       
  2028 
       
  2029     // Append last 0x00 0x00
       
  2030     pPkcs12PassWord.Append(0x00);
       
  2031     pPkcs12PassWord.Append(0x00);
       
  2032 
       
  2033     return VerifyMacL(pPkcs12PassWord);
       
  2034     }
       
  2035 
       
  2036 // -----------------------------------------------------------------------------
       
  2037 // CCrPKCS12::JumpNextObjectAtSameLevel
       
  2038 // Returns integer value of how many objects shoud be jumped to get
       
  2039 // next object at same level. Works, when CCrBer-library works with
       
  2040 // definite values correctly.
       
  2041 // Parameters:     None.
       
  2042 // Return Values:  TUint   Next object's index-number at same level
       
  2043 // -----------------------------------------------------------------------------
       
  2044 TUint CCrPKCS12::JumpNextObjectAtSameLevel()
       
  2045     {
       
  2046     TUint levelAt = iberObject->Level();
       
  2047     TUint jumps = 1;
       
  2048     
       
  2049     TUint index_to = iObjectNum + 1;
       
  2050 
       
  2051     iberObject = iberSet->At( index_to );
       
  2052     
       
  2053     while( iberObject->Level() != levelAt )
       
  2054         {
       
  2055         jumps++;
       
  2056         index_to++;
       
  2057         iberObject = iberSet->At( index_to );
       
  2058         }   
       
  2059 
       
  2060     return jumps;
       
  2061     }
       
  2062 // -----------------------------------------------------------------------------
       
  2063 // CCrPKCS12::GetAlgorithm
       
  2064 // This function identifies algorithm and returns integer about what
       
  2065 // algorithm was. Algorithm is identified via ObjectIdentifier.
       
  2066 // For example, in case if aBuf = "1.2.840.113549.1.12.1.2",
       
  2067 // (pbeWithSHAAnd40BitRC4) function returns 2.
       
  2068 // Parameters:     aBuf    buffer containing ObjectIdentifier
       
  2069 // Return Values:  TUint   Last number of an algorithm
       
  2070 // -----------------------------------------------------------------------------
       
  2071 TUint CCrPKCS12::GetAlgorithmL( HBufC* aBuf )
       
  2072     {
       
  2073     // What is the algorithm?
       
  2074     TUint algorithm = 0;
       
  2075 
       
  2076     if ( *aBuf == KpbeWithSHAAnd128BitRC4 )
       
  2077         {
       
  2078         algorithm = ECrpbeWithSHAAnd128BitRC4;
       
  2079         }
       
  2080     else if ( *aBuf == KpbeWithSHAAnd40BitRC4 )
       
  2081         {
       
  2082         algorithm = ECrpbeWithSHAAnd40BitRC4;
       
  2083         }
       
  2084     else if ( *aBuf == KpbeWithSHAAnd3_KeyTripleDES_CBC )
       
  2085         {
       
  2086         algorithm = ECrpbeWithSHAAnd3_KeyTripleDES_CBC;
       
  2087         }
       
  2088     else if ( *aBuf == KpbeWithSHAAnd2_KeyTripleDES_CBC )
       
  2089         {
       
  2090         algorithm = ECrpbeWithSHAAnd2_KeyTripleDES_CBC;
       
  2091         }
       
  2092     else if ( *aBuf == KpbeWithSHAAnd128BitRC2_CBC )
       
  2093         {
       
  2094         algorithm = ECrKpbeWithSHAAnd128BitRC2_CBC;
       
  2095         }
       
  2096     else if ( *aBuf == KpbeWithSHAAnd40BitRC2_CBC )
       
  2097         {
       
  2098         algorithm = ECrKpbeWithSHAAnd40BitRC2_CBC;
       
  2099         }
       
  2100     else
       
  2101         {
       
  2102         User::Leave(KErrNotSupported);
       
  2103         }
       
  2104 
       
  2105     return algorithm;
       
  2106     }
       
  2107 
       
  2108 // -----------------------------------------------------------------------------
       
  2109 // CCrPKCS12::PutCertsIntoSet
       
  2110 // This function puts all certificates into set given at parameter.
       
  2111 // DecodeCertsL calls this functiuon.
       
  2112 // Parameters:     *set    Set, where certificates will be put into
       
  2113 // Return Values:  TInt    Value of error
       
  2114 // -----------------------------------------------------------------------------
       
  2115 void CCrPKCS12::PutCertsIntoSetL( CX509CertificateSet* aSet,
       
  2116                                   CArrayPtrFlat<TDesC8>* aBufSet,
       
  2117                                   HBufC8* aX509certificate )
       
  2118     {
       
  2119     // Pointer to certificate given at third parameter
       
  2120     TPtr8 paX509certificate = aX509certificate->Des();
       
  2121 
       
  2122     // Add certificate to CertificateSet given at first parameter
       
  2123     aSet->DecodeCertsL( paX509certificate );
       
  2124     
       
  2125     // Add certificate to CertificateSet given at second parameter 
       
  2126     aBufSet->AppendL(aX509certificate);        
       
  2127     }
       
  2128 
       
  2129 // -----------------------------------------------------------------------------
       
  2130 // CCrPKCS12::GetPrivateKeys
       
  2131 // -----------------------------------------------------------------------------
       
  2132 const CArrayPtrFlat<HBufC8>& CCrPKCS12::PrivateKeys() const
       
  2133     {
       
  2134     return *iPKCS8PrivateKeyArray;
       
  2135     }
       
  2136 
       
  2137 // -----------------------------------------------------------------------------
       
  2138 // CCrPKCS12::GetUserCertificates
       
  2139 // This function returns CX509CertificateSet, set of CX509Certificates,
       
  2140 // that are defined in certman. These certificates are user certificates.
       
  2141 // All certificates from X509Certificates are tested and if certificate
       
  2142 // isn't CA Certificate and if KeyUsage don't mach to one given at
       
  2143 // parameter, it is removed from set. After that, UserCertificates
       
  2144 // (type CX509CertificateSet *) are returned to caller.
       
  2145 // Parameters:     TKeyUsage aKeyUsage.
       
  2146 // Return Values:  CX509CertificateSet*  Pointer to the CX509CertificateSet.
       
  2147 // -----------------------------------------------------------------------------
       
  2148 const CX509CertificateSet& CCrPKCS12::UserCertificates() const
       
  2149     {
       
  2150 	return *iUserCertificates;
       
  2151     }
       
  2152 
       
  2153 // -----------------------------------------------------------------------------
       
  2154 // CCrPKCS12::GetUserCertificateBuffer
       
  2155 // This function returns CX509CertificateSet, set of CX509Certificates,
       
  2156 // that are defined in certman. These certificates are user certificates.
       
  2157 // All certificates from X509Certificates are tested and if certificate
       
  2158 // isn't CA Certificate and if KeyUsage don't mach to one given at
       
  2159 // parameter, it is removed from set. After that, UserCertificateBuffer
       
  2160 // (type CArrayPtrFlat<TDes>* ) are returned to caller.
       
  2161 // Parameters:     TKeyUsage aKeyUsage.
       
  2162 // Return Values:  CArrayPtrFlat<TDesC8>*  Pointer to a buffer.
       
  2163 // -----------------------------------------------------------------------------
       
  2164 const CArrayPtrFlat<TDesC8>& CCrPKCS12::UserCertificateBuffer() const
       
  2165                                         
       
  2166     {
       
  2167     return *iUserCertificateBuffer;
       
  2168     }
       
  2169 
       
  2170 // -----------------------------------------------------------------------------
       
  2171 // CCrPKCS12::GetCACertificates
       
  2172 // This function returns CX509CertificateSet, set of CX509Certificates,
       
  2173 // that are defined in certman. These certificates are CA certificates.
       
  2174 // All certificates from X509Certificates are tested and if certificate
       
  2175 // isn't CA Certificate, it is removed from set. After that,
       
  2176 // CACertificates (type CX509CertificateSet *) are returned to caller.
       
  2177 // Parameters:     none.
       
  2178 // Return Values:  CX509CertificateSet*  Pointer to the CX509CertificateSet.
       
  2179 // -----------------------------------------------------------------------------
       
  2180 const CX509CertificateSet& CCrPKCS12::CACertificates() const
       
  2181     {
       
  2182     return *iCACertificates;
       
  2183     }
       
  2184 // -----------------------------------------------------------------------------
       
  2185 // CCrPKCS12::GetCACertificateBuffer
       
  2186 // This function returns CX509CertificateSet, set of CX509Certificates,
       
  2187 // that are defined in certman. These certificates are CA certificates.
       
  2188 // All certificates from X509Certificates are tested and if certificate
       
  2189 // isn't CA Certificate, it is removed from set. After that,
       
  2190 // CACertificates (type CArrayPtrFlat<TDesC8>*) are returned to caller.
       
  2191 // Parameters:     none.
       
  2192 // Return Values:  CArrayPtrFlat<TDesC8>*  Pointer to the CX509CertificateSet.
       
  2193 // -----------------------------------------------------------------------------
       
  2194 const CArrayPtrFlat<TDesC8>& CCrPKCS12::CACertificateBuffer() const
       
  2195     {
       
  2196     return *iCACertificateBuffer;
       
  2197     } 
       
  2198 
       
  2199 // -----------------------------------------------------------------------------
       
  2200 // CCrPKCS12::GetIter
       
  2201 // This function returns the number of iterations
       
  2202 // Parameters: none 
       
  2203 // Returns:    TUint    Number of iterations.
       
  2204 // -----------------------------------------------------------------------------
       
  2205 
       
  2206 TUint CCrPKCS12::Iter()
       
  2207 	{
       
  2208 	return iIter;
       
  2209 	}
       
  2210 
       
  2211 // -----------------------------------------------------------------------------
       
  2212 // CCrPKCS12::GetMac
       
  2213 // This function returns the mac
       
  2214 // Parameters: none 
       
  2215 // Returns:    HBufC8*     Pointer to mac.
       
  2216 // -----------------------------------------------------------------------------
       
  2217 HBufC8* CCrPKCS12::Mac()
       
  2218 	{
       
  2219 	return iMac;
       
  2220 	}
       
  2221 
       
  2222 // -----------------------------------------------------------------------------
       
  2223 // CCrPKCS12::GetSalt
       
  2224 // This function returns the salt
       
  2225 // Parameters: none 
       
  2226 // Returns:    HBufC8*     Pointer to salt.
       
  2227 // -----------------------------------------------------------------------------
       
  2228 HBufC8* CCrPKCS12::Salt()
       
  2229     {
       
  2230 	return iSalt;
       
  2231     }
       
  2232 
       
  2233 // -----------------------------------------------------------------------------
       
  2234 // CCrPKCS12::GetSafeBagsCount
       
  2235 // This function returns number of SafeBags
       
  2236 // Parameters: none
       
  2237 // Returns:    TInt      Number of SafeBags
       
  2238 // -----------------------------------------------------------------------------
       
  2239 TUint CCrPKCS12::SafeBagsCount()
       
  2240     {
       
  2241 	return iSafeBagsCount;
       
  2242     }
       
  2243 // EOF