|
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 } |