os/security/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixcons.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200 (2012-06-15)
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     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".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include "pkixCons.h"
    20 
    21 //PKIX constraint
    22 //only function is remove
    23 TPKIXConstraint::TPKIXConstraint(	CPKIXValidationState& aState, 
    24 									CPKIXValidationResultBase& aResult)
    25 	:iState(aState), iResult(aResult)
    26 	{
    27 	}
    28 
    29 void TPKIXConstraint::Remove(CArrayPtrFlat<CX509CertExtension>& aCriticalExtensions, const TDesC& aOID)
    30 	{
    31 	TInt count = aCriticalExtensions.Count();
    32 	for (TInt i = 0; i < count; i++)
    33 		{
    34 		CX509CertExtension* ext = aCriticalExtensions.At(i);
    35 		if (ext->Id() == aOID)
    36 			{
    37 			aCriticalExtensions.Delete(i);
    38 			break;
    39 			}
    40 		}
    41 	}
    42 
    43 //policy constraint
    44 //public functions
    45 TPKIXPolicyConstraint::TPKIXPolicyConstraint(	CPKIXValidationState& aState, 
    46 												CPKIXValidationResultBase& aResult)
    47 	:TPKIXConstraint(aState, aResult)
    48 	{
    49 	}
    50 
    51 void TPKIXPolicyConstraint::CleanupPolicyInfoArray(TAny* aPolicies)
    52 	{
    53 	CArrayPtrFlat<CX509CertPolicyInfo>* array = REINTERPRET_CAST(CArrayPtrFlat<CX509CertPolicyInfo>*, aPolicies);
    54 	array->ResetAndDestroy();
    55 	delete array;
    56 	}
    57 
    58 void TPKIXPolicyConstraint::CheckCertPoliciesL(const CX509Certificate& aCert)
    59 	{
    60 	const CX509CertExtension* ext =  aCert.Extension(KCertPolicies);
    61 	CX509CertPoliciesExt* policyExt = NULL;
    62 	if (ext)
    63 		{
    64 		policyExt = CX509CertPoliciesExt::NewLC(ext->Data());
    65 		}
    66 	if (iState.iPos > iState.iPolicyRequired)
    67 		{
    68 		if (!(policyExt))
    69 			{
    70 			iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
    71 			}
    72 		const CArrayPtrFlat<CX509CertPolicyInfo>& policies = policyExt->Policies();
    73 		if ((iState.iUserPolicies->Count() == 0) || (PolicyIsPresentL(policies, *iState.iUserPolicies)))
    74 			{
    75 			}
    76 		else
    77 			{
    78 			iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
    79 			}
    80 		}
    81 	if (!policyExt)
    82 		{
    83 		if (!iState.iAnyAuthorityPolicy)
    84 			{
    85 			iState.iAuthorityConstrainedPolicies->ResetAndDestroy();//AP becomes NULL 
    86 			}
    87 		}
    88 	else
    89 		{
    90 		IntersectCertPoliciesL(*policyExt);
    91 		if (ext->Critical())
    92 			{
    93 			TInt count = iState.iAuthorityConstrainedPolicies->Count();
    94 			for (TInt i = 0; i < count; i++)
    95 				{
    96 				const CX509CertPolicyInfo* policy = iState.iAuthorityConstrainedPolicies->At(i);
    97 				if (policy->Qualifiers().Count() > 0)
    98 					{
    99 					iResult.AppendWarningL(TValidationStatus(ECriticalCertPoliciesWithQualifiers, i));
   100 					break;
   101 					}
   102 				}
   103 			Remove(*(iState.iCriticalExts), KCertPolicies);
   104 			}
   105 		CleanupStack::PopAndDestroy();//policyExt
   106 		}		
   107 	}
   108 
   109 void TPKIXPolicyConstraint::IntersectCertPoliciesL(const CX509CertPoliciesExt& aPolicyExt)
   110 	{
   111 	//1 intersect AP and CP, assign result to newAP
   112 	CArrayPtrFlat<CX509CertPolicyInfo>* newAP;
   113 	TInt certPolicyCount = aPolicyExt.Policies().Count();
   114 	if (iState.iAnyAuthorityPolicy)
   115 		{
   116 		newAP = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
   117 		TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, newAP);
   118 		CleanupStack::PushL(cleanupPolicies);
   119 		for (TInt i = 0; i < certPolicyCount; i++)
   120 			{
   121 			CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*(aPolicyExt.Policies().At(i)));
   122 			newAP->AppendL(info);
   123 			CleanupStack::Pop();
   124 			}
   125 		iState.iAnyAuthorityPolicy = EFalse;
   126 		}
   127 	else
   128 		{			
   129 		newAP = IntersectionLC(aPolicyExt.Policies(), *(iState.iAuthorityConstrainedPolicies));
   130 		}
   131 
   132 	TInt mappedCount = iState.iMappedPolicies->Count(); 
   133 	for (TInt i = 0; i < mappedCount; i++)
   134 		{
   135 		CX509PolicyMapping* mapping = iState.iMappedPolicies->At(i);
   136 		TInt apCount = iState.iAuthorityConstrainedPolicies->Count();
   137 	//2 for each mapping in MP, if issuer is in AP and subject is in CP, add subject to newAP
   138 		for (TInt j = 0; j < apCount; j++)
   139 			{
   140 			CX509CertPolicyInfo* aCP = iState.iAuthorityConstrainedPolicies->At(j);
   141 			if (aCP->Id() == mapping->IssuerPolicy())
   142 				{
   143 				for (TInt k = 0; k < certPolicyCount; k++)
   144 					{
   145 					CX509CertPolicyInfo* cp = aPolicyExt.Policies().At(k);
   146 					if (mapping->SubjectPolicy() == cp->Id())
   147 						{
   148 						CX509CertPolicyInfo* newPolicy = CX509CertPolicyInfo::NewLC(*cp);
   149 						newAP->AppendL(newPolicy);
   150 						CleanupStack::Pop();
   151 						}
   152 					}
   153 				}
   154 			}
   155 		}
   156 	//new acceptable policies  = intersection
   157 	iState.iAuthorityConstrainedPolicies->ResetAndDestroy(); 
   158 	delete iState.iAuthorityConstrainedPolicies;
   159 	iState.iAuthorityConstrainedPolicies = newAP;
   160 	CleanupStack::Pop();//newAP
   161 	}
   162 
   163 void TPKIXPolicyConstraint::UpdatePolicyConstraintsL(const CX509Certificate& aCert)
   164 	{
   165 	//get mapping ext
   166 	const CX509CertExtension* ext = aCert.Extension(KPolicyMapping);
   167 	if ((iState.iPos <= iState.iPolicyMapping) && (ext))
   168 		{
   169 		CX509PolicyMappingExt* policyMappingExt = CX509PolicyMappingExt::NewLC(ext->Data());
   170 		const CArrayPtrFlat<CX509PolicyMapping>& mappings = policyMappingExt->Mappings();
   171 		//for each policy mapping
   172 		TInt countM = mappings.Count();
   173 		for (TInt i = 0; i < countM; i++)
   174 			{
   175 			CX509PolicyMapping* mapping = mappings.At(i);
   176 			CX509PolicyMapping* newMapping = CX509PolicyMapping::NewLC(*mapping);
   177 			iState.iMappedPolicies->AppendL(newMapping);
   178 			CleanupStack::Pop();
   179 			TInt uCount = iState.iUserPolicies->Count();
   180 			for (TInt j = 0; j < uCount; j++)
   181 				{
   182 				HBufC* userPolicy = iState.iUserPolicies->At(j);
   183 				if (newMapping->IssuerPolicy() == *userPolicy)
   184 					{
   185 					HBufC* newUP = newMapping->SubjectPolicy().AllocL();
   186 					CleanupStack::PushL(newUP);
   187 					iState.iUserPolicies->AppendL(newUP);
   188 					CleanupStack::Pop();
   189 					break;
   190 					}
   191 				}
   192 			}
   193 		CleanupStack::PopAndDestroy();//mapping ext
   194 		}
   195 	iState.iPolicyMapping --;
   196 	iState.iPolicyRequired --;
   197 	//get constraints 
   198 	ext = aCert.Extension(KPolicyConstraints);
   199 	if ( ext )
   200 		{
   201 		CX509PolicyConstraintsExt* policyConstraintsExt = CX509PolicyConstraintsExt::NewLC(ext->Data());
   202 		UpdateConstraint(policyConstraintsExt->InhibitPolicyMapping(), iState.iPolicyMapping);
   203 		UpdateConstraint(policyConstraintsExt->ExplicitPolicyRequired(), iState.iPolicyRequired);
   204 		CleanupStack::PopAndDestroy();//constraint ext
   205 		//remove it from the 'critical list'
   206 		if (ext->Critical())
   207 			{
   208 			Remove(*(iState.iCriticalExts), KPolicyConstraints);
   209 			}	
   210 		}
   211 	}
   212 
   213 //private functions
   214 TBool TPKIXPolicyConstraint::PolicyIsPresentL(	const CArrayPtrFlat<CX509CertPolicyInfo>& aPolicies,
   215 												const CArrayPtr<HBufC>& aAcceptablePolicies)
   216 	{
   217 	TInt certCount = aPolicies.Count();
   218 	TInt chainCount = aAcceptablePolicies.Count();
   219 	for (TInt i = 0; i < certCount; i++)
   220 		{
   221 		CX509CertPolicyInfo* certPolicy = aPolicies.At(i);
   222 		for (TInt j = 0; j < chainCount; j++)
   223 			{
   224 			HBufC* chainPolicy = aAcceptablePolicies.At(j);
   225 			if (certPolicy->Id() == chainPolicy->Des())
   226 				{
   227 				return ETrue;
   228 				}
   229 			}
   230 		}
   231 	return EFalse;
   232 	}
   233 
   234 void TPKIXPolicyConstraint::UpdateConstraint(const TX509PolicyConstraint& aConstraint, TInt& aCountdown)
   235 	{
   236 	if (aConstraint.iRequired)
   237 		{
   238 		if (aConstraint.iCountdown < aCountdown)
   239 			aCountdown = aConstraint.iCountdown;
   240 		}
   241 	}
   242 
   243 void TPKIXPolicyConstraint::FinishPolicyCheckL()
   244 	{
   245 	if (iState.iUserConstrainedPolicies)
   246 		{
   247 		TBool passed = EFalse;
   248 		if (!(iState.iAnyAuthorityPolicy))
   249 			{//policy from user policies must be in authority policy set
   250 			if ((PolicyIsPresentL(*(iState.iAuthorityConstrainedPolicies), *(iState.iUserPolicies))))
   251 				{
   252 				passed = ETrue;
   253 				}
   254 			}		
   255 		if (!passed)
   256 			{
   257 			iResult.SetErrorAndLeaveL(ERequiredPolicyNotFound, iState.iPos);
   258 			}
   259 		}
   260 	}
   261 
   262 CArrayPtrFlat<CX509CertPolicyInfo>* TPKIXPolicyConstraint::IntersectionLC(
   263 									const CArrayPtrFlat<CX509CertPolicyInfo>& aFirst,
   264 									const CArrayPtrFlat<CX509CertPolicyInfo>& aSecond)
   265 	//constructs an array of certificate policy objects, 
   266 	//populating it with policies that occur in both of the array parameters
   267 	{
   268 	CArrayPtrFlat<CX509CertPolicyInfo>* inter = new(ELeave) CArrayPtrFlat<CX509CertPolicyInfo> (1);
   269 	TCleanupItem cleanupPolicies(CleanupPolicyInfoArray, inter);
   270 	CleanupStack::PushL(cleanupPolicies);
   271 	TInt count1 = aFirst.Count();
   272 	TInt count2 = aSecond.Count();
   273 	for (TInt i = 0; i < count1; i++)
   274 		{
   275 		CX509CertPolicyInfo* policy1 = aFirst.At(i);
   276 		for (TInt j = 0; j < count2; j++)
   277 			{
   278 			CX509CertPolicyInfo* policy2 = aSecond.At(j);
   279 			if (policy1->Id() == policy2->Id())
   280 				{
   281 				CX509CertPolicyInfo* info = CX509CertPolicyInfo::NewLC(*policy1);
   282 				inter->AppendL(info);
   283 				CleanupStack::Pop();
   284 				}
   285 			}
   286 		}
   287 	return inter;
   288 	}
   289 
   290 //name constraint
   291 //public functions
   292 TPKIXNameConstraint::TPKIXNameConstraint(	CPKIXValidationState& aState, 
   293 											CPKIXValidationResultBase& aResult)
   294 	:TPKIXConstraint(aState, aResult)
   295 	{
   296 	}
   297 
   298 void TPKIXNameConstraint::CheckNameConstraintsL(const CX509Certificate& aCert) 
   299 	{
   300 	//*do the subject name
   301 	if (NameIsPresentL(aCert.SubjectName(), *(iState.iExcludedDNSubtrees)))
   302 		{
   303 		iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   304 		}
   305 	TInt pCount = iState.iPermittedDNSubtrees->Count();
   306 	if ((pCount > 0) && (!(NameIsPresentL(aCert.SubjectName(), *(iState.iPermittedDNSubtrees)))))
   307 		{
   308 		iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   309 		}
   310 	//*do the alt name
   311 	const CX509CertExtension* ext = aCert.Extension(KSubjectAltName);
   312 	if (ext)
   313 		{
   314 		CX509AltNameExt* altNameExt = CX509AltNameExt::NewLC(ext->Data());
   315 		const CArrayPtrFlat<CX509GeneralName>& altName = altNameExt->AltName();
   316 		TInt count = altName.Count();
   317 		for (TInt i = 0; i < count; i++)
   318 			{
   319 			const CX509GeneralName* gN = altName.At(i);
   320 			switch (gN->Tag())
   321 				{
   322 				case EX509DirectoryName://X500DN
   323 					{
   324 					const CX500DistinguishedName* dN = CX500DistinguishedName::NewLC(gN->Data());
   325 					if (NameIsPresentL(*dN, *(iState.iExcludedDNSubtrees)))
   326 						{
   327 						iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   328 						}
   329 					if ((pCount > 0) && (!(NameIsPresentL(*dN, *(iState.iPermittedDNSubtrees)))))
   330 						{
   331 						iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   332 						}
   333 					CleanupStack::PopAndDestroy();
   334 					}			
   335 					break;
   336 				case EX509RFC822Name://IA5String
   337 					{
   338 					const CX509RFC822Name* name = CX509RFC822Name::NewLC(gN->Data());
   339 					if (NameIsPresent(*name, *(iState.iExcludedRFC822Subtrees)))
   340 						{
   341 						iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   342 						}
   343 					if ((iState.iPermittedRFC822Subtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedRFC822Subtrees)))))
   344 						{
   345 						iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   346 						}
   347 					CleanupStack::PopAndDestroy();
   348 					}
   349 					break;
   350 				case EX509URI://IA5String
   351 					{
   352 					const CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN->Data());
   353 					const CX509DNSName& domain = name->Host();
   354 					if (NameIsPresent(domain, *(iState.iExcludedDNSNameSubtrees)))
   355 						{
   356 						iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   357 						}
   358 					if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(domain, *(iState.iPermittedDNSNameSubtrees)))))
   359 						{
   360 						iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   361 						}
   362 					CleanupStack::PopAndDestroy();
   363 					}
   364 					break;
   365 				case EX509DNSName://IA5String
   366 					{
   367 					const CX509DNSName* name = CX509DNSName::NewLC(gN->Data());
   368 					if (NameIsPresent(*name, *(iState.iExcludedDNSNameSubtrees)))
   369 						{
   370 						iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   371 						}
   372 					if ((iState.iPermittedDNSNameSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedDNSNameSubtrees)))))
   373 						{
   374 						iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   375 						}
   376 					CleanupStack::PopAndDestroy();
   377 					}
   378 					break;
   379 				case EX509IPAddress://octet string
   380 					{
   381 					const CX509IPAddress* name = CX509IPAddress::NewLC(gN->Data());
   382 					if (NameIsPresent(*name, *(iState.iExcludedIPAddressSubtrees)))
   383 						{
   384 						iResult.SetErrorAndLeaveL(ENameIsExcluded, iState.iPos);
   385 						}
   386 					if ((iState.iPermittedIPAddressSubtrees->Count() > 0) && (!(NameIsPresent(*name, *(iState.iPermittedIPAddressSubtrees)))))
   387 						{
   388 						iResult.SetErrorAndLeaveL(ENameNotPermitted, iState.iPos);
   389 						}
   390 					CleanupStack::PopAndDestroy();
   391 					}
   392 					break;
   393 				}
   394 			}//end of for loop
   395 		//we've handled this now, so can remove it from the critical list
   396 		Remove(*(iState.iCriticalExts), KSubjectAltName);
   397 		CleanupStack::PopAndDestroy();//altNameExt
   398 		}//end of if(ext)
   399 	}
   400 
   401 void TPKIXNameConstraint::UpdateNameConstraintsL(const CX509Certificate& aCert)
   402 	{
   403 	const CX509CertExtension* ext = aCert.Extension(KNameConstraints);
   404 	if (ext)
   405 		{
   406 		CX509NameConstraintsExt* nameCons = CX509NameConstraintsExt::NewLC(ext->Data());
   407 		const CArrayPtrFlat<CX509GeneralSubtree>& excSubtrees = nameCons->ExcludedSubtrees();
   408 		TInt count = excSubtrees.Count();
   409 		for (TInt i = 0; i < count; i++)
   410 			{
   411 			const CX509GeneralSubtree* subtree = excSubtrees.At(i);
   412 			const CX509GeneralName& gN = subtree->Name();
   413 			switch (gN.Tag())
   414 				{
   415 				case EX509DirectoryName://X500DN
   416 					{
   417 					CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
   418 					iState.iExcludedDNSubtrees->AppendL(name);
   419 					CleanupStack::Pop();
   420 					}			
   421 					break;
   422 				case EX509RFC822Name://IA5String
   423 					{
   424 					CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
   425 					iState.iExcludedRFC822Subtrees->AppendL(name);
   426 					CleanupStack::Pop();
   427 					}
   428 					break;
   429 				case EX509URI://IA5String
   430 					{
   431 					CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
   432 					CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
   433 					iState.iExcludedDNSNameSubtrees->AppendL(domain);
   434 					CleanupStack::Pop();
   435 					CleanupStack::PopAndDestroy();
   436 					}
   437 					break;
   438 				case EX509DNSName://IA5String
   439 					{
   440 					CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
   441 					iState.iExcludedDNSNameSubtrees->AppendL(name);
   442 					CleanupStack::Pop();
   443 					}
   444 					break;
   445 				case EX509IPAddress://octet string
   446 					{
   447 					CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
   448 					iState.iExcludedIPAddressSubtrees->AppendL(name);
   449 					CleanupStack::Pop();
   450 					}	
   451 					break;
   452 				default:
   453 					{
   454 					User::Leave(KErrNotSupported);
   455 					}
   456 					break;
   457 				}
   458 			}//end of for loop
   459 		const CArrayPtrFlat<CX509GeneralSubtree>& perSubtrees = nameCons->PermittedSubtrees();
   460 		count = perSubtrees.Count();
   461 		for (TInt j = 0; j < count; j++)
   462 			{
   463 			const CX509GeneralSubtree* subtree = perSubtrees.At(j);
   464 			const CX509GeneralName& gN = subtree->Name();
   465 			switch (gN.Tag())
   466 				{
   467 				case EX509DirectoryName://X500DN
   468 					{
   469 					CX500DistinguishedName* name = CX500DistinguishedName::NewLC(gN.Data());
   470 					iState.iPermittedDNSubtrees->AppendL(name);
   471 					CleanupStack::Pop();
   472 					}			
   473 					break;
   474 				case EX509RFC822Name://IA5String
   475 					{
   476 					CX509RFC822Name* name = CX509RFC822Name::NewLC(gN.Data());
   477 					iState.iPermittedRFC822Subtrees->AppendL(name);
   478 					CleanupStack::Pop();
   479 					}
   480 					break;
   481 				case EX509URI://IA5String
   482 					{
   483 					CX509IPBasedURI* name = CX509IPBasedURI::NewLC(gN.Data());
   484 					CX509DNSName* domain = CX509DNSName::NewLC(name->Host());
   485 					iState.iPermittedDNSNameSubtrees->AppendL(domain);
   486 					CleanupStack::Pop();
   487 					CleanupStack::PopAndDestroy();
   488 					}
   489 					break;
   490 				case EX509DNSName://IA5String
   491 					{
   492 					CX509DNSName* name = CX509DNSName::NewLC(gN.Data());
   493 					iState.iPermittedDNSNameSubtrees->AppendL(name);
   494 					CleanupStack::Pop();
   495 					}
   496 					break;
   497 				case EX509IPAddress://octet string
   498 					{
   499 					CX509IPSubnetMask* name = CX509IPSubnetMask::NewLC(gN.Data());
   500 					iState.iPermittedIPAddressSubtrees->AppendL(name);
   501 					CleanupStack::Pop();
   502 					}
   503 					break;
   504 				default:
   505 					{
   506 					User::Leave(KErrNotSupported);
   507 					}
   508 					break;
   509 				}
   510 			}//end of for loop
   511 		CleanupStack::PopAndDestroy();//nameConsExt
   512 		//we've handled this now, so can remove it from the critical list
   513 		Remove(*(iState.iCriticalExts), KNameConstraints);
   514 		}//end of if(ext)
   515 	}
   516 
   517 
   518 //private functions
   519 TBool TPKIXNameConstraint::NameIsPresentL(	const CX500DistinguishedName& aSubject,
   520 											const CArrayPtrFlat<CX500DistinguishedName>& aSubtrees)
   521 	{
   522 	TInt count = aSubtrees.Count();
   523 	for (TInt i = 0; i < count; i++)
   524 		{
   525 		const CX500DistinguishedName* excluded = aSubtrees.At(i);
   526 		if (aSubject.IsWithinSubtreeL(*excluded))
   527 			{
   528 			return ETrue;
   529 			}
   530 		}
   531 	return EFalse;
   532 	}
   533 
   534 TBool TPKIXNameConstraint::NameIsPresent(	const CX509DomainName& aSubject,
   535 											const CArrayPtrFlat<CX509DomainName>& aSubtrees)
   536 	{
   537 	TInt count = aSubtrees.Count();
   538 	for (TInt i = 0; i < count; i++)
   539 		{
   540 		const CX509DomainName* excluded = aSubtrees.At(i);
   541 		if (aSubject.IsWithinSubtree(*excluded))
   542 			{
   543 			return ETrue;
   544 			}
   545 		}
   546 	return EFalse;
   547 	}	
   548 
   549 TBool TPKIXNameConstraint::NameIsPresent(	const CX509IPAddress& aSubject,
   550 											const CArrayPtrFlat<CX509IPSubnetMask>& aSubtrees)
   551 	{
   552 	TInt count = aSubtrees.Count();
   553 	for (TInt i = 0; i < count; i++)
   554 		{
   555 		const CX509IPSubnetMask* excluded = aSubtrees.At(i);
   556 		if (aSubject.IsWithinSubtree(*excluded))
   557 			{
   558 			return ETrue;
   559 			}
   560 		}
   561 	return EFalse;
   562 	}
   563 
   564 //basic constraint
   565 TPKIXBasicConstraint::TPKIXBasicConstraint(	CPKIXValidationState& aState, 
   566 											CPKIXValidationResultBase& aResult)
   567 	:TPKIXConstraint(aState, aResult)
   568 	{
   569 	}
   570 
   571 void TPKIXBasicConstraint::CheckCertSubjectTypeL(const CX509Certificate& aCert)
   572 	{
   573 	TBool markedAsCA = EFalse;
   574 	TBool actsAsCA = iState.iPos > 0;
   575 	const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
   576 	if (ext)
   577 		{
   578 		CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
   579 		markedAsCA = basic->IsCA();
   580 		CleanupStack::PopAndDestroy();
   581 		}
   582 	if (actsAsCA && (!markedAsCA))
   583 		{
   584 		iResult.SetErrorAndLeaveL(ENotCACert, iState.iPos);
   585 		}
   586 	}
   587 
   588 void TPKIXBasicConstraint::UpdatePathLengthConstraintsL(const CX509Certificate& aCert)
   589 	{
   590 	const CX509CertExtension* ext = aCert.Extension(KBasicConstraints);
   591 	if (ext)
   592 		{
   593 		CX509BasicConstraintsExt* basic = CX509BasicConstraintsExt::NewLC(ext->Data());
   594 		TInt pathLength = basic->MaxChainLength();
   595 		if (pathLength < 0)
   596 			{
   597 			iResult.SetErrorAndLeaveL(ENegativePathLengthSpecified, iState.iPos);
   598 			}
   599 		if (iState.iPos > pathLength)
   600 			{
   601 			iState.iMaxPathLength = pathLength + 1;
   602 			}
   603 		Remove(*(iState.iCriticalExts), KBasicConstraints);
   604 		CleanupStack::PopAndDestroy();//basic
   605 		}
   606 	}
   607 
   608 //key usage constraint
   609 TPKIXKeyUsageConstraint::TPKIXKeyUsageConstraint(	CPKIXValidationState& aState, 
   610 											CPKIXValidationResultBase& aResult)
   611 	:TPKIXConstraint(aState, aResult)
   612 	{
   613 	}
   614 
   615 void TPKIXKeyUsageConstraint::CheckKeyUsageL(const CX509Certificate& aCert)
   616 	{
   617 	//if key usage is critical and this is a CA cert, the keyCertSign bit must be set
   618 	const CX509CertExtension* ext = aCert.Extension(KKeyUsage);
   619 	if (ext)
   620 			{
   621 			CX509KeyUsageExt* keyUsage = CX509KeyUsageExt::NewLC(ext->Data());
   622 			if ( (iState.iPos > 0) && (!(keyUsage->IsSet(EX509KeyCertSign))))
   623 				{
   624 				iResult.SetErrorAndLeaveL(EBadKeyUsage, iState.iPos);
   625 				}
   626 			CleanupStack::PopAndDestroy();
   627 			//we've processed this critical ext, so remove it
   628 			Remove(*(iState.iCriticalExts), KKeyUsage);
   629 			}
   630 	}