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