]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/sa/ikev1/phase1.c
ha: Add auth method for HA IKEv1 key derivation
[thirdparty/strongswan.git] / src / libcharon / sa / ikev1 / phase1.c
1 /*
2 * Copyright (C) 2012-2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2012 Martin Willi
6 * Copyright (C) 2012 revosec AG
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include "phase1.h"
20
21 #include <daemon.h>
22 #include <sa/ikev1/keymat_v1.h>
23 #include <encoding/payloads/ke_payload.h>
24 #include <encoding/payloads/nonce_payload.h>
25 #include <collections/linked_list.h>
26
27 typedef struct private_phase1_t private_phase1_t;
28
29 /**
30 * Private data of an phase1_t object.
31 */
32 struct private_phase1_t {
33
34 /**
35 * Public phase1_t interface.
36 */
37 phase1_t public;
38
39 /**
40 * IKE_SA we negotiate
41 */
42 ike_sa_t *ike_sa;
43
44 /**
45 * Currently selected peer config
46 */
47 peer_cfg_t *peer_cfg;
48
49 /**
50 * Other possible peer config candidates
51 */
52 linked_list_t *candidates;
53
54 /**
55 * Acting as initiator
56 */
57 bool initiator;
58
59 /**
60 * Extracted SA payload bytes
61 */
62 chunk_t sa_payload;
63
64 /**
65 * DH exchange
66 */
67 diffie_hellman_t *dh;
68
69 /**
70 * Keymat derivation (from SA)
71 */
72 keymat_v1_t *keymat;
73
74 /**
75 * Received public DH value from peer
76 */
77 chunk_t dh_value;
78
79 /**
80 * Initiators nonce
81 */
82 chunk_t nonce_i;
83
84 /**
85 * Responder nonce
86 */
87 chunk_t nonce_r;
88 };
89
90 /**
91 * Get the first authentcation config from peer config
92 */
93 static auth_cfg_t *get_auth_cfg(peer_cfg_t *peer_cfg, bool local)
94 {
95 enumerator_t *enumerator;
96 auth_cfg_t *cfg = NULL;
97
98 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
99 enumerator->enumerate(enumerator, &cfg);
100 enumerator->destroy(enumerator);
101 return cfg;
102 }
103
104 /**
105 * Find a shared key for the given identities
106 */
107 static shared_key_t *find_shared_key(identification_t *my_id, host_t *me,
108 identification_t *other_id, host_t *other)
109 {
110 identification_t *any_id = NULL;
111 shared_key_t *shared_key;
112
113 if (!other_id)
114 {
115 any_id = identification_create_from_encoding(ID_ANY, chunk_empty);
116 other_id = any_id;
117 }
118 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
119 my_id, other_id);
120 if (!shared_key)
121 {
122 DBG1(DBG_IKE, "no shared key found for '%Y'[%H] - '%Y'[%H]",
123 my_id, me, other_id, other);
124 }
125 DESTROY_IF(any_id);
126 return shared_key;
127 }
128
129 /**
130 * Lookup a shared secret for this IKE_SA
131 */
132 static shared_key_t *lookup_shared_key(private_phase1_t *this,
133 peer_cfg_t *peer_cfg)
134 {
135 host_t *me, *other;
136 identification_t *my_id, *other_id;
137 shared_key_t *shared_key = NULL;
138 auth_cfg_t *my_auth, *other_auth;
139 enumerator_t *enumerator;
140
141 me = this->ike_sa->get_my_host(this->ike_sa);
142 other = this->ike_sa->get_other_host(this->ike_sa);
143
144 if (peer_cfg)
145 { /* as initiator or aggressive responder, use identities */
146 my_auth = get_auth_cfg(peer_cfg, TRUE);
147 other_auth = get_auth_cfg(peer_cfg, FALSE);
148 if (my_auth && other_auth)
149 {
150 my_id = my_auth->get(my_auth, AUTH_RULE_IDENTITY);
151 if (peer_cfg->use_aggressive(peer_cfg))
152 {
153 other_id = this->ike_sa->get_other_id(this->ike_sa);
154 }
155 else
156 {
157 other_id = other_auth->get(other_auth, AUTH_RULE_IDENTITY);
158 }
159 if (my_id)
160 {
161 shared_key = find_shared_key(my_id, me, other_id, other);
162 }
163 }
164 }
165 else
166 { /* as responder, we try to find a config by IP addresses and use the
167 * configured identities to find the PSK */
168 enumerator = charon->backends->create_peer_cfg_enumerator(
169 charon->backends, me, other, NULL, NULL, IKEV1);
170 while (enumerator->enumerate(enumerator, &peer_cfg))
171 {
172 my_auth = get_auth_cfg(peer_cfg, TRUE);
173 other_auth = get_auth_cfg(peer_cfg, FALSE);
174 if (my_auth && other_auth)
175 {
176 my_id = my_auth->get(my_auth, AUTH_RULE_IDENTITY);
177 other_id = other_auth->get(other_auth, AUTH_RULE_IDENTITY);
178 if (my_id)
179 {
180 shared_key = find_shared_key(my_id, me, other_id, other);
181 if (shared_key)
182 {
183 break;
184 }
185 }
186 }
187 }
188 enumerator->destroy(enumerator);
189 }
190 if (!shared_key)
191 { /* try to get a PSK for IP addresses */
192 my_id = identification_create_from_sockaddr(me->get_sockaddr(me));
193 other_id = identification_create_from_sockaddr(
194 other->get_sockaddr(other));
195 if (my_id && other_id)
196 {
197 shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE,
198 my_id, other_id);
199 }
200 DESTROY_IF(my_id);
201 DESTROY_IF(other_id);
202 if (!shared_key)
203 {
204 DBG1(DBG_IKE, "no shared key found for %H - %H", me, other);
205 }
206 }
207 return shared_key;
208 }
209
210 METHOD(phase1_t, create_hasher, bool,
211 private_phase1_t *this)
212 {
213 return this->keymat->create_hasher(this->keymat,
214 this->ike_sa->get_proposal(this->ike_sa));
215 }
216
217 METHOD(phase1_t, create_dh, bool,
218 private_phase1_t *this, diffie_hellman_group_t group)
219 {
220 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, group);
221 return this->dh != NULL;
222 }
223
224 METHOD(phase1_t, derive_keys, bool,
225 private_phase1_t *this, peer_cfg_t *peer_cfg, auth_method_t method)
226 {
227 shared_key_t *shared_key = NULL;
228
229 switch (method)
230 {
231 case AUTH_PSK:
232 case AUTH_XAUTH_INIT_PSK:
233 case AUTH_XAUTH_RESP_PSK:
234 shared_key = lookup_shared_key(this, peer_cfg);
235 if (!shared_key)
236 {
237 return FALSE;
238 }
239 break;
240 default:
241 break;
242 }
243
244 if (!this->keymat->derive_ike_keys(this->keymat,
245 this->ike_sa->get_proposal(this->ike_sa),
246 this->dh, this->dh_value, this->nonce_i, this->nonce_r,
247 this->ike_sa->get_id(this->ike_sa), method, shared_key))
248 {
249 DESTROY_IF(shared_key);
250 DBG1(DBG_IKE, "key derivation for %N failed", auth_method_names, method);
251 return FALSE;
252 }
253 charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, this->dh_value,
254 this->nonce_i, this->nonce_r, NULL, shared_key,
255 method);
256 DESTROY_IF(shared_key);
257 return TRUE;
258 }
259
260 /**
261 * Check if a peer skipped authentication by using Hybrid authentication
262 */
263 static bool skipped_auth(private_phase1_t *this,
264 auth_method_t method, bool local)
265 {
266 bool initiator;
267
268 initiator = local == this->initiator;
269 if (initiator && method == AUTH_HYBRID_INIT_RSA)
270 {
271 return TRUE;
272 }
273 if (!initiator && method == AUTH_HYBRID_RESP_RSA)
274 {
275 return TRUE;
276 }
277 return FALSE;
278 }
279
280 /**
281 * Check if remote authentication constraints fulfilled
282 */
283 static bool check_constraints(private_phase1_t *this, auth_method_t method)
284 {
285 identification_t *id;
286 auth_cfg_t *auth, *cfg;
287 peer_cfg_t *peer_cfg;
288
289 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
290 /* auth identity to comply */
291 id = this->ike_sa->get_other_id(this->ike_sa);
292 auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
293 if (skipped_auth(this, method, FALSE))
294 {
295 return TRUE;
296 }
297 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
298 cfg = get_auth_cfg(peer_cfg, FALSE);
299 return cfg && auth->complies(auth, cfg, TRUE);
300 }
301
302 /**
303 * Save authentication information after authentication succeeded
304 */
305 static void save_auth_cfg(private_phase1_t *this,
306 auth_method_t method, bool local)
307 {
308 auth_cfg_t *auth;
309
310 if (skipped_auth(this, method, local))
311 {
312 return;
313 }
314 auth = auth_cfg_create();
315 /* for local config, we _copy_ entries from the config, as it contains
316 * certificates we must send later. */
317 auth->merge(auth, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
318 this->ike_sa->add_auth_cfg(this->ike_sa, local, auth);
319 }
320
321 /**
322 * Create an authenticator instance
323 */
324 static authenticator_t* create_authenticator(private_phase1_t *this,
325 auth_method_t method, chunk_t id)
326 {
327 authenticator_t *authenticator;
328
329 authenticator = authenticator_create_v1(this->ike_sa, this->initiator,
330 method, this->dh, this->dh_value, this->sa_payload, id);
331 if (!authenticator)
332 {
333 DBG1(DBG_IKE, "negotiated authentication method %N not supported",
334 auth_method_names, method);
335 }
336 return authenticator;
337 }
338
339 METHOD(phase1_t, verify_auth, bool,
340 private_phase1_t *this, auth_method_t method, message_t *message,
341 chunk_t id_data)
342 {
343 authenticator_t *authenticator;
344 status_t status;
345
346 authenticator = create_authenticator(this, method, id_data);
347 if (authenticator)
348 {
349 status = authenticator->process(authenticator, message);
350 authenticator->destroy(authenticator);
351 if (status == SUCCESS && check_constraints(this, method))
352 {
353 save_auth_cfg(this, method, FALSE);
354 return TRUE;
355 }
356 }
357 return FALSE;
358 }
359
360 METHOD(phase1_t, build_auth, bool,
361 private_phase1_t *this, auth_method_t method, message_t *message,
362 chunk_t id_data)
363 {
364 authenticator_t *authenticator;
365 status_t status;
366
367 authenticator = create_authenticator(this, method, id_data);
368 if (authenticator)
369 {
370 status = authenticator->build(authenticator, message);
371 authenticator->destroy(authenticator);
372 if (status == SUCCESS)
373 {
374 save_auth_cfg(this, method, TRUE);
375 return TRUE;
376 }
377 }
378 return FALSE;
379 }
380
381 /**
382 * Get the two auth classes from local or remote config
383 */
384 static void get_auth_class(peer_cfg_t *peer_cfg, bool local,
385 auth_class_t *c1, auth_class_t *c2)
386 {
387 enumerator_t *enumerator;
388 auth_cfg_t *auth;
389
390 *c1 = *c2 = AUTH_CLASS_ANY;
391
392 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
393 while (enumerator->enumerate(enumerator, &auth))
394 {
395 if (*c1 == AUTH_CLASS_ANY)
396 {
397 *c1 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
398 }
399 else
400 {
401 *c2 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
402 break;
403 }
404 }
405 enumerator->destroy(enumerator);
406 }
407
408 /**
409 * Select an auth method to use by checking what key we have
410 */
411 static auth_method_t get_pubkey_method(private_phase1_t *this, auth_cfg_t *auth)
412 {
413 auth_method_t method = AUTH_NONE;
414 identification_t *id;
415 private_key_t *private;
416
417 if (auth)
418 {
419 id = (identification_t*)auth->get(auth, AUTH_RULE_IDENTITY);
420 if (id)
421 {
422 private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, NULL);
423 if (private)
424 {
425 switch (private->get_type(private))
426 {
427 case KEY_RSA:
428 method = AUTH_RSA;
429 break;
430 case KEY_ECDSA:
431 switch (private->get_keysize(private))
432 {
433 case 256:
434 method = AUTH_ECDSA_256;
435 break;
436 case 384:
437 method = AUTH_ECDSA_384;
438 break;
439 case 521:
440 method = AUTH_ECDSA_521;
441 break;
442 default:
443 DBG1(DBG_IKE, "%d bit ECDSA private key size not "
444 "supported", private->get_keysize(private));
445 break;
446 }
447 break;
448 default:
449 DBG1(DBG_IKE, "private key of type %N not supported",
450 key_type_names, private->get_type(private));
451 break;
452 }
453 private->destroy(private);
454 }
455 else
456 {
457 DBG1(DBG_IKE, "no private key found for '%Y'", id);
458 }
459 }
460 }
461 return method;
462 }
463
464 /**
465 * Calculate authentication method from a peer config
466 */
467 static auth_method_t calc_auth_method(private_phase1_t *this,
468 peer_cfg_t *peer_cfg)
469 {
470 auth_class_t i1, i2, r1, r2;
471
472 get_auth_class(peer_cfg, this->initiator, &i1, &i2);
473 get_auth_class(peer_cfg, !this->initiator, &r1, &r2);
474
475 if (i1 == AUTH_CLASS_PUBKEY && r1 == AUTH_CLASS_PUBKEY)
476 {
477 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
478 {
479 /* for any pubkey method, return RSA */
480 return AUTH_RSA;
481 }
482 if (i2 == AUTH_CLASS_XAUTH)
483 {
484 return AUTH_XAUTH_INIT_RSA;
485 }
486 if (r2 == AUTH_CLASS_XAUTH)
487 {
488 return AUTH_XAUTH_RESP_RSA;
489 }
490 }
491 if (i1 == AUTH_CLASS_PSK && r1 == AUTH_CLASS_PSK)
492 {
493 if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
494 {
495 return AUTH_PSK;
496 }
497 if (i2 == AUTH_CLASS_XAUTH)
498 {
499 return AUTH_XAUTH_INIT_PSK;
500 }
501 if (r2 == AUTH_CLASS_XAUTH)
502 {
503 return AUTH_XAUTH_RESP_PSK;
504 }
505 }
506 if (i1 == AUTH_CLASS_XAUTH && r1 == AUTH_CLASS_PUBKEY &&
507 i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
508 {
509 return AUTH_HYBRID_INIT_RSA;
510 }
511 return AUTH_NONE;
512 }
513
514 METHOD(phase1_t, get_auth_method, auth_method_t,
515 private_phase1_t *this, peer_cfg_t *peer_cfg)
516 {
517 auth_method_t method;
518
519 method = calc_auth_method(this, peer_cfg);
520 if (method == AUTH_RSA)
521 {
522 return get_pubkey_method(this, get_auth_cfg(peer_cfg, TRUE));
523 }
524 return method;
525 }
526
527 /**
528 * Check if a peer config can be used with a given auth method
529 */
530 static bool check_auth_method(private_phase1_t *this, peer_cfg_t *peer_cfg,
531 auth_method_t given)
532 {
533 auth_method_t method;
534
535 method = calc_auth_method(this, peer_cfg);
536 switch (given)
537 {
538 case AUTH_ECDSA_256:
539 case AUTH_ECDSA_384:
540 case AUTH_ECDSA_521:
541 return method == AUTH_RSA;
542 default:
543 return method == given;
544 }
545 }
546
547 METHOD(phase1_t, select_config, peer_cfg_t*,
548 private_phase1_t *this, auth_method_t method, bool aggressive,
549 identification_t *id)
550 {
551 enumerator_t *enumerator;
552 peer_cfg_t *current;
553 host_t *me, *other;
554 int unusable = 0;
555
556 if (this->peer_cfg)
557 { /* try to find an alternative config */
558 if (this->candidates->remove_first(this->candidates,
559 (void**)&current) != SUCCESS)
560 {
561 DBG1(DBG_CFG, "no alternative config found");
562 return NULL;
563 }
564 DBG1(DBG_CFG, "switching to peer config '%s'",
565 current->get_name(current));
566 return current;
567 }
568
569 me = this->ike_sa->get_my_host(this->ike_sa);
570 other = this->ike_sa->get_other_host(this->ike_sa);
571 DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]",
572 auth_method_names, method, me, other, id);
573 enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
574 me, other, NULL, id, IKEV1);
575 while (enumerator->enumerate(enumerator, &current))
576 {
577 if (check_auth_method(this, current, method) &&
578 current->use_aggressive(current) == aggressive)
579 {
580 current->get_ref(current);
581 if (!this->peer_cfg)
582 {
583 this->peer_cfg = current;
584 }
585 else
586 {
587 this->candidates->insert_last(this->candidates, current);
588 }
589 }
590 else
591 {
592 unusable++;
593 }
594 }
595 enumerator->destroy(enumerator);
596
597 if (this->peer_cfg)
598 {
599 DBG1(DBG_CFG, "selected peer config \"%s\"",
600 this->peer_cfg->get_name(this->peer_cfg));
601 return this->peer_cfg->get_ref(this->peer_cfg);
602 }
603 if (unusable)
604 {
605 DBG1(DBG_IKE, "found %d matching config%s, but none allows %N "
606 "authentication using %s Mode", unusable, unusable > 1 ? "s" : "",
607 auth_method_names, method, aggressive ? "Aggressive" : "Main");
608 return NULL;
609 }
610 DBG1(DBG_IKE, "no peer config found");
611 return NULL;
612 }
613
614 METHOD(phase1_t, get_id, identification_t*,
615 private_phase1_t *this, peer_cfg_t *peer_cfg, bool local)
616 {
617 identification_t *id = NULL;
618 auth_cfg_t *auth;
619
620 auth = get_auth_cfg(peer_cfg, local);
621 if (auth)
622 {
623 id = auth->get(auth, AUTH_RULE_IDENTITY);
624 if (local && (!id || id->get_type(id) == ID_ANY))
625 { /* no ID configured, use local IP address */
626 host_t *me;
627
628 me = this->ike_sa->get_my_host(this->ike_sa);
629 if (!me->is_anyaddr(me))
630 {
631 id = identification_create_from_sockaddr(me->get_sockaddr(me));
632 auth->add(auth, AUTH_RULE_IDENTITY, id);
633 }
634 }
635 }
636 return id;
637 }
638
639 METHOD(phase1_t, has_virtual_ip, bool,
640 private_phase1_t *this, peer_cfg_t *peer_cfg)
641 {
642 enumerator_t *enumerator;
643 bool found = FALSE;
644 host_t *host;
645
646 enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
647 found = enumerator->enumerate(enumerator, &host);
648 enumerator->destroy(enumerator);
649
650 return found;
651 }
652
653 METHOD(phase1_t, has_pool, bool,
654 private_phase1_t *this, peer_cfg_t *peer_cfg)
655 {
656 enumerator_t *enumerator;
657 bool found = FALSE;
658 char *pool;
659
660 enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
661 found = enumerator->enumerate(enumerator, &pool);
662 enumerator->destroy(enumerator);
663
664 return found;
665 }
666
667 METHOD(phase1_t, save_sa_payload, bool,
668 private_phase1_t *this, message_t *message)
669 {
670 enumerator_t *enumerator;
671 payload_t *payload, *sa = NULL;
672 chunk_t data;
673 size_t offset = IKE_HEADER_LENGTH;
674
675 enumerator = message->create_payload_enumerator(message);
676 while (enumerator->enumerate(enumerator, &payload))
677 {
678 if (payload->get_type(payload) == PLV1_SECURITY_ASSOCIATION)
679 {
680 sa = payload;
681 break;
682 }
683 else
684 {
685 offset += payload->get_length(payload);
686 }
687 }
688 enumerator->destroy(enumerator);
689
690 data = message->get_packet_data(message);
691 if (sa && data.len >= offset + sa->get_length(sa))
692 {
693 /* Get SA payload without 4 byte fixed header */
694 data = chunk_skip(data, offset);
695 data.len = sa->get_length(sa);
696 data = chunk_skip(data, 4);
697 this->sa_payload = chunk_clone(data);
698 return TRUE;
699 }
700 DBG1(DBG_IKE, "unable to extract SA payload encoding");
701 return FALSE;
702 }
703
704 METHOD(phase1_t, add_nonce_ke, bool,
705 private_phase1_t *this, message_t *message)
706 {
707 nonce_payload_t *nonce_payload;
708 ke_payload_t *ke_payload;
709 nonce_gen_t *nonceg;
710 chunk_t nonce;
711
712 ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
713 this->dh);
714 if (!ke_payload)
715 {
716 DBG1(DBG_IKE, "creating KE payload failed");
717 return FALSE;
718 }
719 message->add_payload(message, &ke_payload->payload_interface);
720
721 nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
722 if (!nonceg)
723 {
724 DBG1(DBG_IKE, "no nonce generator found to create nonce");
725 return FALSE;
726 }
727 if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &nonce))
728 {
729 DBG1(DBG_IKE, "nonce allocation failed");
730 nonceg->destroy(nonceg);
731 return FALSE;
732 }
733 nonceg->destroy(nonceg);
734
735 nonce_payload = nonce_payload_create(PLV1_NONCE);
736 nonce_payload->set_nonce(nonce_payload, nonce);
737 message->add_payload(message, &nonce_payload->payload_interface);
738
739 if (this->initiator)
740 {
741 this->nonce_i = nonce;
742 }
743 else
744 {
745 this->nonce_r = nonce;
746 }
747 return TRUE;
748 }
749
750 METHOD(phase1_t, get_nonce_ke, bool,
751 private_phase1_t *this, message_t *message)
752 {
753 nonce_payload_t *nonce_payload;
754 ke_payload_t *ke_payload;
755
756 ke_payload = (ke_payload_t*)message->get_payload(message, PLV1_KEY_EXCHANGE);
757 if (!ke_payload)
758 {
759 DBG1(DBG_IKE, "KE payload missing in message");
760 return FALSE;
761 }
762 this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
763 if (!this->dh->set_other_public_value(this->dh, this->dh_value))
764 {
765 DBG1(DBG_IKE, "unable to apply received KE value");
766 return FALSE;
767 }
768
769 nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
770 if (!nonce_payload)
771 {
772 DBG1(DBG_IKE, "NONCE payload missing in message");
773 return FALSE;
774 }
775
776 if (this->initiator)
777 {
778 this->nonce_r = nonce_payload->get_nonce(nonce_payload);
779 }
780 else
781 {
782 this->nonce_i = nonce_payload->get_nonce(nonce_payload);
783 }
784 return TRUE;
785 }
786
787 METHOD(phase1_t, destroy, void,
788 private_phase1_t *this)
789 {
790 DESTROY_IF(this->peer_cfg);
791 this->candidates->destroy_offset(this->candidates,
792 offsetof(peer_cfg_t, destroy));
793 chunk_free(&this->sa_payload);
794 DESTROY_IF(this->dh);
795 free(this->dh_value.ptr);
796 free(this->nonce_i.ptr);
797 free(this->nonce_r.ptr);
798 free(this);
799 }
800
801 /**
802 * See header
803 */
804 phase1_t *phase1_create(ike_sa_t *ike_sa, bool initiator)
805 {
806 private_phase1_t *this;
807
808 INIT(this,
809 .public = {
810 .create_hasher = _create_hasher,
811 .create_dh = _create_dh,
812 .derive_keys = _derive_keys,
813 .get_auth_method = _get_auth_method,
814 .get_id = _get_id,
815 .select_config = _select_config,
816 .has_virtual_ip = _has_virtual_ip,
817 .has_pool = _has_pool,
818 .verify_auth = _verify_auth,
819 .build_auth = _build_auth,
820 .save_sa_payload = _save_sa_payload,
821 .add_nonce_ke = _add_nonce_ke,
822 .get_nonce_ke = _get_nonce_ke,
823 .destroy = _destroy,
824 },
825 .candidates = linked_list_create(),
826 .ike_sa = ike_sa,
827 .initiator = initiator,
828 .keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
829 );
830
831 return &this->public;
832 }