|
1 /* |
|
2 * Copyright (c) 2008-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 "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: IKEv2 specifig certificate reading related stuff |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <x500dn.h> |
|
19 #include <x509cert.h> |
|
20 #include <asn1dec.h> |
|
21 |
|
22 #include "ikev2pkiservice.h" |
|
23 #include "utlcrypto.h" |
|
24 #include "ikecert.h" |
|
25 #include "ikecaelem.h" |
|
26 #include "ikecalist.h" |
|
27 #include "ikedebug.h" |
|
28 #include "ikepolparser.h" |
|
29 #include "ikev2const.h" |
|
30 #include "ikecertconst.h" |
|
31 // |
|
32 // CIkePkiService Class |
|
33 // |
|
34 _LIT8(KEmptyString, ""); |
|
35 |
|
36 |
|
37 const TInt KDefaultCertificateBufferSize = 2048; |
|
38 |
|
39 // |
|
40 // Certificate field indicators for GetCertificateFieldDERL() |
|
41 // |
|
42 |
|
43 #ifdef _DEBUG |
|
44 |
|
45 #define SET_ACTIVE DEBUG_LOG2(_L("CIkeV2PkiService::SetActive (0x%x) %d\n"), this, __LINE__);\ |
|
46 SetActive() |
|
47 |
|
48 #else |
|
49 |
|
50 #define SET_ACTIVE SetActive() |
|
51 |
|
52 #endif |
|
53 |
|
54 |
|
55 EXPORT_C CIkeV2PkiService* CIkeV2PkiService::NewL(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug) |
|
56 { |
|
57 CIkeV2PkiService* self = new (ELeave) CIkeV2PkiService(aObserver, aDebug); |
|
58 CleanupStack::PushL(self); |
|
59 self->ConstructL(); |
|
60 CleanupStack::Pop(self); |
|
61 return self; |
|
62 } |
|
63 |
|
64 |
|
65 CIkeV2PkiService::CIkeV2PkiService(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug) |
|
66 :CActive(EPriorityStandard), |
|
67 iObserver(aObserver), |
|
68 iDebug(aDebug), |
|
69 iState(EPkiServiceIdle), |
|
70 iCertPtr(NULL, 0) |
|
71 { |
|
72 CActiveScheduler::Add(this); |
|
73 } |
|
74 |
|
75 |
|
76 void CIkeV2PkiService::ConstructL() |
|
77 { |
|
78 User::LeaveIfError(iPkiService.Connect()); |
|
79 |
|
80 iTrustedCAList = new (ELeave) CIkeCaList(2); |
|
81 iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize); |
|
82 iCertPtr.Set(iReadCertificate->Des()); |
|
83 |
|
84 //The code assumes that these are not NULL. |
|
85 //Reallocated, when needed |
|
86 iSubjName = HBufC8::NewL(2); |
|
87 iRfc822Name = HBufC8::NewL(2); |
|
88 } |
|
89 |
|
90 |
|
91 EXPORT_C CIkeV2PkiService::~CIkeV2PkiService() |
|
92 { |
|
93 Cancel(); |
|
94 |
|
95 delete iUserCertificate; |
|
96 delete i1Certificate; |
|
97 delete i2Certificate; |
|
98 delete i2CertificateName; |
|
99 delete iTrustedCAList; |
|
100 |
|
101 iCasTrustedByPeer.Reset(); |
|
102 iCasTrustedByPeer.Close(); |
|
103 |
|
104 delete iCaName; |
|
105 delete iReadCertificate; |
|
106 delete iSubjName; |
|
107 delete iRfc822Name; |
|
108 |
|
109 iPkiService.Close(); |
|
110 } |
|
111 |
|
112 |
|
113 void CIkeV2PkiService::DoCancel() |
|
114 { |
|
115 |
|
116 iPkiService.CancelPendingOperation(); |
|
117 iState = EPkiServiceIdle; |
|
118 |
|
119 delete iCaName; |
|
120 iCaName = NULL; |
|
121 |
|
122 __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant()); |
|
123 iReadCertificate->Des().Zero(); |
|
124 |
|
125 |
|
126 __ASSERT_DEBUG(iSubjName != NULL, User::Invariant()); |
|
127 iSubjName->Des().Zero(); |
|
128 |
|
129 __ASSERT_DEBUG(iRfc822Name != NULL, User::Invariant()); |
|
130 iRfc822Name->Des().Zero(); |
|
131 |
|
132 |
|
133 iCasTrustedByPeer.Reset(); |
|
134 |
|
135 delete iIkeDataCAList; |
|
136 iIkeDataCAList = NULL; |
|
137 |
|
138 iTrustedCAList->ResetAndDestroy(); |
|
139 } |
|
140 |
|
141 |
|
142 TInt CIkeV2PkiService::RunError(TInt /*aError*/) |
|
143 { |
|
144 //Currently RunL may leave. |
|
145 //But we seem to ignore the possible leave. |
|
146 |
|
147 return KErrNone; |
|
148 } |
|
149 |
|
150 |
|
151 EXPORT_C void CIkeV2PkiService::ReadTrustedUserCertificateL() |
|
152 { |
|
153 __ASSERT_ALWAYS(!IsActive(), User::Invariant()); |
|
154 __ASSERT_ALWAYS(iTrustedCAList != NULL, User::Invariant()); |
|
155 __ASSERT_ALWAYS(iIkeData->iOwnCert.iOwnCertExists, User::Invariant()); |
|
156 |
|
157 iCasTrustedByPeer.Reset(); |
|
158 |
|
159 for (TInt i = 0; i < iTrustedCAList->Count(); ++i) |
|
160 { |
|
161 CIkeCaElem* caElem = (*iTrustedCAList)[i]; |
|
162 User::LeaveIfError(iCasTrustedByPeer.Append(caElem)); |
|
163 } |
|
164 |
|
165 |
|
166 iState = EReadingCertificate; |
|
167 |
|
168 if (iTrustedCAList->Count() > 0) |
|
169 { |
|
170 CIkeCaElem* CaElem = iCasTrustedByPeer[0]; |
|
171 HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); |
|
172 if (caName == NULL) |
|
173 { |
|
174 User::Leave(KErrArgument); |
|
175 } |
|
176 delete iCaName; |
|
177 iCaName = caName; |
|
178 |
|
179 ReadUserCertificateL(*iCaName, EFalse); |
|
180 } |
|
181 else |
|
182 { |
|
183 //No CA's found. |
|
184 //We can't read anything |
|
185 User::Leave(KErrNotFound); |
|
186 } |
|
187 } |
|
188 |
|
189 |
|
190 EXPORT_C TInt CIkeV2PkiService::Ikev2SignatureL(const TDesC8& aTrustedAuthority, |
|
191 const TOwnCertInfo& aOwnCertInfo, |
|
192 const TDesC8& aMsgOctets, |
|
193 TDes8& aSignature, TUint8 aAuthMeth) |
|
194 { |
|
195 __ASSERT_ALWAYS(!IsActive(), User::Invariant()); |
|
196 |
|
197 TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; |
|
198 TInt length = aOwnCertInfo.iSubjectDnSuffix.Length(); |
|
199 if ( length ) |
|
200 { |
|
201 delete iSubjName; |
|
202 iSubjName = NULL; |
|
203 iSubjName = HBufC8::NewL(length); |
|
204 iSubjName->Des().Copy(aOwnCertInfo.iSubjectDnSuffix); |
|
205 } |
|
206 else |
|
207 { |
|
208 iSubjName->Des().Zero(); |
|
209 } |
|
210 |
|
211 length = aOwnCertInfo.iRfc822NameFqdn.Length(); |
|
212 if ( length ) |
|
213 { |
|
214 delete iRfc822Name; |
|
215 iRfc822Name = NULL; |
|
216 iRfc822Name = HBufC8::NewL(length); |
|
217 iRfc822Name->Des().Copy(aOwnCertInfo.iRfc822NameFqdn); |
|
218 } |
|
219 else |
|
220 { |
|
221 iRfc822Name->Des().Zero(); |
|
222 } |
|
223 |
|
224 // |
|
225 // Build PKCS1v15 format signature (ASN1 encoded) for RSA and SHA1 for DSA |
|
226 // |
|
227 CUtlMessageDigest* digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); |
|
228 CleanupStack::PushL(digest); |
|
229 HBufC8* asn1EncodedHash =NULL; |
|
230 HBufC8* DSSHash = NULL; |
|
231 |
|
232 switch( aAuthMeth ) |
|
233 { |
|
234 case RSA_DIGITAL_SIGN: |
|
235 asn1EncodedHash = IkeCert::BuildPkcs1v15HashL(digest->Final(aMsgOctets)); |
|
236 User::LeaveIfNull(asn1EncodedHash); |
|
237 CleanupStack::PopAndDestroy(digest); |
|
238 CleanupStack::PushL(asn1EncodedHash); |
|
239 User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name, |
|
240 EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength, |
|
241 keyAlgorithm, *asn1EncodedHash, aSignature)); |
|
242 CleanupStack::PopAndDestroy(asn1EncodedHash); |
|
243 DEBUG_LOG(_L("Signing Auth data using RSA key.")); |
|
244 break; |
|
245 case DSS_DIGITAL_SIGN: |
|
246 DSSHash = HBufC8::New(20); |
|
247 DSSHash->Des().Append(digest->Final(aMsgOctets)); |
|
248 CleanupStack::PopAndDestroy(digest); |
|
249 CleanupStack::PushL(DSSHash); |
|
250 User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name, |
|
251 EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength, |
|
252 keyAlgorithm, *DSSHash, aSignature)); |
|
253 CleanupStack::PopAndDestroy(DSSHash); |
|
254 DEBUG_LOG(_L("Signing Auth data using DSA key.")); |
|
255 break; |
|
256 default: |
|
257 DEBUG_LOG1(_L("Authentication method %d not supported when using digital signatures."), aAuthMeth); |
|
258 User::Leave(KErrNotSupported); |
|
259 break; |
|
260 } |
|
261 |
|
262 return aSignature.Length(); |
|
263 } |
|
264 |
|
265 |
|
266 EXPORT_C const CIkeCaList& CIkeV2PkiService::CaList() const |
|
267 { |
|
268 return *iTrustedCAList; |
|
269 } |
|
270 |
|
271 |
|
272 EXPORT_C const TDesC8& CIkeV2PkiService::UserCertificateData() const |
|
273 { |
|
274 if (iUserCertificate != NULL) |
|
275 { |
|
276 return *iUserCertificate; |
|
277 } |
|
278 else |
|
279 { |
|
280 return KEmptyString; |
|
281 } |
|
282 } |
|
283 |
|
284 EXPORT_C const TDesC8& CIkeV2PkiService::I2CertificateData() const |
|
285 { |
|
286 if (i2Certificate != NULL) |
|
287 { |
|
288 return *i2Certificate; |
|
289 } |
|
290 else |
|
291 { |
|
292 return KEmptyString; |
|
293 } |
|
294 } |
|
295 |
|
296 EXPORT_C const TDesC8& CIkeV2PkiService::I1CertificateData() const |
|
297 { |
|
298 if (i1Certificate != NULL) |
|
299 { |
|
300 return *i1Certificate; |
|
301 } |
|
302 else |
|
303 { |
|
304 return KEmptyString; |
|
305 } |
|
306 } |
|
307 |
|
308 |
|
309 EXPORT_C const TDesC8& CIkeV2PkiService::TrustedCaName() const |
|
310 { |
|
311 if ( i2CertificateName != NULL ) |
|
312 { |
|
313 return *i2CertificateName; |
|
314 } |
|
315 if (iCaName != NULL) |
|
316 { |
|
317 return *iCaName; |
|
318 } |
|
319 else |
|
320 { |
|
321 return KEmptyString; |
|
322 } |
|
323 } |
|
324 |
|
325 |
|
326 void CIkeV2PkiService::ReadUserCertificateL(const TDesC8& aTrustedAuthority, TBool aGetCACert) |
|
327 { |
|
328 __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant()); |
|
329 // |
|
330 // Read certificate from PKI store using pkiserviceapi |
|
331 // |
|
332 TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; |
|
333 TPKICertificateOwnerType ownerType; |
|
334 TUint keySize = 0; |
|
335 |
|
336 if ( aGetCACert ) |
|
337 { |
|
338 ownerType = EPKICACertificate; |
|
339 |
|
340 //Init CA cert ident data. |
|
341 //aTrustedAuthority (issuer) checking for CA certs is not supported. |
|
342 //__ASSERT_ALWAYS(aTrustedAuthority.Length() == 0, User::Invariant()); |
|
343 if ( aTrustedAuthority.Length() == 0 ) |
|
344 { |
|
345 delete iSubjName; |
|
346 iSubjName = NULL; |
|
347 iSubjName = iCaName->AllocL(); |
|
348 iRfc822Name->Des().Zero(); |
|
349 } |
|
350 } |
|
351 else |
|
352 { |
|
353 ownerType = EPKIUserCertificate; |
|
354 TInt length = iIkeData->iOwnCert.iSubjectDnSuffix.Length(); |
|
355 if ( length ) |
|
356 { |
|
357 delete iSubjName; |
|
358 iSubjName = NULL; |
|
359 iSubjName = HBufC8::NewL(length); |
|
360 iSubjName->Des().Copy(iIkeData->iOwnCert.iSubjectDnSuffix); |
|
361 } |
|
362 else |
|
363 { |
|
364 iSubjName->Des().Zero(); |
|
365 } |
|
366 |
|
367 length = iIkeData->iOwnCert.iRfc822NameFqdn.Length(); |
|
368 if ( length ) |
|
369 { |
|
370 delete iRfc822Name; |
|
371 iRfc822Name = NULL; |
|
372 iRfc822Name = HBufC8::NewL(length); |
|
373 iRfc822Name->Des().Copy(iIkeData->iOwnCert.iRfc822NameFqdn); |
|
374 } |
|
375 else |
|
376 { |
|
377 iRfc822Name->Des().Zero(); |
|
378 } |
|
379 keySize = iIkeData->iOwnCert.iPrivateKeyLength; |
|
380 } |
|
381 iPkiService.ReadCertificateL(aTrustedAuthority, |
|
382 *iSubjName, *iRfc822Name, |
|
383 ownerType, keySize, |
|
384 keyAlgorithm, iCertPtr, |
|
385 &iResArray, iStatus); |
|
386 SET_ACTIVE; |
|
387 } |
|
388 |
|
389 |
|
390 void CIkeV2PkiService::CIkeV2PkiServiceApplUidArrayCleanup(TAny* any) |
|
391 { |
|
392 RArray<TUid>* applUidList = reinterpret_cast<RArray<TUid>*>(any); |
|
393 applUidList->Reset(); |
|
394 applUidList->Close(); |
|
395 delete applUidList; |
|
396 } |
|
397 |
|
398 |
|
399 void CIkeV2PkiService::RunL() |
|
400 { |
|
401 DEBUG_LOG1(_L("CIkeV2PkiService::RunL: Status %d"), iStatus.Int()); |
|
402 |
|
403 // |
|
404 // A PKI service operation completed. Take actions according to |
|
405 // iOperation code |
|
406 // |
|
407 |
|
408 TInt err = KErrNone; |
|
409 |
|
410 TInt status = iStatus.Int(); |
|
411 |
|
412 iPkiService.Finalize(iResArray); |
|
413 iResArray = NULL; |
|
414 |
|
415 |
|
416 switch ( iState ) |
|
417 { |
|
418 case EBuildingCaList: |
|
419 TRAP(err, BuildingCaListRunL()); |
|
420 break; |
|
421 case EReadingCertificate: |
|
422 TRAP(err, ReadUserCertificateRunL()); |
|
423 break; |
|
424 case EReadingCertificateChain: |
|
425 TRAP(err, ReadCertificateChainRunL()); |
|
426 break; |
|
427 default: |
|
428 DEBUG_LOG(_L("RunL called in unknown state")); |
|
429 User::Invariant(); |
|
430 break; |
|
431 } |
|
432 |
|
433 if ( err != KErrNone ) |
|
434 { |
|
435 DEBUG_LOG(_L("Operation completed. Signalling observer.")); |
|
436 |
|
437 SignalObserverL(err); |
|
438 } |
|
439 } |
|
440 |
|
441 |
|
442 void CIkeV2PkiService::ReadUserCertificateRunL() |
|
443 { |
|
444 // |
|
445 // A Certificate has been read PKI store. |
|
446 // Build X509 certificate object from certificate data |
|
447 // |
|
448 switch(iStatus.Int()) |
|
449 { |
|
450 case KErrNone: |
|
451 iUserCertificate = iReadCertificate->AllocL(); |
|
452 iReadCertificate->Des().Zero(); |
|
453 SignalObserverL(KErrNone); |
|
454 break; |
|
455 case KPKIErrBufferTooShort: |
|
456 { |
|
457 // |
|
458 // Allocate a new buffer for ASN1 coded certificate read from PKI store |
|
459 // Buffer size is now asked from pkiserviceapi |
|
460 // |
|
461 TInt realCertSize; |
|
462 User::LeaveIfError(iPkiService.GetRequiredBufferSize(realCertSize)); |
|
463 |
|
464 delete iReadCertificate; |
|
465 iReadCertificate = NULL; |
|
466 |
|
467 iReadCertificate = HBufC8::NewL(realCertSize); |
|
468 iCertPtr.Set(iReadCertificate->Des()); |
|
469 |
|
470 ReadUserCertificateL(*iCaName, EFalse); |
|
471 } |
|
472 break; |
|
473 case KPKIErrNotFound: |
|
474 { |
|
475 // |
|
476 // Get next user certificate from PKI store using either Key |
|
477 // identifier or CA name as read argument |
|
478 // |
|
479 iCasTrustedByPeer.Remove(0); |
|
480 if ( iCasTrustedByPeer.Count() > 0 ) |
|
481 { |
|
482 |
|
483 CIkeCaElem* CaElem = iCasTrustedByPeer[0]; |
|
484 HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); |
|
485 if (caName == NULL) |
|
486 { |
|
487 User::Leave(KErrArgument); |
|
488 } |
|
489 delete iCaName; |
|
490 iCaName = caName; |
|
491 caName=NULL; |
|
492 delete caName; |
|
493 ReadUserCertificateL(*iCaName, EFalse); |
|
494 } |
|
495 else |
|
496 { |
|
497 User::Leave(KErrNotFound); |
|
498 } |
|
499 } |
|
500 break; |
|
501 case KErrNotFound: |
|
502 ReadCertificateChainL(); |
|
503 break; |
|
504 default: |
|
505 User::Leave(iStatus.Int()); |
|
506 break; |
|
507 } |
|
508 } |
|
509 |
|
510 |
|
511 void CIkeV2PkiService::BuildingCaListRunL() |
|
512 { |
|
513 |
|
514 switch(iStatus.Int()) |
|
515 { |
|
516 case KErrNone: |
|
517 { |
|
518 iIkeDataCAList->Delete(0); |
|
519 |
|
520 ASSERT(iReadCertificate); |
|
521 HBufC8* caCert = iReadCertificate; // Link CA buffer to CIkeCaElem |
|
522 CleanupStack::PushL(caCert); |
|
523 |
|
524 iReadCertificate = NULL; |
|
525 iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize); |
|
526 iCertPtr.Set(iReadCertificate->Des()); |
|
527 |
|
528 |
|
529 CIkeCaElem* caElem = CIkeCaElem::NewL(caCert); |
|
530 CleanupStack::Pop(caCert); |
|
531 CleanupStack::PushL(caElem); |
|
532 |
|
533 //Append ca cert to list, if not already present. |
|
534 if (iTrustedCAList->FindCaElem(caElem->KeyHash()) == NULL) |
|
535 { |
|
536 iTrustedCAList->AppendL(caElem); |
|
537 CleanupStack::Pop(caElem); |
|
538 } |
|
539 else |
|
540 { |
|
541 CleanupStack::PopAndDestroy(caElem); |
|
542 } |
|
543 |
|
544 if (iIkeDataCAList->Count() > 0) |
|
545 { |
|
546 ImportNextCaElemFromIkeDataListL(); |
|
547 } |
|
548 else |
|
549 { |
|
550 |
|
551 if (iIkeData->iOwnCert.iOwnCertExists) |
|
552 { |
|
553 ReadTrustedUserCertificateL(); |
|
554 } |
|
555 else |
|
556 { |
|
557 SignalObserverL(KErrNone); |
|
558 } |
|
559 } |
|
560 } |
|
561 break; |
|
562 case KPKIErrBufferTooShort: |
|
563 { |
|
564 |
|
565 DEBUG_LOG(_L("Buffer too short")); |
|
566 |
|
567 TInt certSize = 0; |
|
568 User::LeaveIfError(iPkiService.GetRequiredBufferSize(certSize)); |
|
569 |
|
570 __ASSERT_DEBUG(iCertPtr.MaxLength() < certSize, User::Invariant()); |
|
571 |
|
572 delete iReadCertificate; |
|
573 iReadCertificate = NULL; |
|
574 iReadCertificate = HBufC8::NewL(certSize); |
|
575 iCertPtr.Set(iReadCertificate->Des()); |
|
576 |
|
577 //Tries to reimport the certificate. |
|
578 ImportNextCaElemFromIkeDataListL(); |
|
579 } |
|
580 break; |
|
581 default: |
|
582 DEBUG_LOG1(_L("Error code %d"), iStatus.Int()); |
|
583 User::Leave(iStatus.Int()); |
|
584 break; |
|
585 } |
|
586 } |
|
587 |
|
588 |
|
589 EXPORT_C void CIkeV2PkiService::InitIkeV2PkiService(const CIkeData* aIkeData) |
|
590 { |
|
591 __ASSERT_DEBUG(iState == EPkiServiceIdle, User::Invariant()); |
|
592 __ASSERT_DEBUG(iIkeDataCAList == NULL, User::Invariant()); |
|
593 __ASSERT_DEBUG(aIkeData->iCAList != NULL, User::Invariant()); |
|
594 __ASSERT_DEBUG(aIkeData->iCAList->Count() > 0, User::Invariant()); |
|
595 __ASSERT_DEBUG(iIkeData == NULL, User::Invariant()); |
|
596 |
|
597 iIkeData = aIkeData; |
|
598 |
|
599 iState = EBuildingCaList; |
|
600 TRAPD(err, InitIkeV2PkiServiceL()); |
|
601 if (err != KErrNone) |
|
602 { |
|
603 iStatus = KRequestPending; |
|
604 SET_ACTIVE; |
|
605 |
|
606 TRequestStatus* status = &iStatus; |
|
607 User::RequestComplete(status, err); |
|
608 } |
|
609 } |
|
610 |
|
611 |
|
612 void CIkeV2PkiService::InitIkeV2PkiServiceL() |
|
613 { |
|
614 if (iIkeData->iClientCertType != NULL) |
|
615 { |
|
616 if (iIkeData->iClientCertType->GetData().Compare(_L("DEVICE")) == 0) |
|
617 { |
|
618 User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeDevice)); |
|
619 } |
|
620 else |
|
621 { |
|
622 User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeUser)); |
|
623 } |
|
624 } |
|
625 |
|
626 iIkeDataCAList = new (ELeave) CArrayFixFlat<TCertInfo>(2); |
|
627 for (TInt i = 0; i < iIkeData->iCAList->Count(); ++i) |
|
628 { |
|
629 const TCertInfo* info = (*iIkeData->iCAList)[i]; |
|
630 iIkeDataCAList->AppendL(*info); |
|
631 } |
|
632 |
|
633 ImportNextCaElemFromIkeDataListL(); |
|
634 } |
|
635 |
|
636 |
|
637 void CIkeV2PkiService::ImportNextCaElemFromIkeDataListL() |
|
638 { |
|
639 __ASSERT_DEBUG(iIkeDataCAList != NULL, User::Invariant()); |
|
640 __ASSERT_DEBUG(iIkeDataCAList->Count() > 0, User::Invariant()); |
|
641 |
|
642 const TCertInfo certInfo = (*iIkeDataCAList)[0]; |
|
643 switch(certInfo.iFormat) |
|
644 { |
|
645 case CA_NAME: |
|
646 delete iSubjName; |
|
647 iSubjName = NULL; |
|
648 iSubjName = HBufC8::NewL(certInfo.iData.Length()); |
|
649 iSubjName->Des().Copy(certInfo.iData); |
|
650 iPkiService.ReadCertificateL(KEmptyString, |
|
651 *iSubjName, KEmptyString, |
|
652 EPKICACertificate, 0, |
|
653 EPKIRSA, iCertPtr, |
|
654 &iResArray, iStatus); |
|
655 SET_ACTIVE; |
|
656 break; |
|
657 case KEY_ID: |
|
658 if (!IkeParser::TextToHexOctets(certInfo.iData, iCertKeyId)) |
|
659 { |
|
660 User::Leave(KErrArgument); |
|
661 } |
|
662 iPkiService.ReadCertificateL(iCertKeyId, iCertPtr, |
|
663 &iResArray, iStatus); |
|
664 SET_ACTIVE; |
|
665 break; |
|
666 case APPL_UID: |
|
667 { |
|
668 //Get the list of applicable CA certs and appends it |
|
669 //to the original list, which was defined in the policy. |
|
670 //After this removes the currently handled node and |
|
671 //calls the method recursively. |
|
672 RArray<TUid>* applUidList = IkeParser::GetApplUidListL(certInfo.iData); |
|
673 CleanupStack::PushL(TCleanupItem(CIkeV2PkiServiceApplUidArrayCleanup, |
|
674 applUidList)); |
|
675 |
|
676 CArrayFix<TCertificateListEntry>* applicableCaCertList; |
|
677 iPkiService.ListApplicableCertificatesL(*applUidList, applicableCaCertList); |
|
678 |
|
679 CleanupStack::PopAndDestroy(); //applUidList |
|
680 |
|
681 if (applicableCaCertList->Count() > 0) |
|
682 { |
|
683 CleanupStack::PushL(applicableCaCertList); |
|
684 TCertInfo* info = new (ELeave) TCertInfo; |
|
685 CleanupDeletePushL(info); |
|
686 for (TInt i = 0; i < applicableCaCertList->Count(); i++) |
|
687 { |
|
688 const TCertificateListEntry& entry = (*applicableCaCertList)[i]; |
|
689 info->iFormat = CA_NAME; |
|
690 info->iData.Zero(); |
|
691 info->iData.Copy(entry.iIdentitySubjectName); |
|
692 |
|
693 iIkeDataCAList->AppendL(*info); |
|
694 DEBUG_LOG1(_L("Appending Applicable cert to the list (%S)"), &(info->iData)); |
|
695 |
|
696 } |
|
697 |
|
698 CleanupStack::PopAndDestroy(info); |
|
699 CleanupStack::PopAndDestroy(applicableCaCertList); |
|
700 |
|
701 iIkeDataCAList->Delete(0); |
|
702 ImportNextCaElemFromIkeDataListL(); |
|
703 } |
|
704 else |
|
705 { |
|
706 delete applicableCaCertList; |
|
707 applicableCaCertList = NULL; |
|
708 |
|
709 iStatus = KRequestPending; |
|
710 SET_ACTIVE; |
|
711 |
|
712 TRequestStatus* status = &iStatus; |
|
713 User::RequestComplete(status, KErrNotFound); |
|
714 } |
|
715 } |
|
716 break; |
|
717 default: |
|
718 User::Leave(KErrArgument); |
|
719 break; |
|
720 } |
|
721 } |
|
722 |
|
723 void CIkeV2PkiService::ReadCertificateChainL() |
|
724 { |
|
725 delete iCaName; |
|
726 iCaName = NULL; |
|
727 iCaName = IkeCert::GetCertificateFieldDERL(iCasTrustedByPeer[0]->Certificate(), KSubjectName);; |
|
728 iState = EReadingCertificateChain; |
|
729 ReadUserCertificateL(KEmptyString, EFalse); |
|
730 } |
|
731 |
|
732 void CIkeV2PkiService::ReadCertificateChainRunL() |
|
733 { |
|
734 TInt err; |
|
735 HBufC8* issuerName=NULL; |
|
736 TRAP(err, issuerName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName)); |
|
737 if (err!=KErrNone) |
|
738 { |
|
739 err=KKmdIkeNoCertFoundErr; |
|
740 User::Leave(err); |
|
741 } |
|
742 if ( issuerName->Compare(iCaName->Des())==0) |
|
743 { |
|
744 iReadCertificate->Des().Zero(); |
|
745 delete issuerName; |
|
746 issuerName = NULL; |
|
747 SignalObserverL(KErrNone); |
|
748 } |
|
749 else |
|
750 { |
|
751 delete issuerName; |
|
752 issuerName = NULL; |
|
753 delete iCaName; |
|
754 iCaName = NULL; |
|
755 iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName); |
|
756 delete iSubjName; |
|
757 iSubjName = NULL; |
|
758 iSubjName = iCaName->AllocL(); |
|
759 if ( !iUserCertificate) |
|
760 iUserCertificate = iReadCertificate->AllocL(); |
|
761 else if ( !i2Certificate ) |
|
762 { |
|
763 i2Certificate = iReadCertificate->AllocL(); |
|
764 i2CertificateName= IkeCert::GetCertificateFieldDERL(i2Certificate, KSubjectName); |
|
765 } |
|
766 else if ( !i1Certificate) |
|
767 i1Certificate = iReadCertificate->AllocL(); |
|
768 |
|
769 iPkiService.ReadCertificateL(KEmptyString, |
|
770 *iSubjName, KEmptyString, |
|
771 EPKICACertificate, 0, |
|
772 EPKIRSA, iCertPtr, |
|
773 &iResArray, iStatus); |
|
774 SET_ACTIVE; |
|
775 } |
|
776 |
|
777 } |
|
778 |
|
779 void CIkeV2PkiService::SignalObserverL(TInt aStatus) |
|
780 { |
|
781 DEBUG_LOG1(_L("CIkeV2PkiService::SignalObserverL: Signalling with %d"), aStatus); |
|
782 |
|
783 if (aStatus != KErrNone) |
|
784 { |
|
785 delete iUserCertificate; |
|
786 iUserCertificate = NULL; |
|
787 |
|
788 delete iCaName; |
|
789 iCaName = NULL; |
|
790 |
|
791 iCertPtr.Zero(); |
|
792 |
|
793 iTrustedCAList->ResetAndDestroy(); // Trusted CA certificate list |
|
794 |
|
795 } |
|
796 |
|
797 iIkeData = NULL; |
|
798 |
|
799 iSubjName->Des().Zero(); |
|
800 iRfc822Name->Des().Zero(); |
|
801 |
|
802 iCertKeyId.Zero(); |
|
803 iResArray = NULL; |
|
804 |
|
805 iCasTrustedByPeer.Reset(); |
|
806 |
|
807 delete iIkeDataCAList; |
|
808 iIkeDataCAList = NULL; |
|
809 |
|
810 iState = EPkiServiceIdle; |
|
811 iObserver.IkeV2PkiInitCompleteL(aStatus); |
|
812 } |