]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/isakmp_agg.c
network_cmds-245.1.4.tar.gz
[apple/network_cmds.git] / racoon.tproj / isakmp_agg.c
1 /* $KAME: isakmp_agg.c,v 1.55 2001/12/12 15:29:13 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 /* Aggressive Exchange (Aggressive 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 #if TIME_WITH_SYS_TIME
42 # include <sys/time.h>
43 # include <time.h>
44 #else
45 # if HAVE_SYS_TIME_H
46 # include <sys/time.h>
47 # else
48 # include <time.h>
49 # endif
50 #endif
51 #include <netinet/in.h>
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_agg.h"
71 #include "isakmp_inf.h"
72 #include "isakmp_natd.h"
73 #include "vendorid.h"
74 #include "strnames.h"
75
76 #ifdef HAVE_GSSAPI
77 #include "gssapi.h"
78 #endif
79
80 /*
81 * begin Aggressive Mode as initiator.
82 */
83 /*
84 * send to responder
85 * psk: HDR, SA, KE, Ni, IDi1
86 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
87 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi
88 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
89 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
90 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
91 */
92 int
93 agg_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 need_cr = 0;
101 vchar_t *cr = NULL, *gsstoken = NULL;
102 vchar_t *vid_natt_rfc = NULL;
103 vchar_t *vid_natt_apple = NULL;
104 vchar_t *vid_natt_02 = NULL;
105 vchar_t *vid_natt_02N = NULL;
106 int error = -1;
107 int nptype;
108 #ifdef HAVE_GSSAPI
109 int len;
110 #endif
111
112 /* validity check */
113 if (msg != NULL) {
114 plog(LLV_ERROR, LOCATION, NULL,
115 "msg has to be NULL in this function.\n");
116 goto end;
117 }
118 if (iph1->status != PHASE1ST_START) {
119 plog(LLV_ERROR, LOCATION, NULL,
120 "status mismatched %d.\n", iph1->status);
121 goto end;
122 }
123
124 /* create isakmp index */
125 memset(&iph1->index, 0, sizeof(iph1->index));
126 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
127
128 /* make ID payload into isakmp status */
129 if (ipsecdoi_setid1(iph1) < 0)
130 goto end;
131
132 /* create SA payload for my proposal */
133 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
134 if (iph1->sa == NULL)
135 goto end;
136
137 /* consistency check of proposals */
138 if (iph1->rmconf->dhgrp == NULL) {
139 plog(LLV_ERROR, LOCATION, NULL,
140 "configuration failure about DH group.\n");
141 goto end;
142 }
143
144 /* generate DH public value */
145 if (oakley_dh_generate(iph1->rmconf->dhgrp,
146 &iph1->dhpub, &iph1->dhpriv) < 0)
147 goto end;
148
149 /* generate NONCE value */
150 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
151 if (iph1->nonce == NULL)
152 goto end;
153
154 #ifdef IKE_NAT_T
155 vid_natt_rfc = set_vendorid(VENDORID_NATT_RFC);
156 vid_natt_apple = set_vendorid(VENDORID_NATT_APPLE);
157 vid_natt_02 = set_vendorid(VENDORID_NATT_02);
158 vid_natt_02N = set_vendorid(VENDORID_NATT_02N);
159
160 if (vid_natt_rfc == NULL ||
161 vid_natt_apple == NULL ||
162 vid_natt_02 == NULL ||
163 vid_natt_02N == NULL) {
164 plog(LLV_ERROR, LOCATION, NULL,
165 "failed to get vendor ID buffer.\n");
166 goto end;
167 }
168
169 #endif
170
171 #ifdef HAVE_SIGNING_C
172 /* create CR if need */
173 if (iph1->rmconf->send_cr
174 && oakley_needcr(iph1->rmconf->proposal->authmethod)
175 && iph1->rmconf->peerscertfile == NULL) {
176 need_cr = 1;
177 cr = oakley_getcr(iph1);
178 if (cr == NULL) {
179 plog(LLV_ERROR, LOCATION, NULL,
180 "failed to get cr buffer.\n");
181 goto end;
182 }
183 }
184 #endif
185 plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
186 s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
187 /* create buffer to send isakmp payload */
188 tlen = sizeof(struct isakmp)
189 + sizeof(*gen) + iph1->sa->l
190 + sizeof(*gen) + iph1->dhpub->l
191 + sizeof(*gen) + iph1->nonce->l
192 + sizeof(*gen) + iph1->id->l;
193 if (need_cr)
194 tlen += sizeof(*gen) + cr->l;
195 #ifdef HAVE_GSSAPI
196 if (iph1->rmconf->proposal->authmethod ==
197 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
198 gssapi_get_itoken(iph1, &len);
199 tlen += sizeof (*gen) + len;
200 }
201 #endif
202 if (vid_natt_rfc) {
203 tlen += sizeof(*gen) + vid_natt_rfc->l;
204 tlen += sizeof(*gen) + vid_natt_apple->l;
205 tlen += sizeof(*gen) + vid_natt_02->l;
206 tlen += sizeof(*gen) + vid_natt_02N->l;
207 }
208
209 iph1->sendbuf = vmalloc(tlen);
210 if (iph1->sendbuf == NULL) {
211 plog(LLV_ERROR, LOCATION, NULL,
212 "failed to get buffer to send.\n");
213 goto end;
214 }
215
216 /* set isakmp header */
217 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
218 if (p == NULL)
219 goto end;
220
221 /* set SA payload to propose */
222 p = set_isakmp_payload(p, iph1->sa, ISAKMP_NPTYPE_KE);
223
224 /* create isakmp KE payload */
225 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
226
227 /* create isakmp NONCE payload */
228 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
229
230 /* create isakmp ID payload */
231 #ifdef HAVE_GSSAPI
232 if (iph1->rmconf->proposal->authmethod ==
233 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
234 nptype = ISAKMP_NPTYPE_GSS;
235 else
236 #endif
237 if (need_cr)
238 nptype = ISAKMP_NPTYPE_CR;
239 else
240 nptype = vid_natt_rfc ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE;
241
242 p = set_isakmp_payload(p, iph1->id, nptype);
243
244 #ifdef HAVE_GSSAPI
245 if (iph1->rmconf->proposal->authmethod ==
246 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
247 gssapi_get_token_to_send(iph1, &gsstoken);
248 p = set_isakmp_payload(p, gsstoken, vid_natt_rfc ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE);
249 } else
250 #endif
251 if (need_cr)
252 /* create isakmp CR payload */
253 p = set_isakmp_payload(p, cr, vid_natt_rfc ? ISAKMP_NPTYPE_VID : ISAKMP_NPTYPE_NONE);
254
255 if (vid_natt_rfc) {
256 p = set_isakmp_payload(p, vid_natt_rfc, ISAKMP_NPTYPE_VID);
257 p = set_isakmp_payload(p, vid_natt_apple, ISAKMP_NPTYPE_VID);
258 p = set_isakmp_payload(p, vid_natt_02, ISAKMP_NPTYPE_VID);
259 p = set_isakmp_payload(p, vid_natt_02N, ISAKMP_NPTYPE_NONE);
260 }
261
262 #ifdef HAVE_PRINT_ISAKMP_C
263 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
264 #endif
265
266 /* send the packet, add to the schedule to resend */
267 iph1->retry_counter = iph1->rmconf->retry_counter;
268 if (isakmp_ph1resend(iph1) == -1)
269 goto end;
270
271 iph1->status = PHASE1ST_MSG1SENT;
272
273 error = 0;
274
275 end:
276 if (cr)
277 vfree(cr);
278 if (gsstoken)
279 vfree(gsstoken);
280 if (vid_natt_rfc)
281 vfree(vid_natt_rfc);
282 if (vid_natt_apple)
283 vfree(vid_natt_apple);
284 if (vid_natt_02)
285 vfree(vid_natt_02);
286 if (vid_natt_02N)
287 vfree(vid_natt_02N);
288
289 return error;
290 }
291
292 /*
293 * receive from responder
294 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
295 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
296 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
297 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
298 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
299 */
300 int
301 agg_i2recv(iph1, msg)
302 struct ph1handle *iph1;
303 vchar_t *msg;
304 {
305 vchar_t *pbuf = NULL;
306 struct isakmp_parse_t *pa;
307 vchar_t *satmp = NULL;
308 int error = -1;
309 #ifdef HAVE_GSSAPI
310 vchar_t *gsstoken = NULL;
311 #endif
312
313 /* validity check */
314 if (iph1->status != PHASE1ST_MSG1SENT) {
315 plog(LLV_ERROR, LOCATION, NULL,
316 "status mismatched %d.\n", iph1->status);
317 goto end;
318 }
319
320 /* validate the type of next payload */
321 pbuf = isakmp_parse(msg);
322 if (pbuf == NULL)
323 goto end;
324 pa = (struct isakmp_parse_t *)pbuf->v;
325
326 iph1->pl_hash = NULL;
327
328 /* SA payload is fixed postion */
329 if (pa->type != ISAKMP_NPTYPE_SA) {
330 plog(LLV_ERROR, LOCATION, iph1->remote,
331 "received invalid next payload type %d, "
332 "expecting %d.\n",
333 pa->type, ISAKMP_NPTYPE_SA);
334 goto end;
335 }
336 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
337 goto end;
338 pa++;
339
340 for (/*nothing*/;
341 pa->type != ISAKMP_NPTYPE_NONE;
342 pa++) {
343
344 switch (pa->type) {
345 case ISAKMP_NPTYPE_KE:
346 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
347 goto end;
348 break;
349 case ISAKMP_NPTYPE_NONCE:
350 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
351 goto end;
352 break;
353 case ISAKMP_NPTYPE_ID:
354 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
355 goto end;
356 break;
357 case ISAKMP_NPTYPE_HASH:
358 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
359 break;
360 #ifdef HAVE_SIGNING_C
361 case ISAKMP_NPTYPE_CR:
362 if (oakley_savecr(iph1, pa->ptr) < 0)
363 goto end;
364 break;
365 case ISAKMP_NPTYPE_CERT:
366 if (oakley_savecert(iph1, pa->ptr) < 0)
367 goto end;
368 break;
369 case ISAKMP_NPTYPE_SIG:
370 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
371 goto end;
372 break;
373 #endif
374 case ISAKMP_NPTYPE_VID:
375 #ifdef IKE_NAT_T
376 {
377 int vid = check_vendorid(pa->ptr);
378
379 if (vid == VENDORID_NATT_RFC)
380 iph1->natt_flags |= natt_type_rfc;
381 else if (vid == VENDORID_NATT_APPLE)
382 iph1->natt_flags |= natt_type_apple;
383 else if (vid == VENDORID_NATT_02)
384 iph1->natt_flags |= natt_type_02;
385 else if (vid == VENDORID_NATT_02N)
386 iph1->natt_flags |= natt_type_02N;
387 }
388 #endif
389 break;
390 case ISAKMP_NPTYPE_N:
391 isakmp_check_notify(pa->ptr, iph1);
392 break;
393 #ifdef HAVE_GSSAPI
394 case ISAKMP_NPTYPE_GSS:
395 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
396 goto end;
397 gssapi_save_received_token(iph1, gsstoken);
398 break;
399 #endif
400 case ISAKMP_NPTYPE_NATD_RFC:
401 case ISAKMP_NPTYPE_NATD_DRAFT:
402 case ISAKMP_NPTYPE_NATD_BADDRAFT:
403 /*
404 * ignored for now, we need to know the hash
405 * algorithm before we can evaluate the natd
406 * payload.
407 */
408 break;
409 default:
410 /* don't send information, see isakmp_ident_r1() */
411 plog(LLV_ERROR, LOCATION, iph1->remote,
412 "ignore the packet, "
413 "received unexpecting payload type %d.\n",
414 pa->type);
415 goto end;
416 }
417 }
418
419 /* if natt vid(s) received - select type to use */
420 natt_select_type(iph1);
421
422 /* payload existency check */
423 /* XXX to be checked each authentication method. */
424
425 /* verify identifier */
426 if (ipsecdoi_checkid1(iph1) != 0) {
427 plog(LLV_ERROR, LOCATION, iph1->remote,
428 "invalid ID payload.\n");
429 goto end;
430 }
431
432 /* check SA payload and set approval SA for use */
433 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
434 plog(LLV_ERROR, LOCATION, iph1->remote,
435 "failed to get valid proposal.\n");
436 /* XXX send information */
437 goto end;
438 }
439 if (iph1->sa_ret) {
440 vfree(iph1->sa_ret);
441 iph1->sa_ret = NULL;
442 }
443
444 /* fix isakmp index */
445 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
446 sizeof(cookie_t));
447
448
449 #ifdef IKE_NAT_T
450
451 /* check natd payloads */
452 for (pa = (struct isakmp_parse_t *)pbuf->v;
453 pa->type != ISAKMP_NPTYPE_NONE;
454 pa++)
455 {
456 if (pa->type == ISAKMP_NPTYPE_NATD_RFC ||
457 pa->type == ISAKMP_NPTYPE_NATD_DRAFT ||
458 pa->type == ISAKMP_NPTYPE_NATD_BADDRAFT)
459 {
460 if (pa->type != iph1->natd_payload_type) {
461 plog(LLV_ERROR, LOCATION, iph1->remote,
462 "ignore the packet, "
463 "received unexpected natd payload type %d.\n",
464 pa->type);
465 goto end;
466 }
467
468 natd_match_t match = natd_matches(iph1, pa->ptr);
469 iph1->natt_flags |= natt_natd_received;
470 if ((match & natd_match_local) != 0)
471 iph1->natt_flags |= natt_no_local_nat;
472 if ((match & natd_match_remote) != 0)
473 iph1->natt_flags |= natt_no_remote_nat;
474 }
475 }
476 #endif
477
478 /* compute sharing secret of DH */
479 if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
480 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
481 goto end;
482
483 /* generate SKEYIDs & IV & final cipher key */
484 if (oakley_skeyid(iph1) < 0)
485 goto end;
486 if (oakley_skeyid_dae(iph1) < 0)
487 goto end;
488 if (oakley_compute_enckey(iph1) < 0)
489 goto end;
490 if (oakley_newiv(iph1) < 0)
491 goto end;
492
493 #ifdef IKE_NAT_T
494 /* Determine if we need to switch to port 4500 */
495 if (natd_hasnat(iph1))
496 {
497 /* There is a NAT between us! Switch to port 4500. */
498 if (iph1->remote->sa_family == AF_INET)
499 {
500 struct sockaddr_in *sin = (struct sockaddr_in*)iph1->remote;
501 plog(LLV_INFO, LOCATION, NULL,
502 "detected NAT, switching to port %d for %s",
503 PORT_ISAKMP_NATT, saddr2str(iph1->remote));
504 sin->sin_port = htons(PORT_ISAKMP_NATT);
505 sin = (struct sockaddr_in*)iph1->local;
506 sin->sin_port = htons(PORT_ISAKMP_NATT);
507 }
508 }
509 #endif
510
511 /* validate authentication value */
512 {
513 int type;
514 type = oakley_validate_auth(iph1);
515 if (type != 0) {
516 if (type == -1) {
517 /* message printed inner oakley_validate_auth() */
518 goto end;
519 }
520 isakmp_info_send_n1(iph1, type, NULL);
521 goto end;
522 }
523 }
524
525 #ifdef HAVE_SIGNING_C
526 if (oakley_checkcr(iph1) < 0) {
527 /* Ignore this error in order to be interoperability. */
528 ;
529 }
530 #endif
531
532 /* change status of isakmp status entry */
533 iph1->status = PHASE1ST_MSG2RECEIVED;
534
535 error = 0;
536
537 end:
538 if (pbuf)
539 vfree(pbuf);
540 if (satmp)
541 vfree(satmp);
542 if (error) {
543 VPTRINIT(iph1->dhpub_p);
544 VPTRINIT(iph1->nonce_p);
545 VPTRINIT(iph1->id_p);
546 oakley_delcert(iph1->cert_p);
547 iph1->cert_p = NULL;
548 oakley_delcert(iph1->crl_p);
549 iph1->crl_p = NULL;
550 VPTRINIT(iph1->sig_p);
551 oakley_delcert(iph1->cr_p);
552 iph1->cr_p = NULL;
553 }
554
555 return error;
556 }
557
558 /*
559 * send to responder
560 * psk: HDR, HASH_I
561 * gssapi: HDR, HASH_I
562 * sig: HDR, [ CERT, ] SIG_I
563 * rsa: HDR, HASH_I
564 * rev: HDR, HASH_I
565 */
566 int
567 agg_i2send(iph1, msg)
568 struct ph1handle *iph1;
569 vchar_t *msg;
570 {
571 struct isakmp_gen *gen;
572 char *p = NULL;
573 int tlen;
574 int need_cert = 0;
575 int error = -1;
576 vchar_t *gsshash = NULL;
577 int natd_type = 0;
578
579 /* validity check */
580 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
581 plog(LLV_ERROR, LOCATION, NULL,
582 "status mismatched %d.\n", iph1->status);
583 goto end;
584 }
585
586 /* generate HASH to send */
587 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
588 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
589 if (iph1->hash == NULL) {
590 #ifdef HAVE_GSSAPI
591 if (gssapi_more_tokens(iph1))
592 isakmp_info_send_n1(iph1,
593 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
594 #endif
595 goto end;
596 }
597
598 tlen = sizeof(struct isakmp);
599
600 #ifdef IKE_NAT_T
601 if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) {
602 natd_type = iph1->natd_payload_type;
603 natd_create(iph1);
604 if (iph1->local_natd)
605 tlen += sizeof(*gen) + iph1->local_natd->l;
606 if (iph1->remote_natd)
607 tlen += sizeof(*gen) + iph1->remote_natd->l;
608 }
609 #endif
610
611 switch (iph1->approval->authmethod) {
612 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
613 tlen += sizeof(*gen) + iph1->hash->l;
614
615 iph1->sendbuf = vmalloc(tlen);
616 if (iph1->sendbuf == NULL) {
617 plog(LLV_ERROR, LOCATION, NULL,
618 "failed to get buffer to send.\n");
619 goto end;
620 }
621
622 /* set isakmp header */
623 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
624 if (p == NULL)
625 goto end;
626
627 /* set HASH payload */
628 p = set_isakmp_payload(p, iph1->hash,
629 natd_type ? natd_type
630 : ISAKMP_NPTYPE_NONE);
631 break;
632 #ifdef HAVE_SIGNING_C
633 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
634 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
635 /* XXX if there is CR or not ? */
636
637 if (oakley_getmycert(iph1) < 0)
638 goto end;
639
640 if (oakley_getsign(iph1) < 0)
641 goto end;
642
643 if (iph1->cert != NULL && iph1->rmconf->send_cert)
644 need_cert = 1;
645
646 tlen += sizeof(*gen) + iph1->sig->l;
647 if (need_cert)
648 tlen += sizeof(*gen) + iph1->cert->pl->l;
649
650 iph1->sendbuf = vmalloc(tlen);
651 if (iph1->sendbuf == NULL) {
652 plog(LLV_ERROR, LOCATION, NULL,
653 "failed to get buffer to send.\n");
654 goto end;
655 }
656
657 /* set isakmp header */
658 p = set_isakmp_header(iph1->sendbuf, iph1, need_cert
659 ? ISAKMP_NPTYPE_CERT
660 : ISAKMP_NPTYPE_SIG);
661 if (p == NULL)
662 goto end;
663
664 /* add CERT payload if there */
665 if (need_cert)
666 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
667 /* add SIG payload */
668 p = set_isakmp_payload(p, iph1->sig,
669 natd_type ? natd_type
670 : ISAKMP_NPTYPE_NONE);
671 break;
672 #endif
673 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
674 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
675 tlen += sizeof(*gen) + iph1->hash->l;
676 break;
677 #ifdef HAVE_GSSAPI
678 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
679 gsshash = gssapi_wraphash(iph1);
680 if (gsshash == NULL) {
681 plog(LLV_ERROR, LOCATION, NULL,
682 "failed to wrap hash\n");
683 isakmp_info_send_n1(iph1,
684 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
685 goto end;
686 }
687 tlen += sizeof(*gen) + gsshash->l;
688
689 iph1->sendbuf = vmalloc(tlen);
690 if (iph1->sendbuf == NULL) {
691 plog(LLV_ERROR, LOCATION, NULL,
692 "failed to get buffer to send.\n");
693 goto end;
694 }
695 /* set isakmp header */
696 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
697 if (p == NULL)
698 goto end;
699 p = set_isakmp_payload(p, gsshash,
700 natd_type ? natd_type
701 : ISAKMP_NPTYPE_NONE);
702 break;
703 #endif
704 }
705
706 #ifdef IKE_NAT_T
707 if (natd_type) {
708 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
709 if (iph1->local_natd)
710 p = set_isakmp_payload(p, iph1->local_natd, natd_type);
711 if (iph1->remote_natd)
712 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
713 } else {
714 if (iph1->remote_natd)
715 p = set_isakmp_payload(p, iph1->remote_natd, natd_type);
716 if (iph1->local_natd)
717 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
718 }
719 }
720 #endif
721
722 #ifdef HAVE_PRINT_ISAKMP_C
723 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
724 #endif
725
726 /* send to responder */
727 if (isakmp_send(iph1, iph1->sendbuf) < 0)
728 goto end;
729
730 /* the sending message is added to the received-list. */
731 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
732 plog(LLV_ERROR , LOCATION, NULL,
733 "failed to add a response packet to the tree.\n");
734 goto end;
735 }
736
737 /* set encryption flag */
738 iph1->flags |= ISAKMP_FLAG_E;
739
740 iph1->status = PHASE1ST_ESTABLISHED;
741
742 error = 0;
743
744 end:
745 if (gsshash)
746 vfree(gsshash);
747 return error;
748 }
749
750 /*
751 * receive from initiator
752 * psk: HDR, SA, KE, Ni, IDi1
753 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
754 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
755 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
756 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
757 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
758 */
759 int
760 agg_r1recv(iph1, msg)
761 struct ph1handle *iph1;
762 vchar_t *msg;
763 {
764 int error = -1;
765 vchar_t *pbuf = NULL;
766 struct isakmp_parse_t *pa;
767 #ifdef HAVE_GSSAPI
768 vchar_t *gsstoken = NULL;
769 #endif
770
771 /* validity check */
772 if (iph1->status != PHASE1ST_START) {
773 plog(LLV_ERROR, LOCATION, NULL,
774 "status mismatched %d.\n", iph1->status);
775 goto end;
776 }
777
778 /* validate the type of next payload */
779 pbuf = isakmp_parse(msg);
780 if (pbuf == NULL)
781 goto end;
782 pa = (struct isakmp_parse_t *)pbuf->v;
783
784 /* SA payload is fixed postion */
785 if (pa->type != ISAKMP_NPTYPE_SA) {
786 plog(LLV_ERROR, LOCATION, iph1->remote,
787 "received invalid next payload type %d, "
788 "expecting %d.\n",
789 pa->type, ISAKMP_NPTYPE_SA);
790 goto end;
791 }
792 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
793 goto end;
794 pa++;
795
796 for (/*nothing*/;
797 pa->type != ISAKMP_NPTYPE_NONE;
798 pa++) {
799
800 plog(LLV_DEBUG, LOCATION, NULL,
801 "received payload of type %s\n",
802 s_isakmp_nptype(pa->type));
803
804 switch (pa->type) {
805 case ISAKMP_NPTYPE_KE:
806 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
807 goto end;
808 break;
809 case ISAKMP_NPTYPE_NONCE:
810 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
811 goto end;
812 break;
813 case ISAKMP_NPTYPE_ID:
814 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
815 goto end;
816 break;
817 case ISAKMP_NPTYPE_VID:
818 #ifdef IKE_NAT_T
819 {
820 int vid = check_vendorid(pa->ptr);
821
822 if (vid == VENDORID_NATT_RFC)
823 iph1->natt_flags |= natt_type_rfc;
824 else if (vid == VENDORID_NATT_APPLE)
825 iph1->natt_flags |= natt_type_apple;
826 else if (vid == VENDORID_NATT_02)
827 iph1->natt_flags |= natt_type_02;
828 else if (vid == VENDORID_NATT_02N)
829 iph1->natt_flags |= natt_type_02N;
830 }
831 #endif
832 break;
833 #ifdef HAVE_SIGNING_C
834 case ISAKMP_NPTYPE_CR:
835 if (oakley_savecr(iph1, pa->ptr) < 0)
836 goto end;
837 break;
838 #endif
839 #ifdef HAVE_GSSAPI
840 case ISAKMP_NPTYPE_GSS:
841 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
842 goto end;
843 gssapi_save_received_token(iph1, gsstoken);
844 break;
845 #endif
846 default:
847 /* don't send information, see isakmp_ident_r1() */
848 plog(LLV_ERROR, LOCATION, iph1->remote,
849 "ignore the packet, "
850 "received unexpecting payload type %d.\n",
851 pa->type);
852 goto end;
853 }
854 }
855
856 /* payload existency check */
857 /* XXX to be checked each authentication method. */
858
859 /* verify identifier */
860 if (ipsecdoi_checkid1(iph1) != 0) {
861 plog(LLV_ERROR, LOCATION, iph1->remote,
862 "invalid ID payload.\n");
863 goto end;
864 }
865
866 /* check SA payload and set approval SA for use */
867 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
868 plog(LLV_ERROR, LOCATION, iph1->remote,
869 "failed to get valid proposal.\n");
870 /* XXX send information */
871 goto end;
872 }
873
874 #ifdef IKE_NAT_T
875 /* if natt vid(s) received - select type to use */
876 natt_select_type(iph1);
877 #endif
878
879 #ifdef HAVE_SIGNING_C
880 if (oakley_checkcr(iph1) < 0) {
881 /* Ignore this error in order to be interoperability. */
882 ;
883 }
884 #endif
885
886 iph1->status = PHASE1ST_MSG1RECEIVED;
887
888 error = 0;
889
890 end:
891 if (pbuf)
892 vfree(pbuf);
893 if (error) {
894 VPTRINIT(iph1->sa);
895 VPTRINIT(iph1->dhpub_p);
896 VPTRINIT(iph1->nonce_p);
897 VPTRINIT(iph1->id_p);
898 oakley_delcert(iph1->cr_p);
899 iph1->cr_p = NULL;
900 }
901
902 return error;
903 }
904
905 /*
906 * send to initiator
907 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
908 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
909 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
910 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
911 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
912 */
913 int
914 agg_r1send(iph1, msg)
915 struct ph1handle *iph1;
916 vchar_t *msg;
917 {
918 struct isakmp_gen *gen;
919 char *p = NULL;
920 int tlen;
921 int need_cr = 0;
922 int need_cert = 0;
923 vchar_t *cr = NULL;
924 vchar_t *vid = NULL;
925 int error = -1;
926 #ifdef HAVE_GSSAPI
927 int gsslen;
928 vchar_t *gsstoken = NULL, *gsshash = NULL;
929 vchar_t *gss_sa = NULL;
930 #endif
931 vchar_t *nattvid = NULL;
932
933 /* validity check */
934 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
935 plog(LLV_ERROR, LOCATION, NULL,
936 "status mismatched %d.\n", iph1->status);
937 goto end;
938 }
939
940 /* set responder's cookie */
941 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
942
943 /* make ID payload into isakmp status */
944 if (ipsecdoi_setid1(iph1) < 0)
945 goto end;
946
947 /* generate DH public value */
948 if (oakley_dh_generate(iph1->rmconf->dhgrp,
949 &iph1->dhpub, &iph1->dhpriv) < 0)
950 goto end;
951
952 /* generate NONCE value */
953 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
954 if (iph1->nonce == NULL)
955 goto end;
956
957 /* compute sharing secret of DH */
958 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
959 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
960 goto end;
961
962 /* generate SKEYIDs & IV & final cipher key */
963 if (oakley_skeyid(iph1) < 0)
964 goto end;
965 if (oakley_skeyid_dae(iph1) < 0)
966 goto end;
967 if (oakley_compute_enckey(iph1) < 0)
968 goto end;
969 if (oakley_newiv(iph1) < 0)
970 goto end;
971
972 #ifdef HAVE_GSSAPI
973 if (iph1->rmconf->proposal->authmethod ==
974 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
975 gssapi_get_rtoken(iph1, &gsslen);
976 #endif
977
978 /* generate HASH to send */
979 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
980 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
981 if (iph1->hash == NULL) {
982 #ifdef HAVE_GSSAPI
983 if (gssapi_more_tokens(iph1))
984 isakmp_info_send_n1(iph1,
985 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
986 #endif
987 goto end;
988 }
989
990 #ifdef HAVE_SIGNING_C
991 /* create CR if need */
992 if (iph1->rmconf->send_cr
993 && oakley_needcr(iph1->approval->authmethod)
994 && iph1->rmconf->peerscertfile == NULL) {
995 need_cr = 1;
996 cr = oakley_getcr(iph1);
997 if (cr == NULL) {
998 plog(LLV_ERROR, LOCATION, NULL,
999 "failed to get cr buffer.\n");
1000 goto end;
1001 }
1002 }
1003 #endif
1004
1005 tlen = sizeof(struct isakmp);
1006
1007 #ifdef IKE_NAT_T
1008 if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) {
1009 int vid_type;
1010 int natt_type = iph1->natt_flags & NATT_TYPE_MASK;
1011 if (natt_type == natt_type_rfc)
1012 vid_type = VENDORID_NATT_RFC;
1013 else if (natt_type == natt_type_apple)
1014 vid_type = VENDORID_NATT_APPLE;
1015 else if (natt_type == natt_type_02)
1016 vid_type = VENDORID_NATT_02;
1017 else
1018 vid_type = VENDORID_NATT_02N;
1019 nattvid = set_vendorid(vid_type);
1020 natd_create(iph1);
1021 if (nattvid) {
1022 tlen += sizeof(*gen) + nattvid->l;
1023 if (iph1->local_natd)
1024 tlen += sizeof(*gen) + iph1->local_natd->l;
1025 if (iph1->remote_natd)
1026 tlen += sizeof(*gen) + iph1->remote_natd->l;
1027 }
1028 }
1029 #endif
1030
1031 switch (iph1->approval->authmethod) {
1032 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1033 /* create buffer to send isakmp payload */
1034 tlen += sizeof(*gen) + iph1->sa_ret->l
1035 + sizeof(*gen) + iph1->dhpub->l
1036 + sizeof(*gen) + iph1->nonce->l
1037 + sizeof(*gen) + iph1->id->l
1038 + sizeof(*gen) + iph1->hash->l;
1039 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1040 tlen += sizeof(*gen) + vid->l;
1041 if (need_cr)
1042 tlen += sizeof(*gen) + cr->l;
1043
1044 iph1->sendbuf = vmalloc(tlen);
1045 if (iph1->sendbuf == NULL) {
1046 plog(LLV_ERROR, LOCATION, NULL,
1047 "failed to get buffer to send\n");
1048 goto end;
1049 }
1050
1051 /* set isakmp header */
1052 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1053 if (p == NULL)
1054 goto end;
1055
1056 /* set SA payload to reply */
1057 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1058
1059 /* create isakmp KE payload */
1060 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1061
1062 /* create isakmp NONCE payload */
1063 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1064
1065 /* create isakmp ID payload */
1066 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_HASH);
1067
1068 /* create isakmp HASH payload */
1069 p = set_isakmp_payload(p, iph1->hash,
1070 vid ? ISAKMP_NPTYPE_VID
1071 : (need_cr ? ISAKMP_NPTYPE_CR
1072 : (nattvid ? ISAKMP_NPTYPE_VID
1073 : ISAKMP_NPTYPE_NONE)));
1074
1075 /* append vendor id, if needed */
1076 if (vid)
1077 p = set_isakmp_payload(p, vid,
1078 need_cr ? ISAKMP_NPTYPE_CR
1079 : (nattvid ? ISAKMP_NPTYPE_VID
1080 : ISAKMP_NPTYPE_NONE));
1081
1082 /* create isakmp CR payload if needed */
1083 if (need_cr)
1084 p = set_isakmp_payload(p, cr,
1085 nattvid ? ISAKMP_NPTYPE_VID
1086 : ISAKMP_NPTYPE_NONE);
1087 break;
1088 #ifdef HAVE_SIGNING_C
1089 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1090 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1091 /* XXX if there is CR or not ? */
1092
1093 if (oakley_getmycert(iph1) < 0)
1094 goto end;
1095
1096 if (oakley_getsign(iph1) < 0)
1097 goto end;
1098
1099 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1100 need_cert = 1;
1101
1102 tlen += sizeof(*gen) + iph1->sa_ret->l
1103 + sizeof(*gen) + iph1->dhpub->l
1104 + sizeof(*gen) + iph1->nonce->l
1105 + sizeof(*gen) + iph1->id->l
1106 + sizeof(*gen) + iph1->sig->l;
1107 if (need_cert)
1108 tlen += sizeof(*gen) + iph1->cert->pl->l;
1109 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1110 tlen += sizeof(*gen) + vid->l;
1111 if (need_cr)
1112 tlen += sizeof(*gen) + cr->l;
1113
1114 iph1->sendbuf = vmalloc(tlen);
1115 if (iph1->sendbuf == NULL) {
1116 plog(LLV_ERROR, LOCATION, NULL,
1117 "failed to get buffer to send.\n");
1118 goto end;
1119 }
1120
1121 /* set isakmp header */
1122 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1123 if (p == NULL)
1124 goto end;
1125
1126 /* set SA payload to reply */
1127 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1128
1129 /* create isakmp KE payload */
1130 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1131
1132 /* create isakmp NONCE payload */
1133 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1134
1135 /* add ID payload */
1136 p = set_isakmp_payload(p, iph1->id, need_cert
1137 ? ISAKMP_NPTYPE_CERT
1138 : ISAKMP_NPTYPE_SIG);
1139
1140 /* add CERT payload if there */
1141 if (need_cert)
1142 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
1143 /* add SIG payload */
1144 p = set_isakmp_payload(p, iph1->sig,
1145 vid ? ISAKMP_NPTYPE_VID
1146 : (need_cr ? ISAKMP_NPTYPE_CR
1147 : ISAKMP_NPTYPE_NONE));
1148
1149 /* append vendor id, if needed */
1150 if (vid)
1151 p = set_isakmp_payload(p, vid,
1152 need_cr ? ISAKMP_NPTYPE_CR
1153 : (nattvid ? ISAKMP_NPTYPE_VID
1154 : ISAKMP_NPTYPE_NONE));
1155
1156 /* create isakmp CR payload if needed */
1157 if (need_cr)
1158 p = set_isakmp_payload(p, cr,
1159 nattvid ? ISAKMP_NPTYPE_VID
1160 : ISAKMP_NPTYPE_NONE);
1161
1162 #ifdef IKE_NAT_T
1163 if (nattvid) {
1164 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1165 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
1166 if (iph1->local_natd)
1167 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1168 if (iph1->remote_natd)
1169 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1170 } else {
1171 if (iph1->remote_natd)
1172 p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
1173 if (iph1->local_natd)
1174 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
1175 }
1176 }
1177 #endif
1178 break;
1179 #endif
1180 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1181 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1182 tlen += sizeof(*gen) + iph1->hash->l;
1183 break;
1184 #ifdef HAVE_GSSAPI
1185 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1186 /* create buffer to send isakmp payload */
1187 gsshash = gssapi_wraphash(iph1);
1188 if (gsshash == NULL) {
1189 plog(LLV_ERROR, LOCATION, NULL,
1190 "failed to wrap hash\n");
1191 /*
1192 * This is probably due to the GSS roundtrips not
1193 * being finished yet. Return this error in
1194 * the hope that a fallback to main mode will
1195 * be done.
1196 */
1197 isakmp_info_send_n1(iph1,
1198 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1199 goto end;
1200 }
1201 if (iph1->approval->gssid != NULL)
1202 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
1203 else
1204 gss_sa = iph1->sa_ret;
1205
1206 tlen += sizeof(*gen) + gss_sa->l
1207 + sizeof(*gen) + iph1->dhpub->l
1208 + sizeof(*gen) + iph1->nonce->l
1209 + sizeof(*gen) + iph1->id->l
1210 + sizeof(*gen) + gsslen
1211 + sizeof(*gen) + gsshash->l;
1212 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1213 tlen += sizeof(*gen) + vid->l;
1214 iph1->sendbuf = vmalloc(tlen);
1215 if (iph1->sendbuf == NULL) {
1216 plog(LLV_ERROR, LOCATION, NULL,
1217 "failed to get buffer to send\n");
1218 goto end;
1219 }
1220
1221 /* set isakmp header */
1222 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1223 if (p == NULL)
1224 goto end;
1225
1226 /* set SA payload to reply */
1227 p = set_isakmp_payload(p, gss_sa, ISAKMP_NPTYPE_KE);
1228
1229 /* create isakmp KE payload */
1230 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1231
1232 /* create isakmp NONCE payload */
1233 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1234
1235 /* create isakmp ID payload */
1236 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_GSS);
1237
1238 /* create GSS payload */
1239 gssapi_get_token_to_send(iph1, &gsstoken);
1240 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_HASH);
1241
1242 /* create isakmp HASH payload */
1243 p = set_isakmp_payload(p, gsshash,
1244 vid != NULL || nattvid != NULL ? ISAKMP_NPTYPE_VID
1245 : ISAKMP_NPTYPE_NONE);
1246
1247 /* append vendor id, if needed */
1248 if (vid)
1249 p = set_isakmp_payload(p, vid,
1250 nattvid != NULL ? ISAKMP_NPTYPE_VID
1251 : ISAKMP_NPTYPE_NONE);
1252 break;
1253 #endif
1254 }
1255
1256 #ifdef IKE_NAT_T
1257 if (nattvid) {
1258 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1259 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
1260 if (iph1->local_natd)
1261 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1262 if (iph1->remote_natd)
1263 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1264 } else {
1265 if (iph1->remote_natd)
1266 p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
1267 if (iph1->local_natd)
1268 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
1269 }
1270 }
1271 #endif
1272
1273
1274 #ifdef HAVE_PRINT_ISAKMP_C
1275 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1276 #endif
1277
1278 /* send the packet, add to the schedule to resend */
1279 iph1->retry_counter = iph1->rmconf->retry_counter;
1280 if (isakmp_ph1resend(iph1) == -1)
1281 goto end;
1282
1283 /* the sending message is added to the received-list. */
1284 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1285 plog(LLV_ERROR , LOCATION, NULL,
1286 "failed to add a response packet to the tree.\n");
1287 goto end;
1288 }
1289
1290 iph1->status = PHASE1ST_MSG1SENT;
1291
1292 error = 0;
1293
1294 end:
1295 if (cr)
1296 vfree(cr);
1297 if (vid)
1298 vfree(vid);
1299 if (nattvid)
1300 vfree(nattvid);
1301 #ifdef HAVE_GSSAPI
1302 if (gsstoken)
1303 vfree(gsstoken);
1304 if (gsshash)
1305 vfree(gsshash);
1306 if (gss_sa != iph1->sa_ret)
1307 vfree(gss_sa);
1308 #endif
1309
1310 return error;
1311 }
1312
1313 /*
1314 * receive from initiator
1315 * psk: HDR, HASH_I
1316 * gssapi: HDR, HASH_I
1317 * sig: HDR, [ CERT, ] SIG_I
1318 * rsa: HDR, HASH_I
1319 * rev: HDR, HASH_I
1320 */
1321 int
1322 agg_r2recv(iph1, msg0)
1323 struct ph1handle *iph1;
1324 vchar_t *msg0;
1325 {
1326 vchar_t *msg = NULL;
1327 vchar_t *pbuf = NULL;
1328 struct isakmp_parse_t *pa;
1329 int error = -1;
1330
1331 /* validity check */
1332 if (iph1->status != PHASE1ST_MSG1SENT) {
1333 plog(LLV_ERROR, LOCATION, NULL,
1334 "status mismatched %d.\n", iph1->status);
1335 goto end;
1336 }
1337
1338 /* decrypting if need. */
1339 /* XXX configurable ? */
1340 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1341 msg = oakley_do_decrypt(iph1, msg0,
1342 iph1->ivm->iv, iph1->ivm->ive);
1343 if (msg == NULL)
1344 goto end;
1345 } else
1346 msg = vdup(msg0);
1347
1348 /* validate the type of next payload */
1349 pbuf = isakmp_parse(msg);
1350 if (pbuf == NULL)
1351 goto end;
1352
1353 iph1->pl_hash = NULL;
1354
1355 for (pa = (struct isakmp_parse_t *)pbuf->v;
1356 pa->type != ISAKMP_NPTYPE_NONE;
1357 pa++) {
1358
1359 switch (pa->type) {
1360 case ISAKMP_NPTYPE_HASH:
1361 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1362 break;
1363 case ISAKMP_NPTYPE_VID:
1364 (void)check_vendorid(pa->ptr);
1365 break;
1366 #ifdef HAVE_SIGNING_C
1367 case ISAKMP_NPTYPE_CERT:
1368 if (oakley_savecert(iph1, pa->ptr) < 0)
1369 goto end;
1370 break;
1371 case ISAKMP_NPTYPE_SIG:
1372 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1373 goto end;
1374 break;
1375 #endif
1376 case ISAKMP_NPTYPE_N:
1377 isakmp_check_notify(pa->ptr, iph1);
1378 break;
1379 case ISAKMP_NPTYPE_NATD_RFC:
1380 case ISAKMP_NPTYPE_NATD_DRAFT:
1381 case ISAKMP_NPTYPE_NATD_BADDRAFT:
1382 #ifdef IKE_NAT_T
1383 if (pa->type != iph1->natd_payload_type) {
1384 plog(LLV_ERROR, LOCATION, iph1->remote,
1385 "ignore the packet, "
1386 "received unexpected natd payload type %d.\n",
1387 pa->type);
1388 goto end;
1389 }
1390
1391 {
1392 natd_match_t match = natd_matches(iph1, pa->ptr);
1393 iph1->natt_flags |= natt_natd_received;
1394 if ((match & natd_match_local) != 0)
1395 iph1->natt_flags |= natt_no_local_nat;
1396 if ((match & natd_match_remote) != 0)
1397 iph1->natt_flags |= natt_no_remote_nat;
1398 }
1399 #endif
1400 break;
1401 default:
1402 /* don't send information, see isakmp_ident_r1() */
1403 plog(LLV_ERROR, LOCATION, iph1->remote,
1404 "ignore the packet, "
1405 "received unexpecting payload type %d.\n",
1406 pa->type);
1407 goto end;
1408 }
1409 }
1410
1411 /* validate authentication value */
1412 {
1413 int type;
1414 type = oakley_validate_auth(iph1);
1415 if (type != 0) {
1416 if (type == -1) {
1417 /* message printed inner oakley_validate_auth() */
1418 goto end;
1419 }
1420 isakmp_info_send_n1(iph1, type, NULL);
1421 goto end;
1422 }
1423 }
1424
1425 iph1->status = PHASE1ST_MSG2RECEIVED;
1426
1427 error = 0;
1428
1429 end:
1430 if (pbuf)
1431 vfree(pbuf);
1432 if (msg)
1433 vfree(msg);
1434 if (error) {
1435 oakley_delcert(iph1->cert_p);
1436 iph1->cert_p = NULL;
1437 oakley_delcert(iph1->crl_p);
1438 iph1->crl_p = NULL;
1439 VPTRINIT(iph1->sig_p);
1440 }
1441
1442 return error;
1443 }
1444
1445 /*
1446 * status update and establish isakmp sa.
1447 */
1448 int
1449 agg_r2send(iph1, msg)
1450 struct ph1handle *iph1;
1451 vchar_t *msg;
1452 {
1453 int error = -1;
1454
1455 /* validity check */
1456 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1457 plog(LLV_ERROR, LOCATION, NULL,
1458 "status mismatched %d.\n", iph1->status);
1459 goto end;
1460 }
1461
1462 /* IV synchronized when packet encrypted. */
1463 /* see handler.h about IV synchronization. */
1464 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1465 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1466
1467 /* set encryption flag */
1468 iph1->flags |= ISAKMP_FLAG_E;
1469
1470 iph1->status = PHASE1ST_ESTABLISHED;
1471
1472 error = 0;
1473
1474 end:
1475 return error;
1476 }