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