diff -r 000000000000 -r 164170e6151a pkiutilities/CertSaver/src/CertSaverModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkiutilities/CertSaver/src/CertSaverModel.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,1634 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class that handles user input and launching of dialogs +* +*/ + + +// INCLUDE FILES +#include // Note dialogs +#include // For CAknMessageQueryDialog +#include // For loading resource strings +#include // For saving the certificates +#include // For saving the certificates +#include // For FFSSpaceBelowCriticalLevelL(..) +#include // For default label +#include // For CX509Certificate +#include // For WTLSCertificate +#include // MD5 fingerprint +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "CertSaverModel.h" +#include "CertSaverDocument.h" +#include "CertSaverAppUi.h" +#include "CertSaverSyncWrapper.h" +#include "certsaver.hrh" +#include "securityuisvariant.hrh" + +// CONSTANTS +const TInt32 KWTLSTrusterUID( 268479059 ); +const TInt32 KInternetTrusterUID( 268441661 ); +const TInt32 KApplicationControllerTrusterUID( 268452523 ); +const TInt32 KJavaInstallTrusterUID( 270506792 ); +const TInt32 KOCSPTrusterUID( 268478646 ); +const TInt32 KVPNUID( 270498195 ); + +const TInt KTrusterArrayInitSize( 2 ); + +const TInt KMaxLengthTextMeassageBody( 5000 ); +const TInt KMaxLengthTextDateString( 11 ); // "dd/mm/yyyy0" + +//Issuer and Owner max visible length +const TInt KMaxLengthTextCertIdentifierVisible( 1000 ); +const TInt KAttempts( 3 ); + +const TInt KFingerprintLength( 50 ); + +_LIT( KCertSaverListBoxItemPrefix, "1\t" ); +const TInt KItemBufLen = 2 + KMaxName; + +_LIT( KPrivateKeyLabel, "PrivateKey " ); +const TInt KPrivaKeyLabelLength( 50 ); +_LIT( KDateString,"%D%M%Y%1%2%3" ); +_LIT( KTimeString,"%-B%:0%J%:1%T%:2%S%:3%+B" ); +_LIT( KSpace, " " ); +_LIT( KDoubleEnter, "\n\n" ); +_LIT( KEnter, "\n" ); + +const TUid KTrustedServerTokenUid = { 0x101FB66F }; +const TUid KFileTokensUid = { 0x101F501A }; + +_LIT_SECURITY_POLICY_V1( KSymbianKeyStoreMgmtPolicy, + VID_DEFAULT, ECapabilityWriteUserData ); +_LIT_SECURITY_POLICY_C1( KSymbianKeyStoreUsePolicy, ECapabilityReadUserData ); + + +// ================= MEMBER FUNCTIONS ======================= + +// Destructor +CCertSaverModel::~CCertSaverModel() + { + delete iWrapper; + iEntries.Close(); + delete iUnifiedCertStore; + iTrusterUids.Close(); + } + +// ---------------------------------------------------------- +// CCertSaverModel::CCertSaverModel( +// const CCertSaverDocument* aDocument, CCertSaverAppUi* aAppUi) +// ---------------------------------------------------------- +// +CCertSaverModel::CCertSaverModel( + CCertSaverAppUi* aAppUi, + const CCertParser& aParser ): + iAppUi( aAppUi ), iFs( iAppUi->CoeEnv()->FsSession() ), iParser( aParser ), + iSavedCACertsCount( 0 ), iSavedKeysCount( 0 ), + iSavedUserCertsCount( 0 ), iKeyAlreadyExists( EFalse ) + { + } + +// ---------------------------------------------------------- +// CCertSaverModel::SaveCertificateL() +// ---------------------------------------------------------- +// +void CCertSaverModel::SaveCertificateL( + const CX509Certificate& aCertificate, + const TCertificateOwnerType& aOwnerType, + const TCertificateFormat& aCertFormat ) + { + iCertOwnerType = aOwnerType; + iCertFormat = aCertFormat; + iNewCert = &aCertificate; + + if ( aOwnerType == EPeerCertificate ) + { + TInt ret = QueryTrustedSiteL(); + if ( ret != KErrNone ) + { + return; + } + } + + SaveCertL(); + } + +// ---------------------------------------------------------- +// CCertSaverModel::DoSavePrivateKeyL() +// +// ---------------------------------------------------------- +// +void CCertSaverModel::DoSavePrivateKeyL( const TDesC8& aKey ) + { + CheckFSSpaceL( aKey ); + + TKeyIdentifier keyIdentifier; + CDecPKCS8Data* pkcs8Data = TASN1DecPKCS8::DecodeDERL( aKey ); + CleanupStack::PushL( pkcs8Data ); + MPKCS8DecodedKeyPairData* keyPairData = pkcs8Data->KeyPairData(); + keyPairData->GetKeyIdentifierL( keyIdentifier ); + + TTime startDate; + TTime endDate; + GetKeyValidityPeriodL( startDate, endDate, keyIdentifier ); + + TInt err = KErrNone; + CCTKeyInfo* keyInfo = NULL; + TBuf keyLabel( KPrivateKeyLabel ); + TKeyUsagePKCS15 keyUsage = KeyUsageL( keyIdentifier, pkcs8Data->Algorithm() ); + CleanupStack::PopAndDestroy( pkcs8Data ); + if (KeyAlreadyExistsL( startDate, endDate, keyIdentifier, keyUsage) ) + { + User::Leave( KErrNone ); + } + + TInt accessType( 0 ); + + accessType |= CCTKeyInfo::EExtractable; + + for ( TInt i = 0; i < KAttempts; i++ ) + { + CreateKeyLabelL( keyLabel ); + // Should not use hardcoded index + err = iWrapper->AddKey( 0, aKey, keyUsage, keyLabel, + accessType, startDate, endDate, keyInfo ); + if ( err != KErrAlreadyExists ) + { + i = KAttempts; + } + keyLabel.Zero(); + } + + TCTTokenObjectHandle handle; + if ( keyInfo ) + { + handle = keyInfo->Handle(); + keyInfo->Release(); + keyInfo = NULL; + } + + switch ( err ) + { + case KErrNone: + { + ++iSavedKeysCount; + break; + } + case KErrKeySize: + case KErrArgument: + { + ShowErrorNoteL( R_CERTSAVER_KEY_TYPE_NOT_SUPPORTED ); + User::Leave( KErrCancel ); + break; + } + case KErrKeyValidity: + { + ShowInformationNoteL( R_CERTSAVER_QTN_CM_PKCS12_EXPIRED ); + User::Leave( KErrCancel ); + } + case KErrKeyUsage: + { + ShowErrorNoteL( R_CERTSAVER_PRIVATE_KEY_CORRUPTED ); + User::Leave( KErrCancel ); + break; + } + case KErrCancel: + case KErrPermissionDenied: + { + ShowErrorNoteL( R_CERTSAVER_PKCS12_DISCARDED ); + User::Leave( KErrCancel ); + break; + } + case KErrCorrupt: + case KErrEof: + { + ShowErrorNoteL( R_CERTSAVER_KEYSTORE_CORRUPTED ); + User::Leave( KErrCancel ); + break; + } + case KErrAlreadyExists: + { + User::Leave( KErrCancel ); + break; + } + default: + { + User::Leave( err ); + break; + } + } + + User::LeaveIfError( + iWrapper->SetManagementPolicy( handle, KSymbianKeyStoreMgmtPolicy) ); + User::LeaveIfError( + iWrapper->SetUsePolicy( handle, KSymbianKeyStoreUsePolicy ) ); + } + +// ---------------------------------------------------------- +// TBool CCertSaverModel::KeyAlreadyExistsL() +// +// ---------------------------------------------------------- +// +TBool CCertSaverModel::KeyAlreadyExistsL( + TTime& aStartDate, + TTime& aEndDate, + const TKeyIdentifier& aKeyIdentifier, + TKeyUsagePKCS15& aKeyUsage ) + { + TBool ret = EFalse; + TCTKeyAttributeFilter keyFilter; + keyFilter.iKeyAlgorithm = CKeyInfoBase::EInvalidAlgorithm; + keyFilter.iKeyId = aKeyIdentifier; + keyFilter.iPolicyFilter = TCTKeyAttributeFilter::EManageableKeys; + keyFilter.iUsage = aKeyUsage; + RMPointerArray keyArray; + TInt err = iWrapper->ListKeys( keyArray, keyFilter ); + CleanupClosePushL( keyArray ); + switch ( err ) + { + case KErrNone: + { + break; + } + case KErrCorrupt: + case KErrEof: + { + ShowErrorNoteL( R_CERTSAVER_KEYSTORE_CORRUPTED ); + User::Leave( KErrCancel ); + } + default: + { + User::Leave( err ); + } + } + for ( TInt i = 0; ret == EFalse && i < keyArray.Count(); i++ ) + { + if ( keyArray[i]->StartDate() == aStartDate && + keyArray[i]->EndDate() == aEndDate ) + { + ret = ETrue; + iKeyAlreadyExists = ETrue; + } + } + CleanupStack::PopAndDestroy( &keyArray ); + return ret; + } + +// ---------------------------------------------------------- +// CCertSaverModel::GetKeyValidityPeriodL() +// +// ---------------------------------------------------------- +// +void CCertSaverModel::GetKeyValidityPeriodL( + TTime& aStartDate, + TTime& aEndDate, + const TKeyIdentifier& aKeyIdentifier ) + { + + for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ ) + { + const CX509Certificate* cert = iParser.UserCertificates().At( i ); + if ( cert->KeyIdentifierL() == aKeyIdentifier ) + { + // Associated certificate found + // In the first round aStartDate and aEndDate is initialised. + if ( i == 0 || aStartDate > cert->ValidityPeriod().Start() ) + { + aStartDate = cert->ValidityPeriod().Start(); + } + if ( i == 0 || aEndDate < cert->ValidityPeriod().Finish() ) + { + aEndDate = cert->ValidityPeriod().Finish(); + } + } + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::CreateKeyLabelL() +// +// ---------------------------------------------------------- +// +void CCertSaverModel::CreateKeyLabelL( TDes& aLabel ) + { + TTime time; + time.UniversalTime(); + TBuf dateBuf; + time.FormatL( dateBuf, KDateString ); + aLabel.Append( dateBuf ); + dateBuf.Zero(); + aLabel.Append( KSpace ); + + time.FormatL( dateBuf, KTimeString ); + aLabel.Append( dateBuf ); + } + +// ---------------------------------------------------------- +// CCertSaverModel::SavePrivateKeyL() +// +// ---------------------------------------------------------- +// +void CCertSaverModel::SavePrivateKeyL() + { + if ( iParser.Keys().Count() <= 0 ) + { + return; + } + if ( NULL == iWrapper ) + { + iWrapper = CCertSaverSyncWrapper::NewL(); + } + TInt err = iWrapper->InitializeKeyStoreL( iFs ); + + TInt keyStoreCount = iWrapper->UnifiedKeyStore().KeyStoreManagerCount(); + if ( keyStoreCount <= 0 ) + { + User::Leave( KErrCancel ); + } + else + { + for ( TInt i = 0; i < keyStoreCount; ++i ) + { + TUid uid = + iWrapper->UnifiedKeyStore().KeyStoreManager(i).Token().TokenType().Type(); + if ( uid == TUid::Uid( KTokenTypeFileKeystore ) ) + // if this is not found, we use the first one, + // which is already initialised + { + iSelectedKeyStore = i; + } + } + } + + for ( TInt i = 0; i < iParser.Keys().Count(); i++ ) + { + const HBufC8* key = iParser.Keys().At( i ); + TRAP(err, DoSavePrivateKeyL( *key )); + User::LeaveIfError( err ); + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::KeyUsageL( +// const TKeyIdentifier& aKeyIdentifier, TAlgorithmId aAlgorithm) +// ---------------------------------------------------------- +// +TKeyUsagePKCS15 CCertSaverModel::KeyUsageL( + const TKeyIdentifier& aKeyIdentifier, + TAlgorithmId aAlgorithm ) + { + + TKeyUsagePKCS15 pkcs15KeyUsage = EPKCS15UsageNone; + TKeyUsageX509 x509Usage = EX509UsageNone; + + for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ ) + { + const CX509Certificate* cert = iParser.UserCertificates().At( i ); + if ( cert->KeyIdentifierL() == aKeyIdentifier ) + { + const CX509CertExtension* ext = cert->Extension( KKeyUsage ); + if (ext) + { + CX509KeyUsageExt* keyUsageExt = + CX509KeyUsageExt::NewLC( ext->Data() ); + if ( keyUsageExt->IsSet( EX509DigitalSignature ) ) + { + x509Usage |= EX509UsageDigitalSignature; + } + if ( keyUsageExt->IsSet( EX509NonRepudiation ) ) + { + x509Usage |= EX509UsageNonRepudiation; + } + if ( keyUsageExt->IsSet( EX509KeyEncipherment ) ) + { + x509Usage |= EX509UsageKeyEncipherment; + } + if ( keyUsageExt->IsSet( EX509DataEncipherment ) ) + { + x509Usage |= EX509UsageDataEncipherment; + } + if ( keyUsageExt->IsSet( EX509KeyAgreement ) ) + { + x509Usage |= EX509UsageKeyAgreement; + } + if ( keyUsageExt->IsSet( EX509KeyCertSign ) ) + { + x509Usage |= EX509UsageKeyCertSign; + } + if ( keyUsageExt->IsSet( EX509CRLSign ) ) + { + x509Usage |= EX509UsageCRLSign; + } + if ( keyUsageExt->IsSet( EX509EncipherOnly ) ) + { + x509Usage |= EX509UsageEncipherOnly; + } + if ( keyUsageExt->IsSet( EX509DecipherOnly ) ) + { + x509Usage |= EX509UsageDecipherOnly; + } + CleanupStack::PopAndDestroy( keyUsageExt ); + } + } + } + + pkcs15KeyUsage = KeyUsageX509ToPKCS15Private( x509Usage ); + // If any certificate in the file did not include key usage, + // let's use default values. + if ( EPKCS15UsageNone == pkcs15KeyUsage ) + { + switch ( aAlgorithm ) + { + case ERSA: + { + pkcs15KeyUsage |= EPKCS15UsageSignSignRecover; + pkcs15KeyUsage |= EPKCS15UsageDecryptUnwrap; + break; + } + case EDSA: + { + pkcs15KeyUsage |= EPKCS15UsageSignSignRecover; + break; + } + default: + { + break; + } + } + } + return pkcs15KeyUsage; + } + +// ---------------------------------------------------------- +// CCertSaverModel::CheckFSSpaceL( +// const TDesC8& aDataToSave) +// ---------------------------------------------------------- +// +void CCertSaverModel::CheckFSSpaceL( const TDesC8& aDataToSave ) + { + if (SysUtil::FFSSpaceBelowCriticalLevelL( &iFs, aDataToSave.Size() )) + { + HBufC* p = StringLoader::LoadLC( R_CERTSAVER_MEMORY ); + CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue ); + note->ExecuteLD( p->Des() ); + CleanupStack::PopAndDestroy( p ); + User::Leave( KErrExitApp ); + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::SaveCertL() +// Saves certificate +// ---------------------------------------------------------- +// +void CCertSaverModel::SaveCertL() + { + if ( !CertificateOkL() ) + { + User::Leave( KErrCancel ); + } + + HBufC* message = HBufC::NewLC( KMaxLengthTextMeassageBody ); + TPtr msgPtr = message->Des(); + ConstructMessageL( msgPtr ); + CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL( *message ); + CleanupStack::PopAndDestroy( message ); + CleanupStack::PushL( dlg ); + + + dlg->PrepareLC( R_MESSAGE_QUERY_DOSAVE ); + + HBufC* header = StringLoader::LoadLC( R_CERTSAVER_DETAILS_HEADING ); + dlg->QueryHeading()->SetTextL( header->Des() ); + CleanupStack::PopAndDestroy( header ); + CleanupStack::Pop( dlg ); + TBool doSave = dlg->RunLD(); + + if ( doSave && iCertOwnerType == ECACertificate ) + { + // warn user about security risk + CAknQueryDialog* warningDialog = CAknQueryDialog::NewL(); + doSave = warningDialog->ExecuteLD( R_CERTSAVER_WARNING_NOTE ); + } + + if ( doSave ) + { + //Check that there still is enough space to store the + //certificate. + CheckFSSpaceL( iNewCert->Encoding() ); + DoSaveCertL(); + } + else + { + ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED ); + User::Leave( KErrCancel ); + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::InitCertStoreL() +// +// ---------------------------------------------------------- +// +void CCertSaverModel::InitCertStoreL() + { + if ( !iUnifiedCertStore ) + { + TRAPD( status, iUnifiedCertStore = CUnifiedCertStore::NewL( iFs, ETrue ) ); + if ( status != KErrNone ) + { + ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED ); + User::Leave( KErrExitApp ); + } + // initialize unified cert store + status = iWrapper->InitializeCertStore( *iUnifiedCertStore ); + if ( status ) + { + HandleSaveErrorL( status ); + User::Leave( KErrExitApp ); + } + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::DoSaveCertL() +// Tries to save the certificate to phone memory. +// ---------------------------------------------------------- +// +void CCertSaverModel::DoSaveCertL() + { + TInt status = KErrNone; + CCertAttributeFilter* filter = NULL; + TCertificateFormat certFormat = EX509Certificate; + HBufC* secondaryName = NULL; + TCertLabel labelBuf; + CCertificate* certificate = NULL; + HBufC* label = NULL; + + if ( NULL == iWrapper ) + { + iWrapper = CCertSaverSyncWrapper::NewL(); + } + // Init unified certstore + InitCertStoreL(); + + // Check that certificate doesn't already exist. + // Fingerprint of certificate is used to confirm this. + filter = CCertAttributeFilter::NewL(); + filter->SetFormat( iCertFormat ); + filter->SetOwnerType( iCertOwnerType ); + // Delete old array first + iEntries.Close(); + status = iWrapper->ListCerts( *iUnifiedCertStore, iEntries, *filter ); + delete filter; + filter = NULL; + if ( status ) + { + if ( status != KErrCancel ) + { + HandleSaveErrorL( status ); + } + User::Leave( KErrExitApp ); + } + + TBool found = EFalse; + + for ( TInt i = 0; i < iEntries.Count() && !found; ++i ) + { + iWrapper->Retrieve( *iUnifiedCertStore, *iEntries[i], certificate ); + // Compare fingerprint of listed certificates to + // fingerprint of new certificate + // If the certificate is already in CACerts.dat, + // then don't save it + if ( iNewCert->Fingerprint() == certificate->Fingerprint() && + (( *iEntries[i]).Handle().iTokenHandle.iTokenTypeUid == KFileTokensUid ) ) + { + found = ETrue; + } + delete certificate; + certificate = NULL; + } + + // Cancel if certificate already exists. + if ( found ) + { + HandleSaveErrorL( KErrAlreadyExists ); + User::Leave( KErrCancel ); + } + + // Create default label from the certificate + X509CertNameParser::PrimaryAndSecondaryNameL( + (*(CX509Certificate*)iNewCert), label, secondaryName ); + CleanupStack::PushL( label ); + delete secondaryName; + secondaryName = NULL; + labelBuf = label->Des().Left( CERTSAVER_MAX_LABEL_LEN ); + CleanupStack::PopAndDestroy( label ); + label = NULL; + // Asks unique label from user. + status = QueryLabelL( labelBuf, *iUnifiedCertStore ); + if ( status ) + { + if ( status != KErrCancel ) + { + HandleSaveErrorL( status ); + } + User::Leave( KErrCancel ); + } + + if ( ECACertificate == iCertOwnerType ) + { + // Query trusted UIDs + status = QueryTrusterUidsL( iTrusterUids ); + if ( status ) + { + HandleSaveErrorL( status ); + User::Leave( KErrCancel ); + } + } + + // Get interface to writable store. + TInt certstoreIndex( -1 ); + TInt count = iUnifiedCertStore->WritableCertStoreCount(); + if ( count > 0 ) + { + for ( TInt i = 0; i < count; i++ ) + { + MCTWritableCertStore& writableCertStore = + iUnifiedCertStore->WritableCertStore( i ); + + MCTToken& token = writableCertStore.Token(); + TUid tokenuid = token.Handle().iTokenTypeUid; + if ( ( tokenuid == KTrustedServerTokenUid ) && ( iCertOwnerType == EPeerCertificate ) || + ( tokenuid == KFileTokensUid ) && ( iCertOwnerType == ECACertificate ) || + ( tokenuid == KFileTokensUid ) && ( iCertOwnerType == EUserCertificate ) ) + { + certstoreIndex = i; + break; + } + } + + if ( certstoreIndex < 0 ) + { + // Couldn't find certificate storage + ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED ); + User::Leave( KErrExitApp ); + } + + status = iWrapper->AddCert( iUnifiedCertStore->WritableCertStore( certstoreIndex ), + labelBuf, iCertFormat, iCertOwnerType, 0, 0, iNewCert->Encoding() ); + + if ( ( status == KErrNone ) && ( iCertOwnerType == EPeerCertificate) ) + { + // Adding certificate succeded. Update trust site storage + CTrustSitesStore* trustedSitesStore = CTrustSitesStore::NewL(); + CleanupStack::PushL( trustedSitesStore ); + TPtrC8 certBuf = iParser.CertificateBuf(); + TInt err = trustedSitesStore->AddL( certBuf, labelBuf ); + CleanupStack::PopAndDestroy( trustedSitesStore ); + } + + // If error happened, show error note and give up. Otherwise, continue + HandleSaveErrorL( status ); + if ( status ) + { + User::Leave( KErrCancel ); + } + else + { + if ( ECACertificate == iCertOwnerType ) + { + ++iSavedCACertsCount; + } + else + { + ++iSavedUserCertsCount; + } + } + } + else + { + // If there is none WritableCertStore, + // then at least cacerts.dat is corrupted. + ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED ); + User::Leave( KErrExitApp ); + } + + if ( ECACertificate == iCertOwnerType ) + { + // get just saved certificate + // first, create a filter + filter = CCertAttributeFilter::NewL(); + filter->SetLabel( labelBuf ); + filter->SetFormat( certFormat ); + filter->SetOwnerType( ECACertificate ); + + // Delete array + iEntries.Close(); + // then list certificates + status = iWrapper->ListCerts( *iUnifiedCertStore, iEntries, *filter ); + delete filter; + filter = NULL; + + // If error happened, show error note and give up. Otherwise, continue + if ( status ) + { + HandleSaveErrorL( status ); + User::Leave( KErrExitApp ); + } + + // takes ownership of trusterUids + status = iWrapper->SetApplicability( + iUnifiedCertStore->WritableCertStore( certstoreIndex ), *(iEntries[0]), iTrusterUids ); + + // If error happened, show error note and give up. Otherwise, continue + if ( status ) + { + HandleSaveErrorL( status ); + User::Leave( KErrExitApp ); + } + + // Downloaded certificate is trusted by default + status = iWrapper->SetTrust( + iUnifiedCertStore->WritableCertStore(certstoreIndex), *(iEntries[0]), ETrue ); + if ( status ) + { + HandleSaveErrorL( status ); + } + + + } // if ( ECACertificate == iCertOwnerType ) + } +// ---------------------------------------------------------- +// CCertSaverModel::QueryLabel() +// Queries label from user and confirms that it doesn't +// already exist. +// ---------------------------------------------------------- +// +TInt CCertSaverModel::QueryLabelL( TCertLabel& aLabel, CUnifiedCertStore& aStore ) + { + CCertAttributeFilter* filter = NULL; + TInt status = KErrNone; + RMPointerArray entries; + TBool loop = ETrue; + + while ( loop ) + { + CAknTextQueryDialog* dialog = CAknTextQueryDialog::NewL( aLabel ); + if ( !dialog->ExecuteLD( R_CERTSAVER_LABEL_QUERY ) ) + { + // cancel + ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED ); + return KErrCancel; + } + // Create filter to confirm that label doesn't already exist. + filter = CCertAttributeFilter::NewL(); + filter->SetLabel( aLabel ); + + // then list certificates + status = iWrapper->ListCerts( aStore, entries, *filter ); + CleanupClosePushL( entries ); + delete filter; + + // If error happened, show error note and give up. Otherwise, continue + if ( status ) + { + HandleSaveErrorL( status ); + User::Leave( KErrExitApp ); + } + + if ( entries.Count() ) + { + // Label already exists. Label is queried again. + HandleSaveErrorL( KErrBadName ); + } + else + { + // Label didn't exist. + loop = EFalse; + } + CleanupStack::PopAndDestroy( &entries ); // entries + } // while + + return status; + } + +// ---------------------------------------------------------- +// CCertSaverModel::HandleSaveErrorL() const +// Shows a note according to aStatus. aStatus is the status +// of the save operation. +// ---------------------------------------------------------- +// +void CCertSaverModel::HandleSaveErrorL( TInt aStatus ) const + { + switch ( aStatus ) + { + case KErrNone: + { + ShowConfirmationNoteL( R_CERTSAVER_ERROR_SAVEOK ); + break; + } + case KErrNotSupported: + { + ShowErrorNoteL( R_CERTSAVER_ERROR_UNSUPPORTED_CERT ); + break; + } + case KErrBadName: + { + ShowErrorNoteL( R_CERTSAVER_ERROR_LABEL_ALREADY_EXISTS ); + break; + } + case KErrAlreadyExists: + { + ShowErrorNoteL( R_CERTSAVER_ERROR_ALREADY_EXISTS ); + break; + } + case KErrArgument: + { + ShowErrorNoteL( R_CERTSAVER_ERROR_CACERTS_DB_CORRUPTED ); + break; + } + default: + { + //No error note defined for unknown error. + User::Leave( aStatus ); + break; + } + } //switch + } + +// ---------------------------------------------------------- +// CCertSaverModel::AddToMessageWithStringL() const +// String loaded from resources with StringLoader. +// ---------------------------------------------------------- +// +void CCertSaverModel::AddToMessageWithStringL( + TDes& aMessage, TInt aStringResID, const TDesC& aString ) const + { + HBufC* promptPtr = NULL; + promptPtr = StringLoader::LoadL( aStringResID, aString ); + CleanupStack::PushL( promptPtr ); + TPtrC prompt( promptPtr->Des() ); + + aMessage.Append( prompt ); + + CleanupStack::PopAndDestroy( promptPtr ); // promptPtr + } + +// ---------------------------------------------------------- +// CCertSaverModel::AddToMessageWithStringL() const +// String loaded from resources with StringLoader. +// ---------------------------------------------------------- +// +void CCertSaverModel::AddToMessageWithIntL( + TDes& aMessage, + TInt aStringResID, + TInt aInt ) const + { + HBufC* promptPtr = NULL; + promptPtr = StringLoader::LoadL( aStringResID, aInt ); + CleanupStack::PushL( promptPtr ); + TPtrC prompt( promptPtr->Des() ); + + aMessage.Append( prompt ); + aMessage.Append( KEnter ); + + CleanupStack::PopAndDestroy( promptPtr ); // promptPtr + } + +// ---------------------------------------------------------- +// CCertSaverModel::AddToMessageL() const +// String loaded from resources with StringLoader. +// ---------------------------------------------------------- +// +void CCertSaverModel::AddToMessageL( TDes& aMessage, TInt aStringResID ) const + { + HBufC* promptPtr = NULL; + promptPtr = StringLoader::LoadL( aStringResID ); + CleanupStack::PushL( promptPtr ); + TPtrC prompt( promptPtr->Des() ); + + aMessage.Append( prompt ); + aMessage.Append( KEnter ); + + CleanupStack::PopAndDestroy( promptPtr ); // promptPtr + } + +// ---------------------------------------------------------- +// CCertSaverModel::ConstructMessageL() const +// Creates the certificate details message shown to the user. +// ---------------------------------------------------------- +// +void CCertSaverModel::ConstructMessageL( TDes& aMessage ) const + { + HBufC16* issuerName = NULL; + HBufC16* subjectName = NULL; + + + X509CertNameParser::SubjectFullNameL( *((CX509Certificate*)iNewCert), + subjectName ); + CleanupStack::PushL( subjectName ); + + X509CertNameParser::IssuerFullNameL( *((CX509Certificate*)iNewCert), + issuerName ); + CleanupStack::PushL( issuerName ); + + AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_LABEL, + CutCertificateField(*subjectName) ); + AddNewlinesToMessage( aMessage ); + + AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_ISSUER, + CutCertificateField( *issuerName ) ); + CleanupStack::PopAndDestroy( 2, subjectName ); + AddNewlinesToMessage( aMessage ); + + if ( iCertOwnerType==EUserCertificate ) + { + AddKeyUsageL( aMessage, *((CX509Certificate*)iNewCert) ); + } + + AddValidityPeriodL( aMessage, *((CX509Certificate*)iNewCert) ); + + // SHA-1 fingerprint + TBuf divided_fingerprint; + DivideToBlocks( iNewCert->Fingerprint(), divided_fingerprint ); + AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_FINGERPRINT, + divided_fingerprint ); + + AddNewlinesToMessage( aMessage ); + divided_fingerprint.Zero(); + + // MD5 fingerprint + CMD5* md5 = CMD5::NewL(); + CleanupStack::PushL( md5 ); + TPtrC8 MD5fingerprint = md5->Hash( iNewCert->Encoding() ); + + // Divide fingerprint to blocks + DivideToBlocks( MD5fingerprint, divided_fingerprint ); + CleanupStack::PopAndDestroy( md5 ); + AddToMessageWithStringL( aMessage, R_CERTSAVER_TEXT_FINGERPRINT_MD5, + divided_fingerprint ); + AddNewlinesToMessage( aMessage ); + } + +// ----------------------------------------------------------------------------- +// CCTSecurityDialogsAO::AddKeyUsageL(...) +// ----------------------------------------------------------------------------- +// +void CCertSaverModel::AddKeyUsageL( TDes& aMessage, const CX509Certificate& aCert ) const + { + TKeyUsageX509 x509Usage = EX509UsageNone; + TKeyUsagePKCS15 pkcs15KeyUsage = EPKCS15UsageNone; + const CX509CertExtension* ext = aCert.Extension( KKeyUsage ); + if (ext) + { + CX509KeyUsageExt* keyUsageExt = + CX509KeyUsageExt::NewLC( ext->Data() ); + if ( keyUsageExt->IsSet( EX509DigitalSignature ) ) + { + x509Usage |= EX509UsageDigitalSignature; + } + if ( keyUsageExt->IsSet( EX509NonRepudiation ) ) + { + x509Usage |= EX509UsageNonRepudiation; + } + if ( keyUsageExt->IsSet( EX509KeyEncipherment ) ) + { + x509Usage |= EX509UsageKeyEncipherment; + } + if ( keyUsageExt->IsSet( EX509DataEncipherment ) ) + { + x509Usage |= EX509UsageDataEncipherment; + } + if ( keyUsageExt->IsSet( EX509KeyAgreement ) ) + { + x509Usage |= EX509UsageKeyAgreement; + } + if ( keyUsageExt->IsSet( EX509KeyCertSign ) ) + { + x509Usage |= EX509UsageKeyCertSign; + } + if ( keyUsageExt->IsSet( EX509CRLSign ) ) + { + x509Usage |= EX509UsageCRLSign; + } + if ( keyUsageExt->IsSet( EX509EncipherOnly ) ) + { + x509Usage |= EX509UsageEncipherOnly; + } + if ( keyUsageExt->IsSet( EX509DecipherOnly ) ) + { + x509Usage |= EX509UsageDecipherOnly; + } + CleanupStack::PopAndDestroy( keyUsageExt ); + } + + pkcs15KeyUsage = KeyUsageX509ToPKCS15Private( x509Usage ); + + TInt usage = 0; + switch( pkcs15KeyUsage ) + { + case EPKCS15UsageSignSignRecover: + case EPKCS15UsageSign: + case EPKCS15UsageSignDecrypt: + { + usage = R_QTN_CM_CLIENT_AUTHENTICATION; + break; + } + case EPKCS15UsageNonRepudiation: + { + usage = R_QTN_CM_DIGITAL_SIGNING; + break; + } + default: + { + usage = R_QTN_CM_NOT_DEFINED; + break; + } + } + AddToMessageL( aMessage, R_QTN_CM_KEY_USAGE ); + HBufC* usageString = iAppUi->CoeEnv()->AllocReadResourceLC( usage ); + aMessage.Append( *usageString ); + CleanupStack::PopAndDestroy( usageString ); + AddNewlinesToMessage( aMessage ); + } + +// ----------------------------------------------------------------------------- +// CCTSecurityDialogsAO::AddValidityPeriodL(...) +// ----------------------------------------------------------------------------- +// +void CCertSaverModel::AddValidityPeriodL( + TDes& aMessage, const CX509Certificate& aCert ) const + { + // Hometime's offset to UTC + TLocale locale; + TTimeIntervalSeconds offSet = locale.UniversalTimeOffset(); + AddToMessageL( aMessage, R_CERTSAVER_QTN_CM_VALID_FROM ); + + const CValidityPeriod& validityPeriod = aCert.ValidityPeriod(); + TTime startValue = validityPeriod.Start(); + startValue += offSet; + TBuf startString; + // read format string from AVKON resource + HBufC* dateFormatString = iAppUi->CoeEnv()->AllocReadResourceLC( + R_QTN_DATE_USUAL_WITH_ZERO ); + // format the date to user readable format. The format is locale dependent + startValue.FormatL( startString, *dateFormatString ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( startString ); + CleanupStack::PopAndDestroy( dateFormatString ); // dateFormatString + aMessage.Append( startString ); + AddNewlinesToMessage( aMessage ); + + AddToMessageL( aMessage, R_CERTSAVER_QTN_CM_VALID_UNTIL ); + TTime finishValue = validityPeriod.Finish(); + finishValue += offSet; + TBuf finishString; + // read format string from AVKON resource + dateFormatString = iAppUi->CoeEnv()->AllocReadResourceLC( + R_QTN_DATE_USUAL_WITH_ZERO ); + // format the date to user readable format. The format is locale dependent + finishValue.FormatL( finishString, *dateFormatString ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( finishString ); + CleanupStack::PopAndDestroy(); // dateFormatString + aMessage.Append( finishString ); + AddNewlinesToMessage( aMessage ); + } + +// ---------------------------------------------------------- +// CCertSaverModel::AddNewlinesToMessage() const +// Adds two new lines to message. +// ---------------------------------------------------------- +// +void CCertSaverModel::AddNewlinesToMessage( TDes& aMessage ) const + { + aMessage.Append( KDoubleEnter ); + } + +// ---------------------------------------------------------- +// CCertSaverModel::CertificateSupported() const +// Checks that cert is of supported type. +// ---------------------------------------------------------- +// +TBool CCertSaverModel::CertificateSupported() const + { + if ( iCertFormat == EX509Certificate && + ( iCertOwnerType == ECACertificate || + iCertOwnerType == EPeerCertificate || + iCertOwnerType == EUserCertificate)) + { + return ETrue; + } + return EFalse; + } + + +// ---------------------------------------------------------- +// CCertSaverModel::CertificateOkL() const +// Checks that cert is ok. Shows an error note if not. +// If certificate is not valid yet/anymore an error note is shown +// but ETrue is returned so that user can still save the +// certificate. +// ---------------------------------------------------------- +// +TBool CCertSaverModel::CertificateOkL() const + { + if ( !CertificateSupported() ) + { + ShowErrorNoteL( R_CERTSAVER_ERROR_UNSUPPORTED_CERT ); + return EFalse; + } + if ( CertNotValidAnymore() ) + { + ShowErrorNoteL( R_CERTSAVER_ERROR_CERT_NOT_VALID ); + return ETrue; + } + else if ( CertNotValidYet() ) + { + ShowErrorNoteL( R_CERTSAVER_ERROR_CERT_NOT_VALID_YET ); + } + return ETrue; + } + +// ---------------------------------------------------------- +// CCertSaverModel::CertNotValidAnymore() const +// Checks if cert isn't valid anymore. +// ---------------------------------------------------------- +// +TBool CCertSaverModel::CertNotValidAnymore() const + { + TTime homeTime; + homeTime.HomeTime(); + if ( iNewCert->ValidityPeriod().Finish() < homeTime ) + { + return ETrue; + } + return EFalse; + } + +// ---------------------------------------------------------- +// CCertSaverModel::CertNotValidYet() const +// Checks if cert isn't valid yet. +// ---------------------------------------------------------- +// +TBool CCertSaverModel::CertNotValidYet() const + { + TTime homeTime; + homeTime.HomeTime(); + if ( iNewCert->ValidityPeriod().Start() > homeTime ) + { + return ETrue; + } + return EFalse; + } + +// ---------------------------------------------------------- +// CCertSaverModel::ShowInformationNoteL() const +// Creates and shows a confirmation note. +// ---------------------------------------------------------- +// +void CCertSaverModel::ShowInformationNoteL( TInt aResourceID ) const + { + HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID ); + CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue ); + note->ExecuteLD( buffer->Des() ); + CleanupStack::PopAndDestroy( buffer ); + } +// ---------------------------------------------------------- +// CCertSaverModel::ShowConfirmationNoteL() const +// Creates and shows a confirmation note. +// ---------------------------------------------------------- +// +void CCertSaverModel::ShowConfirmationNoteL( TInt aResourceID ) const + { + HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID ); + CAknConfirmationNote* note = new (ELeave) CAknConfirmationNote( ETrue ); + note->ExecuteLD( buffer->Des() ); + CleanupStack::PopAndDestroy( buffer ); + } + +// ---------------------------------------------------------- +// CCertSaverModel::ShowErrorNoteL() const +// Creates and shows an error note. +// ---------------------------------------------------------- +// +void CCertSaverModel::ShowErrorNoteL( TInt aResourceID ) const + { + HBufC* buffer = iAppUi->CoeEnv()->AllocReadResourceLC( aResourceID ); + CAknErrorNote* note = new (ELeave) CAknErrorNote( ETrue ); + note->ExecuteLD(buffer->Des()); + CleanupStack::PopAndDestroy( buffer ); + } + +// ---------------------------------------------------------- +// CCertSaverModel::TrimCertificateFields() const +// Trims given descriptor so that everything after and +// including the fourth semicolon (;) is cropped. +// Returns the trimmed certificate field. +// ---------------------------------------------------------- +// +TPtrC CCertSaverModel::TrimCertificateFields( TPtrC aField ) const + { + TPtrC cutField = CutCertificateField( aField ); + // Find one semicolon at a time and crop the + // helpField from the left to search for the next semicolon + TInt position = cutField.Locate( ';' ); // 1st semicolon + TInt fieldLength = cutField.Length(); + + // Need to check that position is not bigger than the length of cutField + if ( position != KErrNotFound && position < fieldLength ) + { + // Locate function counts from zero, Mid function + // counts also from zero, add one to exclude the found semicolon + TInt totalPosition = position; + TPtrC field = cutField.Mid(totalPosition + 1); + position = field.Locate(';'); // 2nd semicolon + fieldLength = field.Length(); + + if ( position != KErrNotFound && position < fieldLength ) + { + totalPosition += position + 1; + TPtrC field = cutField.Mid( totalPosition + 1 ); + position = field.Locate( ';' ); // 3rd semicolon + fieldLength = field.Length(); + + if ( position != KErrNotFound && position < fieldLength ) + { + totalPosition += position + 1; + TPtrC field = cutField.Mid( totalPosition + 1 ); + position = field.Locate( ';' ); // 4th semicolon + fieldLength = field.Length(); + + if ( position != KErrNotFound && position < fieldLength ) + { + totalPosition += position + 1; + // Extract the leftmost part of the data field up to n:th character + TPtrC field = cutField.Mid( 0, totalPosition ); + return field; + } // if + } // if + } // if + } // if + return cutField; + } + +// ---------------------------------------------------------- +// CCertSaverModel::CutCertificateField() const +// If given descriptor is larger than defined maximum length +// this function cuts it. +// ---------------------------------------------------------- +// +TPtrC CCertSaverModel::CutCertificateField( TPtrC aField ) const + { + TInt fieldLength = aField.Length(); + if ( fieldLength >= KMaxLengthTextCertIdentifierVisible ) + { + TPtrC cutCertLabel = aField.Mid( 0, KMaxLengthTextCertIdentifierVisible ); + return cutCertLabel; + } + return aField; + } + +// ---------------------------------------------------------- +// CCertSaverModel::QueryTrusterUidsL() +// Does needed tasks to exit. +// ---------------------------------------------------------- +// +TInt CCertSaverModel::QueryTrusterUidsL( RArray& aUids ) + { + TInt ret = KErrCancel; + CArrayFixFlat* selectionArray = + new (ELeave) CArrayFixFlat( KTrusterArrayInitSize ); + CleanupStack::PushL( selectionArray ); + CDesCArray* itemsArray = new (ELeave) CDesCArrayFlat( KTrusterArrayInitSize ); + CleanupStack::PushL( itemsArray ); + + CCertificateAppInfoManager* appInfoManager = + CCertificateAppInfoManager::NewL( iFs, EFalse ); + CleanupStack::PushL( appInfoManager ); + // copy applications to own array + const RArray& apps = appInfoManager->Applications(); + RArray appsInItemArray( KTrusterArrayInitSize ); + CleanupClosePushL( appsInItemArray ); + UpdateTrustListboxItemL( apps, appsInItemArray, *itemsArray ); + + CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog( selectionArray ); + CleanupStack::PushL( dlg ); + dlg->PrepareLC( R_CERTSAVER_TRUST_SETTINGS_QUERY ); + dlg->SetItemTextArray( itemsArray ); + dlg->SetOwnershipType( ELbmDoesNotOwnItemArray ); + if ( dlg->RunLD() ) + { + for ( TInt i = 0; i < selectionArray->Count(); ++i ) + { + TInt ii = (*selectionArray)[ i ]; + aUids.Append( appsInItemArray[ ii ].Id() ); + } + ret = KErrNone; + } + else + { + ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED ); + ret = KErrCancel; + } + CleanupStack::Pop( dlg ); + CleanupStack::PopAndDestroy( 4, selectionArray ); + return ret; + } + +// ---------------------------------------------------------- +// CCertSaverModel::QueryTrustedSiteL() +// Shows query for trusted site certificate +// ---------------------------------------------------------- +// +TInt CCertSaverModel::QueryTrustedSiteL() + { + TInt ret = KErrCancel; + HBufC* label = NULL; + HBufC* secondaryName = NULL; + TCertLabel labelBuf; + + X509CertNameParser::PrimaryAndSecondaryNameL( + (*(CX509Certificate*)iNewCert), label, secondaryName ); + CleanupStack::PushL( label ); + delete secondaryName; + secondaryName = NULL; + labelBuf = label->Des().Left( CERTSAVER_MAX_LABEL_LEN ); + + + HBufC* prompt = StringLoader::LoadLC( R_CERTSAVER_TRUSTEDSITE_WARNING, labelBuf ); + + CAknMessageQueryDialog* note = CAknMessageQueryDialog::NewL( *prompt ); + + note->PrepareLC( R_CERTSAVER_TRUSTED_SITE_QUERY ); + note->SetPromptL( *prompt ); + + if ( note->RunLD() ) + { + ret = KErrNone; + } + else + { + ShowConfirmationNoteL( R_CERTSAVER_CERT_DISCARDED ); + ret = KErrCancel; + } + + CleanupStack::PopAndDestroy( prompt ); + + CleanupStack::PopAndDestroy( label ); + return ret; + } + +// ---------------------------------------------------------- +// CCertSaverModel::UpdateTrustListboxItemL() +// Updates trust setting listbox items +// ---------------------------------------------------------- +// +void CCertSaverModel::UpdateTrustListboxItemL( + const RArray& aApps, + RArray& aAppsInItemArray, + CDesCArray& aItemsArray ) const + { + for ( TInt i = 0; i < aApps.Count(); i++ ) + { + TCertificateAppInfo appInfo = aApps[ i ]; + TBuf item; + item.Append( KCertSaverListBoxItemPrefix ); + TBuf resource; + + switch( appInfo.Id().iUid ) + { + case KWTLSTrusterUID: + { + // X.509 certiticate isn't needed with WTLS + break; + } + case KInternetTrusterUID: + { + iAppUi->CoeEnv()->ReadResource( + resource, R_CERTSAVER_ITEM_MAIL_IMAGE_CONN ); + break; + } + case KApplicationControllerTrusterUID: + { + // SWI certs are ROM based in platsec world. + break; + } + case KJavaInstallTrusterUID: + { + // MIDP certstore is read-only.. + break; + } + case KOCSPTrusterUID: + { + iAppUi->CoeEnv()->ReadResource( resource, R_CERTSAVER_ITEM_OCSP ); + break; + } + case KVPNUID: + { + iAppUi->CoeEnv()->ReadResource( resource, R_CERTSAVER_ITEM_VPN ); + break; + } + default: + { + resource = appInfo.Name(); + break; + } + } + if ( 0 < resource.Length()) + { + item.Append( resource ); + aItemsArray.AppendL( item ); + aAppsInItemArray.Append( appInfo ); + resource.Zero(); + } + } + } + +// --------------------------------------------------------- +// CCertManUIViewAuthority::DevideToBlocks +// --------------------------------------------------------- +// +void CCertSaverModel::DivideToBlocks( const TDesC8& aInput, TDes& aOutput ) const + { + _LIT( KBlockSeparator, " " ); + const TInt KBlockLength = 2; + TInt blockIndex = 0; + for ( TInt j = 0 ; j < aInput.Length() ; j++ ) + { + if ( blockIndex == KBlockLength ) + { + aOutput.Append( KBlockSeparator ); + blockIndex = 0; + } + aOutput.AppendNumFixedWidthUC( (TUint)(aInput[ j ]), EHex, 2 ); + ++blockIndex; + } + } + +// ---------------------------------------------------- +// CCertSaverModel::SavePKCS12L() +// Saves content of the PKCS#12 file +// ---------------------------------------------------- +// +void CCertSaverModel::SavePKCS12L() + { + HBufC* message = HBufC::NewLC( KMaxLengthTextMeassageBody ); + TPtr msgPtr = message->Des(); + ConstructPKCS12QueryMsgL(msgPtr, iParser.Keys().Count(), + iParser.UserCertificates().Count(), + iParser.CACertificates().Count() ); + TBool save = DoMessageQueryL( + R_MESSAGE_QUERY_DOSAVE, R_CERTSAVER_HEADER_PKCS12_FILE_CONTAINS, + *message ); + CleanupStack::PopAndDestroy( message ); + message = NULL; + if ( !save ) + { + ShowInformationNoteL( R_CERTSAVER_PKCS12_DISCARDED ); + User::Leave( KErrExitApp ); + } + TInt status = KErrNone; + // save private keys + TRAP( status, SavePrivateKeyL() ); + + // save user certificates if private key was saved. + if ( ( iSavedKeysCount > 0 || iKeyAlreadyExists ) && iParser.UserCertificates().Count() > 0 ) + { + for ( TInt i = 0; i < iParser.UserCertificates().Count(); i++ ) + { + const CX509Certificate* cert = iParser.UserCertificates().At(i); + iCertOwnerType = EUserCertificate; + iCertFormat = EX509Certificate; + iNewCert = cert; + TRAP( status, SaveCertL() ); + if ( KErrExitApp == status ) + { + User::Leave( KErrExitApp ); + } + } + } + // save CA certificates + if ( iParser.CACertificates().Count() > 0 ) + { + for ( TInt i = 0; i < iParser.CACertificates().Count(); i++ ) + { + const CX509Certificate* cert = iParser.CACertificates().At( i ); + iCertOwnerType = ECACertificate; + iCertFormat = EX509Certificate; + iNewCert = cert; + TRAP( status, SaveCertL() ); + if ( KErrExitApp == status ) + { + User::Leave( KErrExitApp ); + } + } + } + if ( iSavedCACertsCount != 0 || iSavedKeysCount != 0 + || iSavedUserCertsCount != 0 ) + { + message = HBufC::NewLC( KMaxLengthTextMeassageBody ); + TPtr msgPtr2 = message->Des(); + ConstructPKCS12QueryMsgL( + msgPtr2, iSavedKeysCount, iSavedUserCertsCount, iSavedCACertsCount ); + DoMessageQueryL( + R_MESSAGE_QUERY_SAVED, R_CERTSAVER_HEADER_SAVED, *message ); + CleanupStack::PopAndDestroy( message ); + } + else + { + ShowInformationNoteL( R_QTN_CM_PKCS12_SAVING_FAILED ); + } + } + +// ---------------------------------------------------------- +// CCertSaverModel::DoMessageQuery() +// Displays message query dialog for user. +// ---------------------------------------------------------- +// +TBool CCertSaverModel::DoMessageQueryL( + TInt aDialogResId, + TInt aHeadingResId, + TDesC& aMessage ) + { + CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL( aMessage ); + CleanupStack::PushL( dlg ); + dlg->PrepareLC( aDialogResId ); + + HBufC* header = StringLoader::LoadLC( aHeadingResId ); + dlg->QueryHeading()->SetTextL( header->Des() ); + CleanupStack::PopAndDestroy( header ); + CleanupStack::Pop( dlg ); + return dlg->RunLD(); + } + +// ---------------------------------------------------------- +// CCertSaverModel::ConstructPKCS12QueryMsgL() const +// Creates the certificate details message shown to the user. +// ---------------------------------------------------------- +// +void CCertSaverModel::ConstructPKCS12QueryMsgL( + TDes& aMessage, + TInt aPrivateKeys, + TInt aUserCerts, + TInt aCACerts ) const + { + if ( aPrivateKeys > 0 ) + { + if ( aPrivateKeys == 1 ) + { + AddToMessageL( aMessage, R_CERTSAVER_ONE_PRIVATE_KEY ); + } + else + { + AddToMessageWithIntL( aMessage, R_CERTSAVER_PRIVATE_KEYS, aPrivateKeys ); + } + } + if ( aUserCerts > 0 ) + { + if ( aUserCerts == 1 ) + { + AddToMessageL( + aMessage, R_CERTSAVER_ONE_PERSONAL_CERTIFICATE ); + } + else + { + AddToMessageWithIntL( + aMessage, R_CERTSAVER_PERSONAL_CERTIFICATES, aUserCerts ); + } + } + if ( aCACerts > 0 ) + { + + if ( aCACerts == 1 ) + { + AddToMessageL( + aMessage, R_CERTSAVER_ONE_AUTHORITY_CERTIFICATE ); + } + else + { + AddToMessageWithIntL( + aMessage, R_CERTSAVER_AUTHORITY_CERTIFICATES, aCACerts ); + } + } + } + +// End of File