--- /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 <aknnotewrappers.h> // Note dialogs
+#include <aknmessagequerydialog.h> // For CAknMessageQueryDialog
+#include <StringLoader.h> // For loading resource strings
+#include <unifiedcertstore.h> // For saving the certificates
+#include <mctwritablecertstore.h> // For saving the certificates
+#include <sysutil.h> // For FFSSpaceBelowCriticalLevelL(..)
+#include <X509CertNameParser.h> // For default label
+#include <x509cert.h> // For CX509Certificate
+#include <wtlscert.h> // For WTLSCertificate
+#include <hash.h> // MD5 fingerprint
+#include <certificateapps.h>
+#include <mctkeystore.h>
+#include <securityerr.h>
+#include <asnpkcs.h>
+#include <unifiedkeystore.h>
+#include <x509certext.h>
+#include <mctkeystore.h>
+#include <TrustedSitesStore.h>
+
+#include <CertSaver.rsg>
+#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<KPrivaKeyLabelLength> 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<CCTKeyInfo> 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<KPrivaKeyLabelLength> 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<CCTCertInfo> 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<KFingerprintLength> 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<KMaxLengthTextDateString> 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<KMaxLengthTextDateString> 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<TUid>& aUids )
+ {
+ TInt ret = KErrCancel;
+ CArrayFixFlat<TInt>* selectionArray =
+ new (ELeave) CArrayFixFlat<TInt>( 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<TCertificateAppInfo>& apps = appInfoManager->Applications();
+ RArray<TCertificateAppInfo> 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<TCertificateAppInfo>& aApps,
+ RArray<TCertificateAppInfo>& aAppsInItemArray,
+ CDesCArray& aItemsArray ) const
+ {
+ for ( TInt i = 0; i < aApps.Count(); i++ )
+ {
+ TCertificateAppInfo appInfo = aApps[ i ];
+ TBuf<KItemBufLen> item;
+ item.Append( KCertSaverListBoxItemPrefix );
+ TBuf<KMaxName> 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