|
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 "pkixcertchainao.h" |
|
20 #include "pkixCons.h" |
|
21 #include <x509keys.h> |
|
22 #include <pkixcertchain.h> |
|
23 #include <x509constraintext.h> |
|
24 |
|
25 CPKIXCertChainAO* CPKIXCertChainAO::NewL(MCertStore& aCertStore, |
|
26 CPKIXCertChainBase &aPKIXCertChain, |
|
27 const RPointerArray<CX509Certificate>& aRootCerts) |
|
28 { |
|
29 CPKIXCertChainAO* self = new(ELeave) CPKIXCertChainAO(aCertStore, aPKIXCertChain); |
|
30 CleanupStack::PushL(self); |
|
31 self->ConstructL(aRootCerts); |
|
32 CleanupStack::Pop(self); |
|
33 return self; |
|
34 } |
|
35 |
|
36 CPKIXCertChainAO* CPKIXCertChainAO::NewL(MCertStore& aCertStore, |
|
37 CPKIXCertChainBase &aPKIXCertChain, |
|
38 const TUid aClient) |
|
39 { |
|
40 return new(ELeave) CPKIXCertChainAO(aCertStore, aPKIXCertChain, aClient); |
|
41 } |
|
42 |
|
43 CPKIXCertChainAO::~CPKIXCertChainAO() |
|
44 { |
|
45 Cancel(); |
|
46 |
|
47 delete iRoots; |
|
48 delete iBuilder; |
|
49 delete iCertsFromStoreRoots; |
|
50 } |
|
51 |
|
52 CPKIXCertChainAO::CPKIXCertChainAO(MCertStore& aCertStore, |
|
53 CPKIXCertChainBase &aPKIXCertChain) |
|
54 : CActive(EPriorityNormal), iCertStore(&aCertStore), iPKIXCertChain(aPKIXCertChain) |
|
55 { |
|
56 CActiveScheduler::Add(this); |
|
57 } |
|
58 |
|
59 CPKIXCertChainAO::CPKIXCertChainAO(MCertStore& aCertStore, |
|
60 CPKIXCertChainBase &aPKIXCertChain, |
|
61 const TUid aClient) |
|
62 : CActive(EPriorityNormal), iCertStore(&aCertStore), |
|
63 iPKIXCertChain(aPKIXCertChain), iClient(aClient) |
|
64 { |
|
65 CActiveScheduler::Add(this); |
|
66 } |
|
67 |
|
68 void CPKIXCertChainAO::ConstructL(const RPointerArray<CX509Certificate>& aRootCerts) |
|
69 { |
|
70 CPKIXCertsFromClient* roots = CPKIXCertsFromClient::NewLC(aRootCerts); |
|
71 iRoots = CPKIXChainBuilder::NewL(); |
|
72 iRoots->AddSourceL(roots); |
|
73 CleanupStack::Pop(roots); |
|
74 } |
|
75 |
|
76 void CPKIXCertChainAO::RunL() |
|
77 { |
|
78 User::LeaveIfError(iStatus.Int()); |
|
79 |
|
80 switch (iState) |
|
81 { |
|
82 case EAddRoots: |
|
83 HandleEAddRootsL(); |
|
84 break; |
|
85 |
|
86 case ERootsInitialized: |
|
87 HandleERootsInitializedL(); |
|
88 break; |
|
89 |
|
90 case EBuildChainStart: |
|
91 HandleEBuildChainStartL(); |
|
92 break; |
|
93 |
|
94 case EBuildChainAddCandidateEnd: |
|
95 HandleEBuildChainAddCandidateEndL(); |
|
96 break; |
|
97 |
|
98 case EBuildChainCertsFromStoreBegin: |
|
99 HandleEBuildChainCertsFromStoreBeginL(); |
|
100 break; |
|
101 |
|
102 case EBuildChainCertsFromStoreEnd: |
|
103 HandleEBuildChainCertsFromStoreEndL(); |
|
104 break; |
|
105 |
|
106 case EAddCandidateIntermediateCertsEnd: |
|
107 HandleEAddCandidateIntermediateCertsEndL(); |
|
108 break; |
|
109 |
|
110 case EValidateEnd: |
|
111 HandleEValidateEndL(); |
|
112 break; |
|
113 |
|
114 default: |
|
115 User::Panic(_L("CPKIXCertChainAO"), 1); |
|
116 break; |
|
117 } |
|
118 } |
|
119 |
|
120 TInt CPKIXCertChainAO::RunError(TInt aError) |
|
121 { |
|
122 iPKIXCertChain.RemoveLastCerts(iNumberOfAddedCertificates); |
|
123 iNumberOfAddedCertificates = 0; |
|
124 |
|
125 delete iRoots; |
|
126 iRoots = 0; |
|
127 |
|
128 delete iBuilder; |
|
129 iBuilder = 0; |
|
130 delete iCertsFromStoreRoots; |
|
131 iCertsFromStoreRoots = 0; |
|
132 |
|
133 iValidationResult->RemovePolicies(); |
|
134 |
|
135 User::RequestComplete(iOriginalRequestStatus, aError); |
|
136 return KErrNone; |
|
137 } |
|
138 |
|
139 /** |
|
140 * Creates a list of all the certificates retrieved from the store based on the filter passed. |
|
141 */ |
|
142 |
|
143 void CPKIXCertChainAO::HandleEAddRootsL() |
|
144 { |
|
145 __ASSERT_DEBUG(!iCertsFromStoreRoots, User::Panic(_L("CPKICCertChainAO"), 1)); |
|
146 iCertsFromStoreRoots = CPKIXCertsFromStore::NewL(*iCertStore, iClient); |
|
147 iCertsFromStoreRoots->Initialize(iStatus); |
|
148 iState = ERootsInitialized; |
|
149 SetActive(); |
|
150 } |
|
151 |
|
152 /** |
|
153 * Adds the list of certificates retrieved from the store, iRoots (CPKIXChainBuilder) |
|
154 * maintains a templatized list of all the certificates in MPKIXCertSource format. |
|
155 */ |
|
156 |
|
157 void CPKIXCertChainAO::HandleERootsInitializedL() |
|
158 { |
|
159 iRoots->AddSourceL(iCertsFromStoreRoots); |
|
160 // Ownership has been passed to iRoots |
|
161 iCertsFromStoreRoots = 0; |
|
162 iState = EBuildChainStart; |
|
163 TRequestStatus* status = &iStatus; |
|
164 User::RequestComplete(status, KErrNone); |
|
165 SetActive(); |
|
166 } |
|
167 |
|
168 void CPKIXCertChainAO::HandleEBuildChainStartL() |
|
169 { |
|
170 if ( false == iPKIXCertChain.ChainHasRoot()) |
|
171 { |
|
172 if (iPKIXCertChain.Chain().Count() == 0) |
|
173 { |
|
174 iState = EValidateEnd; |
|
175 TRequestStatus* status = &iStatus; |
|
176 User::RequestComplete(status, KErrNone); |
|
177 } |
|
178 else |
|
179 { |
|
180 //1) look for an issuer that's a root |
|
181 iRoots->AddIssuer(iNumberOfAddedCertificates, iAddIssuerResult, iPKIXCertChain.Chain(), iStatus); |
|
182 iState = EBuildChainAddCandidateEnd; |
|
183 } |
|
184 } |
|
185 else |
|
186 { |
|
187 // This is the correct state as at this point the chain of certificate has been build upto a |
|
188 // root certificate. |
|
189 iState = EValidateEnd; |
|
190 TRequestStatus* status = &iStatus; |
|
191 User::RequestComplete(status, KErrNone); |
|
192 } |
|
193 SetActive(); |
|
194 } |
|
195 |
|
196 void CPKIXCertChainAO::HandleEBuildChainAddCandidateEndL() |
|
197 { |
|
198 if (iAddIssuerResult) |
|
199 { |
|
200 iPKIXCertChain.SetChainHasRoot(ETrue); |
|
201 iState = EValidateEnd; |
|
202 } |
|
203 else |
|
204 { |
|
205 //2) look for a non-root issuer in intermediate certs |
|
206 iBuilder = CPKIXChainBuilder::NewL(); |
|
207 |
|
208 CPKIXCertsFromClient* serverCerts = CPKIXCertsFromClient::NewLC(iPKIXCertChain.IntermediateCerts()); |
|
209 iBuilder->AddSourceL(serverCerts); |
|
210 CleanupStack::Pop(serverCerts); |
|
211 |
|
212 iState = EBuildChainCertsFromStoreBegin; |
|
213 } |
|
214 |
|
215 TRequestStatus* status = &iStatus; |
|
216 User::RequestComplete(status, KErrNone); |
|
217 SetActive(); |
|
218 } |
|
219 |
|
220 void CPKIXCertChainAO::HandleEBuildChainCertsFromStoreBeginL() |
|
221 { |
|
222 //3) look for a non-root issuer in the store |
|
223 iCertsFromStoreRoots = CPKIXCertsFromStore::NewL(*iCertStore); |
|
224 iCertsFromStoreRoots->Initialize(iStatus); |
|
225 iState = EBuildChainCertsFromStoreEnd; |
|
226 SetActive(); |
|
227 } |
|
228 |
|
229 void CPKIXCertChainAO::HandleEBuildChainCertsFromStoreEndL() |
|
230 { |
|
231 iBuilder->AddSourceL(iCertsFromStoreRoots); |
|
232 iCertsFromStoreRoots = 0; |
|
233 |
|
234 iBuilder->AddIssuer(iNumberOfAddedCertificates, iAddIssuerResult, iPKIXCertChain.Chain(), iStatus); |
|
235 iState = EAddCandidateIntermediateCertsEnd; |
|
236 SetActive(); |
|
237 } |
|
238 |
|
239 void CPKIXCertChainAO::HandleEAddCandidateIntermediateCertsEndL() |
|
240 { |
|
241 if (iAddIssuerResult) |
|
242 { |
|
243 // cert is a pointer to something we don't own |
|
244 CX509Certificate* cert = iPKIXCertChain.Chain().At(iPKIXCertChain.Chain().Count() - 1); |
|
245 |
|
246 /* If the issuer is not a self signed certificate then it cannot be trusted anchor for the chain |
|
247 * validation process, this means that we restart the certification validation process. |
|
248 */ |
|
249 |
|
250 if (!(cert->IsSelfSignedL())) |
|
251 { |
|
252 iState = EBuildChainStart; |
|
253 } |
|
254 else |
|
255 { |
|
256 iState = EValidateEnd; |
|
257 } |
|
258 } |
|
259 else |
|
260 { |
|
261 iState = EValidateEnd; |
|
262 } |
|
263 |
|
264 delete iBuilder; |
|
265 iBuilder = 0; |
|
266 |
|
267 TRequestStatus* status = &iStatus; |
|
268 User::RequestComplete(status, KErrNone); |
|
269 SetActive(); |
|
270 } |
|
271 |
|
272 void CPKIXCertChainAO::HandleEValidateEndL() |
|
273 { |
|
274 InitParamsL(); |
|
275 |
|
276 __ASSERT_DEBUG(iValidationResult, User::Panic(_L("CPKICCertChainAO"), 1)); |
|
277 DoValidateL(*iValidationResult, iValidationTime, iInitialPolicies); |
|
278 |
|
279 User::RequestComplete(iOriginalRequestStatus, KErrNone); |
|
280 } |
|
281 |
|
282 void CPKIXCertChainAO::DoCancel() |
|
283 { |
|
284 delete iRoots; |
|
285 iRoots = 0; |
|
286 |
|
287 delete iBuilder; |
|
288 iBuilder = 0; |
|
289 |
|
290 delete iCertsFromStoreRoots; |
|
291 iCertsFromStoreRoots = 0; |
|
292 |
|
293 User::RequestComplete(iOriginalRequestStatus, KErrCancel); |
|
294 } |
|
295 |
|
296 void CPKIXCertChainAO::ValidateL(CPKIXValidationResultBase& aValidationResult, |
|
297 const TTime& aValidationTime, |
|
298 const CArrayPtr<HBufC>* aInitialPolicies, |
|
299 TRequestStatus& aStatus) |
|
300 { |
|
301 aValidationResult.Reset(); |
|
302 iValidationResult = &aValidationResult; |
|
303 iValidationTime = aValidationTime; |
|
304 iInitialPolicies = aInitialPolicies; |
|
305 iOriginalRequestStatus = &aStatus; |
|
306 iNumberOfAddedCertificates = 0; |
|
307 |
|
308 __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CPKICCertChainAO"), 1)); |
|
309 |
|
310 if (!iRoots) |
|
311 { |
|
312 // If iRoots is 0, it means that the caller gave a uid and that |
|
313 // we must retrieve the trusted certificates from the different |
|
314 // stores |
|
315 iRoots = CPKIXChainBuilder::NewL(); |
|
316 iState = EAddRoots; |
|
317 } |
|
318 else |
|
319 { |
|
320 // The caller gave a set of certificates it trusts, |
|
321 // so we don't have to retrieve anything from the stores |
|
322 iState = EBuildChainStart; |
|
323 } |
|
324 |
|
325 aStatus = KRequestPending; |
|
326 TRequestStatus *status = &iStatus; |
|
327 User::RequestComplete(status, KErrNone); |
|
328 SetActive(); |
|
329 } |
|
330 |
|
331 void CPKIXCertChainAO::CancelValidate() |
|
332 { |
|
333 Cancel(); |
|
334 } |
|
335 |
|
336 void CPKIXCertChainAO::InitParamsL() |
|
337 /* |
|
338 this function initialises signing key parameters for the certificates |
|
339 -only DSA needs these at present |
|
340 -we get the signing key, from the spki of the issuer |
|
341 -if it's dsa, we look for params here |
|
342 -if we find them we initialise the cert with them |
|
343 -otherwise, we look in the issuer's issuer |
|
344 -if we don't find them there we give up. |
|
345 */ |
|
346 { |
|
347 |
|
348 // If the root is DSA signed, set its parameters |
|
349 |
|
350 TInt count = iPKIXCertChain.Chain().Count(); |
|
351 |
|
352 CX509Certificate* current = iPKIXCertChain.Chain().At(count-1); |
|
353 TAlgorithmId signingAlgorithm = current->SigningAlgorithm().AsymmetricAlgorithm().Algorithm(); |
|
354 |
|
355 if (signingAlgorithm == EDSA) |
|
356 { |
|
357 |
|
358 const CSubjectPublicKeyInfo& key = current->PublicKey(); |
|
359 SetParamsL(*current, key.EncodedParams()); |
|
360 |
|
361 } |
|
362 |
|
363 // Also the rest of the chain |
|
364 |
|
365 for (TInt i = count - 2; i >= 0; i--) |
|
366 { |
|
367 |
|
368 current = iPKIXCertChain.Chain().At(i); |
|
369 TAlgorithmId signingAlgorithm = current->SigningAlgorithm().AsymmetricAlgorithm().Algorithm(); |
|
370 |
|
371 if (signingAlgorithm == EDSA) |
|
372 { |
|
373 |
|
374 // Look down the chain for parameters |
|
375 |
|
376 for (TInt j = i+1; j < count; j++) |
|
377 { |
|
378 |
|
379 CX509Certificate* issuer = iPKIXCertChain.Chain().At(j); |
|
380 const CSubjectPublicKeyInfo& key = issuer->PublicKey(); |
|
381 if (key.EncodedParams() != KNullDesC8 && key.AlgorithmId() == EDSA) |
|
382 { |
|
383 SetParamsL(*current, key.EncodedParams()); |
|
384 break; |
|
385 } |
|
386 |
|
387 } |
|
388 |
|
389 } |
|
390 |
|
391 } |
|
392 } |
|
393 |
|
394 void CPKIXCertChainAO::SetParamsL(CX509Certificate& aCert, const TPtrC8& aEncodedParams) |
|
395 { |
|
396 TX509KeyFactory factory; |
|
397 CDSAParameters* theDSAParams = factory.DSAParametersL(aEncodedParams); |
|
398 CleanupStack::PushL(theDSAParams); |
|
399 |
|
400 CSigningKeyParameters* params = CSigningKeyParameters::NewLC(); |
|
401 params->SetDSAParamsL(*theDSAParams); |
|
402 |
|
403 aCert.SetParametersL(*params); |
|
404 |
|
405 CleanupStack::PopAndDestroy(2, theDSAParams); |
|
406 } |
|
407 |
|
408 void CPKIXCertChainAO::DoValidateL(CPKIXValidationResultBase& aValidationResult, |
|
409 const TTime& aValidationTime, |
|
410 const CArrayPtr<HBufC>* aInitialPolicies) |
|
411 { |
|
412 if (!iPKIXCertChain.ChainHasRoot()) |
|
413 { |
|
414 aValidationResult.SetError(EChainHasNoRoot, 0); |
|
415 } |
|
416 else |
|
417 { |
|
418 CPKIXValidationState* state = CPKIXValidationState::NewLC(aValidationTime, iPKIXCertChain.Chain().Count(), aInitialPolicies); |
|
419 TRAPD(err, ProcessCertsL(*state, aValidationResult)); |
|
420 //a leave here means either: |
|
421 // -a validation error, in which case we've set the error field in result, or |
|
422 // -some other error (e.g. OOM) in which case error is still EChainHasNoRoot |
|
423 if ((err != KErrNone) && ((aValidationResult.Error().iReason) == EChainHasNoRoot)) |
|
424 //then we left with a non-validation-related error, so leave again... |
|
425 { |
|
426 User::Leave(err); |
|
427 } |
|
428 CleanupStack::PopAndDestroy(state); |
|
429 } |
|
430 } |
|
431 |
|
432 // ProcessCertsL: This function validates a complete certificate |
|
433 // chain. If an error occurs in this function the function |
|
434 // SetErrorAndLeaveL must be called. |
|
435 // |
|
436 // Note Do not use SetErrorAndLeaveL with EChainHasNoRoot (see TRAP code in |
|
437 // CPKIXCertChainAO::DoValidateL ) |
|
438 void CPKIXCertChainAO::ProcessCertsL(CPKIXValidationState& aState, |
|
439 CPKIXValidationResultBase& aResult) const |
|
440 { |
|
441 TPKIXPolicyConstraint policy(aState, aResult); |
|
442 TPKIXNameConstraint name(aState, aResult); |
|
443 TPKIXBasicConstraint basic(aState, aResult); |
|
444 TPKIXKeyUsageConstraint keyUsage(aState, aResult); |
|
445 for (; aState.iPos >= 0; aState.iPos--) |
|
446 { |
|
447 aState.iMaxPathLength--; |
|
448 if (aState.iMaxPathLength < aState.iPos) |
|
449 { |
|
450 aResult.SetErrorAndLeaveL(EPathTooLong, aState.iPos); |
|
451 } |
|
452 const CX509Certificate* current = iPKIXCertChain.Chain().At(aState.iPos); |
|
453 CCertificateValidationWarnings* certWarnings = CCertificateValidationWarnings::NewLC(aState.iPos); |
|
454 aResult.AppendCertificateValidationObjectL(*certWarnings); |
|
455 CleanupStack::Pop(certWarnings); |
|
456 CriticalExtsL(aState, *current); |
|
457 CheckCriticalExtsL(aState, aResult); |
|
458 CheckSignatureAndNameL(*current, aState, aResult); |
|
459 //!!!!NO!!checks for revocation at this time!! |
|
460 |
|
461 if (!(current->ValidityPeriod().Valid(aState.iValidationTime))) |
|
462 { |
|
463 //validity period invalid, now check how to report this |
|
464 if (iPKIXCertChain.ValidityPeriodCheckFatal()) |
|
465 { |
|
466 aResult.SetErrorAndLeaveL(EDateOutOfRange, aState.iPos); |
|
467 } |
|
468 else |
|
469 { |
|
470 aResult.AppendWarningL(TValidationStatus(EDateOutOfRange, aState.iPos)); |
|
471 } |
|
472 } |
|
473 |
|
474 policy.CheckCertPoliciesL(*current); |
|
475 name.CheckNameConstraintsL(*current); |
|
476 keyUsage.CheckKeyUsageL(*current); |
|
477 if (aState.iPos < (iPKIXCertChain.Chain().Count() - 1)) |
|
478 { |
|
479 basic.CheckCertSubjectTypeL(*current); |
|
480 } |
|
481 basic.UpdatePathLengthConstraintsL(*current); |
|
482 name.UpdateNameConstraintsL(*current); |
|
483 policy.UpdatePolicyConstraintsL(*current); |
|
484 aState.iCriticalExts->Reset(); |
|
485 } |
|
486 policy.FinishPolicyCheckL(); |
|
487 //*copy* all policies from aState.iAuthorityConstrainedPolicies into aResult.iPolicies |
|
488 TInt policyCount = aState.iAuthorityConstrainedPolicies->Count(); |
|
489 for (TInt i = 0; i < policyCount; i ++) |
|
490 { |
|
491 CX509CertPolicyInfo* policyInfo = CX509CertPolicyInfo::NewLC(*(aState.iAuthorityConstrainedPolicies->At(i))); |
|
492 aResult.AppendPolicyL(*policyInfo); |
|
493 CleanupStack::Pop(policyInfo); |
|
494 } |
|
495 |
|
496 aResult.SetError(EValidatedOK, 0); |
|
497 } |
|
498 |
|
499 void CPKIXCertChainAO::CriticalExtsL(CPKIXValidationState& aState, |
|
500 const CX509Certificate& aCert) const |
|
501 { |
|
502 const CArrayPtrFlat<CX509CertExtension>& exts = aCert.Extensions(); |
|
503 TInt count = exts.Count(); |
|
504 for (TInt i = 0; i < count; i++) |
|
505 { |
|
506 CX509CertExtension* ext = exts.At(i); |
|
507 if (ext->Critical()) |
|
508 { |
|
509 aState.iCriticalExts->AppendL(ext); |
|
510 } |
|
511 } |
|
512 } |
|
513 |
|
514 void CPKIXCertChainAO::CheckSignatureAndNameL(const CX509Certificate& aCert, CPKIXValidationState& aState, |
|
515 CPKIXValidationResultBase& aResult) const |
|
516 { |
|
517 TInt issuerPos = aState.iPos + 1; |
|
518 if (issuerPos == iPKIXCertChain.Chain().Count()) |
|
519 //then it's the root |
|
520 { |
|
521 if (aCert.IssuerName().ExactMatchL(aCert.SubjectName())) |
|
522 //then it claims to be self signed, sig must verify |
|
523 { |
|
524 if (!(aCert.VerifySignatureL(aCert.PublicKey().KeyData()))) |
|
525 { |
|
526 aResult.SetErrorAndLeaveL(ESignatureInvalid, aState.iPos); |
|
527 } |
|
528 } |
|
529 else |
|
530 //we generate a warning |
|
531 { |
|
532 aResult.AppendWarningL(TValidationStatus(ERootCertNotSelfSigned, aState.iPos)); |
|
533 } |
|
534 } |
|
535 else |
|
536 //then it isn't the root: so names must chain & sigs must verify |
|
537 { |
|
538 const CX509Certificate* issuer = iPKIXCertChain.Chain().At(issuerPos); |
|
539 if (!(aCert.IssuerName().ExactMatchL(issuer->SubjectName()))) |
|
540 { |
|
541 aResult.SetErrorAndLeaveL(ENamesDontChain, aState.iPos); |
|
542 } |
|
543 if (!(aCert.VerifySignatureL(issuer->PublicKey().KeyData()))) |
|
544 { |
|
545 aResult.SetErrorAndLeaveL(ESignatureInvalid, aState.iPos); |
|
546 } |
|
547 } |
|
548 } |
|
549 |
|
550 void CPKIXCertChainAO::CheckCriticalExtsL(CPKIXValidationState& aState, CPKIXValidationResultBase& aResult) const |
|
551 { |
|
552 TBool foundUnrecognisedCritExt; |
|
553 |
|
554 // retrieve the supported list of critical extensions. If a critical extension is found whose OID matches an |
|
555 // element in this set then certificate validation shall treat this as a warning instead of an error. |
|
556 const RPointerArray<TDesC>& supportedCritExt = iPKIXCertChain.SupportedCriticalExtensions(); |
|
557 |
|
558 TInt count = aState.iCriticalExts->Count(); |
|
559 TInt supportedCount = supportedCritExt.Count(); |
|
560 for (TInt i = 0; i < count; i++) |
|
561 { |
|
562 foundUnrecognisedCritExt = ETrue; |
|
563 const CX509CertExtension* ext = aState.iCriticalExts->At(i); |
|
564 const TPtrC& extName = ext->Id(); |
|
565 |
|
566 for (TInt j = 0; j < supportedCount; ++j) |
|
567 { |
|
568 if (extName == *supportedCritExt[j]) |
|
569 { |
|
570 foundUnrecognisedCritExt = EFalse; |
|
571 HBufC* oid = extName.AllocLC(); |
|
572 aResult.AppendCriticalExtensionWarningL(*oid); |
|
573 CleanupStack::Pop(oid); |
|
574 break; |
|
575 } |
|
576 } |
|
577 |
|
578 if (extName == KExtendedKeyUsage) |
|
579 { |
|
580 aResult.AppendWarningL(TValidationStatus(ECriticalExtendedKeyUsage, aState.iPos)); |
|
581 } |
|
582 else if (extName == KPolicyMapping) |
|
583 { |
|
584 aResult.AppendWarningL(TValidationStatus(ECriticalPolicyMapping, aState.iPos)); |
|
585 } |
|
586 else if (extName == KInhibitAnyPolicy) |
|
587 { |
|
588 //ignore this in the same way |
|
589 } |
|
590 else if (extName == KDeviceIdListConstraint) |
|
591 { |
|
592 aResult.AppendWarningL(TValidationStatus(ECriticalDeviceId, aState.iPos)); |
|
593 } |
|
594 else if(extName == KSidListConstraint) |
|
595 { |
|
596 aResult.AppendWarningL(TValidationStatus(ECriticalSid, aState.iPos)); |
|
597 } |
|
598 else if(extName == KVidListConstraint) |
|
599 { |
|
600 aResult.AppendWarningL(TValidationStatus(ECriticalVid, aState.iPos)); |
|
601 } |
|
602 else if(extName == KCapabilitiesConstraint) |
|
603 { |
|
604 aResult.AppendWarningL(TValidationStatus(ECriticalCapabilities, aState.iPos)); |
|
605 } |
|
606 |
|
607 if (foundUnrecognisedCritExt) |
|
608 { |
|
609 aResult.SetErrorAndLeaveL(EUnrecognizedCriticalExtension, aState.iPos); |
|
610 } |
|
611 |
|
612 } |
|
613 } |