--- a/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixcons.cpp Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixcons.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -1,630 +1,630 @@
-/*
-* Copyright (c) 1998-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 "pkixCons.h"
-
-//PKIX constraint
-//only function is remove
-TPKIXConstraint::TPKIXConstraint( CPKIXValidationState& aState,
- CPKIXValidationResultBase& aResult)
- :iState(aState), iResult(aResult)
- {
- }
-
-void TPKIXConstraint::Remove(CArrayPtrFlat<CX509CertExtension>& aCriticalExtensions, const TDesC& aOID)
- {
- TInt count = aCriticalExtensions.Count();
- for (TInt i = 0; i < count; i++)
- {
- CX509CertExtension* ext = aCriticalExtensions.At(i);
- if (ext->Id() == aOID)
- {
- aCriticalExtensions.Delete(i);
- break;
- }
- }
- }
-
-//policy constraint
-//public functions
-TPKIXPolicyConstraint::TPKIXPolicyConstraint( CPKIXValidationState& aState,
- CPKIXValidationResultBase& aResult)
- :TPKIXConstraint(aState, aResult)
- {
- }
-
-void TPKIXPolicyConstraint::CleanupPolicyInfoArray(TAny* aPolicies)
- {
- CArrayPtrFlat<CX509CertPolicyInfo>* array = REINTERPRET_CAST(CArrayPtrFlat<CX509CertPolicyInfo>*, aPolicies);
- array->ResetAndDestroy();
- delete array;
- }
-
-void TPKIXPolicyConstraint::CheckCertPoliciesL(const CX509Certificate& aCert)
- {
- const CX509CertExtension* ext = aCert.Extension(KCertPolicies);
- CX509CertPoliciesExt* policyExt = NULL;
- if (ext)
- {
- policyExt = CX509CertPoliciesExt::NewLC(ext->Data());
- }
- if (iState.iPos > iState.iPolicyRequired)
- {
- if (!(policyExt))
- {
- iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
- }
- const CArrayPtrFlat<CX509CertPolicyInfo>& policies = policyExt->Policies();
- if ((iState.iUserPolicies->Count() == 0) || (PolicyIsPresentL(policies, *iState.iUserPolicies)))
- {
- }
- else
- {
- iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
- }
- }
- if (!policyExt)
- {
- if (!iState.iAnyAuthorityPolicy)
- {
- iState.iAuthorityConstrainedPolicies->ResetAndDestroy();//AP becomes NULL
- }
- }
- else
- {
- IntersectCertPoliciesL(*policyExt);
- if (ext->Critical())
- {
- TInt count = iState.iAuthorityConstrainedPolicies->Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX509CertPolicyInfo* policy = iState.iAuthorityConstrainedPolicies->At(i);
- if (policy->Qualifiers().Count() > 0)
- {
- iResult.AppendWarningL(TValidationStatus(ECriticalCertPoliciesWithQualifiers, i));
- break;
- }
- }
- Remove(*(iState.iCriticalExts), KCertPolicies);
- }
- CleanupStack::PopAndDestroy();//policyExt
- }
- }
-
-void TPKIXPolicyConstraint::IntersectCertPoliciesL(const CX509CertPoliciesExt& aPolicyExt)
- {
- //1 intersect AP and CP, assign result to newAP
- CArrayPtrFlat<CX509CertPolicyInfo>* newAP;
- TInt certPolicyCount = aPolicyExt.Policies().Count();
- if (iState.iAnyAuthorityPolicy)
- {
- newAP = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
- TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, newAP);
- CleanupStack::PushL(cleanupPolicies);
- for (TInt i = 0; i < certPolicyCount; i++)
- {
- CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*(aPolicyExt.Policies().At(i)));
- newAP->AppendL(info);
- CleanupStack::Pop();
- }
- iState.iAnyAuthorityPolicy = EFalse;
- }
- else
- {
- newAP = IntersectionLC(aPolicyExt.Policies(), *(iState.iAuthorityConstrainedPolicies));
- }
-
- TInt mappedCount = iState.iMappedPolicies->Count();
- for (TInt i = 0; i < mappedCount; i++)
- {
- CX509PolicyMapping* mapping = iState.iMappedPolicies->At(i);
- TInt apCount = iState.iAuthorityConstrainedPolicies->Count();
- //2 for each mapping in MP, if issuer is in AP and subject is in CP, add subject to newAP
- for (TInt j = 0; j < apCount; j++)
- {
- CX509CertPolicyInfo* aCP = iState.iAuthorityConstrainedPolicies->At(j);
- if (aCP->Id() == mapping->IssuerPolicy())
- {
- for (TInt k = 0; k < certPolicyCount; k++)
- {
- CX509CertPolicyInfo* cp = aPolicyExt.Policies().At(k);
- if (mapping->SubjectPolicy() == cp->Id())
- {
- CX509CertPolicyInfo* newPolicy = CX509CertPolicyInfo::NewLC(*cp);
- newAP->AppendL(newPolicy);
- CleanupStack::Pop();
- }
- }
- }
- }
- }
- //new acceptable policies = intersection
- iState.iAuthorityConstrainedPolicies->ResetAndDestroy();
- delete iState.iAuthorityConstrainedPolicies;
- iState.iAuthorityConstrainedPolicies = newAP;
- CleanupStack::Pop();//newAP
- }
-
-void TPKIXPolicyConstraint::UpdatePolicyConstraintsL(const CX509Certificate& aCert)
- {
- //get mapping ext
- const CX509CertExtension* ext = aCert.Extension(KPolicyMapping);
- if ((iState.iPos <= iState.iPolicyMapping) && (ext))
- {
- CX509PolicyMappingExt* policyMappingExt = CX509PolicyMappingExt::NewLC(ext->Data());
- const CArrayPtrFlat<CX509PolicyMapping>& mappings = policyMappingExt->Mappings();
- //for each policy mapping
- TInt countM = mappings.Count();
- for (TInt i = 0; i < countM; i++)
- {
- CX509PolicyMapping* mapping = mappings.At(i);
- CX509PolicyMapping* newMapping = CX509PolicyMapping::NewLC(*mapping);
- iState.iMappedPolicies->AppendL(newMapping);
- CleanupStack::Pop();
- TInt uCount = iState.iUserPolicies->Count();
- for (TInt j = 0; j < uCount; j++)
- {
- HBufC* userPolicy = iState.iUserPolicies->At(j);
- if (newMapping->IssuerPolicy() == *userPolicy)
- {
- HBufC* newUP = newMapping->SubjectPolicy().AllocL();
- CleanupStack::PushL(newUP);
- iState.iUserPolicies->AppendL(newUP);
- CleanupStack::Pop();
- break;
- }
- }
- }
- CleanupStack::PopAndDestroy();//mapping ext
- }
- iState.iPolicyMapping --;
- iState.iPolicyRequired --;
- //get constraints
- ext = aCert.Extension(KPolicyConstraints);
- if ( ext )
- {
- CX509PolicyConstraintsExt* policyConstraintsExt = CX509PolicyConstraintsExt::NewLC(ext->Data());
- UpdateConstraint(policyConstraintsExt->InhibitPolicyMapping(), iState.iPolicyMapping);
- UpdateConstraint(policyConstraintsExt->ExplicitPolicyRequired(), iState.iPolicyRequired);
- CleanupStack::PopAndDestroy();//constraint ext
- //remove it from the 'critical list'
- if (ext->Critical())
- {
- Remove(*(iState.iCriticalExts), KPolicyConstraints);
- }
- }
- }
-
-//private functions
-TBool TPKIXPolicyConstraint::PolicyIsPresentL( const CArrayPtrFlat<CX509CertPolicyInfo>& aPolicies,
- const CArrayPtr<HBufC>& aAcceptablePolicies)
- {
- TInt certCount = aPolicies.Count();
- TInt chainCount = aAcceptablePolicies.Count();
- for (TInt i = 0; i < certCount; i++)
- {
- CX509CertPolicyInfo* certPolicy = aPolicies.At(i);
- for (TInt j = 0; j < chainCount; j++)
- {
- HBufC* chainPolicy = aAcceptablePolicies.At(j);
- if (certPolicy->Id() == chainPolicy->Des())
- {
- return ETrue;
- }
- }
- }
- return EFalse;
- }
-
-void TPKIXPolicyConstraint::UpdateConstraint(const TX509PolicyConstraint& aConstraint, TInt& aCountdown)
- {
- if (aConstraint.iRequired)
- {
- if (aConstraint.iCountdown < aCountdown)
- aCountdown = aConstraint.iCountdown;
- }
- }
-
-void TPKIXPolicyConstraint::FinishPolicyCheckL()
- {
- if (iState.iUserConstrainedPolicies)
- {
- TBool passed = EFalse;
- if (!(iState.iAnyAuthorityPolicy))
- {//policy from user policies must be in authority policy set
- if ((PolicyIsPresentL(*(iState.iAuthorityConstrainedPolicies), *(iState.iUserPolicies))))
- {
- passed = ETrue;
- }
- }
- if (!passed)
- {
- iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
- }
- }
- }
-
-CArrayPtrFlat<CX509CertPolicyInfo>* TPKIXPolicyConstraint::IntersectionLC(
- const CArrayPtrFlat<CX509CertPolicyInfo>& aFirst,
- const CArrayPtrFlat<CX509CertPolicyInfo>& aSecond)
- //constructs an array of certificate policy objects,
- //populating it with policies that occur in both of the array parameters
- {
- CArrayPtrFlat<CX509CertPolicyInfo>* inter = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
- TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, inter);
- CleanupStack::PushL(cleanupPolicies);
- TInt count1 = aFirst.Count();
- TInt count2 = aSecond.Count();
- for (TInt i = 0; i < count1; i++)
- {
- CX509CertPolicyInfo* policy1 = aFirst.At(i);
- for (TInt j = 0; j < count2; j++)
- {
- CX509CertPolicyInfo* policy2 = aSecond.At(j);
- if (policy1->Id() == policy2->Id())
- {
- CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*policy1);
- inter->AppendL(info);
- CleanupStack::Pop();
- }
- }
- }
- return inter;
- }
-
-//name constraint
-//public functions
-TPKIXNameConstraint::TPKIXNameConstraint( CPKIXValidationState& aState,
- CPKIXValidationResultBase& aResult)
- :TPKIXConstraint(aState, aResult)
- {
- }
-
-void TPKIXNameConstraint::CheckNameConstraintsL(const CX509Certificate& aCert)
- {
- //*do the subject name
- if (NameIsPresentL(aCert.SubjectName(), *(iState.iExcludedDNSubtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- TInt pCount = iState.iPermittedDNSubtrees->Count();
- if ((pCount > 0) && (!(NameIsPresentL(aCert.SubjectName(), *(iState.iPermittedDNSubtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- //*do the alt name
- const CX509CertExtension* ext = aCert.Extension(KSubjectAltName);
- if (ext)
- {
- CX509AltNameExt* altNameExt = CX509AltNameExt::NewLC(ext->Data());
- const CArrayPtrFlat<CX509GeneralName>& altName = altNameExt->AltName();
- TInt count = altName.Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX509GeneralName* gN = altName.At(i);
- switch (gN->Tag())
- {
- case EX509DirectoryName://X500DN
- {
- const CX500DistinguishedName* dN = CX500DistinguishedName::NewLC(gN->Data());
- if (NameIsPresentL(*dN, *(iState.iExcludedDNSubtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- if ((pCount > 0) && (!(NameIsPresentL(*dN, *(iState.iPermittedDNSubtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509RFC822Name://IA5String
- {
- const CX509RFC822Name* name = CX509RFC822Name::NewLC(gN->Data());
- if (NameIsPresent(*name, *(iState.iExcludedRFC822Subtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- if ((iState.iPermittedRFC822Subtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedRFC822Subtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509URI://IA5String
- {
- const CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN->Data());
- const CX509DNSName& domain = name->Host();
- if (NameIsPresent(domain, *(iState.iExcludedDNSNameSubtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(domain, *(iState.iPermittedDNSNameSubtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509DNSName://IA5String
- {
- const CX509DNSName* name = CX509DNSName::NewLC(gN->Data());
- if (NameIsPresent(*name, *(iState.iExcludedDNSNameSubtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedDNSNameSubtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509IPAddress://octet string
- {
- const CX509IPAddress* name = CX509IPAddress::NewLC(gN->Data());
- if (NameIsPresent(*name, *(iState.iExcludedIPAddressSubtrees)))
- {
- iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
- }
- if ((iState.iPermittedIPAddressSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedIPAddressSubtrees)))))
- {
- iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- }
- break;
- }
- }//end of for loop
- //we've handled this now, so can remove it from the critical list
- Remove(*(iState.iCriticalExts), KSubjectAltName);
- CleanupStack::PopAndDestroy();//altNameExt
- }//end of if(ext)
- }
-
-void TPKIXNameConstraint::UpdateNameConstraintsL(const CX509Certificate& aCert)
- {
- const CX509CertExtension* ext = aCert.Extension(KNameConstraints);
- if (ext)
- {
- CX509NameConstraintsExt* nameCons = CX509NameConstraintsExt::NewLC(ext->Data());
- const CArrayPtrFlat<CX509GeneralSubtree>& excSubtrees = nameCons->ExcludedSubtrees();
- TInt count = excSubtrees.Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX509GeneralSubtree* subtree = excSubtrees.At(i);
- const CX509GeneralName& gN = subtree->Name();
- switch (gN.Tag())
- {
- case EX509DirectoryName://X500DN
- {
- CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
- iState.iExcludedDNSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509RFC822Name://IA5String
- {
- CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
- iState.iExcludedRFC822Subtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509URI://IA5String
- {
- CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
- CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
- iState.iExcludedDNSNameSubtrees->AppendL(domain);
- CleanupStack::Pop();
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509DNSName://IA5String
- {
- CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
- iState.iExcludedDNSNameSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509IPAddress://octet string
- {
- CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
- iState.iExcludedIPAddressSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- default:
- {
- User::Leave(KErrNotSupported);
- }
- break;
- }
- }//end of for loop
- const CArrayPtrFlat<CX509GeneralSubtree>& perSubtrees = nameCons->PermittedSubtrees();
- count = perSubtrees.Count();
- for (TInt j = 0; j < count; j++)
- {
- const CX509GeneralSubtree* subtree = perSubtrees.At(j);
- const CX509GeneralName& gN = subtree->Name();
- switch (gN.Tag())
- {
- case EX509DirectoryName://X500DN
- {
- CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
- iState.iPermittedDNSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509RFC822Name://IA5String
- {
- CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
- iState.iPermittedRFC822Subtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509URI://IA5String
- {
- CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
- CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
- iState.iPermittedDNSNameSubtrees->AppendL(domain);
- CleanupStack::Pop();
- CleanupStack::PopAndDestroy();
- }
- break;
- case EX509DNSName://IA5String
- {
- CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
- iState.iPermittedDNSNameSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- case EX509IPAddress://octet string
- {
- CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
- iState.iPermittedIPAddressSubtrees->AppendL(name);
- CleanupStack::Pop();
- }
- break;
- default:
- {
- User::Leave(KErrNotSupported);
- }
- break;
- }
- }//end of for loop
- CleanupStack::PopAndDestroy();//nameConsExt
- //we've handled this now, so can remove it from the critical list
- Remove(*(iState.iCriticalExts), KNameConstraints);
- }//end of if(ext)
- }
-
-
-//private functions
-TBool TPKIXNameConstraint::NameIsPresentL( const CX500DistinguishedName& aSubject,
- const CArrayPtrFlat<CX500DistinguishedName>& aSubtrees)
- {
- TInt count = aSubtrees.Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX500DistinguishedName* excluded = aSubtrees.At(i);
- if (aSubject.IsWithinSubtreeL(*excluded))
- {
- return ETrue;
- }
- }
- return EFalse;
- }
-
-TBool TPKIXNameConstraint::NameIsPresent( const CX509DomainName& aSubject,
- const CArrayPtrFlat<CX509DomainName>& aSubtrees)
- {
- TInt count = aSubtrees.Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX509DomainName* excluded = aSubtrees.At(i);
- if (aSubject.IsWithinSubtree(*excluded))
- {
- return ETrue;
- }
- }
- return EFalse;
- }
-
-TBool TPKIXNameConstraint::NameIsPresent( const CX509IPAddress& aSubject,
- const CArrayPtrFlat<CX509IPSubnetMask>& aSubtrees)
- {
- TInt count = aSubtrees.Count();
- for (TInt i = 0; i < count; i++)
- {
- const CX509IPSubnetMask* excluded = aSubtrees.At(i);
- if (aSubject.IsWithinSubtree(*excluded))
- {
- return ETrue;
- }
- }
- return EFalse;
- }
-
-//basic constraint
-TPKIXBasicConstraint::TPKIXBasicConstraint( CPKIXValidationState& aState,
- CPKIXValidationResultBase& aResult)
- :TPKIXConstraint(aState, aResult)
- {
- }
-
-void TPKIXBasicConstraint::CheckCertSubjectTypeL(const CX509Certificate& aCert)
- {
- TBool markedAsCA = EFalse;
- TBool actsAsCA = iState.iPos > 0;
- const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
- if (ext)
- {
- CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
- markedAsCA = basic->IsCA();
- CleanupStack::PopAndDestroy();
- }
- if (actsAsCA && (!markedAsCA))
- {
- iResult.SetErrorAndLeaveL(ENotCACert, iState.iPos);
- }
- }
-
-void TPKIXBasicConstraint::UpdatePathLengthConstraintsL(const CX509Certificate& aCert)
- {
- const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
- if (ext)
- {
- CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
- TInt pathLength = basic->MaxChainLength();
- if (pathLength < 0)
- {
- iResult.SetErrorAndLeaveL(ENegativePathLengthSpecified, iState.iPos);
- }
- if (iState.iPos > pathLength)
- {
- iState.iMaxPathLength = pathLength + 1;
- }
- Remove(*(iState.iCriticalExts), KBasicConstraints);
- CleanupStack::PopAndDestroy();//basic
- }
- }
-
-//key usage constraint
-TPKIXKeyUsageConstraint::TPKIXKeyUsageConstraint( CPKIXValidationState& aState,
- CPKIXValidationResultBase& aResult)
- :TPKIXConstraint(aState, aResult)
- {
- }
-
-void TPKIXKeyUsageConstraint::CheckKeyUsageL(const CX509Certificate& aCert)
- {
- //if key usage is critical and this is a CA cert, the keyCertSign bit must be set
- const CX509CertExtension* ext = aCert.Extension(KKeyUsage);
- if (ext)
- {
- CX509KeyUsageExt* keyUsage = CX509KeyUsageExt::NewLC(ext->Data());
- if ( (iState.iPos > 0) && (!(keyUsage->IsSet(EX509KeyCertSign))))
- {
- iResult.SetErrorAndLeaveL(EBadKeyUsage, iState.iPos);
- }
- CleanupStack::PopAndDestroy();
- //we've processed this critical ext, so remove it
- Remove(*(iState.iCriticalExts), KKeyUsage);
- }
- }
+/*
+* Copyright (c) 1998-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 "pkixCons.h"
+
+//PKIX constraint
+//only function is remove
+TPKIXConstraint::TPKIXConstraint( CPKIXValidationState& aState,
+ CPKIXValidationResultBase& aResult)
+ :iState(aState), iResult(aResult)
+ {
+ }
+
+void TPKIXConstraint::Remove(CArrayPtrFlat<CX509CertExtension>& aCriticalExtensions, const TDesC& aOID)
+ {
+ TInt count = aCriticalExtensions.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ CX509CertExtension* ext = aCriticalExtensions.At(i);
+ if (ext->Id() == aOID)
+ {
+ aCriticalExtensions.Delete(i);
+ break;
+ }
+ }
+ }
+
+//policy constraint
+//public functions
+TPKIXPolicyConstraint::TPKIXPolicyConstraint( CPKIXValidationState& aState,
+ CPKIXValidationResultBase& aResult)
+ :TPKIXConstraint(aState, aResult)
+ {
+ }
+
+void TPKIXPolicyConstraint::CleanupPolicyInfoArray(TAny* aPolicies)
+ {
+ CArrayPtrFlat<CX509CertPolicyInfo>* array = REINTERPRET_CAST(CArrayPtrFlat<CX509CertPolicyInfo>*, aPolicies);
+ array->ResetAndDestroy();
+ delete array;
+ }
+
+void TPKIXPolicyConstraint::CheckCertPoliciesL(const CX509Certificate& aCert)
+ {
+ const CX509CertExtension* ext = aCert.Extension(KCertPolicies);
+ CX509CertPoliciesExt* policyExt = NULL;
+ if (ext)
+ {
+ policyExt = CX509CertPoliciesExt::NewLC(ext->Data());
+ }
+ if (iState.iPos > iState.iPolicyRequired)
+ {
+ if (!(policyExt))
+ {
+ iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
+ }
+ const CArrayPtrFlat<CX509CertPolicyInfo>& policies = policyExt->Policies();
+ if ((iState.iUserPolicies->Count() == 0) || (PolicyIsPresentL(policies, *iState.iUserPolicies)))
+ {
+ }
+ else
+ {
+ iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
+ }
+ }
+ if (!policyExt)
+ {
+ if (!iState.iAnyAuthorityPolicy)
+ {
+ iState.iAuthorityConstrainedPolicies->ResetAndDestroy();//AP becomes NULL
+ }
+ }
+ else
+ {
+ IntersectCertPoliciesL(*policyExt);
+ if (ext->Critical())
+ {
+ TInt count = iState.iAuthorityConstrainedPolicies->Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX509CertPolicyInfo* policy = iState.iAuthorityConstrainedPolicies->At(i);
+ if (policy->Qualifiers().Count() > 0)
+ {
+ iResult.AppendWarningL(TValidationStatus(ECriticalCertPoliciesWithQualifiers, i));
+ break;
+ }
+ }
+ Remove(*(iState.iCriticalExts), KCertPolicies);
+ }
+ CleanupStack::PopAndDestroy();//policyExt
+ }
+ }
+
+void TPKIXPolicyConstraint::IntersectCertPoliciesL(const CX509CertPoliciesExt& aPolicyExt)
+ {
+ //1 intersect AP and CP, assign result to newAP
+ CArrayPtrFlat<CX509CertPolicyInfo>* newAP;
+ TInt certPolicyCount = aPolicyExt.Policies().Count();
+ if (iState.iAnyAuthorityPolicy)
+ {
+ newAP = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
+ TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, newAP);
+ CleanupStack::PushL(cleanupPolicies);
+ for (TInt i = 0; i < certPolicyCount; i++)
+ {
+ CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*(aPolicyExt.Policies().At(i)));
+ newAP->AppendL(info);
+ CleanupStack::Pop();
+ }
+ iState.iAnyAuthorityPolicy = EFalse;
+ }
+ else
+ {
+ newAP = IntersectionLC(aPolicyExt.Policies(), *(iState.iAuthorityConstrainedPolicies));
+ }
+
+ TInt mappedCount = iState.iMappedPolicies->Count();
+ for (TInt i = 0; i < mappedCount; i++)
+ {
+ CX509PolicyMapping* mapping = iState.iMappedPolicies->At(i);
+ TInt apCount = iState.iAuthorityConstrainedPolicies->Count();
+ //2 for each mapping in MP, if issuer is in AP and subject is in CP, add subject to newAP
+ for (TInt j = 0; j < apCount; j++)
+ {
+ CX509CertPolicyInfo* aCP = iState.iAuthorityConstrainedPolicies->At(j);
+ if (aCP->Id() == mapping->IssuerPolicy())
+ {
+ for (TInt k = 0; k < certPolicyCount; k++)
+ {
+ CX509CertPolicyInfo* cp = aPolicyExt.Policies().At(k);
+ if (mapping->SubjectPolicy() == cp->Id())
+ {
+ CX509CertPolicyInfo* newPolicy = CX509CertPolicyInfo::NewLC(*cp);
+ newAP->AppendL(newPolicy);
+ CleanupStack::Pop();
+ }
+ }
+ }
+ }
+ }
+ //new acceptable policies = intersection
+ iState.iAuthorityConstrainedPolicies->ResetAndDestroy();
+ delete iState.iAuthorityConstrainedPolicies;
+ iState.iAuthorityConstrainedPolicies = newAP;
+ CleanupStack::Pop();//newAP
+ }
+
+void TPKIXPolicyConstraint::UpdatePolicyConstraintsL(const CX509Certificate& aCert)
+ {
+ //get mapping ext
+ const CX509CertExtension* ext = aCert.Extension(KPolicyMapping);
+ if ((iState.iPos <= iState.iPolicyMapping) && (ext))
+ {
+ CX509PolicyMappingExt* policyMappingExt = CX509PolicyMappingExt::NewLC(ext->Data());
+ const CArrayPtrFlat<CX509PolicyMapping>& mappings = policyMappingExt->Mappings();
+ //for each policy mapping
+ TInt countM = mappings.Count();
+ for (TInt i = 0; i < countM; i++)
+ {
+ CX509PolicyMapping* mapping = mappings.At(i);
+ CX509PolicyMapping* newMapping = CX509PolicyMapping::NewLC(*mapping);
+ iState.iMappedPolicies->AppendL(newMapping);
+ CleanupStack::Pop();
+ TInt uCount = iState.iUserPolicies->Count();
+ for (TInt j = 0; j < uCount; j++)
+ {
+ HBufC* userPolicy = iState.iUserPolicies->At(j);
+ if (newMapping->IssuerPolicy() == *userPolicy)
+ {
+ HBufC* newUP = newMapping->SubjectPolicy().AllocL();
+ CleanupStack::PushL(newUP);
+ iState.iUserPolicies->AppendL(newUP);
+ CleanupStack::Pop();
+ break;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy();//mapping ext
+ }
+ iState.iPolicyMapping --;
+ iState.iPolicyRequired --;
+ //get constraints
+ ext = aCert.Extension(KPolicyConstraints);
+ if ( ext )
+ {
+ CX509PolicyConstraintsExt* policyConstraintsExt = CX509PolicyConstraintsExt::NewLC(ext->Data());
+ UpdateConstraint(policyConstraintsExt->InhibitPolicyMapping(), iState.iPolicyMapping);
+ UpdateConstraint(policyConstraintsExt->ExplicitPolicyRequired(), iState.iPolicyRequired);
+ CleanupStack::PopAndDestroy();//constraint ext
+ //remove it from the 'critical list'
+ if (ext->Critical())
+ {
+ Remove(*(iState.iCriticalExts), KPolicyConstraints);
+ }
+ }
+ }
+
+//private functions
+TBool TPKIXPolicyConstraint::PolicyIsPresentL( const CArrayPtrFlat<CX509CertPolicyInfo>& aPolicies,
+ const CArrayPtr<HBufC>& aAcceptablePolicies)
+ {
+ TInt certCount = aPolicies.Count();
+ TInt chainCount = aAcceptablePolicies.Count();
+ for (TInt i = 0; i < certCount; i++)
+ {
+ CX509CertPolicyInfo* certPolicy = aPolicies.At(i);
+ for (TInt j = 0; j < chainCount; j++)
+ {
+ HBufC* chainPolicy = aAcceptablePolicies.At(j);
+ if (certPolicy->Id() == chainPolicy->Des())
+ {
+ return ETrue;
+ }
+ }
+ }
+ return EFalse;
+ }
+
+void TPKIXPolicyConstraint::UpdateConstraint(const TX509PolicyConstraint& aConstraint, TInt& aCountdown)
+ {
+ if (aConstraint.iRequired)
+ {
+ if (aConstraint.iCountdown < aCountdown)
+ aCountdown = aConstraint.iCountdown;
+ }
+ }
+
+void TPKIXPolicyConstraint::FinishPolicyCheckL()
+ {
+ if (iState.iUserConstrainedPolicies)
+ {
+ TBool passed = EFalse;
+ if (!(iState.iAnyAuthorityPolicy))
+ {//policy from user policies must be in authority policy set
+ if ((PolicyIsPresentL(*(iState.iAuthorityConstrainedPolicies), *(iState.iUserPolicies))))
+ {
+ passed = ETrue;
+ }
+ }
+ if (!passed)
+ {
+ iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
+ }
+ }
+ }
+
+CArrayPtrFlat<CX509CertPolicyInfo>* TPKIXPolicyConstraint::IntersectionLC(
+ const CArrayPtrFlat<CX509CertPolicyInfo>& aFirst,
+ const CArrayPtrFlat<CX509CertPolicyInfo>& aSecond)
+ //constructs an array of certificate policy objects,
+ //populating it with policies that occur in both of the array parameters
+ {
+ CArrayPtrFlat<CX509CertPolicyInfo>* inter = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
+ TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, inter);
+ CleanupStack::PushL(cleanupPolicies);
+ TInt count1 = aFirst.Count();
+ TInt count2 = aSecond.Count();
+ for (TInt i = 0; i < count1; i++)
+ {
+ CX509CertPolicyInfo* policy1 = aFirst.At(i);
+ for (TInt j = 0; j < count2; j++)
+ {
+ CX509CertPolicyInfo* policy2 = aSecond.At(j);
+ if (policy1->Id() == policy2->Id())
+ {
+ CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*policy1);
+ inter->AppendL(info);
+ CleanupStack::Pop();
+ }
+ }
+ }
+ return inter;
+ }
+
+//name constraint
+//public functions
+TPKIXNameConstraint::TPKIXNameConstraint( CPKIXValidationState& aState,
+ CPKIXValidationResultBase& aResult)
+ :TPKIXConstraint(aState, aResult)
+ {
+ }
+
+void TPKIXNameConstraint::CheckNameConstraintsL(const CX509Certificate& aCert)
+ {
+ //*do the subject name
+ if (NameIsPresentL(aCert.SubjectName(), *(iState.iExcludedDNSubtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ TInt pCount = iState.iPermittedDNSubtrees->Count();
+ if ((pCount > 0) && (!(NameIsPresentL(aCert.SubjectName(), *(iState.iPermittedDNSubtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ //*do the alt name
+ const CX509CertExtension* ext = aCert.Extension(KSubjectAltName);
+ if (ext)
+ {
+ CX509AltNameExt* altNameExt = CX509AltNameExt::NewLC(ext->Data());
+ const CArrayPtrFlat<CX509GeneralName>& altName = altNameExt->AltName();
+ TInt count = altName.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX509GeneralName* gN = altName.At(i);
+ switch (gN->Tag())
+ {
+ case EX509DirectoryName://X500DN
+ {
+ const CX500DistinguishedName* dN = CX500DistinguishedName::NewLC(gN->Data());
+ if (NameIsPresentL(*dN, *(iState.iExcludedDNSubtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ if ((pCount > 0) && (!(NameIsPresentL(*dN, *(iState.iPermittedDNSubtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509RFC822Name://IA5String
+ {
+ const CX509RFC822Name* name = CX509RFC822Name::NewLC(gN->Data());
+ if (NameIsPresent(*name, *(iState.iExcludedRFC822Subtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ if ((iState.iPermittedRFC822Subtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedRFC822Subtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509URI://IA5String
+ {
+ const CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN->Data());
+ const CX509DNSName& domain = name->Host();
+ if (NameIsPresent(domain, *(iState.iExcludedDNSNameSubtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(domain, *(iState.iPermittedDNSNameSubtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509DNSName://IA5String
+ {
+ const CX509DNSName* name = CX509DNSName::NewLC(gN->Data());
+ if (NameIsPresent(*name, *(iState.iExcludedDNSNameSubtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedDNSNameSubtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509IPAddress://octet string
+ {
+ const CX509IPAddress* name = CX509IPAddress::NewLC(gN->Data());
+ if (NameIsPresent(*name, *(iState.iExcludedIPAddressSubtrees)))
+ {
+ iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
+ }
+ if ((iState.iPermittedIPAddressSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedIPAddressSubtrees)))))
+ {
+ iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ }
+ }//end of for loop
+ //we've handled this now, so can remove it from the critical list
+ Remove(*(iState.iCriticalExts), KSubjectAltName);
+ CleanupStack::PopAndDestroy();//altNameExt
+ }//end of if(ext)
+ }
+
+void TPKIXNameConstraint::UpdateNameConstraintsL(const CX509Certificate& aCert)
+ {
+ const CX509CertExtension* ext = aCert.Extension(KNameConstraints);
+ if (ext)
+ {
+ CX509NameConstraintsExt* nameCons = CX509NameConstraintsExt::NewLC(ext->Data());
+ const CArrayPtrFlat<CX509GeneralSubtree>& excSubtrees = nameCons->ExcludedSubtrees();
+ TInt count = excSubtrees.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX509GeneralSubtree* subtree = excSubtrees.At(i);
+ const CX509GeneralName& gN = subtree->Name();
+ switch (gN.Tag())
+ {
+ case EX509DirectoryName://X500DN
+ {
+ CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
+ iState.iExcludedDNSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509RFC822Name://IA5String
+ {
+ CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
+ iState.iExcludedRFC822Subtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509URI://IA5String
+ {
+ CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
+ CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
+ iState.iExcludedDNSNameSubtrees->AppendL(domain);
+ CleanupStack::Pop();
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509DNSName://IA5String
+ {
+ CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
+ iState.iExcludedDNSNameSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509IPAddress://octet string
+ {
+ CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
+ iState.iExcludedIPAddressSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ default:
+ {
+ User::Leave(KErrNotSupported);
+ }
+ break;
+ }
+ }//end of for loop
+ const CArrayPtrFlat<CX509GeneralSubtree>& perSubtrees = nameCons->PermittedSubtrees();
+ count = perSubtrees.Count();
+ for (TInt j = 0; j < count; j++)
+ {
+ const CX509GeneralSubtree* subtree = perSubtrees.At(j);
+ const CX509GeneralName& gN = subtree->Name();
+ switch (gN.Tag())
+ {
+ case EX509DirectoryName://X500DN
+ {
+ CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
+ iState.iPermittedDNSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509RFC822Name://IA5String
+ {
+ CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
+ iState.iPermittedRFC822Subtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509URI://IA5String
+ {
+ CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
+ CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
+ iState.iPermittedDNSNameSubtrees->AppendL(domain);
+ CleanupStack::Pop();
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ case EX509DNSName://IA5String
+ {
+ CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
+ iState.iPermittedDNSNameSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ case EX509IPAddress://octet string
+ {
+ CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
+ iState.iPermittedIPAddressSubtrees->AppendL(name);
+ CleanupStack::Pop();
+ }
+ break;
+ default:
+ {
+ User::Leave(KErrNotSupported);
+ }
+ break;
+ }
+ }//end of for loop
+ CleanupStack::PopAndDestroy();//nameConsExt
+ //we've handled this now, so can remove it from the critical list
+ Remove(*(iState.iCriticalExts), KNameConstraints);
+ }//end of if(ext)
+ }
+
+
+//private functions
+TBool TPKIXNameConstraint::NameIsPresentL( const CX500DistinguishedName& aSubject,
+ const CArrayPtrFlat<CX500DistinguishedName>& aSubtrees)
+ {
+ TInt count = aSubtrees.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX500DistinguishedName* excluded = aSubtrees.At(i);
+ if (aSubject.IsWithinSubtreeL(*excluded))
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+TBool TPKIXNameConstraint::NameIsPresent( const CX509DomainName& aSubject,
+ const CArrayPtrFlat<CX509DomainName>& aSubtrees)
+ {
+ TInt count = aSubtrees.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX509DomainName* excluded = aSubtrees.At(i);
+ if (aSubject.IsWithinSubtree(*excluded))
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+TBool TPKIXNameConstraint::NameIsPresent( const CX509IPAddress& aSubject,
+ const CArrayPtrFlat<CX509IPSubnetMask>& aSubtrees)
+ {
+ TInt count = aSubtrees.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ const CX509IPSubnetMask* excluded = aSubtrees.At(i);
+ if (aSubject.IsWithinSubtree(*excluded))
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+//basic constraint
+TPKIXBasicConstraint::TPKIXBasicConstraint( CPKIXValidationState& aState,
+ CPKIXValidationResultBase& aResult)
+ :TPKIXConstraint(aState, aResult)
+ {
+ }
+
+void TPKIXBasicConstraint::CheckCertSubjectTypeL(const CX509Certificate& aCert)
+ {
+ TBool markedAsCA = EFalse;
+ TBool actsAsCA = iState.iPos > 0;
+ const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
+ if (ext)
+ {
+ CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
+ markedAsCA = basic->IsCA();
+ CleanupStack::PopAndDestroy();
+ }
+ if (actsAsCA && (!markedAsCA))
+ {
+ iResult.SetErrorAndLeaveL(ENotCACert, iState.iPos);
+ }
+ }
+
+void TPKIXBasicConstraint::UpdatePathLengthConstraintsL(const CX509Certificate& aCert)
+ {
+ const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
+ if (ext)
+ {
+ CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
+ TInt pathLength = basic->MaxChainLength();
+ if (pathLength < 0)
+ {
+ iResult.SetErrorAndLeaveL(ENegativePathLengthSpecified, iState.iPos);
+ }
+ if (iState.iPos > pathLength)
+ {
+ iState.iMaxPathLength = pathLength + 1;
+ }
+ Remove(*(iState.iCriticalExts), KBasicConstraints);
+ CleanupStack::PopAndDestroy();//basic
+ }
+ }
+
+//key usage constraint
+TPKIXKeyUsageConstraint::TPKIXKeyUsageConstraint( CPKIXValidationState& aState,
+ CPKIXValidationResultBase& aResult)
+ :TPKIXConstraint(aState, aResult)
+ {
+ }
+
+void TPKIXKeyUsageConstraint::CheckKeyUsageL(const CX509Certificate& aCert)
+ {
+ //if key usage is critical and this is a CA cert, the keyCertSign bit must be set
+ const CX509CertExtension* ext = aCert.Extension(KKeyUsage);
+ if (ext)
+ {
+ CX509KeyUsageExt* keyUsage = CX509KeyUsageExt::NewLC(ext->Data());
+ if ( (iState.iPos > 0) && (!(keyUsage->IsSet(EX509KeyCertSign))))
+ {
+ iResult.SetErrorAndLeaveL(EBadKeyUsage, iState.iPos);
+ }
+ CleanupStack::PopAndDestroy();
+ //we've processed this critical ext, so remove it
+ Remove(*(iState.iCriticalExts), KKeyUsage);
+ }
+ }