diff -r 000000000000 -r 164170e6151a pkiutilities/CertmanUi/SRC/CertmanuiCertificateHelper.cpp --- /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 +#include +#include // MD5 fingerprint +#include +#include // for validation +#include // for warning & information notes +#include +#include +#include +#include +#include // TX509KeyFactory +#include // 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 CleanupResetAndDestroy + { +public: + inline static void PushL( T& aRef ); +private: + static void ResetAndDestroy( TAny *aPtr ); + }; + +template +inline void CleanupResetAndDestroyPushL( T& aRef ); + +template +inline void CleanupResetAndDestroy::PushL( T& aRef ) + { + CleanupStack::PushL( TCleanupItem( &ResetAndDestroy, &aRef ) ); + } + +template +void CleanupResetAndDestroy::ResetAndDestroy( TAny *aPtr ) + { + if( aPtr ) + { + static_cast( aPtr )->ResetAndDestroy(); + } + } + +template +inline void CleanupResetAndDestroyPushL( T& aRef ) + { + CleanupResetAndDestroy::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* 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* 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( 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 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* CCertManUICertificateHelper:: + ValidateX509CertificateL( CX509Certificate* aDetails ) + { + TInt poppableItems = 0; + CArrayFixFlat* status = + new ( ELeave ) CArrayFixFlat( 1 ); + CleanupStack::PushL( status ); //This is returned, so it isn't destroyed at the end. + + TTime GMTTime; + GMTTime.UniversalTime(); // Get Universal Time + RPointerArray 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* 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*, array)->Sort( ownKey ); //lint !e665 expression macro param ok + TInt markedCount = array->Count(); + CArrayFixFlat* deletedIndexes = new (ELeave)CArrayFixFlat( 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* selection = + new( ELeave ) CArrayFixFlat( 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 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 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 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 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 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* intArr = new (ELeave) CArrayFixFlat( 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