]> git.saurik.com Git - apple/ipsec.git/blame_incremental - ipsec-tools/racoon/isakmp_ident.c
ipsec-34.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_ident.c
... / ...
CommitLineData
1/* $Id: isakmp_ident.c,v 1.13.2.2 2005/11/21 09:46:23 vanhu Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/* Identity Protecion Exchange (Main Mode) */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38
39#include <stdlib.h>
40#include <stdio.h>
41#include <string.h>
42#include <errno.h>
43#if TIME_WITH_SYS_TIME
44# include <sys/time.h>
45# include <time.h>
46#else
47# if HAVE_SYS_TIME_H
48# include <sys/time.h>
49# else
50# include <time.h>
51# endif
52#endif
53
54#include "var.h"
55#include "misc.h"
56#include "vmbuf.h"
57#include "plog.h"
58#include "sockmisc.h"
59#include "schedule.h"
60#include "debug.h"
61
62#include "localconf.h"
63#include "remoteconf.h"
64#include "isakmp_var.h"
65#include "isakmp.h"
66#include "evt.h"
67#include "oakley.h"
68#include "handler.h"
69#include "ipsec_doi.h"
70#include "crypto_openssl.h"
71#include "pfkey.h"
72#include "isakmp_ident.h"
73#include "isakmp_inf.h"
74#include "vendorid.h"
75
76#ifdef ENABLE_NATT
77#include "nattraversal.h"
78#endif
79#ifdef HAVE_GSSAPI
80#include "gssapi.h"
81#endif
82
83#include "vpn_control.h"
84#include "vpn_control_var.h"
85
86static vchar_t *ident_ir2mx __P((struct ph1handle *));
87static vchar_t *ident_ir3mx __P((struct ph1handle *));
88
89/* %%%
90 * begin Identity Protection Mode as initiator.
91 */
92/*
93 * send to responder
94 * psk: HDR, SA
95 * sig: HDR, SA
96 * rsa: HDR, SA
97 * rev: HDR, SA
98 */
99int
100ident_i1send(iph1, msg)
101 struct ph1handle *iph1;
102 vchar_t *msg; /* must be null */
103{
104 struct payload_list *plist = NULL;
105 int error = -1;
106#ifdef ENABLE_NATT
107 vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
108 int i;
109#endif
110#ifdef ENABLE_DPD
111 vchar_t *vid_dpd = NULL;
112#endif
113 /* validity check */
114 if (msg != NULL) {
115 plog(LLV_ERROR, LOCATION, NULL,
116 "msg has to be NULL in this function.\n");
117 goto end;
118 }
119 if (iph1->status != PHASE1ST_START) {
120 plog(LLV_ERROR, LOCATION, NULL,
121 "status mismatched %d.\n", iph1->status);
122 goto end;
123 }
124
125 /* create isakmp index */
126 memset(&iph1->index, 0, sizeof(iph1->index));
127 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
128
129 /* create SA payload for my proposal */
130 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
131 if (iph1->sa == NULL)
132 goto end;
133
134 /* set SA payload to propose */
135 plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
136
137#ifdef ENABLE_NATT
138 /* set VID payload for NAT-T if NAT-T support allowed in the config file */
139 if (iph1->rmconf->nat_traversal)
140 plist = isakmp_plist_append_natt_vids(plist, vid_natt);
141#endif
142#ifdef ENABLE_DPD
143 if(iph1->rmconf->dpd){
144 vid_dpd = set_vendorid(VENDORID_DPD);
145 if (vid_dpd != NULL)
146 plist = isakmp_plist_append(plist, vid_dpd,
147 ISAKMP_NPTYPE_VID);
148 }
149#endif
150
151 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
152
153#ifdef HAVE_PRINT_ISAKMP_C
154 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
155#endif
156
157 /* send the packet, add to the schedule to resend */
158 iph1->retry_counter = iph1->rmconf->retry_counter;
159 if (isakmp_ph1resend(iph1) == -1)
160 goto end;
161
162 iph1->status = PHASE1ST_MSG1SENT;
163
164 error = 0;
165
166end:
167#ifdef ENABLE_NATT
168 for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
169 vfree(vid_natt[i]);
170#endif
171#ifdef ENABLE_DPD
172 if (vid_dpd != NULL)
173 vfree(vid_dpd);
174#endif
175
176 return error;
177}
178
179/*
180 * receive from responder
181 * psk: HDR, SA
182 * sig: HDR, SA
183 * rsa: HDR, SA
184 * rev: HDR, SA
185 */
186int
187ident_i2recv(iph1, msg)
188 struct ph1handle *iph1;
189 vchar_t *msg;
190{
191 vchar_t *pbuf = NULL;
192 struct isakmp_parse_t *pa;
193 vchar_t *satmp = NULL;
194 int error = -1;
195 int vid_numeric;
196
197 /* validity check */
198 if (iph1->status != PHASE1ST_MSG1SENT) {
199 plog(LLV_ERROR, LOCATION, NULL,
200 "status mismatched %d.\n", iph1->status);
201 goto end;
202 }
203
204 /* validate the type of next payload */
205 /*
206 * NOTE: RedCreek(as responder) attaches N[responder-lifetime] here,
207 * if proposal-lifetime > lifetime-redcreek-wants.
208 * (see doi-08 4.5.4)
209 * => According to the seciton 4.6.3 in RFC 2407, This is illegal.
210 * NOTE: we do not really care about ordering of VID and N.
211 * does it matters?
212 * NOTE: even if there's multiple VID/N, we'll ignore them.
213 */
214 pbuf = isakmp_parse(msg);
215 if (pbuf == NULL)
216 goto end;
217 pa = (struct isakmp_parse_t *)pbuf->v;
218
219 /* SA payload is fixed postion */
220 if (pa->type != ISAKMP_NPTYPE_SA) {
221 plog(LLV_ERROR, LOCATION, iph1->remote,
222 "received invalid next payload type %d, "
223 "expecting %d.\n",
224 pa->type, ISAKMP_NPTYPE_SA);
225 goto end;
226 }
227 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
228 goto end;
229 pa++;
230
231 for (/*nothing*/;
232 pa->type != ISAKMP_NPTYPE_NONE;
233 pa++) {
234
235 switch (pa->type) {
236 case ISAKMP_NPTYPE_VID:
237 vid_numeric = check_vendorid(pa->ptr);
238#ifdef ENABLE_NATT
239 if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
240 natt_handle_vendorid(iph1, vid_numeric);
241#endif
242#ifdef ENABLE_DPD
243 if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
244 iph1->dpd_support=1;
245#endif
246 break;
247 default:
248 /* don't send information, see ident_r1recv() */
249 plog(LLV_ERROR, LOCATION, iph1->remote,
250 "ignore the packet, "
251 "received unexpecting payload type %d.\n",
252 pa->type);
253 goto end;
254 }
255 }
256
257#ifdef ENABLE_NATT
258 if (NATT_AVAILABLE(iph1))
259 plog(LLV_INFO, LOCATION, iph1->remote,
260 "Selected NAT-T version: %s\n",
261 vid_string_by_id(iph1->natt_options->version));
262#endif
263
264 /* check SA payload and set approval SA for use */
265 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
266 plog(LLV_ERROR, LOCATION, iph1->remote,
267 "failed to get valid proposal.\n");
268 /* XXX send information */
269 goto end;
270 }
271 VPTRINIT(iph1->sa_ret);
272
273 iph1->status = PHASE1ST_MSG2RECEIVED;
274
275#ifdef ENABLE_VPNCONTROL_PORT
276 vpncontrol_notify_phase_change(1, FROM_REMOTE, iph1, NULL);
277#endif
278
279 error = 0;
280
281end:
282 if (pbuf)
283 vfree(pbuf);
284 if (satmp)
285 vfree(satmp);
286 return error;
287}
288
289/*
290 * send to responder
291 * psk: HDR, KE, Ni
292 * sig: HDR, KE, Ni
293 * gssapi: HDR, KE, Ni, GSSi
294 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
295 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
296 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
297 */
298int
299ident_i2send(iph1, msg)
300 struct ph1handle *iph1;
301 vchar_t *msg;
302{
303 int error = -1;
304
305 /* validity check */
306 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
307 plog(LLV_ERROR, LOCATION, NULL,
308 "status mismatched %d.\n", iph1->status);
309 goto end;
310 }
311
312 /* fix isakmp index */
313 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
314 sizeof(cookie_t));
315
316 /* generate DH public value */
317 if (oakley_dh_generate(iph1->approval->dhgrp,
318 &iph1->dhpub, &iph1->dhpriv) < 0)
319 goto end;
320
321 /* generate NONCE value */
322 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
323 if (iph1->nonce == NULL)
324 goto end;
325
326#ifdef HAVE_GSSAPI
327 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
328 gssapi_get_itoken(iph1, NULL) < 0)
329 goto end;
330#endif
331
332 /* create buffer to send isakmp payload */
333 iph1->sendbuf = ident_ir2mx(iph1);
334 if (iph1->sendbuf == NULL)
335 goto end;
336
337#ifdef HAVE_PRINT_ISAKMP_C
338 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
339#endif
340
341 /* send the packet, add to the schedule to resend */
342 iph1->retry_counter = iph1->rmconf->retry_counter;
343 if (isakmp_ph1resend(iph1) == -1)
344 goto end;
345
346 /* the sending message is added to the received-list. */
347 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
348 plog(LLV_ERROR , LOCATION, NULL,
349 "failed to add a response packet to the tree.\n");
350 goto end;
351 }
352
353 iph1->status = PHASE1ST_MSG2SENT;
354
355 error = 0;
356
357end:
358 return error;
359}
360
361/*
362 * receive from responder
363 * psk: HDR, KE, Nr
364 * sig: HDR, KE, Nr [, CR ]
365 * gssapi: HDR, KE, Nr, GSSr
366 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
367 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
368 */
369int
370ident_i3recv(iph1, msg)
371 struct ph1handle *iph1;
372 vchar_t *msg;
373{
374 vchar_t *pbuf = NULL;
375 struct isakmp_parse_t *pa;
376 int error = -1;
377#ifdef HAVE_GSSAPI
378 vchar_t *gsstoken = NULL;
379#endif
380#ifdef ENABLE_NATT
381 vchar_t *natd_received;
382 int natd_seq = 0, natd_verified;
383#endif
384
385 /* validity check */
386 if (iph1->status != PHASE1ST_MSG2SENT) {
387 plog(LLV_ERROR, LOCATION, NULL,
388 "status mismatched %d.\n", iph1->status);
389 goto end;
390 }
391
392 /* validate the type of next payload */
393 pbuf = isakmp_parse(msg);
394 if (pbuf == NULL)
395 goto end;
396
397 for (pa = (struct isakmp_parse_t *)pbuf->v;
398 pa->type != ISAKMP_NPTYPE_NONE;
399 pa++) {
400
401 switch (pa->type) {
402 case ISAKMP_NPTYPE_KE:
403 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
404 goto end;
405 break;
406 case ISAKMP_NPTYPE_NONCE:
407 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
408 goto end;
409 break;
410 case ISAKMP_NPTYPE_VID:
411 (void)check_vendorid(pa->ptr);
412 break;
413 case ISAKMP_NPTYPE_CR:
414 if (oakley_savecr(iph1, pa->ptr) < 0)
415 goto end;
416 break;
417#ifdef HAVE_GSSAPI
418 case ISAKMP_NPTYPE_GSS:
419 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
420 goto end;
421 gssapi_save_received_token(iph1, gsstoken);
422 break;
423#endif
424
425#ifdef ENABLE_NATT
426 case ISAKMP_NPTYPE_NATD_DRAFT:
427 case ISAKMP_NPTYPE_NATD_RFC:
428#ifdef __APPLE__
429 case ISAKMP_NPTYPE_NATD_BADDRAFT:
430#endif
431 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
432 pa->type == iph1->natt_options->payload_nat_d) {
433 natd_received = NULL;
434 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
435 goto end;
436
437 /* set both bits first so that we can clear them
438 upon verifying hashes */
439 if (natd_seq == 0)
440 iph1->natt_flags |= NAT_DETECTED;
441
442 /* this function will clear appropriate bits bits
443 from iph1->natt_flags */
444 natd_verified = natt_compare_addr_hash (iph1,
445 natd_received, natd_seq++);
446
447 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
448 natd_seq - 1,
449 natd_verified ? "verified" : "doesn't match");
450
451 vfree (natd_received);
452 break;
453 }
454 /* %%%% Be lenient here - some servers send natd payloads */
455 /* when no nat is detected */
456 break;
457#endif
458
459 default:
460 /* don't send information, see ident_r1recv() */
461 plog(LLV_ERROR, LOCATION, iph1->remote,
462 "ignore the packet, "
463 "received unexpecting payload type %d.\n",
464 pa->type);
465 goto end;
466 }
467 }
468
469#ifdef ENABLE_NATT
470 if (NATT_AVAILABLE(iph1)) {
471 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
472 iph1->natt_flags & NAT_DETECTED ?
473 "detected:" : "not detected",
474 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
475 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
476 if (iph1->natt_flags & NAT_DETECTED)
477 natt_float_ports (iph1);
478 }
479#endif
480
481 /* payload existency check */
482 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
483 plog(LLV_ERROR, LOCATION, iph1->remote,
484 "few isakmp message received.\n");
485 goto end;
486 }
487
488 if (oakley_checkcr(iph1) < 0) {
489 /* Ignore this error in order to be interoperability. */
490 ;
491 }
492
493 iph1->status = PHASE1ST_MSG3RECEIVED;
494
495 error = 0;
496
497end:
498 if (pbuf)
499 vfree(pbuf);
500 if (error) {
501 VPTRINIT(iph1->dhpub_p);
502 VPTRINIT(iph1->nonce_p);
503 VPTRINIT(iph1->id_p);
504 oakley_delcert(iph1->cr_p);
505 iph1->cr_p = NULL;
506 }
507
508 return error;
509}
510
511/*
512 * send to responder
513 * psk: HDR*, IDi1, HASH_I
514 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
515 * gssapi: HDR*, IDi1, < Gssi(n) | HASH_I >
516 * rsa: HDR*, HASH_I
517 * rev: HDR*, HASH_I
518 */
519int
520ident_i3send(iph1, msg0)
521 struct ph1handle *iph1;
522 vchar_t *msg0;
523{
524 int error = -1;
525 int dohash = 1;
526#ifdef HAVE_GSSAPI
527 int len;
528#endif
529
530 /* validity check */
531 if (iph1->status != PHASE1ST_MSG3RECEIVED) {
532 plog(LLV_ERROR, LOCATION, NULL,
533 "status mismatched %d.\n", iph1->status);
534 goto end;
535 }
536
537 /* compute sharing secret of DH */
538 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
539 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
540 goto end;
541
542 /* generate SKEYIDs & IV & final cipher key */
543 if (oakley_skeyid(iph1) < 0)
544 goto end;
545 if (oakley_skeyid_dae(iph1) < 0)
546 goto end;
547 if (oakley_compute_enckey(iph1) < 0)
548 goto end;
549 if (oakley_newiv(iph1) < 0)
550 goto end;
551
552 /* make ID payload into isakmp status */
553 if (ipsecdoi_setid1(iph1) < 0)
554 goto end;
555
556#ifdef HAVE_GSSAPI
557 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
558 gssapi_more_tokens(iph1)) {
559 plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n");
560 if (gssapi_get_itoken(iph1, &len) < 0)
561 goto end;
562 if (len != 0)
563 dohash = 0;
564 }
565#endif
566
567 /* generate HASH to send */
568 if (dohash) {
569 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
570 if (iph1->hash == NULL)
571 goto end;
572 } else
573 iph1->hash = NULL;
574
575 /* set encryption flag */
576 iph1->flags |= ISAKMP_FLAG_E;
577
578 /* create HDR;ID;HASH payload */
579 iph1->sendbuf = ident_ir3mx(iph1);
580 if (iph1->sendbuf == NULL)
581 goto end;
582
583 /* send the packet, add to the schedule to resend */
584 iph1->retry_counter = iph1->rmconf->retry_counter;
585 if (isakmp_ph1resend(iph1) == -1)
586 goto end;
587
588 /* the sending message is added to the received-list. */
589 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) {
590 plog(LLV_ERROR , LOCATION, NULL,
591 "failed to add a response packet to the tree.\n");
592 goto end;
593 }
594
595 /* see handler.h about IV synchronization. */
596 memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
597
598 iph1->status = PHASE1ST_MSG3SENT;
599
600 error = 0;
601
602end:
603 return error;
604}
605
606/*
607 * receive from responder
608 * psk: HDR*, IDr1, HASH_R
609 * sig: HDR*, IDr1, [ CERT, ] SIG_R
610 * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
611 * rsa: HDR*, HASH_R
612 * rev: HDR*, HASH_R
613 */
614int
615ident_i4recv(iph1, msg0)
616 struct ph1handle *iph1;
617 vchar_t *msg0;
618{
619 vchar_t *pbuf = NULL;
620 struct isakmp_parse_t *pa;
621 vchar_t *msg = NULL;
622 int error = -1;
623 int type;
624#ifdef HAVE_GSSAPI
625 vchar_t *gsstoken = NULL;
626#endif
627
628 /* validity check */
629 if (iph1->status != PHASE1ST_MSG3SENT) {
630 plog(LLV_ERROR, LOCATION, NULL,
631 "status mismatched %d.\n", iph1->status);
632 goto end;
633 }
634
635 /* decrypting */
636 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
637 plog(LLV_ERROR, LOCATION, iph1->remote,
638 "ignore the packet, "
639 "expecting the packet encrypted.\n");
640 goto end;
641 }
642 msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
643 if (msg == NULL)
644 goto end;
645
646 /* validate the type of next payload */
647 pbuf = isakmp_parse(msg);
648 if (pbuf == NULL)
649 goto end;
650
651 iph1->pl_hash = NULL;
652
653 for (pa = (struct isakmp_parse_t *)pbuf->v;
654 pa->type != ISAKMP_NPTYPE_NONE;
655 pa++) {
656
657 switch (pa->type) {
658 case ISAKMP_NPTYPE_ID:
659 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
660 goto end;
661 break;
662 case ISAKMP_NPTYPE_HASH:
663 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
664 break;
665 case ISAKMP_NPTYPE_CERT:
666 if (oakley_savecert(iph1, pa->ptr) < 0)
667 goto end;
668 break;
669 case ISAKMP_NPTYPE_SIG:
670 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
671 goto end;
672 break;
673#ifdef HAVE_GSSAPI
674 case ISAKMP_NPTYPE_GSS:
675 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
676 goto end;
677 gssapi_save_received_token(iph1, gsstoken);
678 break;
679#endif
680 case ISAKMP_NPTYPE_VID:
681 (void)check_vendorid(pa->ptr);
682 break;
683 case ISAKMP_NPTYPE_N:
684 isakmp_check_notify(pa->ptr, iph1);
685 break;
686 default:
687 /* don't send information, see ident_r1recv() */
688 plog(LLV_ERROR, LOCATION, iph1->remote,
689 "ignore the packet, "
690 "received unexpecting payload type %d.\n",
691 pa->type);
692 goto end;
693 }
694 }
695
696 /* payload existency check */
697
698 /* verify identifier */
699 if (ipsecdoi_checkid1(iph1) != 0) {
700 plog(LLV_ERROR, LOCATION, iph1->remote,
701 "invalid ID payload.\n");
702 goto end;
703 }
704
705 /* validate authentication value */
706#ifdef HAVE_GSSAPI
707 if (gsstoken == NULL) {
708#endif
709 type = oakley_validate_auth(iph1);
710 if (type != 0) {
711 if (type == -1) {
712 /* msg printed inner oakley_validate_auth() */
713 goto end;
714 }
715 EVT_PUSH(iph1->local, iph1->remote,
716 EVTT_PEERPH1AUTH_FAILED, NULL);
717 isakmp_info_send_n1(iph1, type, NULL);
718 goto end;
719 }
720#ifdef HAVE_GSSAPI
721 }
722#endif
723
724 /*
725 * XXX: Should we do compare two addresses, ph1handle's and ID
726 * payload's.
727 */
728
729 plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:");
730 plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
731
732 /* see handler.h about IV synchronization. */
733 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
734
735 /*
736 * If we got a GSS token, we need to this roundtrip again.
737 */
738#ifdef HAVE_GSSAPI
739 iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED :
740 PHASE1ST_MSG4RECEIVED;
741#else
742 iph1->status = PHASE1ST_MSG4RECEIVED;
743#endif
744
745 error = 0;
746
747end:
748 if (pbuf)
749 vfree(pbuf);
750 if (msg)
751 vfree(msg);
752#ifdef HAVE_GSSAPI
753 if (gsstoken)
754 vfree(gsstoken);
755#endif
756
757 if (error) {
758 VPTRINIT(iph1->id_p);
759 oakley_delcert(iph1->cert_p);
760 iph1->cert_p = NULL;
761 oakley_delcert(iph1->crl_p);
762 iph1->crl_p = NULL;
763 VPTRINIT(iph1->sig_p);
764 }
765
766 return error;
767}
768
769/*
770 * status update and establish isakmp sa.
771 */
772int
773ident_i4send(iph1, msg)
774 struct ph1handle *iph1;
775 vchar_t *msg;
776{
777 int error = -1;
778
779 /* validity check */
780 if (iph1->status != PHASE1ST_MSG4RECEIVED) {
781 plog(LLV_ERROR, LOCATION, NULL,
782 "status mismatched %d.\n", iph1->status);
783 goto end;
784 }
785
786 /* see handler.h about IV synchronization. */
787 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
788
789 iph1->status = PHASE1ST_ESTABLISHED;
790
791 error = 0;
792
793end:
794 return error;
795}
796
797/*
798 * receive from initiator
799 * psk: HDR, SA
800 * sig: HDR, SA
801 * rsa: HDR, SA
802 * rev: HDR, SA
803 */
804int
805ident_r1recv(iph1, msg)
806 struct ph1handle *iph1;
807 vchar_t *msg;
808{
809 vchar_t *pbuf = NULL;
810 struct isakmp_parse_t *pa;
811 int error = -1;
812 int vid_numeric;
813
814 /* validity check */
815 if (iph1->status != PHASE1ST_START) {
816 plog(LLV_ERROR, LOCATION, NULL,
817 "status mismatched %d.\n", iph1->status);
818 goto end;
819 }
820
821 /* validate the type of next payload */
822 /*
823 * NOTE: XXX even if multiple VID, we'll silently ignore those.
824 */
825 pbuf = isakmp_parse(msg);
826 if (pbuf == NULL)
827 goto end;
828 pa = (struct isakmp_parse_t *)pbuf->v;
829
830 /* check the position of SA payload */
831 if (pa->type != ISAKMP_NPTYPE_SA) {
832 plog(LLV_ERROR, LOCATION, iph1->remote,
833 "received invalid next payload type %d, "
834 "expecting %d.\n",
835 pa->type, ISAKMP_NPTYPE_SA);
836 goto end;
837 }
838 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
839 goto end;
840 pa++;
841
842 for (/*nothing*/;
843 pa->type != ISAKMP_NPTYPE_NONE;
844 pa++) {
845
846 switch (pa->type) {
847 case ISAKMP_NPTYPE_VID:
848 vid_numeric = check_vendorid(pa->ptr);
849#ifdef ENABLE_NATT
850 if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
851 natt_handle_vendorid(iph1, vid_numeric);
852#endif
853#ifdef ENABLE_DPD
854 if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd)
855 iph1->dpd_support=1;
856#endif
857 break;
858 default:
859 /*
860 * We don't send information to the peer even
861 * if we received malformed packet. Because we
862 * can't distinguish the malformed packet and
863 * the re-sent packet. And we do same behavior
864 * when we expect encrypted packet.
865 */
866 plog(LLV_ERROR, LOCATION, iph1->remote,
867 "ignore the packet, "
868 "received unexpecting payload type %d.\n",
869 pa->type);
870 goto end;
871 }
872 }
873
874#ifdef ENABLE_NATT
875 if (NATT_AVAILABLE(iph1))
876 plog(LLV_INFO, LOCATION, iph1->remote,
877 "Selected NAT-T version: %s\n",
878 vid_string_by_id(iph1->natt_options->version));
879#endif
880
881 /* check SA payload and set approval SA for use */
882 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
883 plog(LLV_ERROR, LOCATION, iph1->remote,
884 "failed to get valid proposal.\n");
885 /* XXX send information */
886 goto end;
887 }
888
889 iph1->status = PHASE1ST_MSG1RECEIVED;
890
891 error = 0;
892
893end:
894 if (pbuf)
895 vfree(pbuf);
896 if (error) {
897 VPTRINIT(iph1->sa);
898 }
899
900 return error;
901}
902
903/*
904 * send to initiator
905 * psk: HDR, SA
906 * sig: HDR, SA
907 * rsa: HDR, SA
908 * rev: HDR, SA
909 */
910int
911ident_r1send(iph1, msg)
912 struct ph1handle *iph1;
913 vchar_t *msg;
914{
915 struct payload_list *plist = NULL;
916 int error = -1;
917 vchar_t *gss_sa = NULL;
918 vchar_t *vid = NULL;
919#ifdef ENABLE_NATT
920 vchar_t *vid_natt = NULL;
921#endif
922#ifdef ENABLE_DPD
923 vchar_t *vid_dpd = NULL;
924#endif
925
926 /* validity check */
927 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
928 plog(LLV_ERROR, LOCATION, NULL,
929 "status mismatched %d.\n", iph1->status);
930 goto end;
931 }
932
933 /* set responder's cookie */
934 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
935
936#ifdef HAVE_GSSAPI
937 if (iph1->approval->gssid != NULL)
938 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
939 else
940#endif
941 gss_sa = iph1->sa_ret;
942
943 /* set SA payload to reply */
944 plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA);
945
946 /* Set Vendor ID, if necessary. */
947 if (vid)
948 plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
949
950#ifdef ENABLE_NATT
951 /* Has the peer announced NAT-T? */
952 if (NATT_AVAILABLE(iph1))
953 vid_natt = set_vendorid(iph1->natt_options->version);
954
955 if (vid_natt)
956 plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
957#endif
958#ifdef ENABLE_DPD
959 /* XXX only send DPD VID if remote sent it ? */
960 if(iph1->rmconf->dpd){
961 vid_dpd = set_vendorid(VENDORID_DPD);
962 if (vid_dpd != NULL)
963 plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
964 }
965#endif
966
967 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
968
969#ifdef HAVE_PRINT_ISAKMP_C
970 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
971#endif
972
973 /* send the packet, add to the schedule to resend */
974 iph1->retry_counter = iph1->rmconf->retry_counter;
975 if (isakmp_ph1resend(iph1) == -1)
976 goto end;
977
978 /* the sending message is added to the received-list. */
979 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
980 plog(LLV_ERROR , LOCATION, NULL,
981 "failed to add a response packet to the tree.\n");
982 goto end;
983 }
984
985 iph1->status = PHASE1ST_MSG1SENT;
986
987#ifdef ENABLE_VPNCONTROL_PORT
988 vpncontrol_notify_phase_change(1, FROM_LOCAL, iph1, NULL);
989#endif
990
991 error = 0;
992
993end:
994#ifdef HAVE_GSSAPI
995 if (gss_sa != iph1->sa_ret)
996 vfree(gss_sa);
997#endif
998 if (vid)
999 vfree(vid);
1000
1001#ifdef ENABLE_NATT
1002 if (vid_natt)
1003 vfree(vid_natt);
1004#endif
1005#ifdef ENABLE_DPD
1006 if (vid_dpd != NULL)
1007 vfree(vid_dpd);
1008#endif
1009
1010 return error;
1011}
1012
1013/*
1014 * receive from initiator
1015 * psk: HDR, KE, Ni
1016 * sig: HDR, KE, Ni
1017 * gssapi: HDR, KE, Ni, GSSi
1018 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
1019 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
1020 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
1021 */
1022int
1023ident_r2recv(iph1, msg)
1024 struct ph1handle *iph1;
1025 vchar_t *msg;
1026{
1027 vchar_t *pbuf = NULL;
1028 struct isakmp_parse_t *pa;
1029 int error = -1;
1030#ifdef HAVE_GSSAPI
1031 vchar_t *gsstoken = NULL;
1032#endif
1033#ifdef ENABLE_NATT
1034 int natd_seq = 0;
1035#endif
1036
1037 /* validity check */
1038 if (iph1->status != PHASE1ST_MSG1SENT) {
1039 plog(LLV_ERROR, LOCATION, NULL,
1040 "status mismatched %d.\n", iph1->status);
1041 goto end;
1042 }
1043
1044 /* validate the type of next payload */
1045 pbuf = isakmp_parse(msg);
1046 if (pbuf == NULL)
1047 goto end;
1048
1049 for (pa = (struct isakmp_parse_t *)pbuf->v;
1050 pa->type != ISAKMP_NPTYPE_NONE;
1051 pa++) {
1052 switch (pa->type) {
1053 case ISAKMP_NPTYPE_KE:
1054 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
1055 goto end;
1056 break;
1057 case ISAKMP_NPTYPE_NONCE:
1058 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
1059 goto end;
1060 break;
1061 case ISAKMP_NPTYPE_VID:
1062 (void)check_vendorid(pa->ptr);
1063 break;
1064 case ISAKMP_NPTYPE_CR:
1065 plog(LLV_WARNING, LOCATION, iph1->remote,
1066 "CR received, ignore it. "
1067 "It should be in other exchange.\n");
1068 break;
1069#ifdef HAVE_GSSAPI
1070 case ISAKMP_NPTYPE_GSS:
1071 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
1072 goto end;
1073 gssapi_save_received_token(iph1, gsstoken);
1074 break;
1075#endif
1076
1077#ifdef ENABLE_NATT
1078 case ISAKMP_NPTYPE_NATD_DRAFT:
1079 case ISAKMP_NPTYPE_NATD_RFC:
1080#ifdef __APPLE__
1081 case ISAKMP_NPTYPE_NATD_BADDRAFT:
1082#endif
1083 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
1084 pa->type == iph1->natt_options->payload_nat_d)
1085 {
1086 vchar_t *natd_received = NULL;
1087 int natd_verified;
1088
1089 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
1090 goto end;
1091
1092 if (natd_seq == 0)
1093 iph1->natt_flags |= NAT_DETECTED;
1094
1095 natd_verified = natt_compare_addr_hash (iph1,
1096 natd_received, natd_seq++);
1097
1098 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
1099 natd_seq - 1,
1100 natd_verified ? "verified" : "doesn't match");
1101
1102 vfree (natd_received);
1103 break;
1104 }
1105 /* %%%% Be lenient here - some servers send natd payloads */
1106 /* when no nat is detected */
1107 break;
1108#endif
1109
1110 default:
1111 /* don't send information, see ident_r1recv() */
1112 plog(LLV_ERROR, LOCATION, iph1->remote,
1113 "ignore the packet, "
1114 "received unexpecting payload type %d.\n",
1115 pa->type);
1116 goto end;
1117 }
1118 }
1119
1120#ifdef ENABLE_NATT
1121 if (NATT_AVAILABLE(iph1))
1122 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1123 iph1->natt_flags & NAT_DETECTED ?
1124 "detected:" : "not detected",
1125 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1126 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1127#endif
1128
1129 /* payload existency check */
1130 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
1131 plog(LLV_ERROR, LOCATION, iph1->remote,
1132 "few isakmp message received.\n");
1133 goto end;
1134 }
1135
1136 iph1->status = PHASE1ST_MSG2RECEIVED;
1137
1138 error = 0;
1139
1140end:
1141 if (pbuf)
1142 vfree(pbuf);
1143#ifdef HAVE_GSSAPI
1144 if (gsstoken)
1145 vfree(gsstoken);
1146#endif
1147
1148 if (error) {
1149 VPTRINIT(iph1->dhpub_p);
1150 VPTRINIT(iph1->nonce_p);
1151 VPTRINIT(iph1->id_p);
1152 }
1153
1154 return error;
1155}
1156
1157/*
1158 * send to initiator
1159 * psk: HDR, KE, Nr
1160 * sig: HDR, KE, Nr [, CR ]
1161 * gssapi: HDR, KE, Nr, GSSr
1162 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
1163 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
1164 */
1165int
1166ident_r2send(iph1, msg)
1167 struct ph1handle *iph1;
1168 vchar_t *msg;
1169{
1170 int error = -1;
1171
1172 /* validity check */
1173 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1174 plog(LLV_ERROR, LOCATION, NULL,
1175 "status mismatched %d.\n", iph1->status);
1176 goto end;
1177 }
1178
1179 /* generate DH public value */
1180 if (oakley_dh_generate(iph1->approval->dhgrp,
1181 &iph1->dhpub, &iph1->dhpriv) < 0)
1182 goto end;
1183
1184 /* generate NONCE value */
1185 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
1186 if (iph1->nonce == NULL)
1187 goto end;
1188
1189#ifdef HAVE_GSSAPI
1190 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1191 gssapi_get_rtoken(iph1, NULL);
1192#endif
1193
1194 /* create HDR;KE;NONCE payload */
1195 iph1->sendbuf = ident_ir2mx(iph1);
1196 if (iph1->sendbuf == NULL)
1197 goto end;
1198
1199#ifdef HAVE_PRINT_ISAKMP_C
1200 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1201#endif
1202
1203 /* send the packet, add to the schedule to resend */
1204 iph1->retry_counter = iph1->rmconf->retry_counter;
1205 if (isakmp_ph1resend(iph1) == -1)
1206 goto end;
1207
1208 /* the sending message is added to the received-list. */
1209 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1210 plog(LLV_ERROR , LOCATION, NULL,
1211 "failed to add a response packet to the tree.\n");
1212 goto end;
1213 }
1214
1215 /* compute sharing secret of DH */
1216 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
1217 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
1218 goto end;
1219
1220 /* generate SKEYIDs & IV & final cipher key */
1221 if (oakley_skeyid(iph1) < 0)
1222 goto end;
1223 if (oakley_skeyid_dae(iph1) < 0)
1224 goto end;
1225 if (oakley_compute_enckey(iph1) < 0)
1226 goto end;
1227 if (oakley_newiv(iph1) < 0)
1228 goto end;
1229
1230 iph1->status = PHASE1ST_MSG2SENT;
1231
1232 error = 0;
1233
1234end:
1235 return error;
1236}
1237
1238/*
1239 * receive from initiator
1240 * psk: HDR*, IDi1, HASH_I
1241 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
1242 * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
1243 * rsa: HDR*, HASH_I
1244 * rev: HDR*, HASH_I
1245 */
1246int
1247ident_r3recv(iph1, msg0)
1248 struct ph1handle *iph1;
1249 vchar_t *msg0;
1250{
1251 vchar_t *msg = NULL;
1252 vchar_t *pbuf = NULL;
1253 struct isakmp_parse_t *pa;
1254 int error = -1;
1255 int type;
1256#ifdef HAVE_GSSAPI
1257 vchar_t *gsstoken = NULL;
1258#endif
1259
1260 /* validity check */
1261 if (iph1->status != PHASE1ST_MSG2SENT) {
1262 plog(LLV_ERROR, LOCATION, NULL,
1263 "status mismatched %d.\n", iph1->status);
1264 goto end;
1265 }
1266
1267 /* decrypting */
1268 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1269 plog(LLV_ERROR, LOCATION, iph1->remote,
1270 "reject the packet, "
1271 "expecting the packet encrypted.\n");
1272 goto end;
1273 }
1274 msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
1275 if (msg == NULL)
1276 goto end;
1277
1278 /* validate the type of next payload */
1279 pbuf = isakmp_parse(msg);
1280 if (pbuf == NULL)
1281 goto end;
1282
1283 iph1->pl_hash = NULL;
1284
1285 for (pa = (struct isakmp_parse_t *)pbuf->v;
1286 pa->type != ISAKMP_NPTYPE_NONE;
1287 pa++) {
1288
1289 switch (pa->type) {
1290 case ISAKMP_NPTYPE_ID:
1291 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
1292 goto end;
1293 break;
1294 case ISAKMP_NPTYPE_HASH:
1295 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1296 break;
1297 case ISAKMP_NPTYPE_CR:
1298 if (oakley_savecr(iph1, pa->ptr) < 0)
1299 goto end;
1300 break;
1301 case ISAKMP_NPTYPE_CERT:
1302 if (oakley_savecert(iph1, pa->ptr) < 0)
1303 goto end;
1304 break;
1305 case ISAKMP_NPTYPE_SIG:
1306 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1307 goto end;
1308 break;
1309#ifdef HAVE_GSSAPI
1310 case ISAKMP_NPTYPE_GSS:
1311 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
1312 goto end;
1313 gssapi_save_received_token(iph1, gsstoken);
1314 break;
1315#endif
1316 case ISAKMP_NPTYPE_VID:
1317 (void)check_vendorid(pa->ptr);
1318 break;
1319 case ISAKMP_NPTYPE_N:
1320 isakmp_check_notify(pa->ptr, iph1);
1321 break;
1322 default:
1323 /* don't send information, see ident_r1recv() */
1324 plog(LLV_ERROR, LOCATION, iph1->remote,
1325 "ignore the packet, "
1326 "received unexpecting payload type %d.\n",
1327 pa->type);
1328 goto end;
1329 }
1330 }
1331
1332 /* payload existency check */
1333 /* XXX same as ident_i4recv(), should be merged. */
1334 {
1335 int ng = 0;
1336
1337 switch (iph1->approval->authmethod) {
1338 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1339 if (iph1->id_p == NULL || iph1->pl_hash == NULL)
1340 ng++;
1341 break;
1342 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1343 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1344 if (iph1->id_p == NULL || iph1->sig_p == NULL)
1345 ng++;
1346 break;
1347 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1348 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1349 if (iph1->pl_hash == NULL)
1350 ng++;
1351 break;
1352#ifdef HAVE_GSSAPI
1353 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1354 if (gsstoken == NULL && iph1->pl_hash == NULL)
1355 ng++;
1356 break;
1357#endif
1358 default:
1359 plog(LLV_ERROR, LOCATION, iph1->remote,
1360 "invalid authmethod %d why ?\n",
1361 iph1->approval->authmethod);
1362 goto end;
1363 }
1364 if (ng) {
1365 plog(LLV_ERROR, LOCATION, iph1->remote,
1366 "few isakmp message received.\n");
1367 goto end;
1368 }
1369 }
1370
1371 /* verify identifier */
1372 if (ipsecdoi_checkid1(iph1) != 0) {
1373 plog(LLV_ERROR, LOCATION, iph1->remote,
1374 "invalid ID payload.\n");
1375 goto end;
1376 }
1377
1378 /* validate authentication value */
1379#ifdef HAVE_GSSAPI
1380 if (gsstoken == NULL) {
1381#endif
1382 type = oakley_validate_auth(iph1);
1383 if (type != 0) {
1384 if (type == -1) {
1385 /* msg printed inner oakley_validate_auth() */
1386 goto end;
1387 }
1388 EVT_PUSH(iph1->local, iph1->remote,
1389 EVTT_PEERPH1AUTH_FAILED, NULL);
1390 isakmp_info_send_n1(iph1, type, NULL);
1391 goto end;
1392 }
1393#ifdef HAVE_GSSAPI
1394 }
1395#endif
1396
1397 if (oakley_checkcr(iph1) < 0) {
1398 /* Ignore this error in order to be interoperability. */
1399 ;
1400 }
1401
1402 /*
1403 * XXX: Should we do compare two addresses, ph1handle's and ID
1404 * payload's.
1405 */
1406
1407 plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n");
1408 plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
1409
1410 /* see handler.h about IV synchronization. */
1411 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
1412
1413#ifdef HAVE_GSSAPI
1414 iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED :
1415 PHASE1ST_MSG3RECEIVED;
1416#else
1417 iph1->status = PHASE1ST_MSG3RECEIVED;
1418#endif
1419
1420 error = 0;
1421
1422end:
1423 if (pbuf)
1424 vfree(pbuf);
1425 if (msg)
1426 vfree(msg);
1427#ifdef HAVE_GSSAPI
1428 if (gsstoken)
1429 vfree(gsstoken);
1430#endif
1431
1432 if (error) {
1433 VPTRINIT(iph1->id_p);
1434 oakley_delcert(iph1->cert_p);
1435 iph1->cert_p = NULL;
1436 oakley_delcert(iph1->crl_p);
1437 iph1->crl_p = NULL;
1438 VPTRINIT(iph1->sig_p);
1439 oakley_delcert(iph1->cr_p);
1440 iph1->cr_p = NULL;
1441 }
1442
1443 return error;
1444}
1445
1446/*
1447 * send to initiator
1448 * psk: HDR*, IDr1, HASH_R
1449 * sig: HDR*, IDr1, [ CERT, ] SIG_R
1450 * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
1451 * rsa: HDR*, HASH_R
1452 * rev: HDR*, HASH_R
1453 */
1454int
1455ident_r3send(iph1, msg)
1456 struct ph1handle *iph1;
1457 vchar_t *msg;
1458{
1459 int error = -1;
1460 int dohash = 1;
1461#ifdef HAVE_GSSAPI
1462 int len;
1463#endif
1464
1465 /* validity check */
1466 if (iph1->status != PHASE1ST_MSG3RECEIVED) {
1467 plog(LLV_ERROR, LOCATION, NULL,
1468 "status mismatched %d.\n", iph1->status);
1469 goto end;
1470 }
1471
1472 /* make ID payload into isakmp status */
1473 if (ipsecdoi_setid1(iph1) < 0)
1474 goto end;
1475
1476#ifdef HAVE_GSSAPI
1477 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
1478 gssapi_more_tokens(iph1)) {
1479 gssapi_get_rtoken(iph1, &len);
1480 if (len != 0)
1481 dohash = 0;
1482 }
1483#endif
1484
1485 if (dohash) {
1486 /* generate HASH to send */
1487 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
1488 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1489 if (iph1->hash == NULL)
1490 goto end;
1491 } else
1492 iph1->hash = NULL;
1493
1494 /* set encryption flag */
1495 iph1->flags |= ISAKMP_FLAG_E;
1496
1497 /* create HDR;ID;HASH payload */
1498 iph1->sendbuf = ident_ir3mx(iph1);
1499 if (iph1->sendbuf == NULL)
1500 goto end;
1501
1502 /* send HDR;ID;HASH to responder */
1503 if (isakmp_send(iph1, iph1->sendbuf) < 0)
1504 goto end;
1505
1506 /* the sending message is added to the received-list. */
1507 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1508 plog(LLV_ERROR , LOCATION, NULL,
1509 "failed to add a response packet to the tree.\n");
1510 goto end;
1511 }
1512
1513 /* see handler.h about IV synchronization. */
1514 memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
1515
1516 iph1->status = PHASE1ST_ESTABLISHED;
1517
1518 error = 0;
1519
1520end:
1521
1522 return error;
1523}
1524
1525/*
1526 * This is used in main mode for:
1527 * initiator's 3rd exchange send to responder
1528 * psk: HDR, KE, Ni
1529 * sig: HDR, KE, Ni
1530 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
1531 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
1532 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
1533 * responders 2nd exchnage send to initiator
1534 * psk: HDR, KE, Nr
1535 * sig: HDR, KE, Nr [, CR ]
1536 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
1537 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
1538 */
1539static vchar_t *
1540ident_ir2mx(iph1)
1541 struct ph1handle *iph1;
1542{
1543 vchar_t *buf = 0;
1544 struct payload_list *plist = NULL;
1545 int need_cr = 0;
1546 vchar_t *cr = NULL;
1547 vchar_t *vid = NULL;
1548 int error = -1;
1549#ifdef HAVE_GSSAPI
1550 vchar_t *gsstoken = NULL;
1551#endif
1552#ifdef ENABLE_NATT
1553 vchar_t *natd[2] = { NULL, NULL };
1554#endif
1555
1556 /* create CR if need */
1557 if (iph1->side == RESPONDER
1558 && iph1->rmconf->send_cr
1559 && oakley_needcr(iph1->approval->authmethod)
1560 && iph1->rmconf->peerscertfile == NULL) {
1561 need_cr = 1;
1562 cr = oakley_getcr(iph1);
1563 if (cr == NULL) {
1564 plog(LLV_ERROR, LOCATION, NULL,
1565 "failed to get cr buffer.\n");
1566 goto end;
1567 }
1568 }
1569
1570#ifdef HAVE_GSSAPI
1571 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1572 gssapi_get_token_to_send(iph1, &gsstoken);
1573#endif
1574
1575 /* create isakmp KE payload */
1576 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1577
1578 /* create isakmp NONCE payload */
1579 plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
1580
1581#ifdef HAVE_GSSAPI
1582 if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1583 plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
1584#endif
1585
1586 /* append vendor id, if needed */
1587 if (vid)
1588 plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
1589
1590 /* create isakmp CR payload if needed */
1591 if (need_cr)
1592 plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
1593
1594#ifdef ENABLE_NATT
1595 /* generate and append NAT-D payloads */
1596 if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED)
1597 {
1598 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1599 plog(LLV_ERROR, LOCATION, NULL,
1600 "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1601 goto end;
1602 }
1603
1604 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1605 plog(LLV_ERROR, LOCATION, NULL,
1606 "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1607 goto end;
1608 }
1609
1610 plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1611#ifdef __APPLE__
1612 /* old Apple version sends natd payloads in the wrong order */
1613 if (iph1->natt_options->version == VENDORID_NATT_APPLE) {
1614 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1615 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1616 } else
1617#endif
1618 {
1619 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1620 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1621 }
1622 }
1623#endif
1624
1625 buf = isakmp_plist_set_all (&plist, iph1);
1626
1627 error = 0;
1628
1629end:
1630 if (error && buf != NULL) {
1631 vfree(buf);
1632 buf = NULL;
1633 }
1634 if (cr)
1635 vfree(cr);
1636#ifdef HAVE_GSSAPI
1637 if (gsstoken)
1638 vfree(gsstoken);
1639#endif
1640 if (vid)
1641 vfree(vid);
1642
1643#ifdef ENABLE_NATT
1644 if (natd[0])
1645 vfree(natd[0]);
1646 if (natd[1])
1647 vfree(natd[1]);
1648#endif
1649
1650 return buf;
1651}
1652
1653/*
1654 * This is used in main mode for:
1655 * initiator's 4th exchange send to responder
1656 * psk: HDR*, IDi1, HASH_I
1657 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
1658 * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
1659 * rsa: HDR*, HASH_I
1660 * rev: HDR*, HASH_I
1661 * responders 3rd exchnage send to initiator
1662 * psk: HDR*, IDr1, HASH_R
1663 * sig: HDR*, IDr1, [ CERT, ] SIG_R
1664 * gssapi: HDR*, [ IDr1, ] < GSSr(n) | HASH_R >
1665 * rsa: HDR*, HASH_R
1666 * rev: HDR*, HASH_R
1667 */
1668static vchar_t *
1669ident_ir3mx(iph1)
1670 struct ph1handle *iph1;
1671{
1672 struct payload_list *plist = NULL;
1673 vchar_t *buf = NULL, *new = NULL;
1674 int need_cr = 0;
1675 int need_cert = 0;
1676 vchar_t *cr = NULL;
1677 int error = -1;
1678#ifdef HAVE_GSSAPI
1679 int nptype;
1680 vchar_t *gsstoken = NULL;
1681 vchar_t *gsshash = NULL;
1682#endif
1683
1684 switch (iph1->approval->authmethod) {
1685 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1686 /* create isakmp ID payload */
1687 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1688
1689 /* create isakmp HASH payload */
1690 plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
1691 break;
1692 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1693 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1694 if (oakley_getmycert(iph1) < 0)
1695 goto end;
1696
1697 if (oakley_getsign(iph1) < 0)
1698 goto end;
1699
1700 /* create CR if need */
1701 if (iph1->side == INITIATOR
1702 && iph1->rmconf->send_cr
1703 && oakley_needcr(iph1->approval->authmethod)
1704 && iph1->rmconf->peerscertfile == NULL) {
1705 need_cr = 1;
1706 cr = oakley_getcr(iph1);
1707 if (cr == NULL) {
1708 plog(LLV_ERROR, LOCATION, NULL,
1709 "failed to get cr buffer.\n");
1710 goto end;
1711 }
1712 }
1713
1714 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1715 need_cert = 1;
1716
1717 /* add ID payload */
1718 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1719
1720 /* add CERT payload if there */
1721 if (need_cert)
1722 plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
1723 /* add SIG payload */
1724 plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
1725
1726 /* create isakmp CR payload */
1727 if (need_cr)
1728 plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
1729 break;
1730#ifdef HAVE_GSSAPI
1731 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1732 if (iph1->hash != NULL) {
1733 gsshash = gssapi_wraphash(iph1);
1734 if (gsshash == NULL)
1735 goto end;
1736 } else {
1737 gssapi_get_token_to_send(iph1, &gsstoken);
1738 }
1739
1740 if (!gssapi_id_sent(iph1)) {
1741 /* create isakmp ID payload */
1742 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1743 gssapi_set_id_sent(iph1);
1744 }
1745
1746 if (iph1->hash != NULL)
1747 /* create isakmp HASH payload */
1748 plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH);
1749 else
1750 plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
1751 break;
1752#endif
1753 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1754 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1755 plog(LLV_ERROR, LOCATION, NULL,
1756 "not supported authentication type %d\n",
1757 iph1->approval->authmethod);
1758 goto end;
1759 default:
1760 plog(LLV_ERROR, LOCATION, NULL,
1761 "invalid authentication type %d\n",
1762 iph1->approval->authmethod);
1763 goto end;
1764 }
1765
1766 buf = isakmp_plist_set_all (&plist, iph1);
1767
1768#ifdef HAVE_PRINT_ISAKMP_C
1769 isakmp_printpacket(buf, iph1->local, iph1->remote, 1);
1770#endif
1771
1772 /* encoding */
1773 new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv);
1774 if (new == NULL)
1775 goto end;
1776
1777 vfree(buf);
1778
1779 buf = new;
1780
1781 error = 0;
1782
1783end:
1784 if (cr)
1785 vfree(cr);
1786 if (error && buf != NULL) {
1787 vfree(buf);
1788 buf = NULL;
1789 }
1790
1791 return buf;
1792}