--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/CertmanUi/SRC/CertmanuiCertificateHelper.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1619 @@
+/*
+* Copyright (c) 2003-2009 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: Implementation of class CCertManUICertificateHelper
+*
+*/
+
+
+#include <X509CertNameParser.h>
+#include <certmanui.rsg>
+#include <hash.h> // MD5 fingerprint
+#include <aknmessagequerydialog.h>
+#include <pkixcertchain.h> // for validation
+#include <aknnotewrappers.h> // for warning & information notes
+#include <sysutil.h>
+#include <ErrorUI.h>
+#include <unifiedkeystore.h>
+#include <TrustedSitesStore.h>
+#include <x509keys.h> // TX509KeyFactory
+#include <e32math.h> // Pow
+#include "Certmanui.hrh"
+#include "CertmanuiCertificateHelper.h"
+#include "CertmanuiCommon.h"
+#include "CertmanuiSyncWrapper.h"
+#include "CertManUILogger.h"
+
+const TInt KFileCertStoreUid( 0x101F501A );
+const TInt KTrustedServerCertStoreUid( 0x101FB66F );
+const TInt KDeviceCertStoreUid( 0x101FB668 );
+const TInt KDeviceKeyStoreUid( 0x101FB66A );
+
+_LIT( KBlockSeparator, " " );
+
+template <class T>
+class CleanupResetAndDestroy
+ {
+public:
+ inline static void PushL( T& aRef );
+private:
+ static void ResetAndDestroy( TAny *aPtr );
+ };
+
+template <class T>
+inline void CleanupResetAndDestroyPushL( T& aRef );
+
+template <class T>
+inline void CleanupResetAndDestroy<T>::PushL( T& aRef )
+ {
+ CleanupStack::PushL( TCleanupItem( &ResetAndDestroy, &aRef ) );
+ }
+
+template <class T>
+void CleanupResetAndDestroy<T>::ResetAndDestroy( TAny *aPtr )
+ {
+ if( aPtr )
+ {
+ static_cast<T*>( aPtr )->ResetAndDestroy();
+ }
+ }
+
+template <class T>
+inline void CleanupResetAndDestroyPushL( T& aRef )
+ {
+ CleanupResetAndDestroy<T>::PushL( aRef );
+ }
+
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::CCertManUICertificateHelper()
+// Default C++ Constructor
+// ---------------------------------------------------------
+//
+CCertManUICertificateHelper::CCertManUICertificateHelper( CCertManUIKeeper& aKeeper )
+: iKeeper(aKeeper)
+ {
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::~CCertManUICertificateHelper()
+// Destructor
+// ---------------------------------------------------------
+//
+CCertManUICertificateHelper::~CCertManUICertificateHelper()
+ {
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::CutCertificateField(TPtrC aField)
+// If CertLabel, Issuer and Owner length is over 80 characters,
+// cut it down to 80
+// Returns the cut certificate field.
+// ---------------------------------------------------------
+//
+TPtrC CCertManUICertificateHelper::CutCertificateField( TPtrC aField )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::CutCertificateField" );
+
+ TInt fieldLength = aField.Length();
+ if ( fieldLength >= KMaxLengthTextCertLabelVisible )
+ {
+ TPtrC cutCertLabel = aField.Mid( 0, KMaxLengthTextCertLabelVisible );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::CutCertificateField" );
+
+ return cutCertLabel;
+ }
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::CutCertificateField" );
+
+ return aField;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::IsCertificateDeletable
+// Check whether certificate is deletable
+// ---------------------------------------------------------
+//
+TBool CCertManUICertificateHelper::IsCertificateDeletable( TInt aIndex,
+ TInt aType ) const
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::IsCertificateDeletable" );
+ TBool ret = ETrue;
+
+ // If wim has not been enabled and certificate resides in smart card
+ // we cannot delete it since we don't have smart card certificate
+ // delete functionality in non WIM builds. So in non WIM builds all
+ // smart card certificates are marked read-only.
+ if( aIndex > -1 )
+ {
+ CCTCertInfo* entry;
+ if ( aType == KCertTypeAuthority )
+ {
+ entry = iKeeper.iCALabelEntries[ aIndex ]->iCAEntry;
+ }
+ else if( aType == KCertTypeTrustedSite )
+ {
+ entry = iKeeper.iPeerLabelEntries[ aIndex ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = iKeeper.iDeviceLabelEntries[ aIndex ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = iKeeper.iUserLabelEntries[ aIndex ]->iUserEntry;
+ }
+ if ( !entry->IsDeletable() )
+ {
+ ret = EFalse;
+ }
+ }
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::IsCertificateDeletable" );
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::IsOneMarkedCertificateDeletable
+// Check whether one marked certificate is deletable, or
+// if none certificate is marked, check if the highlighted
+// certificate is deletable
+// ---------------------------------------------------------
+//
+TBool CCertManUICertificateHelper::IsOneMarkedCertificateDeletable
+ ( CEikColumnListBox* aListBox, TInt aType ) const
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::IsOneMarkedCertificateDeletable" );
+
+ const CArrayFix<TInt>* array = aListBox->SelectionIndexes();
+ TInt markedCount = array->Count();
+ TBool oneIsDeletable = EFalse;
+
+ if ( 0 == markedCount )
+ {
+ TInt currentItem = aListBox->CurrentItemIndex();
+ return IsCertificateDeletable( currentItem, aType );
+ }
+
+ for ( TInt i = 0; !oneIsDeletable && i < markedCount; i++ )
+ {
+ oneIsDeletable = IsCertificateDeletable( (*array)[i], aType );
+ }
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::IsOneMarkedCertificateDeletable" );
+
+ return oneIsDeletable;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::MessageQueryViewDetailsL(TInt aIndex)
+// Creates the whole of certificate details view
+// Appends strings from both resources and CertManAPI to one
+// message body text and displays it.
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::MessageQueryViewDetailsL( TInt aIndex,
+ TInt aType,
+ CEikonEnv* aEikonEnv )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::MessageQueryViewDetailsL" );
+ LOG_WRITE_FORMAT( "certificate index %i", aIndex );
+
+ iKeeper.StartWaitDialogL( ECertmanUiWaitDialog );
+
+ HBufC* message = HBufC::NewLC( KMaxLengthTextDetailsBody );
+ TRAPD( err, CreateMessageBodyTextL( aIndex, aType, aEikonEnv, *message ) );
+
+ iKeeper.CloseWaitDialogL();
+ User::LeaveIfError( err );
+
+ if( message->Length() )
+ {
+ HBufC* header = StringLoader::LoadLC( R_TEXT_RESOURCE_DETAILS_VIEW_HEADER );
+ CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL( *message );
+ dlg->PrepareLC( R_MESSAGE_QUERY_DETAILS_VIEW );
+ dlg->QueryHeading()->SetTextL( *header );
+ dlg->RunLD();
+ CleanupStack::PopAndDestroy( header );
+ }
+
+ CleanupStack::PopAndDestroy( message );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::MessageQueryViewDetailsL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUIViewAuthority::ValidateCertificateL(
+// Checks if the certificate is corrupted
+// Checks the validity period of the certificate
+// Display only one warning note, in the following order:
+// 1) Expired/Not yet valid
+// 2) Corrupted
+// 3) Not trusted
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::ValidateCertificateL(
+ TInt aIndex, CCertificate* aDetails, const CCTCertInfo& aCertInfo, TInt aType )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::ValidateCertificateL" );
+
+ TInt poppableItems = 0;
+ // Check allways first the validity period
+ // Show Expired/Not yet valid notes
+ const CValidityPeriod& validityPeriod = aDetails->ValidityPeriod();
+ const TTime& startValue = validityPeriod.Start();
+ const TTime& finishValue = validityPeriod.Finish();
+ TTime current;
+ current.UniversalTime();
+
+ if ( startValue > current )
+ {
+ // certificate is not valid yet
+ HBufC* string = StringLoader::LoadLC(
+ R_WARNING_NOTE_TEXT_CERTIFICATE_NOT_VALID_YET );
+ DisplayWarningNoteLD(string);
+ }
+ else if ( finishValue < current )
+ {
+ // certificate is expired
+ HBufC* string = StringLoader::LoadLC(
+ R_WARNING_NOTE_TEXT_CERTIFICATE_EXPIRED );
+ DisplayWarningNoteLD( string );
+ }
+ else
+ {
+ // put here check for certificate status, show warning notes if needed
+ TBool noValidationError = ETrue;
+ CArrayFixFlat<TValidationError>* status = NULL;
+ TCertificateFormat certificateFormat;
+
+ if ( aType == KCertTypeAuthority )
+ {
+ certificateFormat = iKeeper.iCALabelEntries[aIndex]->
+ iCAEntry->CertificateFormat();
+ }
+ else if ( aType == KCertTypeTrustedSite )
+ {
+ certificateFormat = iKeeper.iPeerLabelEntries[aIndex]->
+ iPeerEntry->CertificateFormat();
+ }
+ else if ( aType == KCertTypeDevice )
+ {
+ certificateFormat = iKeeper.iDeviceLabelEntries[aIndex]->
+ iDeviceEntry->CertificateFormat();
+ }
+ else
+ {
+ certificateFormat = iKeeper.iUserLabelEntries[aIndex]->
+ iUserEntry->CertificateFormat();
+ }
+
+ switch ( certificateFormat )
+ {
+ case EX509Certificate:
+ {
+ status = ValidateX509CertificateL(
+ (CX509Certificate*)aDetails );
+ break;
+ }
+ default:
+ {
+ status = new ( ELeave) CArrayFixFlat<TValidationError>( 1 );
+ break;
+ }
+ }
+ CleanupStack::PushL( status );
+ poppableItems++;
+
+ TInt errorCount = status->Count();
+ TBool ready = EFalse;
+ for ( TInt i = 0; i < errorCount && !ready; i++ )
+ {
+ TValidationError errorType = status->At(i);
+
+ switch ( errorType )
+ {
+ case EValidatedOK:
+ case EChainHasNoRoot:
+ case EBadKeyUsage:
+ // Ignore these errors
+ LOG_WRITE( "Ignored certificate validation error" );
+ break;
+
+ default:
+ // certificate is corrupted
+ noValidationError = EFalse;
+ HBufC* string = StringLoader::LoadLC(
+ R_WARNING_NOTE_TEXT_CERTIFICATE_CORRUPTED );
+ DisplayWarningNoteLD( string );
+ ready = ETrue;
+ break;
+ }
+ }
+
+ if ( noValidationError && (aType == KCertTypeAuthority ))
+ // Check for last if the CA certificate has no clients,
+ // ie. the trust state of every client is No
+ // For user certificates we don't do the check
+ {
+
+ RArray<TUid> trusterUids;
+ CleanupClosePushL( trusterUids );
+ poppableItems++;
+
+ iKeeper.iWrapper->GetApplicationsL(
+ iKeeper.CertManager(), aCertInfo, trusterUids );
+
+ if ( trusterUids.Count() == 0)
+ {
+ HBufC* string = StringLoader::LoadLC(
+ R_WARNING_NOTE_TEXT_CERTIFICATE_NOT_TRUSTED );
+ DisplayWarningNoteLD( string );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( poppableItems );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::ValidateCertificateL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DetailsFieldDynamicL(
+// Appends a field that has string from resources and string from CertManAPI
+// to the details view message body
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DetailsFieldDynamicL(
+ HBufC& aMessage, TPtrC aValue, TInt aResourceOne, TInt aResourceTwo )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DetailsFieldDynamicL" );
+
+ DetailsResourceL( aMessage, aResourceOne );
+ DetailsDynamicL( aMessage, aValue, aResourceTwo );
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DetailsFieldDynamicL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DetailsResourceL(
+// Reads line from resources
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DetailsResourceL(
+ HBufC& aMessage, TInt aResourceOne )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DetailsResourceL" );
+
+ HBufC* stringHolder = StringLoader::LoadLC( aResourceOne );
+ aMessage.Des().Append( stringHolder->Des() );
+ CleanupStack::PopAndDestroy(); // stringHolder
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DetailsResourceL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DetailsFieldResourceL(
+// Appends a field that has two strings from resources
+// to the details view message body
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DetailsFieldResourceL(
+ HBufC& aMessage, TInt aResourceOne,
+ TInt aResourceTwo)
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DetailsFieldResourceL" );
+
+ DetailsResourceL( aMessage, aResourceOne );
+ DetailsResourceL( aMessage, aResourceTwo );
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DetailsFieldResourceL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DevideToBlocks
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DevideToBlocks( const TDesC8& aInput, TPtr aOutput )
+ {
+ 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;
+ }
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DisplayWarningNoteLD(HBufC* aString)
+// Displays the warning note for corrupted/expired/not yet valid certificate
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DisplayWarningNoteLD( HBufC* aString )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DisplayWarningNoteLD" );
+
+ CAknWarningNote* note = new ( ELeave ) CAknWarningNote( ETrue );
+ note->ExecuteLD( *aString );
+ CleanupStack::PopAndDestroy(); // aString
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DisplayWarningNoteLD" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::ValidateX509CertificateL(CX509Certificate* aDetails)
+// Checks if the certificate is corrupted
+// Checks the validity period of the certificate
+// Display only one warning note, in the following order:
+// 1) Expired/Not yet valid
+// 2) Corrupted
+// 3) Not trusted
+// ---------------------------------------------------------
+//
+CArrayFixFlat<TValidationError>* CCertManUICertificateHelper::
+ ValidateX509CertificateL( CX509Certificate* aDetails )
+ {
+ TInt poppableItems = 0;
+ CArrayFixFlat<TValidationError>* status =
+ new ( ELeave ) CArrayFixFlat<TValidationError>( 1 );
+ CleanupStack::PushL( status ); //This is returned, so it isn't destroyed at the end.
+
+ TTime GMTTime;
+ GMTTime.UniversalTime(); // Get Universal Time
+ RPointerArray<CX509Certificate> certArray( &aDetails, 1 );
+
+ CPKIXCertChain* chain = CPKIXCertChain::NewLC(
+ iKeeper.iRfs, aDetails->Encoding(), certArray );
+ poppableItems++;
+
+ CPKIXValidationResult* result = CPKIXValidationResult::NewLC();
+ poppableItems++;
+ iKeeper.iWrapper->ValidateX509RootCertificateL( result, GMTTime, chain );
+
+ TValidationStatus validationStatus = result->Error();
+ //Set reserve space. One for error, other for warnings.
+ status->SetReserveL( 1 + result->Warnings().Count() );
+ status->AppendL(validationStatus.iReason);
+ for ( TUint8 i = 0; i < result->Warnings().Count(); i++ )
+ {
+ status->AppendL( result->Warnings().At(0).iReason );
+ }
+
+ CleanupStack::PopAndDestroy( poppableItems ); // All but status.
+ CleanupStack::Pop(); // status
+ return status;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DetailsDynamicL(
+// HBufC& aMessage, TPtrC aValue, TInt aResourceOne)
+// Reads dynamic text from CertManAPI, if the string is empty
+// put a not defined text from the resource in its place
+// KMaxLengthTextCertLabel = 510, used by CertLabel(), Issuer(), Owner()
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DetailsDynamicL(
+ HBufC& aMessage, TPtrC aValue, TInt aResourceOne )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DetailsDynamicL" );
+
+ HBufC* buf = HBufC::NewLC( KMaxLengthTextCertLabel );
+ buf->Des() = aValue;
+ buf->Des().TrimLeft();
+ // Cut CertLabel after fourth semi colon
+ TPtrC trimmedCertLabel = CutCertificateField( buf->Des() );
+ buf->Des().Copy( trimmedCertLabel );
+ TInt length = buf->Des().Length();
+ if ( length == 0 )
+ {
+ DetailsResourceL( aMessage, aResourceOne );
+ }
+ else
+ {
+ //LRM (Left-to-Right mark 200E)
+ const TInt KLRMark = 0x200E;
+ aMessage.Des().Append( buf->Des() );
+ aMessage.Des().Append(KLRMark);
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+ }
+ CleanupStack::PopAndDestroy(); // buf
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DetailsDynamicL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUIViewAuthority::ConfirmationQueryDeleteCertL()
+// Deletes either certificate in focus if there are no marked items,
+// or deletes the marked items
+// Shows read-only information notes if certificates are not deletable
+// Returns ETrue if at least one certificate is deleted
+// ---------------------------------------------------------
+//
+TBool CCertManUICertificateHelper::ConfirmationQueryDeleteCertL(
+ TInt aType,
+ CEikColumnListBox* aListBox )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::ConfirmationQueryDeleteCertL" );
+
+ TBool result = EFalse;
+
+ const CArrayFix<TInt>* array = aListBox->SelectionIndexes();
+ TInt focusPosition = aListBox->CurrentItemIndex();
+ CCTCertInfo* entry;
+ TInt queryOk = 0;
+ // comes here when there is no selection, can be read-only
+ // certificate if Clear key is pressed, must check
+ if ( array->Count() == 0 && IsCertificateDeletable( focusPosition, aType ) )
+ {
+ if( aType == KCertTypeAuthority )
+ {
+ entry = iKeeper.iCALabelEntries[ focusPosition ]->iCAEntry;
+ }
+ else if( aType == KCertTypeTrustedSite )
+ {
+ entry = iKeeper.iPeerLabelEntries[ focusPosition ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = iKeeper.iDeviceLabelEntries[ focusPosition ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = iKeeper.iUserLabelEntries[ focusPosition ]->iUserEntry;
+ }
+ queryOk = DeleteSingleItemQueryL( *entry );
+ if ( queryOk )
+ {
+ if (IsCertificateDeletable( focusPosition, aType ))
+ {
+ DeleteSingleItemL( *entry, focusPosition, aListBox, aType );
+
+
+ AknListBoxUtils::HandleItemRemovalAndPositionHighlightL(
+ aListBox, focusPosition, ETrue );
+ result = ETrue;
+ }
+ else
+ {
+ ReadOnlySingleItemNoteL( *entry );
+ }
+ }
+ }
+ else if ( IsOneMarkedCertificateDeletable(aListBox, aType) ) //if (array->Count()=>1)
+ {
+ if ( aType == KCertTypeAuthority )
+ {
+ entry = iKeeper.iCALabelEntries[ array->At(0) ]->iCAEntry;
+ }
+ else if ( aType == KCertTypeTrustedSite )
+ {
+ entry = iKeeper.iPeerLabelEntries[ array->At(0) ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = iKeeper.iDeviceLabelEntries[ array->At(0) ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = iKeeper.iUserLabelEntries[ array->At(0) ]->iUserEntry;
+ }
+
+ if (array->Count()==1)
+ {
+ queryOk = DeleteSingleItemQueryL( *entry );
+ }
+ else
+ {
+ HBufC* prompt = StringLoader::LoadLC(
+ R_CONFIRMATION_QUERY_DELETE_CERT_PLURAL, array->Count() );
+ queryOk = DisplayConfirmationLD( prompt );
+ }
+ if ( queryOk )
+ {
+ TInt readonlyCount = 0;
+ TInt singleReadOnlyPosition = 0;
+ TInt markedPosition = 0;
+ TKeyArrayFix ownKey( 0, ECmpTInt );
+ CONST_CAST(CArrayFix<int>*, array)->Sort( ownKey ); //lint !e665 expression macro param ok
+ TInt markedCount = array->Count();
+ CArrayFixFlat<TInt>* deletedIndexes = new (ELeave)CArrayFixFlat<TInt>( 4 );
+ CleanupStack::PushL( deletedIndexes );
+
+ iKeeper.StartWaitDialogL( ECertmanUiDeleteDialog );
+ CleanupCloseWaitDialogPushL( iKeeper );
+
+ for ( TInt i = markedCount; i > 0; i-- )
+ {
+ markedPosition = array->At( i-1 );
+ // move focus up the list if marked items were
+ // between focus and the beginning of the list
+ if ( focusPosition > markedPosition )
+ {
+ focusPosition--;
+ }
+
+ // Check whether certificate is deletable
+
+ if( aType == KCertTypeAuthority )
+ {
+ entry = iKeeper.iCALabelEntries[ markedPosition ]->iCAEntry;
+ }
+ else if( aType == KCertTypeTrustedSite )
+ {
+ entry = iKeeper.iPeerLabelEntries[ markedPosition ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = iKeeper.iDeviceLabelEntries[ markedPosition ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = iKeeper.iUserLabelEntries[ markedPosition ]->iUserEntry;
+ }
+
+ if (IsCertificateDeletable(markedPosition, aType))
+ {
+ DeleteSingleItemL( *entry, markedPosition, aListBox, aType );
+ deletedIndexes->AppendL(markedPosition);
+ result = ETrue;
+ }
+ else // Cannot be deleted
+ {
+ readonlyCount++;
+ singleReadOnlyPosition = markedPosition;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // closes wait dialog
+
+ if ( readonlyCount == 1 )
+ {
+ if( aType == KCertTypeAuthority )
+ {
+ entry = iKeeper.iCALabelEntries[ singleReadOnlyPosition ]->iCAEntry;
+ }
+ else if( aType == KCertTypeTrustedSite )
+ {
+ entry = iKeeper.iPeerLabelEntries[ singleReadOnlyPosition ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = iKeeper.iDeviceLabelEntries[ singleReadOnlyPosition ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = iKeeper.iUserLabelEntries[ singleReadOnlyPosition ]->iUserEntry;
+ }
+
+ ReadOnlySingleItemNoteL( *entry );
+ }
+ else if ( readonlyCount > 1 )
+ {
+ HBufC* string = StringLoader::LoadLC(
+ R_INFO_NOTE_TEXT_CERTIFICATE_READ_ONLY_MULTIPLE,
+ readonlyCount );
+ DisplayNoteLD( string );
+ }
+ else
+ { // For lint
+ }
+
+ aListBox->ClearSelection();
+ AknListBoxUtils::HandleItemRemovalAndPositionHighlightL(
+ aListBox, focusPosition, *deletedIndexes);
+ CleanupStack::PopAndDestroy(deletedIndexes);
+
+ }
+ }
+ else
+ {
+ result = EFalse;
+ }
+
+ aListBox->DrawNow();//lint !e539
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::ConfirmationQueryDeleteCertL" );
+
+
+ return result;
+ }
+
+// ---------------------------------------------------------
+// CCertManUIViewAuthority::DeleteSingleItemQueryL(CCTCertInfo& aEntry)
+// Gets the certificate name (or No label/No subject) for the Confirmation note
+// ---------------------------------------------------------
+//
+TInt CCertManUICertificateHelper::DeleteSingleItemQueryL( CCTCertInfo& aEntry )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DeleteSingleItemQueryL" );
+
+ TInt selection = 0;
+
+ HBufC* buf = HBufC::NewLC( KMaxLengthTextCertLabel );
+ buf->Des() = aEntry.Label();
+ buf->Des().TrimLeft();
+ // Cut CertLabel after fourth semi colon
+ TPtrC trimmedCertLabel = CutCertificateField( buf->Des() );
+ buf->Des().Copy(trimmedCertLabel);
+ TInt length = buf->Des().Length();
+ if ( length == 0 )
+ {
+ // here the resource name is _NO_LABEL, but it returns only "Delete certificate?"
+ // not any "No label" or "No subject" string
+ HBufC* prompt = StringLoader::LoadLC(
+ R_CONFIRMATION_QUERY_DELETE_CERT_NO_LABEL );
+ selection = DisplayConfirmationLD( prompt );
+ }
+ else
+ {
+ HBufC* prompt = StringLoader::LoadLC(
+ R_CONFIRMATION_QUERY_DELETE_CERT, buf->Des() );
+ selection = DisplayConfirmationLD(prompt);
+ }
+ CleanupStack::PopAndDestroy(); // buf
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::DeleteSingleItemQueryL" );
+
+ return selection;
+ }
+
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DeleteSingleItemL(CCrCertEntry& aEntry, TInt aPosition, TInt aType)
+// Deletes one item from CertManAPI and from listbox
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DeleteSingleItemL( CCTCertInfo& aEntry,
+ TInt aPosition,
+ CEikColumnListBox* aListBox,
+ TInt aType )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::DeleteSingleItemL" );
+
+ TInt status( KErrNone );
+
+ if ( aType == KCertTypeTrustedSite )
+ {
+ status = iKeeper.iWrapper->DeleteCertL(
+ iKeeper.CertManager(),
+ aEntry,
+ KCMTrustedServerTokenUid
+ );
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ status = iKeeper.iWrapper->DeleteCertL(
+ iKeeper.CertManager(),
+ aEntry,
+ KCMDeviceCertStoreTokenUid
+ );
+ }
+ else
+ {
+ status = iKeeper.iWrapper->DeleteCertL( iKeeper.CertManager(), aEntry );
+ }
+
+ // Update the list after delete. In case of a error, a note show inside DeleteCertL.
+ if ( status == KErrNone )
+ {
+ MDesCArray *itemList = aListBox->Model()->ItemTextArray();
+ CDesCArray* itemArray = STATIC_CAST( CDesCArray*, itemList );
+ itemArray->Delete( aPosition );
+ }
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::DeleteSingleItemL" ); //lint !e539
+ }
+
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::MoveKeyL(const TCTKeyAttributeFilter& aFilter,
+// TUid aSourceStore, TUid aSourceStore )
+// Moves a key from one store to another
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::MoveKeyL(
+ const TCTKeyAttributeFilter& aFilter,
+ const TUid aSourceStore,
+ const TUid aTargetStore )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::MoveCertL" );
+
+ iKeeper.iWrapper->MoveKeyL( iKeeper.KeyManager(), aFilter, aSourceStore, aTargetStore );
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::MoveCertL" );
+ }
+
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::MoveCertL(CCrCertEntry& aEntry,
+// TInt aPosition, CEikColumnListBox* aListBox,
+// TUid aSourceStore, TUid aSourceStore )
+// Moves a certificate from one store to another
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::MoveCertL( CCTCertInfo& aEntry,
+ TInt aPosition,
+ CEikColumnListBox* aListBox,
+ const TUid aSourceStore,
+ const TUid aTargetStore )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::MoveCertL" );
+
+ TInt certCount(0);
+
+ TRAPD( err, certCount = iKeeper.iWrapper->MoveCertL( iKeeper.CertManager(), aEntry, aSourceStore, aTargetStore ));
+
+ // Update the list after moving the certificate
+ if ( err == KErrNone )
+ {
+ MDesCArray *itemList = aListBox->Model()->ItemTextArray();
+ CDesCArray* itemArray = STATIC_CAST( CDesCArray*, itemList );
+ if ( certCount == 1 )
+ {
+ // Delete single item
+ itemArray->Delete( aPosition );
+ AknListBoxUtils::HandleItemRemovalAndPositionHighlightL(
+ aListBox, aPosition, ETrue );
+ }
+ else
+ {
+ // More than one certificate moved. Empty listbox items.
+ // It will be updated later
+ itemArray->Reset();
+ }
+ }
+ else
+ {
+ User::Leave( err );
+ }
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::MoveCertL" );
+ }
+
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::ReadOnlySingleItemNoteL(CCTCertInfo& aEntry)
+// Gets the certificate name (or No label/No subject) for the read-only note
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::ReadOnlySingleItemNoteL(CCTCertInfo& aEntry )
+ {
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::ReadOnlySingleItemNoteL" );
+
+ HBufC* buf = HBufC::NewLC( KMaxLengthTextCertLabel );
+ buf->Des() = aEntry.Label();
+ buf->Des().TrimLeft();
+ // Cut CertLabel after fourth semi colon
+ TPtrC trimmedCertLabel = CutCertificateField( buf->Des() );
+ buf->Des().Copy(trimmedCertLabel);
+ TInt length = buf->Des().Length();
+ if ( length == 0 )
+ {
+ // here the resource name is _NO_LABEL, but it returns only "Cannot delete certificate"
+ // not any "No label" or "No subject" string
+ HBufC* stringHolder = StringLoader::LoadLC(
+ R_INFO_NOTE_TEXT_CERTIFICATE_READ_ONLY_NO_LABEL );
+ DisplayNoteLD( stringHolder );
+ }
+ else
+ {
+ HBufC* stringHolder = StringLoader::LoadLC(
+ R_INFO_NOTE_TEXT_CERTIFICATE_READ_ONLY, buf->Des() );
+ DisplayNoteLD( stringHolder );
+ }
+ CleanupStack::PopAndDestroy(); // buf
+
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::ReadOnlySingleItemNoteL" );
+ }
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DisplayConfirmationLD(HBufC* aString)
+// Displays Delete yes/no confirmation notes
+// ---------------------------------------------------------
+//
+TInt CCertManUICertificateHelper::DisplayConfirmationLD( HBufC* aString )
+ {
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::DisplayConfirmationLD" );
+
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL( CAknQueryDialog::ENoTone );
+ TInt selection = dlg->ExecuteLD( R_CERTMANUI_CONFIRMATION_QUERY_YES_NO, *aString );
+ // Takes ownership and destroys aString
+ CleanupStack::PopAndDestroy(); // aString
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::DisplayConfirmationLD" );
+
+ return selection;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::DisplayNoteLD(HBufC* aString)
+// Displays read-only information notes
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::DisplayNoteLD(HBufC* aString)
+ {
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::DisplayNoteLD" );
+
+ CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+ note->ExecuteLD( *aString );
+ CleanupStack::PopAndDestroy(); // aString
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::DisplayNoteLD" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::FFSSpaceBelowCriticalLevelL
+// Handle deleting when disk is getting full
+// ---------------------------------------------------------
+//
+TBool CCertManUICertificateHelper::FFSSpaceBelowCriticalLevelL(
+ TBool aShowErrorNote, TInt aBytesToWrite )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::FFSSpaceBelowCriticalLevelL" );
+
+ TBool ret = EFalse;
+ if ( SysUtil::FFSSpaceBelowCriticalLevelL(
+ &(CCoeEnv::Static()->FsSession()), aBytesToWrite ) )
+ {
+ ret = ETrue;
+ if ( aShowErrorNote )
+ {
+ CErrorUI* errorUi = CErrorUI::NewLC( *(CCoeEnv::Static()) );
+ errorUi->ShowGlobalErrorNoteL( KErrDiskFull );
+ CleanupStack::PopAndDestroy(); // errorUi
+ }
+ }
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::FFSSpaceBelowCriticalLevelL" );
+
+ return ret;
+ }
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::HandleMarkableListCommandL( TInt aCommand )
+// Handles marking and unmarking of the list.
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::HandleMarkableListCommandL( TInt aCommand,
+ CEikColumnListBox* aListBox )
+ {
+ CERTMANUILOGGER_ENTERFN(
+ "CCertManUICertificateHelper::HandleMarkableListCommandL" );
+
+ TInt index;
+ switch ( aCommand )
+ {
+ case ECertManUICmdMark:
+ {
+ index = aListBox->CurrentItemIndex();
+ if ( index >= 0 )
+ {
+ // This is done to make sure listbox updates its state
+ // to make shift+arrow work correctly after shift+ok
+ aListBox->View()->UpdateSelectionL( CListBoxView::EDisjointSelection );
+ aListBox->View()->SelectItemL( index );
+ }
+ break;
+ }
+ case ECertManUICmdUnmark:
+ {
+ index = aListBox->CurrentItemIndex();
+ if ( index >= 0 )
+ {
+ // This is done to make sure listbox updates its state
+ // to make shift+arrow work correctly after shift+ok
+ aListBox->View()->UpdateSelectionL(
+ CListBoxView::EDisjointSelection );
+ aListBox->View()->DeselectItem( index );
+ }
+ break;
+ }
+ case ECertManUICmdMarkAll:
+ {
+ aListBox->ClearSelection();
+ TInt count = aListBox->Model()->NumberOfItems();
+ if ( count )
+ {
+ CArrayFixFlat<TInt>* selection =
+ new( ELeave ) CArrayFixFlat<TInt>( 1 );
+ CleanupStack::PushL( selection );
+ selection->SetReserveL( count );
+ for( TInt i = 0; i < count; i++ )
+ {
+ selection->AppendL( i );
+ }
+ aListBox->SetSelectionIndexesL( selection );
+ CleanupStack::PopAndDestroy(); // selection
+ }
+ break;
+ }
+ case ECertManUICmdUnmarkAll:
+ {
+ aListBox->ClearSelection();
+ break;
+ }
+ default:
+ break;
+ }
+
+ CERTMANUILOGGER_LEAVEFN(
+ "CCertManUICertificateHelper::HandleMarkableListCommandL" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::GetKeyUsageAndLocationL( CCTCertInfo* aCertEntry,
+// TUid* aKeyLocation)
+// Returns key usage and location.
+// ---------------------------------------------------------
+//
+TKeyUsagePKCS15 CCertManUICertificateHelper::GetKeyUsageAndLocationL( CCTCertInfo* aCertEntry,
+ TUid* aKeyLocation )
+ {
+ TKeyUsagePKCS15 keyUsage;
+
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::GetKeyUsageAndLocationL" );
+
+ // Check whether we have key for this certificate
+ RMPointerArray<CCTKeyInfo> keyEntry;
+ TCTKeyAttributeFilter filter;
+ filter.iKeyId = aCertEntry->SubjectKeyId();
+
+ iKeeper.iWrapper->ListL( iKeeper.KeyManager(), &keyEntry, filter );
+
+ if (keyEntry.Count())
+ {
+ keyUsage = keyEntry[0]->Usage();
+ // Get Location
+ aKeyLocation->iUid = keyEntry[0]->Token().TokenType().Type().iUid ;
+ }
+ else
+ {
+ keyUsage = EPKCS15UsageNone;
+ }
+
+ keyEntry.Close();
+ LOG_WRITE_FORMAT( "Key usage : %X", keyUsage );
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::GetKeyUsageAndLocationL" );
+ return keyUsage;
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::SetLocationInfoL( (HBufC& aMessage,
+// TBool aCertificate,
+// TUid* aLocUid)
+// Adds certificate/private key's location info to certificate details
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::SetLocationInfoL(
+ HBufC& aMessage,
+ TBool aCertificate,
+ TUid* aLocUid)
+ {
+ TInt location = 0;
+ TInt locationRes = 0;
+
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::SetLocationInfo" );
+
+ switch ( aLocUid->iUid )
+ {
+ case KFileCertStoreUid:
+ case KTrustedServerCertStoreUid:
+ case KDeviceCertStoreUid:
+ case KDeviceKeyStoreUid:
+ case KTokenTypeFileKeystore:
+ location = R_TEXT_RESOURCE_DETAILS_VIEW_LOCATION_PHONE_MEMORY;
+ break;
+
+ case KWIMCertStoreUid:
+ location = R_TEXT_RESOURCE_DETAILS_VIEW_LOCATION_SMART_CARD;
+ break;
+
+ default:
+ if ( aCertificate )
+ {
+ location = R_TEXT_RESOURCE_DETAILS_VIEW_NOT_DEFINED;
+ }
+ else
+ {
+ location = R_TEXT_RESOURCE_DETAILS_VIEW_NO_PRIVATE_KEY;
+ }
+ break;
+ }
+
+ if ( aCertificate )
+ {
+ locationRes = R_TEXT_RESOURCE_DETAILS_VIEW_CERTIFICATE_LOCATION;
+ }
+ else
+ {
+ locationRes = R_TEXT_RESOURCE_DETAILS_VIEW_PRIVATE_KEY_LOCATION;
+ }
+
+ DetailsFieldResourceL( aMessage, locationRes, location );
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::SetLocationInfo" );
+ }
+
+// ---------------------------------------------------------
+// CCertManUICertificateHelper::CreateMessageBodyTextL()
+// ---------------------------------------------------------
+//
+void CCertManUICertificateHelper::CreateMessageBodyTextL( TInt aIndex, TInt aType,
+ CEikonEnv* aEikonEnv, HBufC& aMessage )
+ {
+ CERTMANUILOGGER_ENTERFN( "CCertManUICertificateHelper::CreateMessageBodyTextL" );
+
+ // Use certificate index from previous view
+ HBufC8* urlBuf = NULL;
+ CCTCertInfo* entry = NULL;
+ CCertificate* details = NULL;
+ CUnifiedCertStore*& store = iKeeper.CertManager();
+
+ if( aType == KCertTypeAuthority )
+ {
+ entry = ( iKeeper.iCALabelEntries )[ aIndex ]->iCAEntry;
+ }
+ else if( aType == KCertTypeTrustedSite )
+ {
+ entry = ( iKeeper.iPeerLabelEntries )[ aIndex ]->iPeerEntry;
+ }
+ else if( aType == KCertTypeDevice )
+ {
+ entry = ( iKeeper.iDeviceLabelEntries )[ aIndex ]->iDeviceEntry;
+ }
+ else
+ {
+ entry = ( iKeeper.iUserLabelEntries )[ aIndex ]->iUserEntry;
+ }
+
+ TCertificateFormat certiticateFormat = entry->CertificateFormat();
+
+ if( certiticateFormat != EX509CertificateUrl )
+ {
+ TInt err = iKeeper.iWrapper->GetCertificateL( store, *entry, details );
+ CleanupStack::PushL( details );
+ User::LeaveIfError( err );
+
+ ValidateCertificateL( aIndex, details, *entry, aType );
+ }
+ else
+ {
+ urlBuf = HBufC8::NewLC( entry->Size() );
+ TPtr8 urlPtr = urlBuf->Des();
+ TInt err = iKeeper.iWrapper->GetUrlCertificateL( store, *entry, urlPtr );
+ User::LeaveIfError( err );
+ }
+
+ if( aType == KCertTypeTrustedSite )
+ {
+ CTrustSitesStore* trustedSitesStore = CTrustSitesStore::NewL();
+ CleanupStack::PushL( trustedSitesStore );
+
+ RPointerArray<HBufC> trustedSites;
+ CleanupResetAndDestroyPushL( trustedSites );
+ trustedSitesStore->GetTrustedSitesL( details->Encoding(), trustedSites );
+
+ if( trustedSites.Count() > 0 )
+ {
+ if( trustedSites.Count() == 1 )
+ {
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_SITE );
+ }
+ else
+ {
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_SITES );
+ }
+
+ for( TInt i = 0; i < trustedSites.Count(); i++ )
+ {
+ aMessage.Des().Append( *trustedSites[ i ] );
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+ }
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+ }
+
+ CleanupStack::PopAndDestroy( &trustedSites );
+ CleanupStack::PopAndDestroy( trustedSitesStore );
+ }
+ else
+ {
+ DetailsFieldDynamicL( aMessage, entry->Label(),
+ R_TEXT_RESOURCE_DETAILS_VIEW_LABEL,
+ R_TEXT_RESOURCE_VIEW_NO_LABEL_DETAILS );
+ }
+
+ // certificate issuer and owner
+ if( certiticateFormat == EX509Certificate )
+ {
+ HBufC* owner = NULL;
+ X509CertNameParser::SubjectFullNameL( *(CX509Certificate*)details, owner );
+ CleanupStack::PushL( owner );
+
+ HBufC* issuer = NULL;
+ X509CertNameParser::IssuerFullNameL( *(CX509Certificate*)details, issuer );
+ CleanupStack::PushL( issuer );
+
+ DetailsFieldDynamicL( aMessage, issuer->Des(),
+ R_TEXT_RESOURCE_DETAILS_VIEW_ISSUER,
+ R_TEXT_RESOURCE_DETAILS_VIEW_NOT_DEFINED );
+ CleanupStack::PopAndDestroy( issuer );
+
+ // certificate subject
+ DetailsFieldDynamicL( aMessage, owner->Des(),
+ R_TEXT_RESOURCE_DETAILS_VIEW_SUBJECT,
+ R_TEXT_RESOURCE_VIEW_NO_SUBJECT_DETAILS );
+ CleanupStack::PopAndDestroy( owner );
+ }
+
+ // Get key usage and location. This is done only client certificates.
+ const TInt KLocationUnknown = 0;
+ TUid keyLocation = { KLocationUnknown };
+
+ if(( aType == KCertTypePersonal ) || ( aType == KCertTypeDevice ))
+ {
+ TInt usage;
+ switch( GetKeyUsageAndLocationL( entry, &keyLocation ) )
+ {
+ case EPKCS15UsageSignSignRecover:
+ case EPKCS15UsageSignDecrypt:
+ case EPKCS15UsageSign:
+ usage = R_TEXT_RESOURCE_DETAILS_VIEW_CLIENT_AUTHENTICATION;
+ break;
+ case EPKCS15UsageNonRepudiation:
+ usage = R_TEXT_RESOURCE_DETAILS_VIEW_DIGITAL_SIGNING;
+ break;
+ default:
+ usage = R_TEXT_RESOURCE_DETAILS_VIEW_NOT_DEFINED;
+ break;
+ }
+ DetailsFieldResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_KEY_USAGE, usage );
+ }
+
+ if( certiticateFormat == EX509Certificate )
+ {
+ // Certificate validity period
+ // Hometime's offset to UTC
+ TLocale locale;
+ TTimeIntervalSeconds offSet = locale.UniversalTimeOffset();
+
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_VALID_FROM );
+ const CValidityPeriod& validityPeriod = details->ValidityPeriod();
+ TTime startValue = validityPeriod.Start();
+ startValue += offSet;
+
+ HBufC* dateFormatString = aEikonEnv->AllocReadResourceLC( R_QTN_DATE_USUAL_WITH_ZERO );
+
+ TBuf<KMaxLengthTextDateString> startString;
+ startValue.FormatL( startString, *dateFormatString );
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion( startString );
+ aMessage.Des().Append( startString );
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_VALID_UNTIL );
+ TTime finishValue = validityPeriod.Finish();
+ finishValue += offSet;
+ TBuf<KMaxLengthTextDateString> finishString;
+
+ finishValue.FormatL( finishString, *dateFormatString );
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion( finishString );
+ aMessage.Des().Append( finishString );
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+
+ CleanupStack::PopAndDestroy( dateFormatString );
+
+ TUid certLoc;
+ certLoc.iUid = entry->Token().TokenType().Type().iUid;
+ SetLocationInfoL( aMessage, ETrue, &certLoc );
+ }
+ else if( certiticateFormat == EX509CertificateUrl )
+ {
+ HBufC* urlBuf16 = HBufC::NewLC( urlBuf->Length() );
+ TPtr urlPtr = urlBuf16->Des();
+ urlPtr.Copy(*urlBuf);
+ DetailsFieldDynamicL( aMessage, urlBuf16->Des(),
+ R_TEXT_RESOURCE_DETAILS_VIEW_CERTIFICATE_LOCATION,
+ R_TEXT_RESOURCE_DETAILS_VIEW_NOT_DEFINED );
+ CleanupStack::PopAndDestroy( urlBuf16 );
+ }
+ else
+ {
+ // nothing
+ }
+
+ // certificate format
+ TInt fieldType = 0;
+ TInt fieldType2 = 0;
+ switch( certiticateFormat )
+ {
+ case EX509Certificate:
+ case EX509CertificateUrl:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_CERT_FORMAT_X509;
+ break;
+ }
+ default:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_NOT_DEFINED;
+ break;
+ }
+ }
+ DetailsFieldResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_CERT_FORMAT, fieldType );
+
+ // Private key location, only for user and device certicates
+ if(( aType == KCertTypePersonal ) || ( aType == KCertTypeDevice ))
+ {
+ SetLocationInfoL( aMessage, EFalse, &keyLocation );
+ }
+
+ if( certiticateFormat == EX509Certificate )
+ {
+ __UHEAP_MARK;
+
+ // certificate algorithms
+
+ // digest algorithm
+ TAlgorithmId algorithmId = details->SigningAlgorithm().DigestAlgorithm().Algorithm();
+ switch( algorithmId )
+ {
+ case EMD2:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_MD2;
+ break;
+ }
+ case EMD5:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_MD5;
+ break;
+ }
+ case ESHA1:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_SHA1;
+ break;
+ }
+ default:
+ {
+ fieldType = R_TEXT_RESOURCE_DETAILS_VIEW_UNKNOWN;
+ break;
+ }
+ }
+
+ // public-key algorithm
+ algorithmId = details->SigningAlgorithm().AsymmetricAlgorithm().Algorithm();
+ switch( algorithmId )
+ {
+ case ERSA:
+ {
+ fieldType2 = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_RSA;
+ break;
+ }
+ case EDSA:
+ {
+ fieldType2 = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_DSA;
+ break;
+ }
+ case EDH:
+ {
+ fieldType2 = R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM_DH;
+ break;
+ }
+ default:
+ {
+ fieldType2 = R_TEXT_RESOURCE_DETAILS_VIEW_UNKNOWN;
+ }
+ }
+
+ // If other algorithm is unknown
+ if( fieldType == R_TEXT_RESOURCE_DETAILS_VIEW_UNKNOWN ||
+ fieldType2 == R_TEXT_RESOURCE_DETAILS_VIEW_UNKNOWN )
+ {
+ DetailsFieldResourceL( aMessage,
+ R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM,
+ R_TEXT_RESOURCE_DETAILS_VIEW_UNKNOWN );
+ }
+ else // Both are known.
+ {
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_ALGORITHM );
+ HBufC* stringHolder = StringLoader::LoadLC( fieldType );
+ aMessage.Des().Append( stringHolder->Des() );
+ CleanupStack::PopAndDestroy( stringHolder );
+ stringHolder = StringLoader::LoadLC( fieldType2 );
+ aMessage.Des().Append( stringHolder->Des() );
+ CleanupStack::PopAndDestroy( stringHolder );
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+ }
+
+ // certificate serial number
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_SERIAL_NUMBER );
+ TPtrC8 serialNumber = details->SerialNumber();
+ TBuf<KMaxLengthTextSerialNumberFormatting> buf2;
+
+ for( TInt i = 0; i < serialNumber.Length(); i++ )
+ {
+ buf2.Format( KCertManUIDetailsViewHexaFormat, serialNumber[i] );
+ aMessage.Des().Append( buf2 );
+ }
+
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+
+ // certificate fingerprint SHA-1
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_FINGERPRINT );
+ TPtrC8 sha1_fingerprint = details->Fingerprint();
+ DevideToBlocks( sha1_fingerprint, aMessage.Des() );
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+
+ // certificate fingerprint MD5
+ DetailsResourceL( aMessage, R_TEXT_RESOURCE_DETAILS_VIEW_FINGERPRINT_MD5 );
+
+ CMD5* md5 = CMD5::NewL();
+ CleanupStack::PushL( md5 );
+ TBuf8<20> fingerprint = md5->Hash( details->Encoding() );
+ CleanupStack::PopAndDestroy( md5 );
+
+ DevideToBlocks( fingerprint, aMessage.Des() );
+ aMessage.Des().Append( KCertManUIDetailsViewEnterEnter );
+
+ // Public key
+ // qtn_cm_public_key looks like this "Public key (%0U %1N bit):"
+ // so DetailsResource cannot be used to get it.
+
+ // We already know the public key algorithm, it has been put into fieldType2 above.
+ HBufC* pubkeyHolder = StringLoader::LoadLC( fieldType2 ); // %0U
+
+ CDesCArrayFlat* strArray = new (ELeave) CDesCArrayFlat( 1 );
+ CleanupStack::PushL( strArray );
+
+ strArray->InsertL( 0, *pubkeyHolder );
+
+ // Get public key already here to get length of it for string loader.
+ const CSubjectPublicKeyInfo& publicKey = details->PublicKey();
+ TPtrC8 keyData = publicKey.KeyData();
+ TInt size = keyData.Size(); // %1N
+
+ // To get key size decode DER encoded key got from the certificate.
+ TX509KeyFactory key;
+
+ // There doesn't seem to be definition of MAX_INT anywhere so calculate it.
+ TReal maxInt;
+ TReal intBits = sizeof( TInt ) * 8;
+ Math::Pow( maxInt, 2, intBits );
+ maxInt = ( maxInt / 2 ) - 1;
+
+ switch( algorithmId )
+ {
+ case ERSA:
+ {
+ const CRSAPublicKey* keyRSA = key.RSAPublicKeyL( keyData );
+
+ const TInteger& n = keyRSA->N();
+
+ TUint keySizeN = n.BitCount();
+
+ // Play it safe.
+ if( keySizeN < maxInt )
+ {
+ size = keySizeN;
+ }
+
+ delete keyRSA;
+
+ break;
+ }
+ case EDSA:
+ {
+ TPtrC8 params = publicKey.EncodedParams();
+ const CDSAPublicKey* keyDSA = key.DSAPublicKeyL( params, keyData );
+
+ const TInteger& y = keyDSA->Y();
+
+ TUint keySizeY = y.BitCount();
+
+ // Play it safe.
+ if( keySizeY < maxInt )
+ {
+ size = keySizeY;
+ }
+
+ delete keyDSA;
+
+ break;
+ }
+ // There doesn't seem to be TX509KeyFactory function for DH keys.
+ // If the key is DH or unknown, just multiply length of the key
+ // in bytes with 8. It is not correct but at least gives an idea.
+ // Without setting something to size 'unknown' text should be used
+ // below for the string which is much more error prone than setting
+ // at least something.
+ case EDH:
+ default:
+ {
+ size = 8 * keyData.Size();
+ }
+ }
+
+ CArrayFixFlat<TInt>* intArr = new (ELeave) CArrayFixFlat<TInt>( 1 );
+ CleanupStack::PushL( intArr );
+ intArr->AppendL( size );
+
+ // Load string and set algorithm and key length strings.
+ HBufC* stringHolder = StringLoader::LoadLC( R_TEXT_RESOURCE_DETAILS_VIEW_PUBLIC_KEY,
+ *strArray, *intArr );
+ aMessage.Des().Append( stringHolder->Des() );
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+
+ // Finally append the public key.
+ DevideToBlocks( keyData, aMessage.Des() );
+
+ const TInt KItemsInCleanupStack = 4; // stringHolder, intArr, strArray, pubkeyHolder
+ CleanupStack::PopAndDestroy( KItemsInCleanupStack, pubkeyHolder );
+
+ __UHEAP_MARKEND;
+ }
+ else
+ {
+ // SetUrlCertAlgorihm()
+ }
+
+ if( certiticateFormat != EX509CertificateUrl )
+ {
+ CleanupStack::PopAndDestroy( details );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( urlBuf );
+ }
+
+ aMessage.Des().Append( KCertManUIDetailsViewEnter );
+
+ CERTMANUILOGGER_LEAVEFN( "CCertManUICertificateHelper::CreateMessageBodyTextL" );
+ }
+
+
+// End of file