pkiutilities/CertSaver/src/CertSaverModel.cpp
changeset 0 164170e6151a
child 16 9971b621ef6c
child 30 cc1cea6aabaf
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Class that handles user input and launching of dialogs
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <aknnotewrappers.h>        // Note dialogs
       
    21 #include <aknmessagequerydialog.h>  // For CAknMessageQueryDialog
       
    22 #include <StringLoader.h>           // For loading resource strings
       
    23 #include <unifiedcertstore.h>       // For saving the certificates
       
    24 #include <mctwritablecertstore.h>   // For saving the certificates
       
    25 #include <sysutil.h>                // For FFSSpaceBelowCriticalLevelL(..)
       
    26 #include <X509CertNameParser.h>     // For default label
       
    27 #include <x509cert.h>               // For CX509Certificate
       
    28 #include <wtlscert.h>               // For WTLSCertificate
       
    29 #include <hash.h>                   // MD5 fingerprint
       
    30 #include <certificateapps.h>
       
    31 #include <mctkeystore.h>
       
    32 #include <securityerr.h>
       
    33 #include <asnpkcs.h>
       
    34 #include <unifiedkeystore.h>
       
    35 #include <x509certext.h>
       
    36 #include <mctkeystore.h>
       
    37 #include <TrustedSitesStore.h>
       
    38 
       
    39 #include <CertSaver.rsg>
       
    40 #include "CertSaverModel.h"
       
    41 #include "CertSaverDocument.h"
       
    42 #include "CertSaverAppUi.h"
       
    43 #include "CertSaverSyncWrapper.h"
       
    44 #include "certsaver.hrh"
       
    45 #include "securityuisvariant.hrh"
       
    46 
       
    47 // CONSTANTS
       
    48 const TInt32 KWTLSTrusterUID( 268479059 );
       
    49 const TInt32 KInternetTrusterUID( 268441661 );
       
    50 const TInt32 KApplicationControllerTrusterUID( 268452523 );
       
    51 const TInt32 KJavaInstallTrusterUID( 270506792 );
       
    52 const TInt32 KOCSPTrusterUID( 268478646 );
       
    53 const TInt32 KVPNUID( 270498195 );
       
    54 
       
    55 const TInt KTrusterArrayInitSize( 2 );
       
    56 
       
    57 const TInt KMaxLengthTextMeassageBody( 5000 );
       
    58 const TInt KMaxLengthTextDateString( 11 );    // "dd/mm/yyyy0"
       
    59 
       
    60 //Issuer and Owner max visible length
       
    61 const TInt KMaxLengthTextCertIdentifierVisible( 1000 );
       
    62 const TInt KAttempts( 3 );
       
    63 
       
    64 const TInt KFingerprintLength( 50 );
       
    65 
       
    66 _LIT( KCertSaverListBoxItemPrefix, "1\t" );
       
    67 const TInt KItemBufLen = 2 + KMaxName;
       
    68 
       
    69 _LIT( KPrivateKeyLabel, "PrivateKey " );
       
    70 const TInt KPrivaKeyLabelLength( 50 );
       
    71 _LIT( KDateString,"%D%M%Y%1%2%3" );
       
    72 _LIT( KTimeString,"%-B%:0%J%:1%T%:2%S%:3%+B" );
       
    73 _LIT( KSpace, " " );
       
    74 _LIT( KDoubleEnter, "\n\n" );
       
    75 _LIT( KEnter, "\n" );
       
    76 
       
    77 const TUid KTrustedServerTokenUid = { 0x101FB66F };
       
    78 const TUid KFileTokensUid = { 0x101F501A };
       
    79 
       
    80 _LIT_SECURITY_POLICY_V1( KSymbianKeyStoreMgmtPolicy,
       
    81                          VID_DEFAULT, ECapabilityWriteUserData );
       
    82 _LIT_SECURITY_POLICY_C1( KSymbianKeyStoreUsePolicy, ECapabilityReadUserData );
       
    83 
       
    84 
       
    85 // ================= MEMBER FUNCTIONS =======================
       
    86 
       
    87 // Destructor
       
    88 CCertSaverModel::~CCertSaverModel()
       
    89     {
       
    90     delete iWrapper;
       
    91     iEntries.Close();
       
    92     delete iUnifiedCertStore;
       
    93     iTrusterUids.Close();
       
    94     }
       
    95 
       
    96 // ----------------------------------------------------------
       
    97 // CCertSaverModel::CCertSaverModel(
       
    98 //    const CCertSaverDocument* aDocument, CCertSaverAppUi* aAppUi)
       
    99 // ----------------------------------------------------------
       
   100 //
       
   101 CCertSaverModel::CCertSaverModel(
       
   102     CCertSaverAppUi* aAppUi,
       
   103     const CCertParser& aParser ):
       
   104     iAppUi( aAppUi ), iFs( iAppUi->CoeEnv()->FsSession() ), iParser( aParser ),
       
   105     iSavedCACertsCount( 0 ), iSavedKeysCount( 0 ),
       
   106     iSavedUserCertsCount( 0 ), iKeyAlreadyExists( EFalse )
       
   107     {
       
   108     }
       
   109 
       
   110 // ----------------------------------------------------------
       
   111 // CCertSaverModel::SaveCertificateL()
       
   112 // ----------------------------------------------------------
       
   113 //
       
   114 void CCertSaverModel::SaveCertificateL(
       
   115             const CX509Certificate& aCertificate,
       
   116             const TCertificateOwnerType& aOwnerType,
       
   117             const TCertificateFormat& aCertFormat )
       
   118     {
       
   119     iCertOwnerType = aOwnerType;
       
   120     iCertFormat = aCertFormat;
       
   121     iNewCert = &aCertificate;
       
   122 
       
   123     if ( aOwnerType == EPeerCertificate )
       
   124         {
       
   125         TInt ret = QueryTrustedSiteL();
       
   126         if ( ret != KErrNone )
       
   127             {
       
   128              return;
       
   129             }
       
   130         }
       
   131 
       
   132     SaveCertL();
       
   133     }
       
   134 
       
   135 // ----------------------------------------------------------
       
   136 // CCertSaverModel::DoSavePrivateKeyL()
       
   137 //
       
   138 // ----------------------------------------------------------
       
   139 //
       
   140 void CCertSaverModel::DoSavePrivateKeyL( const TDesC8& aKey )
       
   141     {
       
   142     CheckFSSpaceL( aKey );
       
   143 
       
   144     TKeyIdentifier keyIdentifier;
       
   145     CDecPKCS8Data* pkcs8Data = TASN1DecPKCS8::DecodeDERL( aKey );
       
   146     CleanupStack::PushL( pkcs8Data );
       
   147     MPKCS8DecodedKeyPairData* keyPairData = pkcs8Data->KeyPairData();
       
   148     keyPairData->GetKeyIdentifierL( keyIdentifier );
       
   149 
       
   150     TTime startDate;
       
   151     TTime endDate;
       
   152     GetKeyValidityPeriodL( startDate, endDate, keyIdentifier );
       
   153 
       
   154     TInt err = KErrNone;
       
   155     CCTKeyInfo* keyInfo = NULL;
       
   156     TBuf<KPrivaKeyLabelLength> keyLabel( KPrivateKeyLabel );
       
   157     TKeyUsagePKCS15 keyUsage = KeyUsageL( keyIdentifier, pkcs8Data->Algorithm() );
       
   158     CleanupStack::PopAndDestroy( pkcs8Data );
       
   159     if (KeyAlreadyExistsL( startDate, endDate, keyIdentifier, keyUsage) )
       
   160         {
       
   161         User::Leave( KErrNone );
       
   162         }
       
   163 
       
   164     TInt accessType( 0 );
       
   165 
       
   166     accessType |= CCTKeyInfo::EExtractable;
       
   167 
       
   168     for ( TInt i = 0; i < KAttempts; i++ )
       
   169         {
       
   170         CreateKeyLabelL( keyLabel );
       
   171         // Should not use hardcoded index
       
   172         err = iWrapper->AddKey( 0, aKey, keyUsage, keyLabel,
       
   173             accessType, startDate, endDate, keyInfo );
       
   174         if ( err != KErrAlreadyExists )
       
   175             {
       
   176             i = KAttempts;
       
   177             }
       
   178         keyLabel.Zero();
       
   179         }
       
   180 
       
   181     TCTTokenObjectHandle handle;
       
   182     if ( keyInfo )
       
   183         {
       
   184         handle = keyInfo->Handle();
       
   185         keyInfo->Release();
       
   186         keyInfo = NULL;
       
   187         }
       
   188 
       
   189     switch ( err )
       
   190         {
       
   191         case KErrNone:
       
   192             {
       
   193             ++iSavedKeysCount;
       
   194             break;
       
   195             }
       
   196         case KErrKeySize:
       
   197         case KErrArgument:
       
   198             {
       
   199             ShowErrorNoteL( R_CERTSAVER_KEY_TYPE_NOT_SUPPORTED );
       
   200             User::Leave( KErrCancel );
       
   201             break;
       
   202             }
       
   203         case KErrKeyValidity:
       
   204             {
       
   205             ShowInformationNoteL( R_CERTSAVER_QTN_CM_PKCS12_EXPIRED );
       
   206             User::Leave( KErrCancel );
       
   207             }
       
   208         case KErrKeyUsage:
       
   209             {
       
   210             ShowErrorNoteL( R_CERTSAVER_PRIVATE_KEY_CORRUPTED );
       
   211             User::Leave( KErrCancel );
       
   212             break;
       
   213             }
       
   214         case KErrCancel:
       
   215         case KErrPermissionDenied:
       
   216             {
       
   217             ShowErrorNoteL( R_CERTSAVER_PKCS12_DISCARDED );
       
   218             User::Leave( KErrCancel );
       
   219             break;
       
   220             }
       
   221         case KErrCorrupt:
       
   222         case KErrEof:
       
   223             {
       
   224             ShowErrorNoteL( R_CERTSAVER_KEYSTORE_CORRUPTED );
       
   225             User::Leave( KErrCancel );
       
   226             break;
       
   227             }
       
   228         case KErrAlreadyExists:
       
   229             {
       
   230             User::Leave( KErrCancel );
       
   231             break;
       
   232             }
       
   233         default:
       
   234             {
       
   235             User::Leave( err );
       
   236             break;
       
   237             }
       
   238         }
       
   239 
       
   240     User::LeaveIfError(
       
   241         iWrapper->SetManagementPolicy( handle, KSymbianKeyStoreMgmtPolicy) );
       
   242     User::LeaveIfError(
       
   243         iWrapper->SetUsePolicy( handle, KSymbianKeyStoreUsePolicy ) );
       
   244     }
       
   245 
       
   246 // ----------------------------------------------------------
       
   247 // TBool CCertSaverModel::KeyAlreadyExistsL()
       
   248 //
       
   249 // ----------------------------------------------------------
       
   250 //
       
   251 TBool CCertSaverModel::KeyAlreadyExistsL(
       
   252     TTime& aStartDate,
       
   253     TTime& aEndDate,
       
   254     const TKeyIdentifier& aKeyIdentifier,
       
   255     TKeyUsagePKCS15& aKeyUsage )
       
   256     {
       
   257     TBool ret = EFalse;
       
   258     TCTKeyAttributeFilter keyFilter;
       
   259     keyFilter.iKeyAlgorithm = CKeyInfoBase::EInvalidAlgorithm;
       
   260     keyFilter.iKeyId = aKeyIdentifier;
       
   261     keyFilter.iPolicyFilter = TCTKeyAttributeFilter::EManageableKeys;
       
   262     keyFilter.iUsage = aKeyUsage;
       
   263     RMPointerArray<CCTKeyInfo> keyArray;
       
   264     TInt err = iWrapper->ListKeys( keyArray, keyFilter );
       
   265     CleanupClosePushL( keyArray );
       
   266     switch ( err )
       
   267         {
       
   268         case KErrNone:
       
   269             {
       
   270             break;
       
   271             }
       
   272         case KErrCorrupt:
       
   273         case KErrEof:
       
   274             {
       
   275             ShowErrorNoteL( R_CERTSAVER_KEYSTORE_CORRUPTED );
       
   276             User::Leave( KErrCancel );
       
   277             }
       
   278         default:
       
   279             {
       
   280             User::Leave( err );
       
   281             }
       
   282         }
       
   283     for ( TInt i = 0; ret == EFalse && i < keyArray.Count(); i++ )
       
   284         {
       
   285         if ( keyArray[i]->StartDate() == aStartDate &&
       
   286              keyArray[i]->EndDate() == aEndDate )
       
   287             {
       
   288             ret = ETrue;
       
   289             iKeyAlreadyExists = ETrue;
       
   290             }
       
   291         }
       
   292     CleanupStack::PopAndDestroy( &keyArray );
       
   293     return ret;
       
   294     }
       
   295 
       
   296 // ----------------------------------------------------------
       
   297 // CCertSaverModel::GetKeyValidityPeriodL()
       
   298 //
       
   299 // ----------------------------------------------------------
       
   300 //
       
   301 void CCertSaverModel::GetKeyValidityPeriodL(
       
   302     TTime& aStartDate,
       
   303     TTime& aEndDate,
       
   304     const TKeyIdentifier& aKeyIdentifier )
       
   305     {
       
   306 
       
   307     for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ )
       
   308         {
       
   309         const CX509Certificate* cert = iParser.UserCertificates().At( i );
       
   310         if ( cert->KeyIdentifierL() == aKeyIdentifier )
       
   311             {
       
   312             // Associated certificate found
       
   313             // In the first round aStartDate and aEndDate is initialised.
       
   314             if ( i == 0 || aStartDate > cert->ValidityPeriod().Start() )
       
   315                 {
       
   316                 aStartDate = cert->ValidityPeriod().Start();
       
   317                 }
       
   318             if ( i == 0 || aEndDate < cert->ValidityPeriod().Finish() )
       
   319                 {
       
   320                 aEndDate = cert->ValidityPeriod().Finish();
       
   321                 }
       
   322             }
       
   323         }
       
   324     }
       
   325 
       
   326 // ----------------------------------------------------------
       
   327 // CCertSaverModel::CreateKeyLabelL()
       
   328 //
       
   329 // ----------------------------------------------------------
       
   330 //
       
   331 void CCertSaverModel::CreateKeyLabelL( TDes& aLabel )
       
   332     {
       
   333     TTime time;
       
   334     time.UniversalTime();
       
   335     TBuf<KPrivaKeyLabelLength> dateBuf;
       
   336     time.FormatL( dateBuf, KDateString );
       
   337     aLabel.Append( dateBuf );
       
   338     dateBuf.Zero();
       
   339     aLabel.Append( KSpace );
       
   340 
       
   341     time.FormatL( dateBuf, KTimeString );
       
   342     aLabel.Append( dateBuf );
       
   343     }
       
   344 
       
   345 // ----------------------------------------------------------
       
   346 // CCertSaverModel::SavePrivateKeyL()
       
   347 //
       
   348 // ----------------------------------------------------------
       
   349 //
       
   350 void CCertSaverModel::SavePrivateKeyL()
       
   351     {
       
   352     if ( iParser.Keys().Count() <= 0 )
       
   353         {
       
   354         return;
       
   355         }
       
   356     if ( NULL == iWrapper )
       
   357         {
       
   358         iWrapper = CCertSaverSyncWrapper::NewL();
       
   359         }
       
   360     TInt err = iWrapper->InitializeKeyStoreL( iFs );
       
   361 
       
   362     TInt keyStoreCount = iWrapper->UnifiedKeyStore().KeyStoreManagerCount();
       
   363     if ( keyStoreCount <= 0 )
       
   364         {
       
   365         User::Leave( KErrCancel );
       
   366         }
       
   367     else
       
   368         {
       
   369         for ( TInt i = 0; i < keyStoreCount; ++i )
       
   370             {
       
   371             TUid uid =
       
   372             iWrapper->UnifiedKeyStore().KeyStoreManager(i).Token().TokenType().Type();
       
   373             if ( uid == TUid::Uid( KTokenTypeFileKeystore ) )
       
   374                 // if this is not found, we use the first one,
       
   375                 // which is already initialised
       
   376                 {
       
   377                 iSelectedKeyStore = i;
       
   378                 }
       
   379             }
       
   380         }
       
   381 
       
   382     for ( TInt i = 0; i < iParser.Keys().Count(); i++ )
       
   383         {
       
   384         const HBufC8* key = iParser.Keys().At( i );
       
   385         TRAP(err, DoSavePrivateKeyL( *key ));
       
   386         User::LeaveIfError( err );
       
   387         }
       
   388     }
       
   389 
       
   390 // ----------------------------------------------------------
       
   391 // CCertSaverModel::KeyUsageL(
       
   392 //    const TKeyIdentifier& aKeyIdentifier, TAlgorithmId aAlgorithm)
       
   393 // ----------------------------------------------------------
       
   394 //
       
   395 TKeyUsagePKCS15 CCertSaverModel::KeyUsageL(
       
   396     const TKeyIdentifier& aKeyIdentifier,
       
   397     TAlgorithmId aAlgorithm )
       
   398     {
       
   399 
       
   400     TKeyUsagePKCS15 pkcs15KeyUsage = EPKCS15UsageNone;
       
   401     TKeyUsageX509 x509Usage = EX509UsageNone;
       
   402 
       
   403     for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ )
       
   404         {
       
   405         const CX509Certificate* cert = iParser.UserCertificates().At( i );
       
   406         if ( cert->KeyIdentifierL() == aKeyIdentifier )
       
   407             {
       
   408             const CX509CertExtension* ext = cert->Extension( KKeyUsage );
       
   409             if (ext)
       
   410                 {
       
   411                 CX509KeyUsageExt* keyUsageExt =
       
   412                     CX509KeyUsageExt::NewLC( ext->Data() );
       
   413                 if ( keyUsageExt->IsSet( EX509DigitalSignature ) )
       
   414                   {
       
   415                   x509Usage |= EX509UsageDigitalSignature;
       
   416                   }
       
   417                 if ( keyUsageExt->IsSet( EX509NonRepudiation ) )
       
   418                   {
       
   419                   x509Usage |= EX509UsageNonRepudiation;
       
   420                   }
       
   421                 if ( keyUsageExt->IsSet( EX509KeyEncipherment ) )
       
   422                   {
       
   423                   x509Usage |= EX509UsageKeyEncipherment;
       
   424                   }
       
   425                 if ( keyUsageExt->IsSet( EX509DataEncipherment ) )
       
   426                   {
       
   427                   x509Usage |= EX509UsageDataEncipherment;
       
   428                   }
       
   429                 if ( keyUsageExt->IsSet( EX509KeyAgreement ) )
       
   430                   {
       
   431                   x509Usage |= EX509UsageKeyAgreement;
       
   432                   }
       
   433                 if ( keyUsageExt->IsSet( EX509KeyCertSign ) )
       
   434                   {
       
   435                   x509Usage |= EX509UsageKeyCertSign;
       
   436                   }
       
   437                 if ( keyUsageExt->IsSet( EX509CRLSign ) )
       
   438                   {
       
   439                   x509Usage |= EX509UsageCRLSign;
       
   440                   }
       
   441                 if ( keyUsageExt->IsSet( EX509EncipherOnly ) )
       
   442                   {
       
   443                   x509Usage |= EX509UsageEncipherOnly;
       
   444                   }
       
   445                 if ( keyUsageExt->IsSet( EX509DecipherOnly ) )
       
   446                   {
       
   447                   x509Usage |= EX509UsageDecipherOnly;
       
   448                   }
       
   449                 CleanupStack::PopAndDestroy( keyUsageExt );
       
   450                 }
       
   451             }
       
   452         }
       
   453 
       
   454     pkcs15KeyUsage = KeyUsageX509ToPKCS15Private( x509Usage );
       
   455     // If any certificate in the file did not include key usage,
       
   456     // let's use default values.
       
   457     if ( EPKCS15UsageNone == pkcs15KeyUsage )
       
   458         {
       
   459         switch ( aAlgorithm )
       
   460             {
       
   461             case ERSA:
       
   462                 {
       
   463                 pkcs15KeyUsage |= EPKCS15UsageSignSignRecover;
       
   464                 pkcs15KeyUsage |= EPKCS15UsageDecryptUnwrap;
       
   465                 break;
       
   466                 }
       
   467             case EDSA:
       
   468                 {
       
   469                 pkcs15KeyUsage |= EPKCS15UsageSignSignRecover;
       
   470                 break;
       
   471                 }
       
   472             default:
       
   473                 {
       
   474                 break;
       
   475                 }
       
   476             }
       
   477         }
       
   478     return pkcs15KeyUsage;
       
   479     }
       
   480 
       
   481 // ----------------------------------------------------------
       
   482 // CCertSaverModel::CheckFSSpaceL(
       
   483 //    const TDesC8& aDataToSave)
       
   484 // ----------------------------------------------------------
       
   485 //
       
   486 void CCertSaverModel::CheckFSSpaceL( const TDesC8& aDataToSave )
       
   487     {
       
   488     if (SysUtil::FFSSpaceBelowCriticalLevelL( &iFs, aDataToSave.Size() ))
       
   489         {
       
   490         HBufC* p = StringLoader::LoadLC( R_CERTSAVER_MEMORY );
       
   491         CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue );
       
   492         note->ExecuteLD( p->Des() );
       
   493         CleanupStack::PopAndDestroy( p );
       
   494         User::Leave( KErrExitApp );
       
   495         }
       
   496     }
       
   497 
       
   498 // ----------------------------------------------------------
       
   499 // CCertSaverModel::SaveCertL()
       
   500 // Saves certificate
       
   501 // ----------------------------------------------------------
       
   502 //
       
   503 void CCertSaverModel::SaveCertL()
       
   504   {
       
   505     if ( !CertificateOkL() )
       
   506         {
       
   507         User::Leave( KErrCancel );
       
   508         }
       
   509 
       
   510     HBufC* message = HBufC::NewLC( KMaxLengthTextMeassageBody );
       
   511     TPtr msgPtr = message->Des();
       
   512     ConstructMessageL( msgPtr );
       
   513     CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL( *message );
       
   514     CleanupStack::PopAndDestroy( message );
       
   515     CleanupStack::PushL( dlg );
       
   516 
       
   517 
       
   518     dlg->PrepareLC( R_MESSAGE_QUERY_DOSAVE );
       
   519 
       
   520     HBufC* header = StringLoader::LoadLC( R_CERTSAVER_DETAILS_HEADING );
       
   521     dlg->QueryHeading()->SetTextL( header->Des() );
       
   522     CleanupStack::PopAndDestroy( header );
       
   523     CleanupStack::Pop( dlg );
       
   524     TBool doSave = dlg->RunLD();
       
   525 
       
   526     if ( doSave && iCertOwnerType == ECACertificate )
       
   527         {
       
   528         // warn user about security risk
       
   529         CAknQueryDialog* warningDialog = CAknQueryDialog::NewL();
       
   530         doSave = warningDialog->ExecuteLD( R_CERTSAVER_WARNING_NOTE );
       
   531         }
       
   532 
       
   533     if ( doSave )
       
   534         {
       
   535         //Check that there still is enough space to store the
       
   536         //certificate.
       
   537         CheckFSSpaceL( iNewCert->Encoding() );
       
   538         DoSaveCertL();
       
   539         }
       
   540     else
       
   541         {
       
   542         ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED );
       
   543         User::Leave( KErrCancel );
       
   544         }
       
   545   }
       
   546 
       
   547 // ----------------------------------------------------------
       
   548 // CCertSaverModel::InitCertStoreL()
       
   549 //
       
   550 // ----------------------------------------------------------
       
   551 //
       
   552 void CCertSaverModel::InitCertStoreL()
       
   553     {
       
   554     if ( !iUnifiedCertStore )
       
   555         {
       
   556         TRAPD( status, iUnifiedCertStore = CUnifiedCertStore::NewL( iFs, ETrue ) );
       
   557         if ( status != KErrNone )
       
   558             {
       
   559             ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED );
       
   560             User::Leave( KErrExitApp );
       
   561             }
       
   562         // initialize unified cert store
       
   563         status = iWrapper->InitializeCertStore( *iUnifiedCertStore );
       
   564         if ( status )
       
   565             {
       
   566             HandleSaveErrorL( status );
       
   567             User::Leave( KErrExitApp );
       
   568             }
       
   569         }
       
   570     }
       
   571 
       
   572 // ----------------------------------------------------------
       
   573 // CCertSaverModel::DoSaveCertL()
       
   574 // Tries to save the certificate to phone memory.
       
   575 // ----------------------------------------------------------
       
   576 //
       
   577 void CCertSaverModel::DoSaveCertL()
       
   578     {
       
   579     TInt status = KErrNone;
       
   580     CCertAttributeFilter* filter = NULL;
       
   581     TCertificateFormat certFormat = EX509Certificate;
       
   582     HBufC* secondaryName = NULL;
       
   583     TCertLabel labelBuf;
       
   584     CCertificate* certificate = NULL;
       
   585     HBufC* label = NULL;
       
   586 
       
   587     if ( NULL == iWrapper )
       
   588         {
       
   589         iWrapper = CCertSaverSyncWrapper::NewL();
       
   590         }
       
   591     // Init unified certstore
       
   592     InitCertStoreL();
       
   593 
       
   594     // Check that certificate doesn't already exist.
       
   595     // Fingerprint of certificate is used to confirm this.
       
   596     filter = CCertAttributeFilter::NewL();
       
   597     filter->SetFormat( iCertFormat );
       
   598     filter->SetOwnerType( iCertOwnerType );
       
   599     // Delete old array first
       
   600     iEntries.Close();
       
   601     status = iWrapper->ListCerts( *iUnifiedCertStore, iEntries, *filter );
       
   602     delete filter;
       
   603     filter = NULL;
       
   604     if ( status )
       
   605         {
       
   606         if ( status != KErrCancel )
       
   607             {
       
   608             HandleSaveErrorL( status );
       
   609             }
       
   610         User::Leave( KErrExitApp );
       
   611         }
       
   612 
       
   613     TBool found = EFalse;
       
   614 
       
   615     for ( TInt i = 0; i < iEntries.Count() && !found; ++i )
       
   616         {
       
   617         iWrapper->Retrieve( *iUnifiedCertStore, *iEntries[i], certificate );
       
   618         // Compare fingerprint of listed certificates to
       
   619         // fingerprint of new certificate
       
   620         // If the certificate is already in CACerts.dat,
       
   621         // then don't save it
       
   622         if ( iNewCert->Fingerprint() == certificate->Fingerprint() &&
       
   623             (( *iEntries[i]).Handle().iTokenHandle.iTokenTypeUid == KFileTokensUid ) )
       
   624             {
       
   625             found = ETrue;
       
   626             }
       
   627         delete certificate;
       
   628         certificate = NULL;
       
   629         }
       
   630 
       
   631     // Cancel if certificate already exists.
       
   632     if ( found )
       
   633         {
       
   634         HandleSaveErrorL( KErrAlreadyExists );
       
   635         User::Leave( KErrCancel );
       
   636         }
       
   637 
       
   638     // Create default label from the certificate
       
   639     X509CertNameParser::PrimaryAndSecondaryNameL(
       
   640         (*(CX509Certificate*)iNewCert), label, secondaryName );
       
   641     CleanupStack::PushL( label );
       
   642     delete secondaryName;
       
   643     secondaryName = NULL;
       
   644     labelBuf = label->Des().Left( CERTSAVER_MAX_LABEL_LEN );
       
   645     CleanupStack::PopAndDestroy( label );
       
   646     label = NULL;
       
   647     // Asks unique label from user.
       
   648     status = QueryLabelL( labelBuf, *iUnifiedCertStore );
       
   649     if ( status )
       
   650         {
       
   651         if ( status != KErrCancel )
       
   652             {
       
   653             HandleSaveErrorL( status );
       
   654             }
       
   655         User::Leave( KErrCancel );
       
   656         }
       
   657 
       
   658     if ( ECACertificate == iCertOwnerType )
       
   659         {
       
   660         // Query trusted UIDs
       
   661         status = QueryTrusterUidsL( iTrusterUids );
       
   662         if ( status )
       
   663             {
       
   664             HandleSaveErrorL( status );
       
   665             User::Leave( KErrCancel );
       
   666             }
       
   667         }
       
   668 
       
   669     // Get interface to writable store.
       
   670     TInt certstoreIndex( -1 );
       
   671     TInt count = iUnifiedCertStore->WritableCertStoreCount();
       
   672     if ( count > 0 )
       
   673         {
       
   674         for ( TInt i = 0; i < count; i++ )
       
   675             {
       
   676             MCTWritableCertStore& writableCertStore =
       
   677                     iUnifiedCertStore->WritableCertStore( i );
       
   678 
       
   679             MCTToken& token = writableCertStore.Token();
       
   680             TUid tokenuid = token.Handle().iTokenTypeUid;
       
   681             if ( ( tokenuid == KTrustedServerTokenUid ) && ( iCertOwnerType == EPeerCertificate ) ||
       
   682                  ( tokenuid == KFileTokensUid ) && ( iCertOwnerType == ECACertificate ) ||
       
   683                  ( tokenuid == KFileTokensUid ) && ( iCertOwnerType == EUserCertificate ) )
       
   684                 {
       
   685                 certstoreIndex = i;
       
   686                 break;
       
   687                 }
       
   688             }
       
   689 
       
   690         if ( certstoreIndex < 0 )
       
   691             {
       
   692             // Couldn't find certificate storage
       
   693             ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED );
       
   694             User::Leave( KErrExitApp );
       
   695             }
       
   696 
       
   697         status = iWrapper->AddCert( iUnifiedCertStore->WritableCertStore( certstoreIndex ),
       
   698                         labelBuf, iCertFormat, iCertOwnerType, 0, 0, iNewCert->Encoding() );
       
   699 
       
   700         if ( ( status == KErrNone ) && ( iCertOwnerType == EPeerCertificate) )
       
   701             {
       
   702             // Adding certificate succeded. Update trust site storage
       
   703             CTrustSitesStore* trustedSitesStore = CTrustSitesStore::NewL();
       
   704             CleanupStack::PushL( trustedSitesStore );
       
   705             TPtrC8 certBuf = iParser.CertificateBuf();
       
   706             TInt err = trustedSitesStore->AddL( certBuf, labelBuf );
       
   707             CleanupStack::PopAndDestroy( trustedSitesStore );
       
   708             }
       
   709 
       
   710         // If error happened, show error note and give up. Otherwise, continue
       
   711         HandleSaveErrorL( status );
       
   712         if ( status )
       
   713             {
       
   714             User::Leave( KErrCancel );
       
   715             }
       
   716         else
       
   717             {
       
   718             if ( ECACertificate == iCertOwnerType )
       
   719                 {
       
   720                 ++iSavedCACertsCount;
       
   721                 }
       
   722             else
       
   723                 {
       
   724                 ++iSavedUserCertsCount;
       
   725                 }
       
   726             }
       
   727         }
       
   728     else
       
   729         {
       
   730         // If there is none WritableCertStore,
       
   731         // then at least cacerts.dat is corrupted.
       
   732         ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED );
       
   733         User::Leave( KErrExitApp );
       
   734         }
       
   735 
       
   736     if ( ECACertificate == iCertOwnerType )
       
   737         {
       
   738         // get just saved certificate
       
   739         // first, create a filter
       
   740         filter = CCertAttributeFilter::NewL();
       
   741         filter->SetLabel( labelBuf );
       
   742         filter->SetFormat( certFormat );
       
   743         filter->SetOwnerType( ECACertificate );
       
   744 
       
   745         // Delete array
       
   746         iEntries.Close();
       
   747         // then list certificates
       
   748         status = iWrapper->ListCerts( *iUnifiedCertStore, iEntries, *filter );
       
   749         delete filter;
       
   750         filter = NULL;
       
   751 
       
   752         // If error happened, show error note and give up. Otherwise, continue
       
   753         if ( status )
       
   754             {
       
   755             HandleSaveErrorL( status );
       
   756             User::Leave( KErrExitApp );
       
   757             }
       
   758 
       
   759         // takes ownership of trusterUids
       
   760         status = iWrapper->SetApplicability(
       
   761             iUnifiedCertStore->WritableCertStore( certstoreIndex ), *(iEntries[0]), iTrusterUids );
       
   762 
       
   763         // If error happened, show error note and give up. Otherwise, continue
       
   764         if ( status )
       
   765             {
       
   766             HandleSaveErrorL( status );
       
   767             User::Leave( KErrExitApp );
       
   768             }
       
   769 
       
   770         // Downloaded certificate is trusted by default
       
   771         status = iWrapper->SetTrust(
       
   772             iUnifiedCertStore->WritableCertStore(certstoreIndex), *(iEntries[0]), ETrue );
       
   773         if ( status )
       
   774             {
       
   775             HandleSaveErrorL( status );
       
   776             }
       
   777 
       
   778 
       
   779         } // if ( ECACertificate == iCertOwnerType )
       
   780     }
       
   781 // ----------------------------------------------------------
       
   782 // CCertSaverModel::QueryLabel()
       
   783 // Queries label from user and confirms that it doesn't
       
   784 // already exist.
       
   785 // ----------------------------------------------------------
       
   786 //
       
   787 TInt CCertSaverModel::QueryLabelL( TCertLabel& aLabel, CUnifiedCertStore& aStore )
       
   788     {
       
   789     CCertAttributeFilter* filter = NULL;
       
   790     TInt status = KErrNone;
       
   791     RMPointerArray<CCTCertInfo> entries;
       
   792     TBool loop = ETrue;
       
   793 
       
   794     while ( loop )
       
   795         {
       
   796         CAknTextQueryDialog* dialog = CAknTextQueryDialog::NewL( aLabel );
       
   797       if ( !dialog->ExecuteLD( R_CERTSAVER_LABEL_QUERY ) )
       
   798             {
       
   799             // cancel
       
   800             ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED );
       
   801             return KErrCancel;
       
   802             }
       
   803         // Create filter to confirm that label doesn't already exist.
       
   804         filter = CCertAttributeFilter::NewL();
       
   805         filter->SetLabel( aLabel );
       
   806 
       
   807         // then list certificates
       
   808         status = iWrapper->ListCerts( aStore, entries, *filter );
       
   809         CleanupClosePushL( entries );
       
   810         delete filter;
       
   811 
       
   812         // If error happened, show error note and give up. Otherwise, continue
       
   813         if ( status )
       
   814             {
       
   815             HandleSaveErrorL( status );
       
   816             User::Leave( KErrExitApp );
       
   817             }
       
   818 
       
   819         if ( entries.Count() )
       
   820             {
       
   821             // Label already exists. Label is queried again.
       
   822             HandleSaveErrorL( KErrBadName );
       
   823             }
       
   824         else
       
   825             {
       
   826             // Label didn't exist.
       
   827             loop = EFalse;
       
   828             }
       
   829         CleanupStack::PopAndDestroy( &entries ); // entries
       
   830         } // while
       
   831 
       
   832     return status;
       
   833     }
       
   834 
       
   835 // ----------------------------------------------------------
       
   836 // CCertSaverModel::HandleSaveErrorL() const
       
   837 // Shows a note according to aStatus. aStatus is the status
       
   838 // of the save operation.
       
   839 // ----------------------------------------------------------
       
   840 //
       
   841 void CCertSaverModel::HandleSaveErrorL( TInt aStatus ) const
       
   842     {
       
   843     switch ( aStatus )
       
   844         {
       
   845         case KErrNone:
       
   846             {
       
   847             ShowConfirmationNoteL( R_CERTSAVER_ERROR_SAVEOK );
       
   848             break;
       
   849             }
       
   850         case KErrNotSupported:
       
   851             {
       
   852             ShowErrorNoteL( R_CERTSAVER_ERROR_UNSUPPORTED_CERT );
       
   853             break;
       
   854             }
       
   855         case KErrBadName:
       
   856             {
       
   857             ShowErrorNoteL( R_CERTSAVER_ERROR_LABEL_ALREADY_EXISTS );
       
   858             break;
       
   859             }
       
   860         case KErrAlreadyExists:
       
   861             {
       
   862             ShowErrorNoteL( R_CERTSAVER_ERROR_ALREADY_EXISTS );
       
   863             break;
       
   864             }
       
   865         case KErrArgument:
       
   866             {
       
   867             ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED );
       
   868             break;
       
   869             }
       
   870         default:
       
   871             {
       
   872             //No error note defined for unknown error.
       
   873             User::Leave( aStatus );
       
   874             break;
       
   875             }
       
   876         }   //switch
       
   877     }
       
   878 
       
   879 // ----------------------------------------------------------
       
   880 // CCertSaverModel::AddToMessageWithStringL() const
       
   881 // String loaded from resources with StringLoader.
       
   882 // ----------------------------------------------------------
       
   883 //
       
   884 void CCertSaverModel::AddToMessageWithStringL(
       
   885     TDes& aMessage, TInt aStringResID, const TDesC& aString ) const
       
   886     {
       
   887     HBufC* promptPtr = NULL;
       
   888     promptPtr = StringLoader::LoadL( aStringResID, aString );
       
   889     CleanupStack::PushL( promptPtr );
       
   890     TPtrC prompt( promptPtr->Des() );
       
   891 
       
   892     aMessage.Append( prompt );
       
   893 
       
   894     CleanupStack::PopAndDestroy( promptPtr ); // promptPtr
       
   895     }
       
   896 
       
   897 // ----------------------------------------------------------
       
   898 // CCertSaverModel::AddToMessageWithStringL() const
       
   899 // String loaded from resources with StringLoader.
       
   900 // ----------------------------------------------------------
       
   901 //
       
   902 void CCertSaverModel::AddToMessageWithIntL(
       
   903     TDes& aMessage,
       
   904     TInt aStringResID,
       
   905     TInt aInt ) const
       
   906     {
       
   907     HBufC* promptPtr = NULL;
       
   908     promptPtr = StringLoader::LoadL( aStringResID, aInt );
       
   909     CleanupStack::PushL( promptPtr );
       
   910     TPtrC prompt( promptPtr->Des() );
       
   911 
       
   912     aMessage.Append( prompt );
       
   913     aMessage.Append( KEnter );
       
   914 
       
   915     CleanupStack::PopAndDestroy( promptPtr ); // promptPtr
       
   916     }
       
   917 
       
   918 // ----------------------------------------------------------
       
   919 // CCertSaverModel::AddToMessageL() const
       
   920 // String loaded from resources with StringLoader.
       
   921 // ----------------------------------------------------------
       
   922 //
       
   923 void CCertSaverModel::AddToMessageL( TDes& aMessage, TInt aStringResID ) const
       
   924     {
       
   925     HBufC* promptPtr = NULL;
       
   926     promptPtr = StringLoader::LoadL( aStringResID );
       
   927     CleanupStack::PushL( promptPtr );
       
   928     TPtrC prompt( promptPtr->Des() );
       
   929 
       
   930     aMessage.Append( prompt );
       
   931     aMessage.Append( KEnter );
       
   932 
       
   933     CleanupStack::PopAndDestroy( promptPtr ); // promptPtr
       
   934     }
       
   935 
       
   936 // ----------------------------------------------------------
       
   937 // CCertSaverModel::ConstructMessageL() const
       
   938 // Creates the certificate details message shown to the user.
       
   939 // ----------------------------------------------------------
       
   940 //
       
   941 void CCertSaverModel::ConstructMessageL( TDes& aMessage ) const
       
   942     {
       
   943     HBufC16* issuerName = NULL;
       
   944     HBufC16* subjectName = NULL;
       
   945 
       
   946 
       
   947     X509CertNameParser::SubjectFullNameL( *((CX509Certificate*)iNewCert),
       
   948         subjectName );
       
   949     CleanupStack::PushL( subjectName );
       
   950 
       
   951     X509CertNameParser::IssuerFullNameL( *((CX509Certificate*)iNewCert),
       
   952         issuerName );
       
   953     CleanupStack::PushL( issuerName );
       
   954 
       
   955     AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_LABEL,
       
   956         CutCertificateField(*subjectName) );
       
   957     AddNewlinesToMessage( aMessage );
       
   958 
       
   959     AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_ISSUER,
       
   960         CutCertificateField( *issuerName ) );
       
   961     CleanupStack::PopAndDestroy( 2, subjectName );
       
   962     AddNewlinesToMessage( aMessage );
       
   963 
       
   964     if ( iCertOwnerType==EUserCertificate )
       
   965         {
       
   966         AddKeyUsageL( aMessage, *((CX509Certificate*)iNewCert) );
       
   967         }
       
   968 
       
   969     AddValidityPeriodL( aMessage, *((CX509Certificate*)iNewCert) );
       
   970 
       
   971     // SHA-1 fingerprint
       
   972     TBuf<KFingerprintLength> divided_fingerprint;
       
   973     DivideToBlocks( iNewCert->Fingerprint(), divided_fingerprint );
       
   974     AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_FINGERPRINT,
       
   975         divided_fingerprint );
       
   976 
       
   977     AddNewlinesToMessage( aMessage );
       
   978     divided_fingerprint.Zero();
       
   979 
       
   980     // MD5 fingerprint
       
   981     CMD5* md5 = CMD5::NewL();
       
   982     CleanupStack::PushL( md5 );
       
   983     TPtrC8 MD5fingerprint = md5->Hash( iNewCert->Encoding() );
       
   984 
       
   985     // Divide fingerprint to blocks
       
   986     DivideToBlocks( MD5fingerprint, divided_fingerprint );
       
   987     CleanupStack::PopAndDestroy( md5 );
       
   988     AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_FINGERPRINT_MD5,
       
   989         divided_fingerprint );
       
   990     AddNewlinesToMessage( aMessage );
       
   991     }
       
   992 
       
   993 // -----------------------------------------------------------------------------
       
   994 // CCTSecurityDialogsAO::AddKeyUsageL(...)
       
   995 // -----------------------------------------------------------------------------
       
   996 //
       
   997 void CCertSaverModel::AddKeyUsageL( TDes& aMessage, const CX509Certificate& aCert ) const
       
   998     {
       
   999     TKeyUsageX509 x509Usage = EX509UsageNone;
       
  1000     TKeyUsagePKCS15 pkcs15KeyUsage = EPKCS15UsageNone;
       
  1001     const CX509CertExtension* ext = aCert.Extension( KKeyUsage );
       
  1002     if (ext)
       
  1003         {
       
  1004         CX509KeyUsageExt* keyUsageExt =
       
  1005             CX509KeyUsageExt::NewLC( ext->Data() );
       
  1006         if ( keyUsageExt->IsSet( EX509DigitalSignature ) )
       
  1007             {
       
  1008             x509Usage |= EX509UsageDigitalSignature;
       
  1009             }
       
  1010         if ( keyUsageExt->IsSet( EX509NonRepudiation ) )
       
  1011             {
       
  1012             x509Usage |= EX509UsageNonRepudiation;
       
  1013             }
       
  1014         if ( keyUsageExt->IsSet( EX509KeyEncipherment ) )
       
  1015             {
       
  1016             x509Usage |= EX509UsageKeyEncipherment;
       
  1017             }
       
  1018         if ( keyUsageExt->IsSet( EX509DataEncipherment ) )
       
  1019             {
       
  1020             x509Usage |= EX509UsageDataEncipherment;
       
  1021             }
       
  1022         if ( keyUsageExt->IsSet( EX509KeyAgreement ) )
       
  1023             {
       
  1024             x509Usage |= EX509UsageKeyAgreement;
       
  1025             }
       
  1026         if ( keyUsageExt->IsSet( EX509KeyCertSign ) )
       
  1027             {
       
  1028             x509Usage |= EX509UsageKeyCertSign;
       
  1029             }
       
  1030         if ( keyUsageExt->IsSet( EX509CRLSign ) )
       
  1031             {
       
  1032             x509Usage |= EX509UsageCRLSign;
       
  1033             }
       
  1034         if ( keyUsageExt->IsSet( EX509EncipherOnly ) )
       
  1035             {
       
  1036             x509Usage |= EX509UsageEncipherOnly;
       
  1037             }
       
  1038         if ( keyUsageExt->IsSet( EX509DecipherOnly ) )
       
  1039             {
       
  1040             x509Usage |= EX509UsageDecipherOnly;
       
  1041             }
       
  1042         CleanupStack::PopAndDestroy( keyUsageExt );
       
  1043         }
       
  1044 
       
  1045     pkcs15KeyUsage = KeyUsageX509ToPKCS15Private( x509Usage );
       
  1046 
       
  1047     TInt usage = 0;
       
  1048     switch( pkcs15KeyUsage )
       
  1049         {
       
  1050         case EPKCS15UsageSignSignRecover:
       
  1051         case EPKCS15UsageSign:
       
  1052         case EPKCS15UsageSignDecrypt:
       
  1053             {
       
  1054             usage = R_QTN_CM_CLIENT_AUTHENTICATION;
       
  1055             break;
       
  1056             }
       
  1057         case EPKCS15UsageNonRepudiation:
       
  1058             {
       
  1059             usage = R_QTN_CM_DIGITAL_SIGNING;
       
  1060             break;
       
  1061             }
       
  1062         default:
       
  1063             {
       
  1064             usage = R_QTN_CM_NOT_DEFINED;
       
  1065             break;
       
  1066             }
       
  1067         }
       
  1068     AddToMessageL( aMessage, R_QTN_CM_KEY_USAGE );
       
  1069     HBufC* usageString = iAppUi->CoeEnv()->AllocReadResourceLC( usage );
       
  1070     aMessage.Append( *usageString );
       
  1071     CleanupStack::PopAndDestroy( usageString );
       
  1072     AddNewlinesToMessage( aMessage );
       
  1073     }
       
  1074 
       
  1075 // -----------------------------------------------------------------------------
       
  1076 // CCTSecurityDialogsAO::AddValidityPeriodL(...)
       
  1077 // -----------------------------------------------------------------------------
       
  1078 //
       
  1079 void CCertSaverModel::AddValidityPeriodL(
       
  1080     TDes& aMessage, const CX509Certificate& aCert ) const
       
  1081     {
       
  1082     // Hometime's offset to UTC
       
  1083     TLocale locale;
       
  1084     TTimeIntervalSeconds offSet = locale.UniversalTimeOffset();
       
  1085     AddToMessageL( aMessage, R_CERTSAVER_QTN_CM_VALID_FROM );
       
  1086 
       
  1087     const CValidityPeriod& validityPeriod = aCert.ValidityPeriod();
       
  1088     TTime startValue = validityPeriod.Start();
       
  1089     startValue += offSet;
       
  1090     TBuf<KMaxLengthTextDateString> startString;
       
  1091     // read format string from AVKON resource
       
  1092     HBufC* dateFormatString = iAppUi->CoeEnv()->AllocReadResourceLC(
       
  1093         R_QTN_DATE_USUAL_WITH_ZERO );
       
  1094     // format the date to user readable format. The format is locale dependent
       
  1095     startValue.FormatL( startString, *dateFormatString );
       
  1096     AknTextUtils::DisplayTextLanguageSpecificNumberConversion( startString );
       
  1097     CleanupStack::PopAndDestroy( dateFormatString ); // dateFormatString
       
  1098     aMessage.Append( startString );
       
  1099     AddNewlinesToMessage( aMessage );
       
  1100 
       
  1101     AddToMessageL( aMessage, R_CERTSAVER_QTN_CM_VALID_UNTIL );
       
  1102     TTime finishValue = validityPeriod.Finish();
       
  1103     finishValue += offSet;
       
  1104     TBuf<KMaxLengthTextDateString> finishString;
       
  1105     // read format string from AVKON resource
       
  1106     dateFormatString = iAppUi->CoeEnv()->AllocReadResourceLC(
       
  1107         R_QTN_DATE_USUAL_WITH_ZERO );
       
  1108     // format the date to user readable format. The format is locale dependent
       
  1109     finishValue.FormatL( finishString, *dateFormatString );
       
  1110     AknTextUtils::DisplayTextLanguageSpecificNumberConversion( finishString );
       
  1111     CleanupStack::PopAndDestroy(); // dateFormatString
       
  1112     aMessage.Append( finishString );
       
  1113     AddNewlinesToMessage( aMessage );
       
  1114     }
       
  1115 
       
  1116 // ----------------------------------------------------------
       
  1117 // CCertSaverModel::AddNewlinesToMessage() const
       
  1118 // Adds two new lines to message.
       
  1119 // ----------------------------------------------------------
       
  1120 //
       
  1121 void CCertSaverModel::AddNewlinesToMessage( TDes& aMessage ) const
       
  1122     {
       
  1123     aMessage.Append( KDoubleEnter );
       
  1124     }
       
  1125 
       
  1126 // ----------------------------------------------------------
       
  1127 // CCertSaverModel::CertificateSupported() const
       
  1128 // Checks that cert is of supported type.
       
  1129 // ----------------------------------------------------------
       
  1130 //
       
  1131 TBool CCertSaverModel::CertificateSupported() const
       
  1132     {
       
  1133     if ( iCertFormat == EX509Certificate &&
       
  1134        ( iCertOwnerType == ECACertificate ||
       
  1135          iCertOwnerType == EPeerCertificate ||
       
  1136          iCertOwnerType == EUserCertificate))
       
  1137         {
       
  1138         return ETrue;
       
  1139         }
       
  1140     return EFalse;
       
  1141     }
       
  1142 
       
  1143 
       
  1144 // ----------------------------------------------------------
       
  1145 // CCertSaverModel::CertificateOkL() const
       
  1146 // Checks that cert is ok. Shows an error note if not.
       
  1147 // If certificate is not valid yet/anymore an error note is shown
       
  1148 // but ETrue is returned so that user can still save the
       
  1149 // certificate.
       
  1150 // ----------------------------------------------------------
       
  1151 //
       
  1152 TBool CCertSaverModel::CertificateOkL() const
       
  1153     {
       
  1154     if ( !CertificateSupported() )
       
  1155         {
       
  1156         ShowErrorNoteL( R_CERTSAVER_ERROR_UNSUPPORTED_CERT );
       
  1157         return EFalse;
       
  1158         }
       
  1159     if ( CertNotValidAnymore() )
       
  1160         {
       
  1161         ShowErrorNoteL( R_CERTSAVER_ERROR_CERT_NOT_VALID );
       
  1162         return ETrue;
       
  1163         }
       
  1164     else if ( CertNotValidYet() )
       
  1165         {
       
  1166         ShowErrorNoteL( R_CERTSAVER_ERROR_CERT_NOT_VALID_YET );
       
  1167         }
       
  1168     return ETrue;
       
  1169     }
       
  1170 
       
  1171 // ----------------------------------------------------------
       
  1172 // CCertSaverModel::CertNotValidAnymore() const
       
  1173 // Checks if cert isn't valid anymore.
       
  1174 // ----------------------------------------------------------
       
  1175 //
       
  1176 TBool CCertSaverModel::CertNotValidAnymore() const
       
  1177     {
       
  1178     TTime homeTime;
       
  1179     homeTime.HomeTime();
       
  1180     if ( iNewCert->ValidityPeriod().Finish() < homeTime )
       
  1181         {
       
  1182         return ETrue;
       
  1183         }
       
  1184     return EFalse;
       
  1185     }
       
  1186 
       
  1187 // ----------------------------------------------------------
       
  1188 // CCertSaverModel::CertNotValidYet() const
       
  1189 // Checks if cert isn't valid yet.
       
  1190 // ----------------------------------------------------------
       
  1191 //
       
  1192 TBool CCertSaverModel::CertNotValidYet() const
       
  1193     {
       
  1194     TTime homeTime;
       
  1195     homeTime.HomeTime();
       
  1196     if ( iNewCert->ValidityPeriod().Start() > homeTime )
       
  1197         {
       
  1198         return ETrue;
       
  1199         }
       
  1200     return EFalse;
       
  1201     }
       
  1202 
       
  1203 // ----------------------------------------------------------
       
  1204 // CCertSaverModel::ShowInformationNoteL() const
       
  1205 // Creates and shows a confirmation note.
       
  1206 // ----------------------------------------------------------
       
  1207 //
       
  1208 void CCertSaverModel::ShowInformationNoteL( TInt aResourceID ) const
       
  1209     {
       
  1210     HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID );
       
  1211     CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue );
       
  1212     note->ExecuteLD( buffer->Des() );
       
  1213     CleanupStack::PopAndDestroy( buffer );
       
  1214     }
       
  1215 // ----------------------------------------------------------
       
  1216 // CCertSaverModel::ShowConfirmationNoteL() const
       
  1217 // Creates and shows a confirmation note.
       
  1218 // ----------------------------------------------------------
       
  1219 //
       
  1220 void CCertSaverModel::ShowConfirmationNoteL( TInt aResourceID ) const
       
  1221     {
       
  1222     HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID );
       
  1223     CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote( ETrue );
       
  1224     note->ExecuteLD( buffer->Des() );
       
  1225     CleanupStack::PopAndDestroy( buffer );
       
  1226     }
       
  1227 
       
  1228 // ----------------------------------------------------------
       
  1229 // CCertSaverModel::ShowErrorNoteL() const
       
  1230 // Creates and shows an error note.
       
  1231 // ----------------------------------------------------------
       
  1232 //
       
  1233 void CCertSaverModel::ShowErrorNoteL( TInt aResourceID ) const
       
  1234     {
       
  1235     HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID );
       
  1236     CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue );
       
  1237     note->ExecuteLD(buffer->Des());
       
  1238     CleanupStack::PopAndDestroy( buffer );
       
  1239     }
       
  1240 
       
  1241 // ----------------------------------------------------------
       
  1242 // CCertSaverModel::TrimCertificateFields() const
       
  1243 // Trims given descriptor so that everything after and
       
  1244 // including the fourth semicolon (;) is cropped.
       
  1245 // Returns the trimmed certificate field.
       
  1246 // ----------------------------------------------------------
       
  1247 //
       
  1248 TPtrC CCertSaverModel::TrimCertificateFields( TPtrC aField ) const
       
  1249     {
       
  1250     TPtrC cutField = CutCertificateField( aField );
       
  1251     // Find one semicolon at a time and crop the
       
  1252     // helpField from the left to search for the next semicolon
       
  1253     TInt position = cutField.Locate( ';' ); // 1st semicolon
       
  1254     TInt fieldLength = cutField.Length();
       
  1255 
       
  1256     // Need to check that position is not bigger than the length of cutField
       
  1257     if ( position != KErrNotFound && position < fieldLength )
       
  1258         {
       
  1259         // Locate function counts from zero, Mid function
       
  1260         // counts also from zero, add one to exclude the found semicolon
       
  1261         TInt totalPosition = position;
       
  1262         TPtrC field = cutField.Mid(totalPosition + 1);
       
  1263         position = field.Locate(';'); // 2nd semicolon
       
  1264         fieldLength = field.Length();
       
  1265 
       
  1266         if ( position != KErrNotFound && position < fieldLength )
       
  1267             {
       
  1268             totalPosition += position + 1;
       
  1269             TPtrC field = cutField.Mid( totalPosition + 1 );
       
  1270             position = field.Locate( ';' ); // 3rd semicolon
       
  1271             fieldLength = field.Length();
       
  1272 
       
  1273             if ( position != KErrNotFound && position < fieldLength )
       
  1274                 {
       
  1275                 totalPosition += position + 1;
       
  1276                 TPtrC field = cutField.Mid( totalPosition + 1 );
       
  1277                 position = field.Locate( ';' ); // 4th semicolon
       
  1278                 fieldLength = field.Length();
       
  1279 
       
  1280                 if ( position != KErrNotFound && position < fieldLength )
       
  1281                   {
       
  1282                   totalPosition += position + 1;
       
  1283                   // Extract the leftmost part of the data field up to n:th character
       
  1284                   TPtrC field = cutField.Mid( 0, totalPosition );
       
  1285                   return field;
       
  1286                   } // if
       
  1287                 } // if
       
  1288             } // if
       
  1289         } // if
       
  1290     return cutField;
       
  1291     }
       
  1292 
       
  1293 // ----------------------------------------------------------
       
  1294 // CCertSaverModel::CutCertificateField() const
       
  1295 // If given descriptor is larger than defined maximum length
       
  1296 // this function cuts it.
       
  1297 // ----------------------------------------------------------
       
  1298 //
       
  1299 TPtrC CCertSaverModel::CutCertificateField( TPtrC aField ) const
       
  1300     {
       
  1301     TInt fieldLength = aField.Length();
       
  1302     if ( fieldLength >= KMaxLengthTextCertIdentifierVisible )
       
  1303         {
       
  1304         TPtrC cutCertLabel = aField.Mid( 0, KMaxLengthTextCertIdentifierVisible );
       
  1305         return cutCertLabel;
       
  1306         }
       
  1307     return aField;
       
  1308     }
       
  1309 
       
  1310 // ----------------------------------------------------------
       
  1311 // CCertSaverModel::QueryTrusterUidsL()
       
  1312 // Does needed tasks to exit.
       
  1313 // ----------------------------------------------------------
       
  1314 //
       
  1315 TInt CCertSaverModel::QueryTrusterUidsL( RArray<TUid>& aUids )
       
  1316     {
       
  1317     TInt ret = KErrCancel;
       
  1318     CArrayFixFlat<TInt>* selectionArray =
       
  1319         new (ELeave)  CArrayFixFlat<TInt>( KTrusterArrayInitSize );
       
  1320     CleanupStack::PushL( selectionArray );
       
  1321     CDesCArray* itemsArray = new (ELeave) CDesCArrayFlat( KTrusterArrayInitSize );
       
  1322     CleanupStack::PushL( itemsArray );
       
  1323 
       
  1324     CCertificateAppInfoManager* appInfoManager =
       
  1325         CCertificateAppInfoManager::NewL( iFs, EFalse );
       
  1326     CleanupStack::PushL( appInfoManager );
       
  1327     // copy applications to own array
       
  1328     const RArray<TCertificateAppInfo>& apps = appInfoManager->Applications();
       
  1329     RArray<TCertificateAppInfo> appsInItemArray( KTrusterArrayInitSize );
       
  1330     CleanupClosePushL( appsInItemArray );
       
  1331     UpdateTrustListboxItemL( apps, appsInItemArray, *itemsArray );
       
  1332 
       
  1333     CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog( selectionArray );
       
  1334     CleanupStack::PushL( dlg );
       
  1335     dlg->PrepareLC( R_CERTSAVER_TRUST_SETTINGS_QUERY );
       
  1336     dlg->SetItemTextArray( itemsArray );
       
  1337     dlg->SetOwnershipType( ELbmDoesNotOwnItemArray );
       
  1338     if ( dlg->RunLD() )
       
  1339         {
       
  1340         for ( TInt i = 0; i < selectionArray->Count(); ++i )
       
  1341             {
       
  1342             TInt ii = (*selectionArray)[ i ];
       
  1343             aUids.Append( appsInItemArray[ ii ].Id() );
       
  1344             }
       
  1345         ret = KErrNone;
       
  1346         }
       
  1347     else
       
  1348         {
       
  1349         ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED );
       
  1350         ret = KErrCancel;
       
  1351         }
       
  1352     CleanupStack::Pop( dlg );
       
  1353     CleanupStack::PopAndDestroy( 4, selectionArray );
       
  1354     return ret;
       
  1355     }
       
  1356 
       
  1357 // ----------------------------------------------------------
       
  1358 // CCertSaverModel::QueryTrustedSiteL()
       
  1359 // Shows query for trusted site certificate
       
  1360 // ----------------------------------------------------------
       
  1361 //
       
  1362 TInt CCertSaverModel::QueryTrustedSiteL()
       
  1363     {
       
  1364     TInt ret = KErrCancel;
       
  1365     HBufC* label = NULL;
       
  1366     HBufC* secondaryName = NULL;
       
  1367     TCertLabel labelBuf;
       
  1368 
       
  1369     X509CertNameParser::PrimaryAndSecondaryNameL(
       
  1370         (*(CX509Certificate*)iNewCert), label, secondaryName );
       
  1371     CleanupStack::PushL( label );
       
  1372     delete secondaryName;
       
  1373     secondaryName = NULL;
       
  1374     labelBuf = label->Des().Left( CERTSAVER_MAX_LABEL_LEN );
       
  1375 
       
  1376 
       
  1377     HBufC* prompt = StringLoader::LoadLC( R_CERTSAVER_TRUSTEDSITE_WARNING, labelBuf );
       
  1378 
       
  1379     CAknMessageQueryDialog* note = CAknMessageQueryDialog::NewL( *prompt );
       
  1380 
       
  1381     note->PrepareLC( R_CERTSAVER_TRUSTED_SITE_QUERY );
       
  1382     note->SetPromptL( *prompt );
       
  1383 
       
  1384     if ( note->RunLD() )
       
  1385         {
       
  1386         ret = KErrNone;
       
  1387         }
       
  1388     else
       
  1389         {
       
  1390         ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED );
       
  1391         ret = KErrCancel;
       
  1392         }
       
  1393 
       
  1394     CleanupStack::PopAndDestroy( prompt );
       
  1395 
       
  1396     CleanupStack::PopAndDestroy( label );
       
  1397     return ret;
       
  1398     }
       
  1399 
       
  1400 // ----------------------------------------------------------
       
  1401 // CCertSaverModel::UpdateTrustListboxItemL()
       
  1402 // Updates trust setting listbox items
       
  1403 // ----------------------------------------------------------
       
  1404 //
       
  1405 void CCertSaverModel::UpdateTrustListboxItemL(
       
  1406     const RArray<TCertificateAppInfo>& aApps,
       
  1407     RArray<TCertificateAppInfo>& aAppsInItemArray,
       
  1408     CDesCArray& aItemsArray ) const
       
  1409   {
       
  1410     for ( TInt i = 0; i < aApps.Count(); i++ )
       
  1411         {
       
  1412         TCertificateAppInfo appInfo = aApps[ i ];
       
  1413         TBuf<KItemBufLen> item;
       
  1414         item.Append( KCertSaverListBoxItemPrefix );
       
  1415         TBuf<KMaxName> resource;
       
  1416 
       
  1417         switch( appInfo.Id().iUid )
       
  1418             {
       
  1419             case KWTLSTrusterUID:
       
  1420                 {
       
  1421                 // X.509 certiticate isn't needed with WTLS
       
  1422                 break;
       
  1423                 }
       
  1424             case KInternetTrusterUID:
       
  1425                 {
       
  1426                iAppUi->CoeEnv()->ReadResource(
       
  1427                 resource, R_CERTSAVER_ITEM_MAIL_IMAGE_CONN );
       
  1428                 break;
       
  1429                 }
       
  1430             case KApplicationControllerTrusterUID:
       
  1431                 {
       
  1432                 // SWI certs are ROM based in platsec world.
       
  1433                 break;
       
  1434                 }
       
  1435             case KJavaInstallTrusterUID:
       
  1436                 {
       
  1437                 // MIDP certstore is read-only..
       
  1438                 break;
       
  1439                 }
       
  1440             case KOCSPTrusterUID:
       
  1441                 {
       
  1442                 iAppUi->CoeEnv()->ReadResource( resource, R_CERTSAVER_ITEM_OCSP );
       
  1443                 break;
       
  1444                 }
       
  1445             case KVPNUID:
       
  1446                 {
       
  1447                 iAppUi->CoeEnv()->ReadResource( resource, R_CERTSAVER_ITEM_VPN );
       
  1448                 break;
       
  1449                 }
       
  1450             default:
       
  1451                 {
       
  1452                 resource = appInfo.Name();
       
  1453                 break;
       
  1454                 }
       
  1455             }
       
  1456         if ( 0 < resource.Length())
       
  1457             {
       
  1458             item.Append( resource );
       
  1459             aItemsArray.AppendL( item );
       
  1460             aAppsInItemArray.Append( appInfo );
       
  1461             resource.Zero();
       
  1462             }
       
  1463         }
       
  1464   }
       
  1465 
       
  1466 // ---------------------------------------------------------
       
  1467 // CCertManUIViewAuthority::DevideToBlocks
       
  1468 // ---------------------------------------------------------
       
  1469 //
       
  1470 void CCertSaverModel::DivideToBlocks( const TDesC8& aInput, TDes& aOutput ) const
       
  1471     {
       
  1472     _LIT( KBlockSeparator, " " );
       
  1473     const TInt KBlockLength = 2;
       
  1474     TInt blockIndex = 0;
       
  1475     for ( TInt j = 0 ; j < aInput.Length() ; j++ )
       
  1476         {
       
  1477         if ( blockIndex == KBlockLength )
       
  1478             {
       
  1479             aOutput.Append( KBlockSeparator );
       
  1480             blockIndex = 0;
       
  1481             }
       
  1482         aOutput.AppendNumFixedWidthUC( (TUint)(aInput[ j ]), EHex, 2 );
       
  1483         ++blockIndex;
       
  1484         }
       
  1485     }
       
  1486 
       
  1487 // ----------------------------------------------------
       
  1488 // CCertSaverModel::SavePKCS12L()
       
  1489 // Saves content of the PKCS#12 file
       
  1490 // ----------------------------------------------------
       
  1491 //
       
  1492 void CCertSaverModel::SavePKCS12L()
       
  1493     {
       
  1494     HBufC* message = HBufC::NewLC( KMaxLengthTextMeassageBody );
       
  1495     TPtr msgPtr = message->Des();
       
  1496     ConstructPKCS12QueryMsgL(msgPtr, iParser.Keys().Count(),
       
  1497                             iParser.UserCertificates().Count(),
       
  1498                             iParser.CACertificates().Count() );
       
  1499     TBool save = DoMessageQueryL(
       
  1500         R_MESSAGE_QUERY_DOSAVE, R_CERTSAVER_HEADER_PKCS12_FILE_CONTAINS,
       
  1501         *message );
       
  1502     CleanupStack::PopAndDestroy( message );
       
  1503     message = NULL;
       
  1504     if ( !save )
       
  1505         {
       
  1506         ShowInformationNoteL( R_CERTSAVER_PKCS12_DISCARDED );
       
  1507         User::Leave( KErrExitApp );
       
  1508         }
       
  1509     TInt status = KErrNone;
       
  1510     // save private keys
       
  1511     TRAP( status, SavePrivateKeyL() );
       
  1512 
       
  1513     // save user certificates if private key was saved.
       
  1514     if ( ( iSavedKeysCount > 0 || iKeyAlreadyExists ) && iParser.UserCertificates().Count() > 0 )
       
  1515         {
       
  1516         for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ )
       
  1517             {
       
  1518             const CX509Certificate* cert = iParser.UserCertificates().At(i);
       
  1519             iCertOwnerType = EUserCertificate;
       
  1520             iCertFormat = EX509Certificate;
       
  1521             iNewCert = cert;
       
  1522             TRAP( status, SaveCertL() );
       
  1523             if ( KErrExitApp == status )
       
  1524                 {
       
  1525                 User::Leave( KErrExitApp );
       
  1526                 }
       
  1527             }
       
  1528         }
       
  1529     // save CA certificates
       
  1530     if ( iParser.CACertificates().Count() > 0 )
       
  1531         {
       
  1532         for ( TInt i = 0; i < iParser.CACertificates().Count(); i++ )
       
  1533             {
       
  1534             const CX509Certificate* cert = iParser.CACertificates().At( i );
       
  1535             iCertOwnerType = ECACertificate;
       
  1536             iCertFormat = EX509Certificate;
       
  1537             iNewCert = cert;
       
  1538             TRAP( status, SaveCertL() );
       
  1539             if ( KErrExitApp == status )
       
  1540                 {
       
  1541                 User::Leave( KErrExitApp );
       
  1542                 }
       
  1543             }
       
  1544         }
       
  1545     if ( iSavedCACertsCount != 0 || iSavedKeysCount != 0
       
  1546         || iSavedUserCertsCount != 0 )
       
  1547         {
       
  1548         message = HBufC::NewLC( KMaxLengthTextMeassageBody );
       
  1549         TPtr msgPtr2 = message->Des();
       
  1550         ConstructPKCS12QueryMsgL(
       
  1551             msgPtr2, iSavedKeysCount, iSavedUserCertsCount, iSavedCACertsCount );
       
  1552         DoMessageQueryL(
       
  1553             R_MESSAGE_QUERY_SAVED, R_CERTSAVER_HEADER_SAVED, *message );
       
  1554         CleanupStack::PopAndDestroy( message );
       
  1555         }
       
  1556     else
       
  1557         {
       
  1558         ShowInformationNoteL( R_QTN_CM_PKCS12_SAVING_FAILED );
       
  1559         }
       
  1560     }
       
  1561 
       
  1562 // ----------------------------------------------------------
       
  1563 // CCertSaverModel::DoMessageQuery()
       
  1564 // Displays message query dialog for user.
       
  1565 // ----------------------------------------------------------
       
  1566 //
       
  1567 TBool CCertSaverModel::DoMessageQueryL(
       
  1568     TInt aDialogResId,
       
  1569     TInt aHeadingResId,
       
  1570     TDesC& aMessage )
       
  1571     {
       
  1572     CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL( aMessage );
       
  1573     CleanupStack::PushL( dlg );
       
  1574     dlg->PrepareLC( aDialogResId );
       
  1575 
       
  1576     HBufC* header = StringLoader::LoadLC( aHeadingResId );
       
  1577     dlg->QueryHeading()->SetTextL( header->Des() );
       
  1578     CleanupStack::PopAndDestroy( header );
       
  1579     CleanupStack::Pop( dlg );
       
  1580     return dlg->RunLD();
       
  1581     }
       
  1582 
       
  1583 // ----------------------------------------------------------
       
  1584 // CCertSaverModel::ConstructPKCS12QueryMsgL() const
       
  1585 // Creates the certificate details message shown to the user.
       
  1586 // ----------------------------------------------------------
       
  1587 //
       
  1588 void CCertSaverModel::ConstructPKCS12QueryMsgL(
       
  1589     TDes& aMessage,
       
  1590     TInt aPrivateKeys,
       
  1591     TInt aUserCerts,
       
  1592     TInt aCACerts ) const
       
  1593     {
       
  1594     if ( aPrivateKeys > 0 )
       
  1595         {
       
  1596         if ( aPrivateKeys == 1 )
       
  1597             {
       
  1598             AddToMessageL( aMessage, R_CERTSAVER_ONE_PRIVATE_KEY );
       
  1599             }
       
  1600         else
       
  1601             {
       
  1602             AddToMessageWithIntL( aMessage, R_CERTSAVER_PRIVATE_KEYS, aPrivateKeys );
       
  1603             }
       
  1604         }
       
  1605     if ( aUserCerts > 0 )
       
  1606         {
       
  1607         if ( aUserCerts == 1 )
       
  1608             {
       
  1609             AddToMessageL(
       
  1610                 aMessage, R_CERTSAVER_ONE_PERSONAL_CERTIFICATE );
       
  1611             }
       
  1612         else
       
  1613             {
       
  1614             AddToMessageWithIntL(
       
  1615                 aMessage, R_CERTSAVER_PERSONAL_CERTIFICATES, aUserCerts );
       
  1616             }
       
  1617         }
       
  1618     if ( aCACerts > 0 )
       
  1619         {
       
  1620 
       
  1621         if ( aCACerts == 1 )
       
  1622             {
       
  1623             AddToMessageL(
       
  1624                 aMessage, R_CERTSAVER_ONE_AUTHORITY_CERTIFICATE );
       
  1625             }
       
  1626         else
       
  1627             {
       
  1628             AddToMessageWithIntL(
       
  1629                 aMessage, R_CERTSAVER_AUTHORITY_CERTIFICATES, aCACerts );
       
  1630             }
       
  1631         }
       
  1632     }
       
  1633 
       
  1634 // End of File