|
1 /* |
|
2 * Copyright (c) 2003-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 Acquire definition |
|
15 * Class CIkev2Acquire is a IKEv2 specific data structure |
|
16 * containing information needed, when establishing a new |
|
17 * IPsec SA |
|
18 */ |
|
19 |
|
20 #include <ipsecpolapi.h> |
|
21 |
|
22 #include "ikev2acquire.h" |
|
23 #include "pfkeymsg.h" |
|
24 #include "ipsecproposal.h" |
|
25 #include "ipsecselectors.h" |
|
26 #include "ikev2payloads.h" |
|
27 #include "ikev2ipsecsarekeydata.h" |
|
28 |
|
29 _LIT8(KZeroDesc, ""); |
|
30 // |
|
31 // |
|
32 // CIkev2Acquire |
|
33 // |
|
34 // This class is used to handle PFKEY Acquire primitives received from |
|
35 // Ipsec plug-in. |
|
36 // |
|
37 // |
|
38 CIkev2Acquire::CIkev2Acquire(TInt aId) |
|
39 :iId(aId), iSPIIn(0), iSPIOut(0), iSPIToBeRekeyed(0), iDHGroup(0), |
|
40 iTransport(EFalse), iResponse(EFalse), iSrcSpecific(ETrue), iForVirtualIp(EFalse), |
|
41 iReplayWindow(0), iProtocol(SADB_SATYPE_ESP), iPfKeyPid(0), iPfKeySeq(0), |
|
42 iHard(0,0,0,0), iSoft(0,0,0,0), |
|
43 iSA(0), iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0), iNext(0) |
|
44 { |
|
45 } |
|
46 |
|
47 |
|
48 CIkev2Acquire::~CIkev2Acquire() |
|
49 { |
|
50 delete iSA; |
|
51 iSA = NULL; |
|
52 delete iTS_i; |
|
53 iTS_i = NULL; |
|
54 delete iTS_r; |
|
55 iTS_r = NULL; |
|
56 delete iLocalId; |
|
57 iLocalId = NULL; |
|
58 delete iRemoteId; |
|
59 iRemoteId = NULL; |
|
60 } |
|
61 |
|
62 void CIkev2Acquire::ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, |
|
63 TUint16 aDHGroup, TBool aImplicitSa, |
|
64 const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) |
|
65 { |
|
66 SetIpsecProtocol(aReq.iBase.iMsg->sadb_msg_satype); |
|
67 SetPid(aReq.iBase.iMsg->sadb_msg_pid); |
|
68 SetSeq(aReq.iBase.iMsg->sadb_msg_seq); |
|
69 iSrcSpecific = !(aReq.iSrcAddr.iAddr->IsUnspecified()); |
|
70 |
|
71 if (!aRekeyData) |
|
72 { |
|
73 // SADB_ACQUIRE was received |
|
74 if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS ) |
|
75 { |
|
76 iDHGroup = (TUint32)aDHGroup; |
|
77 } |
|
78 |
|
79 if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL ) |
|
80 { |
|
81 iTransport = EFalse; |
|
82 } |
|
83 else |
|
84 { |
|
85 iTransport = ETrue; |
|
86 } |
|
87 |
|
88 iHard.iAllocations = aReq.iProposal.iComb->sadb_comb_hard_allocations; |
|
89 iHard.iBytes = aReq.iProposal.iComb->sadb_comb_hard_bytes; |
|
90 iHard.iAddtime = aReq.iProposal.iComb->sadb_comb_hard_addtime; |
|
91 iHard.iUsetime = aReq.iProposal.iComb->sadb_comb_hard_usetime; |
|
92 |
|
93 iSoft.iAllocations = aReq.iProposal.iComb->sadb_comb_soft_allocations; |
|
94 iSoft.iBytes = aReq.iProposal.iComb->sadb_comb_soft_bytes; |
|
95 iSoft.iAddtime = aReq.iProposal.iComb->sadb_comb_soft_addtime; |
|
96 iSoft.iUsetime = aReq.iProposal.iComb->sadb_comb_soft_usetime; |
|
97 |
|
98 SetReplayWindow(aReq.iProposal.iExt->sadb_prop_replay); |
|
99 |
|
100 // |
|
101 // Build SA payload (including Proposal and Transform payload) |
|
102 // using parameters in TPfkeyMessage |
|
103 // |
|
104 if ( aImplicitSa ) |
|
105 { |
|
106 aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined |
|
107 } |
|
108 iSA = IpsecProposal::BuildIpsecSaRequestL(aReq, aDHGroup); |
|
109 |
|
110 // |
|
111 // Build Traffic selectors using parameters in TPfkeyMessage. |
|
112 // For some reason the selectors are build using identity |
|
113 // fields. |
|
114 // |
|
115 IpsecSelectors::BuildTrafficSelectorsL(this, aLocalAddr, |
|
116 aReq.iSrcIdent, aReq.iDstIdent, |
|
117 aReq.iDstAddr.iExt->sadb_address_proto); |
|
118 // |
|
119 // Store identity information from TPfkeyMessage to Acquire |
|
120 // |
|
121 if ( aReq.iSrcIdent.iExt ) |
|
122 { |
|
123 iLocalId = HBufC8::NewL(aReq.iSrcIdent.iData.Length()); |
|
124 iLocalId->Des().Copy(aReq.iSrcIdent.iData); |
|
125 } |
|
126 else |
|
127 { |
|
128 iLocalId = KZeroDesc().AllocL(); |
|
129 } |
|
130 |
|
131 if ( aReq.iDstIdent.iExt ) |
|
132 { |
|
133 iRemoteId = HBufC8::NewL(aReq.iDstIdent.iData.Length()); |
|
134 iRemoteId->Des().Copy(aReq.iDstIdent.iData); |
|
135 } |
|
136 else |
|
137 { |
|
138 iRemoteId = KZeroDesc().AllocL(); |
|
139 } |
|
140 } |
|
141 else |
|
142 { |
|
143 // SADB_EXPIRE was received due to soft lifetime expiration |
|
144 TUint16 flags = (TUint16)(aReq.iSa.iExt->sadb_sa_flags | (aSaSpec->iTransportMode ? 0 : SADB_SAFLAGS_TUNNEL)); |
|
145 if ( flags & SADB_SAFLAGS_PFS ) |
|
146 { |
|
147 iDHGroup = (TUint32)aDHGroup; |
|
148 } |
|
149 |
|
150 if ( flags & SADB_SAFLAGS_TUNNEL ) |
|
151 { |
|
152 iTransport = EFalse; |
|
153 } |
|
154 else |
|
155 { |
|
156 iTransport = ETrue; |
|
157 } |
|
158 |
|
159 if ( aImplicitSa ) |
|
160 { |
|
161 aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined |
|
162 } |
|
163 |
|
164 iSA = IpsecProposal::BuildIpsecSaRequestL(iProtocol, |
|
165 aSaSpec->iEalg, aSaSpec->iEalgLen, aSaSpec->iAalg, |
|
166 flags, aDHGroup); |
|
167 |
|
168 iReplayWindow = aRekeyData->ReplayWindow(); |
|
169 iHard = aRekeyData->HardLifetime(); |
|
170 iSoft = aRekeyData->SoftLifetime(); |
|
171 |
|
172 iTS_i = aRekeyData->TsIL(); |
|
173 iTS_r = aRekeyData->TsRL(); |
|
174 |
|
175 |
|
176 iLocalId = aRekeyData->LocalId().AllocL(); |
|
177 iRemoteId = aRekeyData->RemoteId().AllocL(); |
|
178 |
|
179 iResponse = EFalse; |
|
180 } |
|
181 } |
|
182 |
|
183 |
|
184 CIkev2Acquire* CIkev2Acquire::NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, |
|
185 const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa, |
|
186 const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) |
|
187 { |
|
188 CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); |
|
189 CleanupStack::PushL(Acquire); |
|
190 Acquire->ConstructL(aPfkeyMessage, aLocalAddr, aDHGroup, aImplicitSa, aSaSpec, aRekeyData); |
|
191 CleanupStack::Pop(Acquire); |
|
192 return Acquire; |
|
193 } |
|
194 |
|
195 |
|
196 void CIkev2Acquire::AddIpsecSpiToSa(const TDesC8& aSpi) |
|
197 { |
|
198 __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant()); |
|
199 |
|
200 TUint8* saBuffer = const_cast<TUint8*>(iSA->Ptr()); |
|
201 TProposalIkev2* Prop = TProposalIkev2::Cast(saBuffer); |
|
202 |
|
203 while ( Prop ) |
|
204 { |
|
205 TUint32 spiValue = 0; |
|
206 TPtr8 spiValueDesc(reinterpret_cast<TUint8*>(&spiValue), sizeof(spiValue)); |
|
207 spiValueDesc = aSpi; |
|
208 Prop->SetIpsecSPI(spiValue); |
|
209 if ( !Prop->Last() ) |
|
210 { |
|
211 Prop = TProposalIkev2::Cast(TPayloadIkev2::Cast(Prop)->Next()); |
|
212 } |
|
213 else |
|
214 { |
|
215 Prop = NULL; |
|
216 } |
|
217 } |
|
218 } |
|
219 |
|
220 |
|
221 CIkev2Acquire* CIkev2Acquire::NewL(TUint32 aId, HBufC8* aSa, |
|
222 CArrayFix<TIkeV2TrafficSelector>* aTS_i, |
|
223 CArrayFix<TIkeV2TrafficSelector>* aTS_r ) |
|
224 { |
|
225 CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); |
|
226 Acquire->iSA = aSa; |
|
227 Acquire->iTS_i = aTS_i; |
|
228 Acquire->iTS_r = aTS_r; |
|
229 return Acquire; |
|
230 } |
|
231 |
|
232 void CIkev2Acquire::Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) |
|
233 { |
|
234 ASSERT(aAcquire && aAnchor); |
|
235 aAcquire->iNext = NULL; |
|
236 CIkev2Acquire* Last = *aAnchor; |
|
237 if ( Last ) |
|
238 { |
|
239 while ( Last->iNext ) |
|
240 { |
|
241 Last = Last->iNext; |
|
242 } |
|
243 Last->iNext = aAcquire; |
|
244 } |
|
245 else *aAnchor = aAcquire; |
|
246 } |
|
247 |
|
248 CIkev2Acquire* CIkev2Acquire::Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove) |
|
249 { |
|
250 ASSERT(aAnchor); |
|
251 CIkev2Acquire* Prev = NULL; |
|
252 CIkev2Acquire* Elem = *aAnchor; |
|
253 while ( Elem ) |
|
254 { |
|
255 if ( Elem->iId == aId ) |
|
256 { |
|
257 if ( aRemove ) |
|
258 { |
|
259 if ( Prev ) |
|
260 Prev->iNext = Elem->iNext; |
|
261 else *aAnchor = Elem->iNext; |
|
262 } |
|
263 break; |
|
264 } |
|
265 Prev = Elem; |
|
266 Elem = Elem->iNext; |
|
267 } |
|
268 return Elem; |
|
269 } |
|
270 |
|
271 CIkev2Acquire* CIkev2Acquire::GetNext(CIkev2Acquire** aAnchor, TBool aResponse) |
|
272 { |
|
273 ASSERT(aAnchor); |
|
274 CIkev2Acquire* Elem = *aAnchor; |
|
275 while ( Elem ) |
|
276 { |
|
277 if ( Elem->SPI_In().Length() > 0 && (Elem->Response() == aResponse) ) |
|
278 { |
|
279 RemoveFromQue(Elem->Id(), aAnchor); |
|
280 break; |
|
281 } |
|
282 Elem = Elem->iNext; |
|
283 } |
|
284 return Elem; |
|
285 } |
|
286 |
|
287 TBool CIkev2Acquire::Responding(CIkev2Acquire** aAnchor) |
|
288 { |
|
289 ASSERT(aAnchor); |
|
290 CIkev2Acquire* Elem = *aAnchor; |
|
291 while ( Elem ) |
|
292 { |
|
293 if ( Elem->Response() ) |
|
294 { |
|
295 return ETrue; |
|
296 } |
|
297 Elem = Elem->iNext; |
|
298 } |
|
299 return EFalse; |
|
300 } |
|
301 |
|
302 |
|
303 void CIkev2Acquire::PurgeQue(CIkev2Acquire** aAnchor) |
|
304 { |
|
305 ASSERT(aAnchor); |
|
306 CIkev2Acquire* Elem = *aAnchor; |
|
307 while ( Elem ) |
|
308 { |
|
309 RemoveFromQue(Elem->Id(), aAnchor); |
|
310 delete Elem; |
|
311 Elem = *aAnchor; |
|
312 } |
|
313 } |
|
314 |
|
315 void CIkev2Acquire::SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) |
|
316 { |
|
317 ASSERT(aAcquire && aAnchor); |
|
318 aAcquire->iNext = *aAnchor; |
|
319 *aAnchor = aAcquire; |
|
320 } |
|
321 |
|
322 CIkev2Acquire* CIkev2Acquire::PeekFirst(CIkev2Acquire** aAnchor) |
|
323 { |
|
324 return *aAnchor; |
|
325 } |
|
326 |
|
327 CIkev2Acquire* CIkev2Acquire::RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor) |
|
328 { |
|
329 return CIkev2Acquire::Find(aId, aAnchor, ETrue); |
|
330 } |
|
331 |
|
332 TUint32 CIkev2Acquire::Id() |
|
333 { |
|
334 return iId; |
|
335 } |
|
336 |
|
337 TPtrC8 CIkev2Acquire::SPI_In() |
|
338 { |
|
339 return iSPIIn; |
|
340 } |
|
341 |
|
342 TPtrC8 CIkev2Acquire::SPI_Out() |
|
343 { |
|
344 return iSPIOut; |
|
345 } |
|
346 |
|
347 TPtrC8 CIkev2Acquire::SPI_ToBeRekeyed() |
|
348 { |
|
349 return iSPIToBeRekeyed; |
|
350 } |
|
351 |
|
352 void CIkev2Acquire::SetSPI_In(const TDesC8& aSPI) |
|
353 { |
|
354 iSPIIn = aSPI; |
|
355 } |
|
356 |
|
357 void CIkev2Acquire::SetSPI_Out(const TDesC8& aSPI) |
|
358 { |
|
359 iSPIOut = aSPI; |
|
360 } |
|
361 |
|
362 void CIkev2Acquire::SetSPI_ToBeRekeyed(const TDesC8& aSPI) |
|
363 { |
|
364 iSPIToBeRekeyed = aSPI; |
|
365 } |
|
366 |
|
367 TUint16 CIkev2Acquire::DHGroup() |
|
368 { |
|
369 return (TUint16)iDHGroup; |
|
370 } |
|
371 |
|
372 void CIkev2Acquire::DHGroup(TUint16 aDHGroup) |
|
373 { |
|
374 iDHGroup = aDHGroup; |
|
375 } |
|
376 |
|
377 TBool CIkev2Acquire::Transport() |
|
378 { |
|
379 return iTransport; |
|
380 } |
|
381 |
|
382 void CIkev2Acquire::SetTransport() |
|
383 { |
|
384 iTransport = ETrue; |
|
385 } |
|
386 |
|
387 TBool CIkev2Acquire::Response() |
|
388 { |
|
389 return iResponse; |
|
390 } |
|
391 |
|
392 void CIkev2Acquire::SetResponse() |
|
393 { |
|
394 iResponse = ETrue; |
|
395 } |
|
396 |
|
397 void CIkev2Acquire::SetHardLifetime(const TIpsecSALifetime& aHard ) |
|
398 { |
|
399 iHard = aHard; |
|
400 } |
|
401 |
|
402 TIpsecSALifetime* CIkev2Acquire::HardLifetime() |
|
403 { |
|
404 return &iHard; |
|
405 } |
|
406 |
|
407 void CIkev2Acquire::SetSoftLifetime(const TIpsecSALifetime& aSoft ) |
|
408 { |
|
409 iSoft = aSoft; |
|
410 } |
|
411 |
|
412 TIpsecSALifetime* CIkev2Acquire::SoftLifetime() |
|
413 { |
|
414 return &iSoft; |
|
415 } |
|
416 |
|
417 TUint8 CIkev2Acquire::ReplayWindow() |
|
418 { |
|
419 return (TUint8)iReplayWindow; |
|
420 } |
|
421 |
|
422 void CIkev2Acquire::SetReplayWindow(TUint8 aReplayWindow) |
|
423 { |
|
424 iReplayWindow = (TInt)aReplayWindow; |
|
425 } |
|
426 |
|
427 TUint32 CIkev2Acquire::Pid() |
|
428 { |
|
429 return iPfKeyPid; |
|
430 } |
|
431 |
|
432 void CIkev2Acquire::SetPid(TUint32 aPfKeyPid) |
|
433 { |
|
434 iPfKeyPid = aPfKeyPid; |
|
435 } |
|
436 |
|
437 TUint32 CIkev2Acquire::Seq() |
|
438 { |
|
439 return iPfKeySeq; |
|
440 } |
|
441 |
|
442 void CIkev2Acquire::SetSeq(TUint32 aPfKeySeq) |
|
443 { |
|
444 iPfKeySeq = aPfKeySeq; |
|
445 } |
|
446 |
|
447 void CIkev2Acquire::SetVirtualIp() |
|
448 { |
|
449 iForVirtualIp = ETrue; |
|
450 } |
|
451 |
|
452 TBool CIkev2Acquire::ForVirtualIp() |
|
453 { |
|
454 return iForVirtualIp; |
|
455 } |
|
456 |
|
457 TBool CIkev2Acquire::SrcSpecific() |
|
458 { |
|
459 return iSrcSpecific; |
|
460 } |
|
461 |
|
462 void CIkev2Acquire::SetSrcSpecific(TBool aSrcSpecific) |
|
463 { |
|
464 iSrcSpecific = aSrcSpecific; |
|
465 } |
|
466 |
|
467 TUint8 CIkev2Acquire::IpsecProtocol() |
|
468 { |
|
469 return (TUint8)iProtocol; |
|
470 } |
|
471 |
|
472 void CIkev2Acquire::SetIpsecProtocol(TUint8 aProtocol) |
|
473 { |
|
474 iProtocol = (TInt)aProtocol; |
|
475 } |
|
476 |
|
477 HBufC8* CIkev2Acquire::LocalId() |
|
478 { |
|
479 return iLocalId; |
|
480 } |
|
481 |
|
482 HBufC8* CIkev2Acquire::RemoteId() |
|
483 { |
|
484 return iRemoteId; |
|
485 } |
|
486 |
|
487 HBufC8* CIkev2Acquire::SA()const |
|
488 { |
|
489 return iSA; |
|
490 } |
|
491 |
|
492 const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_i() |
|
493 { |
|
494 return *iTS_i; |
|
495 } |
|
496 |
|
497 const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_r() |
|
498 { |
|
499 return *iTS_r; |
|
500 } |
|
501 |
|
502 void CIkev2Acquire::ReplaceSA(HBufC8* aSA) |
|
503 { |
|
504 delete iSA; |
|
505 iSA = aSA; |
|
506 } |
|
507 |
|
508 void CIkev2Acquire::ReplaceTS_i(CArrayFix<TIkeV2TrafficSelector>* aTS) |
|
509 { |
|
510 delete iTS_i; |
|
511 iTS_i = aTS; |
|
512 } |
|
513 |
|
514 void CIkev2Acquire::ReplaceTS_r(CArrayFix<TIkeV2TrafficSelector>* aTS) |
|
515 { |
|
516 delete iTS_r; |
|
517 iTS_r = aTS; |
|
518 } |
|
519 |
|
520 void CIkev2Acquire::ReplaceLocalId(HBufC8* aId) |
|
521 { |
|
522 delete iLocalId; |
|
523 iLocalId = aId; |
|
524 } |
|
525 |
|
526 void CIkev2Acquire::ReplaceRemoteId(HBufC8* aId) |
|
527 { |
|
528 delete iRemoteId; |
|
529 iRemoteId = aId; |
|
530 } |
|
531 |