First public contribution.
2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "unifiedcertstore.h"
20 #include "unifiedcertstoreworkingvars.h"
21 #include "CCheckedCertStore.h"
22 #include <certificateapps.h>
26 #include <ecom/ecom.h>
28 _LIT(KUCSPanic, "CUnifiedCertStore");
29 #define assert(x) __ASSERT_ALWAYS((x), User::Panic(KUCSPanic, 1));
31 /////////////////////////////////////////////////////////////////////////////////////
33 /////////////////////////////////////////////////////////////////////////////////////
35 EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewL(RFs& aFs, TBool aOpenForWrite)
37 CUnifiedCertStore* self = CUnifiedCertStore::NewLC(aFs, aOpenForWrite);
38 CleanupStack::Pop(self);
42 EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewLC(RFs& aFs, TBool aOpenForWrite)
44 CUnifiedCertStore* self = new(ELeave) CUnifiedCertStore(aFs, aOpenForWrite);
45 CleanupStack::PushL(self);
46 RArray<TInt> orderingFilter;
47 self->ConstructL(orderingFilter);
51 EXPORT_C CUnifiedCertStore::~CUnifiedCertStore()
55 assert(!iWorkingVars);
57 TInt end = iReadOnlyCertStores.Count();
59 for (i = 0; i < end; i++)
61 iReadOnlyCertStores[i]->Release();
63 iReadOnlyCertStores.Close();
65 end = iWritableCertStores.Count();
66 for (i = 0; i < end; i++)
68 iWritableCertStores[i]->Release();
70 iWritableCertStores.Close();
72 // The elements are already released by the two loops above
75 // release resources allocated to order attributes list
76 iOrderAttributes.Close();
78 DestroyTemporaryMembers();
79 iHardwareTypeUids.Close();
80 REComSession::FinalClose();
84 EXPORT_C void CUnifiedCertStore::Initialize(TRequestStatus& aStatus)
86 BeginAsyncOp(aStatus, EInitializeGetTokenList);
87 TRAPD(err, InitializeL());
94 void CUnifiedCertStore::InitializeL()
98 // We want the list of all token types that support a readable or writable
99 // certstore interface
100 RArray<TUid> uidArray;
101 CleanupClosePushL(uidArray);
103 User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceWritableCertStore)));
105 TCTFindTokenTypesByInterface filter(uidArray.Array());
106 CCTTokenTypeInfo::ListL(iWorkingVars->iWritableTokenTypes, filter);
110 User::LeaveIfError(uidArray.Append(TUid::Uid(KInterfaceCertStore)));
112 RCPointerArray<CCTTokenTypeInfo> tokenTypes;
113 CleanupClosePushL(tokenTypes);
115 TCTFindTokenTypesByInterface filter2(uidArray.Array());
116 CCTTokenTypeInfo::ListL(tokenTypes, filter2);
118 // Check whether client specified order list has attributes in it
119 if(iOrderAttributes.Count() > 0)
121 ApplyOrderingL(tokenTypes);
124 // Make a note of all hardware token types
126 TInt end = tokenTypes.Count();
129 TCTTokenTypeAttribute software;
130 software.iUID = KCTSoftware;
131 TInt find = tokenTypes[i]->Attributes().Find(software);
132 // In the case (TInt)ETrue == KThirdPartyCertStore == 1
133 if (find != KErrNotFound && tokenTypes[i]->Attributes()[find].iVal !=
134 (TInt)ETrue && tokenTypes[i]->Attributes()[find].iVal != KManufactureCertStore)
136 // This is a hardware type. Add its UID to the list.
137 User::LeaveIfError(iHardwareTypeUids.Append(tokenTypes[i]->Type()));
145 TInt jEnd = iWorkingVars->iWritableTokenTypes.Count();
148 if (iWorkingVars->iWritableTokenTypes[j]->Type() == tokenTypes[i]->Type())
156 User::LeaveIfError(iWorkingVars->iReadOnlyTokenTypes.Append(tokenTypes[i]));
157 tokenTypes.Remove(i);
166 CleanupStack::PopAndDestroy(2); // uidArray, tokenTypes
168 iWorkingVars->iIndex = -1;
170 TRequestStatus* status = &iStatus;
171 User::RequestComplete(status, KErrNone);
175 EXPORT_C void CUnifiedCertStore::CancelInitialize()
177 if (iState == EInitializeGetTokenList ||
178 iState == EInitializeGetToken ||
179 iState == EInitializeGetWritableInterface ||
180 iState == EInitializeGetReadableInterface ||
181 iState == EInitializeGetReadableInterfaceFinished ||
182 iState == EInitializeFinished)
188 void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
189 const CCertAttributeFilter& aFilter,
190 TRequestStatus& aStatus)
192 BeginAsyncOp(aStatus, EList);
193 TRAPD(err, ListL(aCertInfos, aFilter));
200 void CUnifiedCertStore::ListL(RMPointerArray<CCTCertInfo>& aCertInfos,
201 const CCertAttributeFilter& aFilter)
205 User::Leave(KErrNotReady);
209 iWorkingVars->iCertInfos = &aCertInfos;
210 iWorkingVars->iFilter = &aFilter;
211 iWorkingVars->iCertIndex = aCertInfos.Count();
215 TRequestStatus* status = &iStatus;
216 User::RequestComplete(status, KErrNone);
219 void CUnifiedCertStore::CancelList()
221 if (iState == EList ||
222 iState == ERetrieveForList)
228 EXPORT_C void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
229 const CCertAttributeFilter& aFilter,
230 const TDesC8& aIssuer,
231 TRequestStatus& aStatus)
233 RPointerArray<const TDesC8> array;
234 if (array.Append(&aIssuer) != KErrNone)
236 TRequestStatus* status = &aStatus;
237 User::RequestComplete(status, KErrNoMemory);
241 List(aCertInfos, aFilter, array, aStatus);
246 EXPORT_C void CUnifiedCertStore::List(RMPointerArray<CCTCertInfo>& aCertInfos,
247 const CCertAttributeFilter& aFilter,
248 RPointerArray<const TDesC8> aIssuers,
249 TRequestStatus& aStatus)
251 BeginAsyncOp(aStatus, EList);
252 TRAPD(err, ListL(aCertInfos, aFilter, aIssuers));
259 void CUnifiedCertStore::ListL(RMPointerArray<CCTCertInfo>& aCertInfos,
260 const CCertAttributeFilter& aFilter,
261 RPointerArray<const TDesC8> aIssuers)
263 // Obscure special case: If aIssuers has no elements, we should
265 if (aIssuers.Count() == 0)
272 iWorkingVars->iCertInfos = &aCertInfos;
273 iWorkingVars->iFilter = &aFilter;
274 iWorkingVars->iCertIndex = aCertInfos.Count();
276 TInt count = aIssuers.Count();
277 for (TInt i = 0 ; i < count ; ++i)
279 User::LeaveIfError(iWorkingVars->iIssuerNames.Append(aIssuers[i]));
284 TRequestStatus* status = &iStatus;
285 User::RequestComplete(status, KErrNone);
288 EXPORT_C void CUnifiedCertStore::Retrieve(const CCTCertInfo& aCertInfo,
289 CCertificate*& aCert,
290 TRequestStatus& aStatus)
292 BeginAsyncOp(aStatus, ERetrieve);
293 TRAPD(err, RetrieveL(aCertInfo, aCert));
300 void CUnifiedCertStore::RetrieveL(const CCTCertInfo& aCertInfo,
301 CCertificate*& aCert)
303 FindCertStoreL(aCertInfo.Handle());
305 if (aCertInfo.CertificateFormat() != EX509Certificate &&
306 aCertInfo.CertificateFormat() != EWTLSCertificate)
308 User::Leave(KErrNotSupported);
312 iWorkingVars->iCertDesC = HBufC8::NewMaxL(aCertInfo.Size());
313 iWorkingVars->iReturnedCert = &aCert;
314 iWorkingVars->iCertType = aCertInfo.CertificateFormat();
315 iWorkingVars->iCertDes.Set(iWorkingVars->iCertDesC->Des());
316 iCurrentCertStore->Retrieve(aCertInfo, iWorkingVars->iCertDes, iStatus);
320 void CUnifiedCertStore::GetCert(CCTCertInfo*& aCertInfo,
321 const TCTTokenObjectHandle& aHandle,
322 TRequestStatus& aStatus)
324 BeginAsyncOp(aStatus, EGetCert);
325 TRAPD(err, GetCertL(aCertInfo, aHandle));
332 void CUnifiedCertStore::GetCertL(CCTCertInfo*& aCertInfo,
333 const TCTTokenObjectHandle& aHandle)
335 FindCertStoreL(aHandle);
336 iCurrentCertStore->GetCert(aCertInfo, aHandle, iStatus);
340 void CUnifiedCertStore::CancelGetCert()
342 if (iState == EGetCert)
348 void CUnifiedCertStore::Applications(const CCTCertInfo& aCertInfo,
349 RArray<TUid>& aApplications,
350 TRequestStatus& aStatus)
352 BeginAsyncOp(aStatus, EApplications);
353 TRAPD(err, ApplicationsL(aCertInfo, aApplications));
360 void CUnifiedCertStore::ApplicationsL(const CCTCertInfo& aCertInfo,
361 RArray<TUid>& aApplications)
363 FindCertStoreL(aCertInfo.Handle());
364 iCurrentCertStore->Applications(aCertInfo, aApplications, iStatus);
368 void CUnifiedCertStore::CancelApplications()
370 if (iState == EApplications)
376 void CUnifiedCertStore::IsApplicable(const CCTCertInfo& aCertInfo,
378 TBool& aIsApplicable,
379 TRequestStatus& aStatus)
381 BeginAsyncOp(aStatus, EIsApplicable);
382 TRAPD(err, IsApplicableL(aCertInfo, aApplication, aIsApplicable));
389 void CUnifiedCertStore::IsApplicableL(const CCTCertInfo& aCertInfo,
391 TBool& aIsApplicable)
393 FindCertStoreL(aCertInfo.Handle());
394 iCurrentCertStore->IsApplicable(aCertInfo, aApplication, aIsApplicable, iStatus);
398 void CUnifiedCertStore::CancelIsApplicable()
400 if (iState == EIsApplicable)
406 void CUnifiedCertStore::Trusted(const CCTCertInfo& aCertInfo,
408 TRequestStatus& aStatus)
410 BeginAsyncOp(aStatus, ETrusted);
411 TRAPD(err, TrustedL(aCertInfo, aTrusted));
418 void CUnifiedCertStore::TrustedL(const CCTCertInfo& aCertInfo,
421 FindCertStoreL(aCertInfo.Handle());
422 iCurrentCertStore->Trusted(aCertInfo, aTrusted, iStatus);
426 void CUnifiedCertStore::CancelTrusted()
428 if (iState == ETrusted)
434 void CUnifiedCertStore::Retrieve(const CCTCertInfo& aCertInfo,
436 TRequestStatus& aStatus)
438 BeginAsyncOp(aStatus, ERetrieveData);
439 TRAPD(err, RetrieveDataL(aCertInfo, aEncodedCert));
446 void CUnifiedCertStore::RetrieveDataL(const CCTCertInfo& aCertInfo,
449 FindCertStoreL(aCertInfo.Handle());
450 iCurrentCertStore->Retrieve(aCertInfo, aEncodedCert, iStatus);
454 void CUnifiedCertStore::CancelRetrieve()
456 if (iState == ERetrieveData)
462 EXPORT_C void CUnifiedCertStore::Remove(const CCTCertInfo& aCertInfo,
463 TRequestStatus& aStatus)
465 BeginAsyncOp(aStatus, ERemove);
466 TRAPD(err, RemoveL(aCertInfo));
473 void CUnifiedCertStore::RemoveL(const CCTCertInfo& aCertInfo)
475 FindWritableCertStoreL(aCertInfo.Handle());
476 iCurrentWritableCertStore->Remove(aCertInfo, iStatus);
480 EXPORT_C void CUnifiedCertStore::CancelRemove()
482 if (iState == ERemove)
488 EXPORT_C void CUnifiedCertStore::SetApplicability(const CCTCertInfo& aCertInfo,
489 const RArray<TUid>& aApplications,
490 TRequestStatus& aStatus)
492 BeginAsyncOp(aStatus, ESetApplicability);
493 TRAPD(err, SetApplicabilityL(aCertInfo, aApplications));
500 void CUnifiedCertStore::SetApplicabilityL(const CCTCertInfo& aCertInfo,
501 const RArray<TUid>& aApplications)
503 FindWritableCertStoreL(aCertInfo.Handle());
505 // Search for duplicates in the array of application
506 // complete with KErrArgument if there are any duplicates
507 if(aApplications.Count() > 1)
511 for(i=0; i<aApplications.Count()-1; i++ )
513 for(j=i+1; j<aApplications.Count(); j++)
515 if(aApplications[i] == aApplications[j])
517 User::Leave(KErrArgument);
523 // Check requested applications actaully exist
524 CCertificateAppInfoManager* appInfoManager = CCertificateAppInfoManager::NewLC(iFs, EFalse);
525 const RArray<TCertificateAppInfo>& applications = appInfoManager->Applications();
527 for (TInt i = 0 ; i < aApplications.Count() ; ++i)
530 for ( ; j < applications.Count() ; ++j)
532 if (aApplications[i] == applications[j].Id())
537 if (j == applications.Count())
539 User::Leave(KErrArgument);
542 CleanupStack::PopAndDestroy(appInfoManager);
544 iCurrentWritableCertStore->SetApplicability(aCertInfo, aApplications, iStatus);
548 EXPORT_C void CUnifiedCertStore::CancelSetApplicability()
550 if (iState == ESetApplicability)
556 EXPORT_C void CUnifiedCertStore::SetTrust(const CCTCertInfo& aCertInfo,
558 TRequestStatus& aStatus)
560 BeginAsyncOp(aStatus, ESetTrust);
561 TRAPD(err, SetTrustL(aCertInfo, aTrusted));
568 void CUnifiedCertStore::SetTrustL(const CCTCertInfo& aCertInfo, TBool aTrusted)
570 FindWritableCertStoreL(aCertInfo.Handle());
571 iCurrentWritableCertStore->SetTrust(aCertInfo, aTrusted, iStatus);
575 EXPORT_C void CUnifiedCertStore::CancelSetTrust()
577 if (iState == ESetTrust)
584 * Get the certstore containing a given certificate.
586 * Returns the certstore containing the cert referenced in certinfo or NULL if
589 MCTCertStore* CUnifiedCertStore::GetCertStore(const TCTTokenObjectHandle& aHandle)
591 TInt count = iCertStores.Count();
592 for (TInt i = 0; i < count; i++)
594 MCTCertStore* certstore = iCertStores[i];
595 MCTToken& token = certstore->Token();
596 if (token.Handle() == aHandle.iTokenHandle)
605 * Set iCurrentCertStore to the certstore containing a given certificate, or
606 * leave if it could not be found. The handle is the handle of the *certinfo*,
609 void CUnifiedCertStore::FindCertStoreL(const TCTTokenObjectHandle& aHandle)
611 assert(!iCurrentCertStore);
612 assert(!iCurrentWritableCertStore);
616 User::Leave(KErrNotReady);
619 iCurrentCertStore = GetCertStore(aHandle);
621 if (!iCurrentCertStore)
623 User::Leave(KErrNotFound);
628 * Set iCurrentWritableCertStore to the writable certstore containing a given
629 * certificate, or leave if it could not be found. The handle is the handle of
630 * the *certinfo*, *NOT* the token.
632 void CUnifiedCertStore::FindWritableCertStoreL(const TCTTokenObjectHandle& aHandle)
634 assert(!iCurrentCertStore);
635 assert(!iCurrentWritableCertStore);
639 User::Leave(KErrNotReady);
642 if (!iOpenedForWrite)
644 User::Leave(KErrAccessDenied);
647 iCurrentWritableCertStore = NULL;
648 TInt count = iWritableCertStores.Count();
649 for (TInt i = 0; i < count; i++)
651 MCTWritableCertStore* certstore = iWritableCertStores[i];
652 MCTToken& token = certstore->Token();
653 if (token.Handle() == aHandle.iTokenHandle)
655 iCurrentWritableCertStore = certstore;
660 if (!iCurrentWritableCertStore)
662 User::Leave(KErrNotFound);
666 EXPORT_C TInt CUnifiedCertStore::CertStoreCount() const
668 return iCertStores.Count();
671 EXPORT_C MCTCertStore& CUnifiedCertStore::CertStore(TInt aIndex)
673 assert(aIndex < iCertStores.Count());
674 return *iCertStores[aIndex];
677 EXPORT_C TInt CUnifiedCertStore::WritableCertStoreCount() const
679 return iWritableCertStores.Count();
682 EXPORT_C MCTWritableCertStore& CUnifiedCertStore::WritableCertStore(TInt aIndex)
684 assert(aIndex < iWritableCertStores.Count());
685 return *iWritableCertStores[aIndex];
688 EXPORT_C TInt CUnifiedCertStore::ReadOnlyCertStoreCount() const
690 return iReadOnlyCertStores.Count();
693 EXPORT_C MCTCertStore& CUnifiedCertStore::ReadOnlyCertStore(TInt aIndex)
695 assert(aIndex < iReadOnlyCertStores.Count());
696 return *iReadOnlyCertStores[aIndex];
699 CUnifiedCertStore::CUnifiedCertStore(RFs& aFs, TBool aOpenForWrite)
700 : CActive(EPriorityNormal), iFs(aFs), iOpenedForWrite(aOpenForWrite), iOrderAttributes()
702 CActiveScheduler::Add(this);
706 void CUnifiedCertStore::ConstructL(RArray<TInt>& aOrderFilter)
709 for (TInt i=0;i<aOrderFilter.Count();i++)
711 User::LeaveIfError(iOrderAttributes.Append(aOrderFilter[i]));
715 void CUnifiedCertStore::RunL()
717 if ((iState != EInitializeGetReadableInterface) &&
718 (iState != EInitializeGetReadableInterfaceFinished) &&
719 (iState != EInitializeGetToken)) // We don't want to leave if we're in this state
720 // since we want to enumerate all tokens, see below
722 User::LeaveIfError(iStatus.Int());
727 case EInitializeGetTokenList:
728 // We need to try to get a list of Tokens for each of the Token Types
729 iWorkingVars->iIndex++;
731 if (!iCurrentlyDoingReadOnly)
733 end = iWorkingVars->iWritableTokenTypes.Count();
737 end = iWorkingVars->iReadOnlyTokenTypes.Count();
739 if (iWorkingVars->iIndex < end)
742 TInt createRes = KErrNone;
743 if (iCurrentlyDoingReadOnly)
745 TRAP(createRes, iTokenType = MCTTokenType::NewL(*iWorkingVars->iReadOnlyTokenTypes[iWorkingVars->iIndex], iFs));
749 TRAP(createRes, iTokenType = MCTTokenType::NewL(*iWorkingVars->iWritableTokenTypes[iWorkingVars->iIndex], iFs));
752 if (KErrNoMemory==createRes)
754 // Leave if there's no memory, so OOM tests work
755 User::Leave(createRes);
757 else if (KErrNone!=createRes)
759 // ECOM couldn't load that token type, don't give up, try the next...
760 TRequestStatus* stat = &iStatus;
761 User::RequestComplete(stat, KErrNone);
765 assert(iTokens.Count() == 0);
766 iTokenType->List(iTokens, iStatus);
768 iState = EInitializeGetToken;
771 else if (!iCurrentlyDoingReadOnly)
773 iCurrentlyDoingReadOnly = ETrue;
774 iWorkingVars->iIndex = -1;
775 TRequestStatus* status = &iStatus;
776 User::RequestComplete(status, KErrNone);
780 iState = EInitializeFinished;
781 TRequestStatus* status = &iStatus;
782 User::RequestComplete(status, KErrNone);
787 case EInitializeGetToken:
788 if (iStatus.Int() == KErrHardwareNotAvailable)
790 // If the hardware corresponding to this
791 // TokenType has been removed then just skip it
794 iState = EInitializeGetToken;
795 TRequestStatus* status = &iStatus;
796 User::RequestComplete(status,KErrNone);
800 User::LeaveIfError(iStatus.Int());
802 // iIndexTokens is initialized at EInitializeGetTokenList
805 // We need to try to get a certstore interface (readable or
806 // writable) for each of the Tokens in iTokens
807 if (iIndexTokens < iTokens.Count())
810 iTokenType->OpenToken(*iTokens[iIndexTokens], iToken, iStatus);
811 if ((iOpenedForWrite) && !iCurrentlyDoingReadOnly)
813 iState = EInitializeGetWritableInterface;
817 iState = EInitializeGetReadableInterface;
822 // We don't need the iTokenType anymore
823 iTokenType->Release();
825 // We don't need the list of Tokens anymore
827 iState = EInitializeGetTokenList;
828 TRequestStatus* status = &iStatus;
829 User::RequestComplete(status, KErrNone);
835 case EInitializeGetWritableInterface:
837 User::LeaveIfError(iStatus.Int());
838 // First we try to get a writable interface to the store, if
839 // that doesn't work we will try to get a readable interface
841 assert(!iTokenInterface);
842 TUid uid = { KInterfaceWritableCertStore };
843 iToken->GetInterface(uid, iTokenInterface, iStatus);
844 iState = EInitializeGetReadableInterface;
849 case EInitializeGetReadableInterface:
850 // We check if we managed to get a writable interface
851 if (iStatus == KErrNoMemory)
853 User::Leave(KErrNoMemory);
856 if (!iCurrentlyDoingReadOnly && iOpenedForWrite && (iStatus == KErrNone))
858 assert(iTokenInterface);
860 // Drop the interface into a "writable checking" object
861 CCheckedCertStore* interf =
862 CCheckedCertStore::NewCheckedWritableCertStoreL(iTokenInterface, iPSCertstoreChangeProperty);
864 CleanupReleasePushL(*interf);
867 User::LeaveIfError(iWritableCertStores.Append(interf));
870 User::LeaveIfError(iCertStores.Append(interf));
872 // We don't need the Token anymore
875 iState = EInitializeGetToken;
876 TRequestStatus* status = &iStatus;
877 User::RequestComplete(status, KErrNone);
881 // We do the check only if we were not trying to get a Writeable Interface
882 // before, if we trying to get a writeable interface before, we know that we
883 // have a valid iToken.
884 if ((iCurrentlyDoingReadOnly || !iOpenedForWrite) && (iStatus != KErrNone))
886 User::Leave(iStatus.Int());
891 assert(!iTokenInterface);
892 TUid uid = { KInterfaceCertStore };
893 iToken->GetInterface(uid, iTokenInterface, iStatus);
894 iState = EInitializeGetReadableInterfaceFinished;
900 case EInitializeGetReadableInterfaceFinished:
902 if (iStatus == KErrNoMemory)
904 User::Leave(KErrNoMemory);
907 if (iStatus == KErrNone)
909 assert(iTokenInterface);
911 // Drop the interface into a "read only checking" object
912 CCheckedCertStore* interf =
913 CCheckedCertStore::NewCheckedCertStoreL(iTokenInterface, iPSCertstoreChangeProperty);
915 CleanupReleasePushL(*interf);
918 User::LeaveIfError(iReadOnlyCertStores.Append(interf));
919 CleanupStack::Pop(interf);
921 User::LeaveIfError(iCertStores.Append(interf));
924 // We don't need the Token anymore
929 iState = EInitializeGetToken;
930 TRequestStatus* status = &iStatus;
931 User::RequestComplete(status, iStatus.Int());
936 case EInitializeFinished:
939 assert(!iTokenInterface);
940 iIsInitialized = ETrue;
941 Complete(iStatus.Int());
945 // iIndex has been initialized in List
947 iCurrentCertStore = NULL;
948 if (iIndex < iCertStores.Count())
950 iCurrentCertStore = iCertStores[iIndex];
951 iCurrentCertStore->List(*iWorkingVars->iCertInfos, *iWorkingVars->iFilter, iStatus);
952 iWorkingVars->iCertIndex = 0;
955 else if (iWorkingVars->iIssuerNames.Count() > 0)
957 // We have an issuer name. We now remove all certs
958 // that don't match that issuer.
960 // If this is the first time in here, we need to parse
961 // and hash all the issuer names.
962 if (iWorkingVars->iParsedIssuerNames.Count() == 0)
964 CSHA1* sha1 = CSHA1::NewL();
965 CleanupStack::PushL(sha1);
966 TInt count = iWorkingVars->iIssuerNames.Count();
967 for (TInt i = 0; i < count; i++)
969 CX500DistinguishedName* dn =
970 CX500DistinguishedName::NewLC(*iWorkingVars->
973 iWorkingVars->iParsedIssuerNames.Append(dn));
974 CleanupStack::Pop(dn);
975 TPtrC8 hash=sha1->Hash(*iWorkingVars->iIssuerNames[i]);
977 iWorkingVars->iHashedIssuerNames.Append(
981 CleanupStack::PopAndDestroy();
984 while (iWorkingVars->iCertIndex <
985 iWorkingVars->iCertInfos->Count())
988 (*iWorkingVars->iCertInfos)[iWorkingVars->iCertIndex];
989 TCompareResults res = CompareCertInfoDN(info);
992 // It matches. leave it for the next one.
993 iWorkingVars->iCertIndex++;
997 // It doesn't match. Remove it and try the next one.
999 iWorkingVars->iCertInfos->
1000 Remove(iWorkingVars->iCertIndex);
1002 else // res == EMaybe
1004 // Need to load the cert and properly compare the DNs.
1005 iCurrentCertStore = GetCertStore(info->Handle());
1006 assert(iCurrentCertStore);
1008 iWorkingVars->iCertDesC=HBufC8::NewMaxL(info->Size());
1009 iWorkingVars->iCertType = info->CertificateFormat();
1010 iState = ERetrieveForList;
1011 iWorkingVars->iCertDes.Set(iWorkingVars->iCertDesC->Des());
1012 iCurrentCertStore->Retrieve(*info, iWorkingVars->iCertDes, iStatus);
1027 switch (iWorkingVars->iCertType)
1029 case EX509Certificate:
1031 TPtr8 theCert(iWorkingVars->iCertDesC->Des());
1032 *(iWorkingVars->iReturnedCert) = CX509Certificate::NewL(theCert);
1035 case EWTLSCertificate:
1037 TPtr8 theCert(iWorkingVars->iCertDesC->Des());
1038 *(iWorkingVars->iReturnedCert) = CWTLSCertificate::NewL(theCert);
1049 case ERetrieveForList:
1051 TPtr8 theCert(iWorkingVars->iCertDesC->Des());
1052 CX509Certificate* cert=CX509Certificate::NewLC(theCert);
1053 if (MatchL(cert->IssuerName()))
1055 // It matches. leave it for the next one.
1056 iWorkingVars->iCertIndex++;
1060 // It doesn't match. Remove it and try the next one.
1061 (*iWorkingVars->iCertInfos)[iWorkingVars->iCertIndex]->Release();
1062 iWorkingVars->iCertInfos->Remove(iWorkingVars->iCertIndex);
1064 CleanupStack::PopAndDestroy(cert);
1065 delete iWorkingVars->iCertDesC;
1066 iWorkingVars->iCertDesC = 0;
1069 TRequestStatus* status = & iStatus;
1070 User::RequestComplete(status, KErrNone);
1075 case ESetApplicability:
1086 User::Panic(KUCSPanic, 1);
1091 TInt CUnifiedCertStore::RunError(TInt aError)
1097 void CUnifiedCertStore::DoCancel()
1099 // If the current state is the last state involved in handling a request, we
1100 // check to see if we have already been completed - in this case we can
1101 // simply complete the client with iStatus (this may be KErrNone). If we
1102 // have not we cancel the outstanding request and pass the resulting iStatus
1103 // back to the client - this too may indicate a successful completion if the
1104 // cancel arrived after the request was executed.
1106 // For more complex cases, where there are more states to go through before
1107 // we finish servicing the client request, we cancel any outstanding
1108 // request, and return KErrCancel to the client.
1112 case EInitializeFinished:
1120 case ESetApplicability:
1122 if (iStatus == KRequestPending)
1124 // Attempt to cancel outstanding request and pass status back to
1126 CancelOutstandingRequest();
1127 Complete(iStatus.Int());
1131 // We've already been completed - call RunL() to process results
1132 // and complete client
1134 if (err != KErrNone)
1142 CancelOutstandingRequest();
1143 Complete(KErrCancel);
1148 void CUnifiedCertStore::CancelOutstandingRequest()
1152 case EInitializeGetTokenList:
1153 case EInitializeGetToken:
1154 case EInitializeGetWritableInterface:
1155 case EInitializeGetReadableInterface:
1156 case EInitializeGetReadableInterfaceFinished:
1157 case EInitializeFinished:
1158 // Don't have to cancel initialisation stuff - this happens when we
1159 // release the objects in DestroyTemporaryMembers().
1160 iStatus = KErrCancel;
1164 if (iCurrentCertStore)
1166 iCurrentCertStore->CancelList();
1171 case ERetrieveForList:
1173 assert(iCurrentCertStore);
1174 iCurrentCertStore->CancelRetrieve();
1178 assert(iCurrentCertStore);
1179 iCurrentCertStore->CancelGetCert();
1183 assert(iCurrentCertStore);
1184 iCurrentCertStore->CancelApplications();
1188 assert(iCurrentCertStore);
1189 iCurrentCertStore->CancelIsApplicable();
1193 assert(iCurrentCertStore);
1194 iCurrentCertStore->CancelTrusted();
1198 assert(iCurrentWritableCertStore);
1199 iCurrentWritableCertStore->CancelRemove();
1202 case ESetApplicability:
1203 assert(iCurrentWritableCertStore);
1204 iCurrentWritableCertStore->CancelSetApplicability();
1208 assert(iCurrentWritableCertStore);
1209 iCurrentWritableCertStore->CancelSetTrust();
1213 User::Panic(KUCSPanic, 1);
1218 TBool CUnifiedCertStore::MatchL(const CX500DistinguishedName& aName) const
1220 // Return true if the supplied DN is the same as any of the supplied DNs.
1221 TInt count = iWorkingVars->iIssuerNames.Count();
1222 for (TInt i = 0; i < count; i++)
1224 if (aName.ExactMatchL(*iWorkingVars->iParsedIssuerNames[i]))
1230 void CUnifiedCertStore::AllocWorkingVarsL()
1232 assert(!iWorkingVars);
1233 iWorkingVars = new (ELeave) CUnifiedCertStoreWorkingVars;
1236 void CUnifiedCertStore::BeginAsyncOp(TRequestStatus& aStatus, TState aState)
1238 assert(iState == EIdle);
1239 assert(!iClientStatus);
1241 iClientStatus = &aStatus;
1242 *iClientStatus = KRequestPending;
1246 void CUnifiedCertStore::Complete(TInt aError)
1248 assert(iClientStatus);
1249 User::RequestComplete(iClientStatus, aError);
1250 DestroyTemporaryMembers();
1254 void CUnifiedCertStore::DestroyTemporaryMembers()
1256 if (!iIsInitialized)
1258 TInt end = iReadOnlyCertStores.Count();
1260 for (i = 0; i < end; i++)
1262 iReadOnlyCertStores[i]->Release();
1264 iReadOnlyCertStores.Close();
1266 end = iWritableCertStores.Count();
1267 for (i = 0; i < end; i++)
1269 iWritableCertStores[i]->Release();
1271 iWritableCertStores.Close();
1273 // The elements are already released by the two loops above
1274 iCertStores.Close();
1279 iTokenType->Release();
1289 if (iTokenInterface)
1291 iTokenInterface->Release();
1292 iTokenInterface = 0;
1297 delete iWorkingVars;
1300 iCurrentCertStore = NULL;
1301 iCurrentWritableCertStore = NULL;
1304 CUnifiedCertStore::TCompareResults
1305 CUnifiedCertStore::CompareCertInfoDN(const CCTCertInfo* aCertInfo)
1307 if (aCertInfo->IssuerHash() &&
1308 (aCertInfo->CertificateFormat() == EX509CertificateUrl ||
1309 iHardwareTypeUids.Find(aCertInfo->Token().TokenType().Type()) !=
1312 TInt count = iWorkingVars->iHashedIssuerNames.Count();
1313 for (TInt i = 0; i < count; i++)
1315 if (*aCertInfo->IssuerHash()==*iWorkingVars->iHashedIssuerNames[i])
1320 if (aCertInfo->CertificateFormat() != EX509Certificate)
1325 EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewL(RFs& aFs,
1326 TBool aOpenForWrite,
1327 RArray<TInt>& aOrderFilter)
1329 CUnifiedCertStore* self = CUnifiedCertStore::NewLC(aFs,
1332 CleanupStack::Pop(self);
1336 EXPORT_C CUnifiedCertStore* CUnifiedCertStore::NewLC(RFs& aFs,
1337 TBool aOpenForWrite,
1338 RArray<TInt>& aOrderFilter)
1340 CUnifiedCertStore* self = new(ELeave) CUnifiedCertStore(aFs,
1342 CleanupStack::PushL(self);
1343 self->ConstructL(aOrderFilter);
1347 void CUnifiedCertStore::FilterTokenTypesL(RCPointerArray<CCTTokenTypeInfo>& aSearchTokenTypes,
1348 RCPointerArray<CCTTokenTypeInfo>& aTempTokenTypes,
1349 TInt aOrderAttribute)
1351 //We allow aOrderAttribute=KUnknownHardwareCertStore here to keep DC.
1352 //assert(aOrderAttribute);
1354 // Get number of token types
1355 TInt tokenTypesCount = aSearchTokenTypes.Count();
1357 // loop through token types
1358 for(TInt tokenTypesLoop = tokenTypesCount-1; tokenTypesLoop >= 0; tokenTypesLoop--)
1360 // get the list of attributes supported by this token type.
1361 // Note: The attribute list consists of values such as
1362 // KCTSoftware defined in TCTTokenTypeAttribute.h
1363 const RArray<TCTTokenTypeAttribute>& attributesList =
1364 aSearchTokenTypes[tokenTypesLoop]->Attributes();
1366 // Get the number of attributes in the attribute list.
1367 // The number of attributes will match the ECOM resource
1368 // file definition. E.g. see 101f5015.rss for the software
1369 // implementation of certstore.
1370 TInt attributeCount = attributesList.Count();
1372 // Check each attribute in the attribute list
1373 for(TInt attribLoop = 0; attribLoop < attributeCount; attribLoop++)
1375 // Check whether attribute in the list matches an order attribute
1377 if(attributesList[attribLoop].iUID == KCTSoftware
1378 && attributesList[attribLoop].iVal == aOrderAttribute)
1380 // Found the attribute of interest. Add token type to the temp container.
1381 User::LeaveIfError(aTempTokenTypes.Append(aSearchTokenTypes[tokenTypesLoop]));
1382 // Remove from the Searchlist.
1383 aSearchTokenTypes.Remove(tokenTypesLoop);
1384 // No need to examine the other attributes, so break loop
1391 void CUnifiedCertStore::ApplyOrderingL(RCPointerArray<CCTTokenTypeInfo>& aTokenTypes)
1393 // Number of attributes in ordering filter
1394 TInt numOrderAttributes=iOrderAttributes.Count();
1395 assert(numOrderAttributes>0);
1397 // Contains writable tokens types
1398 RCPointerArray<CCTTokenTypeInfo> tempWritableTokenTypes;
1399 CleanupClosePushL(tempWritableTokenTypes);
1401 // Contains read-only tokens types
1402 RCPointerArray<CCTTokenTypeInfo> tempReadOnlyTokenTypes;
1403 CleanupClosePushL(tempReadOnlyTokenTypes);
1405 // For each order attribute, order the token types
1406 for(TInt attributeLoop = 0; attributeLoop < numOrderAttributes; attributeLoop++)
1408 // Get ordering attribute Uid from Order filter
1409 TInt orderAttribute = iOrderAttributes[attributeLoop];
1411 // Order for writable token types
1412 FilterTokenTypesL(iWorkingVars->iWritableTokenTypes,
1413 tempWritableTokenTypes,
1416 // Order for read-only token types
1417 FilterTokenTypesL(aTokenTypes,
1418 tempReadOnlyTokenTypes,
1422 // release and close the resources so can refill container, and get rid of
1423 // the TokenType which have been filtered out.
1424 TInt tokenTypesCount = iWorkingVars->iWritableTokenTypes.Count();
1426 for(i = tokenTypesCount-1; i >= 0 ;i--)
1428 if (iWorkingVars->iWritableTokenTypes[i])
1430 CCTTokenTypeInfo* ptr=iWorkingVars->iWritableTokenTypes[i];
1431 iWorkingVars->iWritableTokenTypes.Remove(i);
1435 iWorkingVars->iWritableTokenTypes.Reset();
1437 // release and close the resources so can refill container, and get rid of
1438 // the TokenType which have been filtered out.
1439 tokenTypesCount = aTokenTypes.Count();
1440 for(i = tokenTypesCount-1; i >= 0 ;i--)
1444 CCTTokenTypeInfo* ptr=aTokenTypes[i];
1445 aTokenTypes.Remove(i);
1449 aTokenTypes.Reset();
1451 // Assign contents of temp token types to containers.
1452 // Note: temp tokens types are ordered according to user specification
1453 tokenTypesCount = tempWritableTokenTypes.Count();
1454 for(i = 0; i < tokenTypesCount; i++)
1456 User::LeaveIfError(iWorkingVars->iWritableTokenTypes.Append(tempWritableTokenTypes[i]));
1457 tempWritableTokenTypes[i] = NULL;
1460 tokenTypesCount = tempReadOnlyTokenTypes.Count();
1461 for(i = 0; i < tokenTypesCount; i++)
1463 User::LeaveIfError(aTokenTypes.Append(tempReadOnlyTokenTypes[i]));
1464 tempReadOnlyTokenTypes[i] = NULL;
1467 CleanupStack::PopAndDestroy(2); // tempReadOnlyTokenTypes, tempWritableTokenTypes,