diff -r 675a964f4eb5 -r 35751d3474b7 cryptoservices/certificateandkeymgmt/pkixcertbase/Pkixchainbuilder.cpp --- a/cryptoservices/certificateandkeymgmt/pkixcertbase/Pkixchainbuilder.cpp Tue Jul 21 01:04:32 2009 +0100 +++ b/cryptoservices/certificateandkeymgmt/pkixcertbase/Pkixchainbuilder.cpp Thu Sep 10 14:01:51 2009 +0300 @@ -1,214 +1,214 @@ -/* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "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: -* -*/ - - -#include "pkixchainbuilder.h" - -CPKIXChainBuilder* CPKIXChainBuilder::NewL() - { - CPKIXChainBuilder* s = CPKIXChainBuilder::NewLC(); - CleanupStack::Pop(s); - return s; - } - -CPKIXChainBuilder* CPKIXChainBuilder::NewLC() - { - CPKIXChainBuilder* s = new (ELeave) CPKIXChainBuilder; - CleanupStack::PushL(s); - s->ConstructL(); - return s; - } - -CPKIXChainBuilder::~CPKIXChainBuilder() - { - Cancel(); - iSources.Close(); - iCandidates.ResetAndDestroy(); - iCandidates.Close(); - } - -void CPKIXChainBuilder::AddSourceL(MPKIXCertSource* aSource) - { - User::LeaveIfError(iSources.Append(aSource)); - } - -void CPKIXChainBuilder::AddIssuer(TInt& aNumberOfCertsAdded, - TBool& aResult, - CArrayPtrFlat& aChain, - TRequestStatus& aStatus) - { - iOriginalRequestStatus = &aStatus; - aStatus = KRequestPending; - iResult = &aResult; - iChain = &aChain; - iNumberOfCertsAdded = &aNumberOfCertsAdded; - - iSubject = aChain[aChain.Count()-1]; - __ASSERT_DEBUG(iSubject, User::Panic(_L("CPKICCertChainAO"), 1)); - __ASSERT_DEBUG(!iCandidates.Count(), User::Panic(_L("CPKICCertChainAO"), 1)); - - iIndex = -1; - iState = EAddCandidate; - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrNone); - SetActive(); - } - -CPKIXChainBuilder::CPKIXChainBuilder() -: CActive(EPriorityNormal) - { - CActiveScheduler::Add(this); - } - -void CPKIXChainBuilder::ConstructL() - { - } - -TBool CPKIXChainBuilder::ResolveIssuersL(CArrayPtr& aChain, - const RPointerArray& aCandidates) const - { - //*this function attempts to figure out which certificate in aCandidates is the issuer of - //the last cert in the aChain, and adds a *copy* of the best guess to aChain - //*it assumes that the names match already - //*if it establishes that none are any good it returns EFalse - TInt count = aCandidates.Count(); - if (count == 0) - { - return EFalse; - } - if (count == 1) - { - CX509Certificate* cert = CX509Certificate::NewLC(*aCandidates[0]); - aChain.AppendL(cert); - (*iNumberOfCertsAdded)++; - CleanupStack::Pop(cert); - return ETrue; - } - - const CX509Certificate* current = aChain[aChain.Count() - 1]; - //1) look for SKI/AKI to distinguish - const CX509CertExtension* akiExt = current->Extension(KAuthorityKeyId); - if (akiExt) - { - const CX509AuthorityKeyIdExt* aki = CX509AuthorityKeyIdExt::NewLC(akiExt->Data()); - TPtrC8 authorityKeyId = aki->KeyId(); - if (authorityKeyId != KNullDesC8) - { - for (TInt i = 0; i < count; i++) - { - const CX509CertExtension* skiExt = (aCandidates[i])->Extension(KSubjectKeyId); - if (skiExt) - { - const CX509SubjectKeyIdExt* ski = CX509SubjectKeyIdExt::NewLC(skiExt->Data()); - if (authorityKeyId == ski->KeyId()) - { - CX509Certificate* issuer = CX509Certificate::NewLC(*aCandidates[i]); - aChain.AppendL(issuer); - (*iNumberOfCertsAdded)++; - CleanupStack::Pop();//issuer - CleanupStack::PopAndDestroy(2);//aki, ski - return ETrue; - } - else - { - CleanupStack::PopAndDestroy();//ski - } - } - } - } - //ok, we haven't got a key ID for the issuer, so try for a serial number instead... - else - { - TPtrC8 authoritySerialNo = aki->AuthorityCertSerialNumber(); - for (TInt i = 0; i < count; i++) - { - const CX509Certificate* candidate = aCandidates[i]; - if (authoritySerialNo == candidate->SerialNumber()) - { - CX509Certificate* issuer = CX509Certificate::NewLC(*candidate); - aChain.AppendL(issuer); - (*iNumberOfCertsAdded)++; - CleanupStack::Pop();//issuer - CleanupStack::PopAndDestroy();//aki - return ETrue; - } - } - } - CleanupStack::PopAndDestroy();//aki - } - - return EFalse; - } - - -void CPKIXChainBuilder::RunL() - { - User::LeaveIfError(iStatus.Int()); - - switch (iState) - { - case EAddCandidate: - iIndex++; - if (iIndex < iSources.Count()) - { - iSources[iIndex]->CandidatesL(*iSubject, iCandidates, iStatus); - } - else - { - iState = EFinished; - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrNone); - } - SetActive(); - break; - - case EFinished: - iState = EIdle; - *iResult = ResolveIssuersL(*iChain, iCandidates); - iCandidates.ResetAndDestroy(); - User::RequestComplete(iOriginalRequestStatus, KErrNone); - break; - - default: - User::Panic(_L("CPKIXChainBuilder"), 1); - break; - } - } - -void CPKIXChainBuilder::DoCancel() - { - int i = 0; - int end = iSources.Count(); - while (i < end) - { - iSources[i]->CancelCandidates(); - i++; - } - iCandidates.ResetAndDestroy(); - - User::RequestComplete(iOriginalRequestStatus, KErrCancel); - - iState = EIdle; - } - -TInt CPKIXChainBuilder::RunError(TInt aError) - { - iState = EIdle; - iCandidates.ResetAndDestroy(); - User::RequestComplete(iOriginalRequestStatus, aError); - return KErrNone; - } +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#include "pkixchainbuilder.h" + +CPKIXChainBuilder* CPKIXChainBuilder::NewL() + { + CPKIXChainBuilder* s = CPKIXChainBuilder::NewLC(); + CleanupStack::Pop(s); + return s; + } + +CPKIXChainBuilder* CPKIXChainBuilder::NewLC() + { + CPKIXChainBuilder* s = new (ELeave) CPKIXChainBuilder; + CleanupStack::PushL(s); + s->ConstructL(); + return s; + } + +CPKIXChainBuilder::~CPKIXChainBuilder() + { + Cancel(); + iSources.Close(); + iCandidates.ResetAndDestroy(); + iCandidates.Close(); + } + +void CPKIXChainBuilder::AddSourceL(MPKIXCertSource* aSource) + { + User::LeaveIfError(iSources.Append(aSource)); + } + +void CPKIXChainBuilder::AddIssuer(TInt& aNumberOfCertsAdded, + TBool& aResult, + CArrayPtrFlat& aChain, + TRequestStatus& aStatus) + { + iOriginalRequestStatus = &aStatus; + aStatus = KRequestPending; + iResult = &aResult; + iChain = &aChain; + iNumberOfCertsAdded = &aNumberOfCertsAdded; + + iSubject = aChain[aChain.Count()-1]; + __ASSERT_DEBUG(iSubject, User::Panic(_L("CPKICCertChainAO"), 1)); + __ASSERT_DEBUG(!iCandidates.Count(), User::Panic(_L("CPKICCertChainAO"), 1)); + + iIndex = -1; + iState = EAddCandidate; + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + SetActive(); + } + +CPKIXChainBuilder::CPKIXChainBuilder() +: CActive(EPriorityNormal) + { + CActiveScheduler::Add(this); + } + +void CPKIXChainBuilder::ConstructL() + { + } + +TBool CPKIXChainBuilder::ResolveIssuersL(CArrayPtr& aChain, + const RPointerArray& aCandidates) const + { + //*this function attempts to figure out which certificate in aCandidates is the issuer of + //the last cert in the aChain, and adds a *copy* of the best guess to aChain + //*it assumes that the names match already + //*if it establishes that none are any good it returns EFalse + TInt count = aCandidates.Count(); + if (count == 0) + { + return EFalse; + } + if (count == 1) + { + CX509Certificate* cert = CX509Certificate::NewLC(*aCandidates[0]); + aChain.AppendL(cert); + (*iNumberOfCertsAdded)++; + CleanupStack::Pop(cert); + return ETrue; + } + + const CX509Certificate* current = aChain[aChain.Count() - 1]; + //1) look for SKI/AKI to distinguish + const CX509CertExtension* akiExt = current->Extension(KAuthorityKeyId); + if (akiExt) + { + const CX509AuthorityKeyIdExt* aki = CX509AuthorityKeyIdExt::NewLC(akiExt->Data()); + TPtrC8 authorityKeyId = aki->KeyId(); + if (authorityKeyId != KNullDesC8) + { + for (TInt i = 0; i < count; i++) + { + const CX509CertExtension* skiExt = (aCandidates[i])->Extension(KSubjectKeyId); + if (skiExt) + { + const CX509SubjectKeyIdExt* ski = CX509SubjectKeyIdExt::NewLC(skiExt->Data()); + if (authorityKeyId == ski->KeyId()) + { + CX509Certificate* issuer = CX509Certificate::NewLC(*aCandidates[i]); + aChain.AppendL(issuer); + (*iNumberOfCertsAdded)++; + CleanupStack::Pop();//issuer + CleanupStack::PopAndDestroy(2);//aki, ski + return ETrue; + } + else + { + CleanupStack::PopAndDestroy();//ski + } + } + } + } + //ok, we haven't got a key ID for the issuer, so try for a serial number instead... + else + { + TPtrC8 authoritySerialNo = aki->AuthorityCertSerialNumber(); + for (TInt i = 0; i < count; i++) + { + const CX509Certificate* candidate = aCandidates[i]; + if (authoritySerialNo == candidate->SerialNumber()) + { + CX509Certificate* issuer = CX509Certificate::NewLC(*candidate); + aChain.AppendL(issuer); + (*iNumberOfCertsAdded)++; + CleanupStack::Pop();//issuer + CleanupStack::PopAndDestroy();//aki + return ETrue; + } + } + } + CleanupStack::PopAndDestroy();//aki + } + + return EFalse; + } + + +void CPKIXChainBuilder::RunL() + { + User::LeaveIfError(iStatus.Int()); + + switch (iState) + { + case EAddCandidate: + iIndex++; + if (iIndex < iSources.Count()) + { + iSources[iIndex]->CandidatesL(*iSubject, iCandidates, iStatus); + } + else + { + iState = EFinished; + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + SetActive(); + break; + + case EFinished: + iState = EIdle; + *iResult = ResolveIssuersL(*iChain, iCandidates); + iCandidates.ResetAndDestroy(); + User::RequestComplete(iOriginalRequestStatus, KErrNone); + break; + + default: + User::Panic(_L("CPKIXChainBuilder"), 1); + break; + } + } + +void CPKIXChainBuilder::DoCancel() + { + int i = 0; + int end = iSources.Count(); + while (i < end) + { + iSources[i]->CancelCandidates(); + i++; + } + iCandidates.ResetAndDestroy(); + + User::RequestComplete(iOriginalRequestStatus, KErrCancel); + + iState = EIdle; + } + +TInt CPKIXChainBuilder::RunError(TInt aError) + { + iState = EIdle; + iCandidates.ResetAndDestroy(); + User::RequestComplete(iOriginalRequestStatus, aError); + return KErrNone; + }