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