cryptoservices/certificateandkeymgmt/pkixcertbase/pkixcons.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     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 	}