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