]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/isakmp_agg.c
7d31b9f3e0034535287d1e286c86971600a44d0c
[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->local_natd)
709 p = set_isakmp_payload(p, iph1->local_natd, natd_type);
710 if (iph1->remote_natd)
711 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
712 }
713 #endif
714
715 #ifdef HAVE_PRINT_ISAKMP_C
716 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
717 #endif
718
719 /* send to responder */
720 if (isakmp_send(iph1, iph1->sendbuf) < 0)
721 goto end;
722
723 /* the sending message is added to the received-list. */
724 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
725 plog(LLV_ERROR , LOCATION, NULL,
726 "failed to add a response packet to the tree.\n");
727 goto end;
728 }
729
730 /* set encryption flag */
731 iph1->flags |= ISAKMP_FLAG_E;
732
733 iph1->status = PHASE1ST_ESTABLISHED;
734
735 error = 0;
736
737 end:
738 if (gsshash)
739 vfree(gsshash);
740 return error;
741 }
742
743 /*
744 * receive from initiator
745 * psk: HDR, SA, KE, Ni, IDi1
746 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
747 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
748 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
749 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
750 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
751 */
752 int
753 agg_r1recv(iph1, msg)
754 struct ph1handle *iph1;
755 vchar_t *msg;
756 {
757 int error = -1;
758 vchar_t *pbuf = NULL;
759 struct isakmp_parse_t *pa;
760 #ifdef HAVE_GSSAPI
761 vchar_t *gsstoken = NULL;
762 #endif
763
764 /* validity check */
765 if (iph1->status != PHASE1ST_START) {
766 plog(LLV_ERROR, LOCATION, NULL,
767 "status mismatched %d.\n", iph1->status);
768 goto end;
769 }
770
771 /* validate the type of next payload */
772 pbuf = isakmp_parse(msg);
773 if (pbuf == NULL)
774 goto end;
775 pa = (struct isakmp_parse_t *)pbuf->v;
776
777 /* SA payload is fixed postion */
778 if (pa->type != ISAKMP_NPTYPE_SA) {
779 plog(LLV_ERROR, LOCATION, iph1->remote,
780 "received invalid next payload type %d, "
781 "expecting %d.\n",
782 pa->type, ISAKMP_NPTYPE_SA);
783 goto end;
784 }
785 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
786 goto end;
787 pa++;
788
789 for (/*nothing*/;
790 pa->type != ISAKMP_NPTYPE_NONE;
791 pa++) {
792
793 plog(LLV_DEBUG, LOCATION, NULL,
794 "received payload of type %s\n",
795 s_isakmp_nptype(pa->type));
796
797 switch (pa->type) {
798 case ISAKMP_NPTYPE_KE:
799 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
800 goto end;
801 break;
802 case ISAKMP_NPTYPE_NONCE:
803 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
804 goto end;
805 break;
806 case ISAKMP_NPTYPE_ID:
807 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
808 goto end;
809 break;
810 case ISAKMP_NPTYPE_VID:
811 #ifdef IKE_NAT_T
812 {
813 int vid = check_vendorid(pa->ptr);
814
815 if (vid == VENDORID_NATT_RFC)
816 iph1->natt_flags |= natt_type_rfc;
817 else if (vid == VENDORID_NATT_APPLE)
818 iph1->natt_flags |= natt_type_apple;
819 else if (vid == VENDORID_NATT_02)
820 iph1->natt_flags |= natt_type_02;
821 else if (vid == VENDORID_NATT_02N)
822 iph1->natt_flags |= natt_type_02N;
823 }
824 #endif
825 break;
826 #ifdef HAVE_SIGNING_C
827 case ISAKMP_NPTYPE_CR:
828 if (oakley_savecr(iph1, pa->ptr) < 0)
829 goto end;
830 break;
831 #endif
832 #ifdef HAVE_GSSAPI
833 case ISAKMP_NPTYPE_GSS:
834 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
835 goto end;
836 gssapi_save_received_token(iph1, gsstoken);
837 break;
838 #endif
839 default:
840 /* don't send information, see isakmp_ident_r1() */
841 plog(LLV_ERROR, LOCATION, iph1->remote,
842 "ignore the packet, "
843 "received unexpecting payload type %d.\n",
844 pa->type);
845 goto end;
846 }
847 }
848
849 /* payload existency check */
850 /* XXX to be checked each authentication method. */
851
852 /* verify identifier */
853 if (ipsecdoi_checkid1(iph1) != 0) {
854 plog(LLV_ERROR, LOCATION, iph1->remote,
855 "invalid ID payload.\n");
856 goto end;
857 }
858
859 /* check SA payload and set approval SA for use */
860 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
861 plog(LLV_ERROR, LOCATION, iph1->remote,
862 "failed to get valid proposal.\n");
863 /* XXX send information */
864 goto end;
865 }
866
867 #ifdef IKE_NAT_T
868 /* if natt vid(s) received - select type to use */
869 natt_select_type(iph1);
870 #endif
871
872 #ifdef HAVE_SIGNING_C
873 if (oakley_checkcr(iph1) < 0) {
874 /* Ignore this error in order to be interoperability. */
875 ;
876 }
877 #endif
878
879 iph1->status = PHASE1ST_MSG1RECEIVED;
880
881 error = 0;
882
883 end:
884 if (pbuf)
885 vfree(pbuf);
886 if (error) {
887 VPTRINIT(iph1->sa);
888 VPTRINIT(iph1->dhpub_p);
889 VPTRINIT(iph1->nonce_p);
890 VPTRINIT(iph1->id_p);
891 oakley_delcert(iph1->cr_p);
892 iph1->cr_p = NULL;
893 }
894
895 return error;
896 }
897
898 /*
899 * send to initiator
900 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
901 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
902 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
903 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
904 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
905 */
906 int
907 agg_r1send(iph1, msg)
908 struct ph1handle *iph1;
909 vchar_t *msg;
910 {
911 struct isakmp_gen *gen;
912 char *p = NULL;
913 int tlen;
914 int need_cr = 0;
915 int need_cert = 0;
916 vchar_t *cr = NULL;
917 vchar_t *vid = NULL;
918 int error = -1;
919 #ifdef HAVE_GSSAPI
920 int gsslen;
921 vchar_t *gsstoken = NULL, *gsshash = NULL;
922 vchar_t *gss_sa = NULL;
923 #endif
924 vchar_t *nattvid = NULL;
925
926 /* validity check */
927 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
928 plog(LLV_ERROR, LOCATION, NULL,
929 "status mismatched %d.\n", iph1->status);
930 goto end;
931 }
932
933 /* set responder's cookie */
934 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
935
936 /* make ID payload into isakmp status */
937 if (ipsecdoi_setid1(iph1) < 0)
938 goto end;
939
940 /* generate DH public value */
941 if (oakley_dh_generate(iph1->rmconf->dhgrp,
942 &iph1->dhpub, &iph1->dhpriv) < 0)
943 goto end;
944
945 /* generate NONCE value */
946 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
947 if (iph1->nonce == NULL)
948 goto end;
949
950 /* compute sharing secret of DH */
951 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
952 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
953 goto end;
954
955 /* generate SKEYIDs & IV & final cipher key */
956 if (oakley_skeyid(iph1) < 0)
957 goto end;
958 if (oakley_skeyid_dae(iph1) < 0)
959 goto end;
960 if (oakley_compute_enckey(iph1) < 0)
961 goto end;
962 if (oakley_newiv(iph1) < 0)
963 goto end;
964
965 #ifdef HAVE_GSSAPI
966 if (iph1->rmconf->proposal->authmethod ==
967 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
968 gssapi_get_rtoken(iph1, &gsslen);
969 #endif
970
971 /* generate HASH to send */
972 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
973 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
974 if (iph1->hash == NULL) {
975 #ifdef HAVE_GSSAPI
976 if (gssapi_more_tokens(iph1))
977 isakmp_info_send_n1(iph1,
978 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
979 #endif
980 goto end;
981 }
982
983 #ifdef HAVE_SIGNING_C
984 /* create CR if need */
985 if (iph1->rmconf->send_cr
986 && oakley_needcr(iph1->approval->authmethod)
987 && iph1->rmconf->peerscertfile == NULL) {
988 need_cr = 1;
989 cr = oakley_getcr(iph1);
990 if (cr == NULL) {
991 plog(LLV_ERROR, LOCATION, NULL,
992 "failed to get cr buffer.\n");
993 goto end;
994 }
995 }
996 #endif
997
998 tlen = sizeof(struct isakmp);
999
1000 #ifdef IKE_NAT_T
1001 if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) {
1002 int vid_type;
1003 int natt_type = iph1->natt_flags & NATT_TYPE_MASK;
1004 if (natt_type == natt_type_rfc)
1005 vid_type = VENDORID_NATT_RFC;
1006 else if (natt_type == natt_type_apple)
1007 vid_type = VENDORID_NATT_APPLE;
1008 else if (natt_type == natt_type_02)
1009 vid_type = VENDORID_NATT_02;
1010 else
1011 vid_type = VENDORID_NATT_02N;
1012 nattvid = set_vendorid(vid_type);
1013 natd_create(iph1);
1014 if (nattvid) {
1015 tlen += sizeof(*gen) + nattvid->l;
1016 if (iph1->local_natd)
1017 tlen += sizeof(*gen) + iph1->local_natd->l;
1018 if (iph1->remote_natd)
1019 tlen += sizeof(*gen) + iph1->remote_natd->l;
1020 }
1021 }
1022 #endif
1023
1024 switch (iph1->approval->authmethod) {
1025 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1026 /* create buffer to send isakmp payload */
1027 tlen += sizeof(*gen) + iph1->sa_ret->l
1028 + sizeof(*gen) + iph1->dhpub->l
1029 + sizeof(*gen) + iph1->nonce->l
1030 + sizeof(*gen) + iph1->id->l
1031 + sizeof(*gen) + iph1->hash->l;
1032 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1033 tlen += sizeof(*gen) + vid->l;
1034 if (need_cr)
1035 tlen += sizeof(*gen) + cr->l;
1036
1037 iph1->sendbuf = vmalloc(tlen);
1038 if (iph1->sendbuf == NULL) {
1039 plog(LLV_ERROR, LOCATION, NULL,
1040 "failed to get buffer to send\n");
1041 goto end;
1042 }
1043
1044 /* set isakmp header */
1045 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1046 if (p == NULL)
1047 goto end;
1048
1049 /* set SA payload to reply */
1050 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1051
1052 /* create isakmp KE payload */
1053 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1054
1055 /* create isakmp NONCE payload */
1056 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1057
1058 /* create isakmp ID payload */
1059 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_HASH);
1060
1061 /* create isakmp HASH payload */
1062 p = set_isakmp_payload(p, iph1->hash,
1063 vid ? ISAKMP_NPTYPE_VID
1064 : (need_cr ? ISAKMP_NPTYPE_CR
1065 : (nattvid ? ISAKMP_NPTYPE_VID
1066 : ISAKMP_NPTYPE_NONE)));
1067
1068 /* append vendor id, if needed */
1069 if (vid)
1070 p = set_isakmp_payload(p, vid,
1071 need_cr ? ISAKMP_NPTYPE_CR
1072 : (nattvid ? ISAKMP_NPTYPE_VID
1073 : ISAKMP_NPTYPE_NONE));
1074
1075 /* create isakmp CR payload if needed */
1076 if (need_cr)
1077 p = set_isakmp_payload(p, cr,
1078 nattvid ? ISAKMP_NPTYPE_VID
1079 : ISAKMP_NPTYPE_NONE);
1080 break;
1081 #ifdef HAVE_SIGNING_C
1082 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1083 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1084 /* XXX if there is CR or not ? */
1085
1086 if (oakley_getmycert(iph1) < 0)
1087 goto end;
1088
1089 if (oakley_getsign(iph1) < 0)
1090 goto end;
1091
1092 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1093 need_cert = 1;
1094
1095 tlen += sizeof(*gen) + iph1->sa_ret->l
1096 + sizeof(*gen) + iph1->dhpub->l
1097 + sizeof(*gen) + iph1->nonce->l
1098 + sizeof(*gen) + iph1->id->l
1099 + sizeof(*gen) + iph1->sig->l;
1100 if (need_cert)
1101 tlen += sizeof(*gen) + iph1->cert->pl->l;
1102 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1103 tlen += sizeof(*gen) + vid->l;
1104 if (need_cr)
1105 tlen += sizeof(*gen) + cr->l;
1106
1107 iph1->sendbuf = vmalloc(tlen);
1108 if (iph1->sendbuf == NULL) {
1109 plog(LLV_ERROR, LOCATION, NULL,
1110 "failed to get buffer to send.\n");
1111 goto end;
1112 }
1113
1114 /* set isakmp header */
1115 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1116 if (p == NULL)
1117 goto end;
1118
1119 /* set SA payload to reply */
1120 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1121
1122 /* create isakmp KE payload */
1123 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1124
1125 /* create isakmp NONCE payload */
1126 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1127
1128 /* add ID payload */
1129 p = set_isakmp_payload(p, iph1->id, need_cert
1130 ? ISAKMP_NPTYPE_CERT
1131 : ISAKMP_NPTYPE_SIG);
1132
1133 /* add CERT payload if there */
1134 if (need_cert)
1135 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
1136 /* add SIG payload */
1137 p = set_isakmp_payload(p, iph1->sig,
1138 vid ? ISAKMP_NPTYPE_VID
1139 : (need_cr ? ISAKMP_NPTYPE_CR
1140 : ISAKMP_NPTYPE_NONE));
1141
1142 /* append vendor id, if needed */
1143 if (vid)
1144 p = set_isakmp_payload(p, vid,
1145 need_cr ? ISAKMP_NPTYPE_CR
1146 : (nattvid ? ISAKMP_NPTYPE_VID
1147 : ISAKMP_NPTYPE_NONE));
1148
1149 /* create isakmp CR payload if needed */
1150 if (need_cr)
1151 p = set_isakmp_payload(p, cr,
1152 nattvid ? ISAKMP_NPTYPE_VID
1153 : ISAKMP_NPTYPE_NONE);
1154
1155 #ifdef IKE_NAT_T
1156 if (nattvid) {
1157 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1158 if (iph1->local_natd)
1159 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1160 if (iph1->remote_natd)
1161 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1162 }
1163 #endif
1164 break;
1165 #endif
1166 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1167 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1168 tlen += sizeof(*gen) + iph1->hash->l;
1169 break;
1170 #ifdef HAVE_GSSAPI
1171 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1172 /* create buffer to send isakmp payload */
1173 gsshash = gssapi_wraphash(iph1);
1174 if (gsshash == NULL) {
1175 plog(LLV_ERROR, LOCATION, NULL,
1176 "failed to wrap hash\n");
1177 /*
1178 * This is probably due to the GSS roundtrips not
1179 * being finished yet. Return this error in
1180 * the hope that a fallback to main mode will
1181 * be done.
1182 */
1183 isakmp_info_send_n1(iph1,
1184 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1185 goto end;
1186 }
1187 if (iph1->approval->gssid != NULL)
1188 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
1189 else
1190 gss_sa = iph1->sa_ret;
1191
1192 tlen += sizeof(*gen) + gss_sa->l
1193 + sizeof(*gen) + iph1->dhpub->l
1194 + sizeof(*gen) + iph1->nonce->l
1195 + sizeof(*gen) + iph1->id->l
1196 + sizeof(*gen) + gsslen
1197 + sizeof(*gen) + gsshash->l;
1198 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1199 tlen += sizeof(*gen) + vid->l;
1200 iph1->sendbuf = vmalloc(tlen);
1201 if (iph1->sendbuf == NULL) {
1202 plog(LLV_ERROR, LOCATION, NULL,
1203 "failed to get buffer to send\n");
1204 goto end;
1205 }
1206
1207 /* set isakmp header */
1208 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1209 if (p == NULL)
1210 goto end;
1211
1212 /* set SA payload to reply */
1213 p = set_isakmp_payload(p, gss_sa, ISAKMP_NPTYPE_KE);
1214
1215 /* create isakmp KE payload */
1216 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1217
1218 /* create isakmp NONCE payload */
1219 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1220
1221 /* create isakmp ID payload */
1222 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_GSS);
1223
1224 /* create GSS payload */
1225 gssapi_get_token_to_send(iph1, &gsstoken);
1226 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_HASH);
1227
1228 /* create isakmp HASH payload */
1229 p = set_isakmp_payload(p, gsshash,
1230 vid != NULL || nattvid != NULL ? ISAKMP_NPTYPE_VID
1231 : ISAKMP_NPTYPE_NONE);
1232
1233 /* append vendor id, if needed */
1234 if (vid)
1235 p = set_isakmp_payload(p, vid,
1236 nattvid != NULL ? ISAKMP_NPTYPE_VID
1237 : ISAKMP_NPTYPE_NONE);
1238 break;
1239 #endif
1240 }
1241
1242 #ifdef IKE_NAT_T
1243 if (nattvid) {
1244 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1245 if (iph1->local_natd)
1246 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1247 if (iph1->remote_natd)
1248 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1249 }
1250 #endif
1251
1252
1253 #ifdef HAVE_PRINT_ISAKMP_C
1254 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1255 #endif
1256
1257 /* send the packet, add to the schedule to resend */
1258 iph1->retry_counter = iph1->rmconf->retry_counter;
1259 if (isakmp_ph1resend(iph1) == -1)
1260 goto end;
1261
1262 /* the sending message is added to the received-list. */
1263 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1264 plog(LLV_ERROR , LOCATION, NULL,
1265 "failed to add a response packet to the tree.\n");
1266 goto end;
1267 }
1268
1269 iph1->status = PHASE1ST_MSG1SENT;
1270
1271 error = 0;
1272
1273 end:
1274 if (cr)
1275 vfree(cr);
1276 if (vid)
1277 vfree(vid);
1278 if (nattvid)
1279 vfree(nattvid);
1280 #ifdef HAVE_GSSAPI
1281 if (gsstoken)
1282 vfree(gsstoken);
1283 if (gsshash)
1284 vfree(gsshash);
1285 if (gss_sa != iph1->sa_ret)
1286 vfree(gss_sa);
1287 #endif
1288
1289 return error;
1290 }
1291
1292 /*
1293 * receive from initiator
1294 * psk: HDR, HASH_I
1295 * gssapi: HDR, HASH_I
1296 * sig: HDR, [ CERT, ] SIG_I
1297 * rsa: HDR, HASH_I
1298 * rev: HDR, HASH_I
1299 */
1300 int
1301 agg_r2recv(iph1, msg0)
1302 struct ph1handle *iph1;
1303 vchar_t *msg0;
1304 {
1305 vchar_t *msg = NULL;
1306 vchar_t *pbuf = NULL;
1307 struct isakmp_parse_t *pa;
1308 int error = -1;
1309
1310 /* validity check */
1311 if (iph1->status != PHASE1ST_MSG1SENT) {
1312 plog(LLV_ERROR, LOCATION, NULL,
1313 "status mismatched %d.\n", iph1->status);
1314 goto end;
1315 }
1316
1317 /* decrypting if need. */
1318 /* XXX configurable ? */
1319 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1320 msg = oakley_do_decrypt(iph1, msg0,
1321 iph1->ivm->iv, iph1->ivm->ive);
1322 if (msg == NULL)
1323 goto end;
1324 } else
1325 msg = vdup(msg0);
1326
1327 /* validate the type of next payload */
1328 pbuf = isakmp_parse(msg);
1329 if (pbuf == NULL)
1330 goto end;
1331
1332 iph1->pl_hash = NULL;
1333
1334 for (pa = (struct isakmp_parse_t *)pbuf->v;
1335 pa->type != ISAKMP_NPTYPE_NONE;
1336 pa++) {
1337
1338 switch (pa->type) {
1339 case ISAKMP_NPTYPE_HASH:
1340 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1341 break;
1342 case ISAKMP_NPTYPE_VID:
1343 (void)check_vendorid(pa->ptr);
1344 break;
1345 #ifdef HAVE_SIGNING_C
1346 case ISAKMP_NPTYPE_CERT:
1347 if (oakley_savecert(iph1, pa->ptr) < 0)
1348 goto end;
1349 break;
1350 case ISAKMP_NPTYPE_SIG:
1351 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1352 goto end;
1353 break;
1354 #endif
1355 case ISAKMP_NPTYPE_N:
1356 isakmp_check_notify(pa->ptr, iph1);
1357 break;
1358 case ISAKMP_NPTYPE_NATD_RFC:
1359 case ISAKMP_NPTYPE_NATD_DRAFT:
1360 case ISAKMP_NPTYPE_NATD_BADDRAFT:
1361 #ifdef IKE_NAT_T
1362 if (pa->type != iph1->natd_payload_type) {
1363 plog(LLV_ERROR, LOCATION, iph1->remote,
1364 "ignore the packet, "
1365 "received unexpected natd payload type %d.\n",
1366 pa->type);
1367 goto end;
1368 }
1369
1370 {
1371 natd_match_t match = natd_matches(iph1, pa->ptr);
1372 iph1->natt_flags |= natt_natd_received;
1373 if ((match & natd_match_local) != 0)
1374 iph1->natt_flags |= natt_no_local_nat;
1375 if ((match & natd_match_remote) != 0)
1376 iph1->natt_flags |= natt_no_remote_nat;
1377 }
1378 #endif
1379 break;
1380 default:
1381 /* don't send information, see isakmp_ident_r1() */
1382 plog(LLV_ERROR, LOCATION, iph1->remote,
1383 "ignore the packet, "
1384 "received unexpecting payload type %d.\n",
1385 pa->type);
1386 goto end;
1387 }
1388 }
1389
1390 /* validate authentication value */
1391 {
1392 int type;
1393 type = oakley_validate_auth(iph1);
1394 if (type != 0) {
1395 if (type == -1) {
1396 /* message printed inner oakley_validate_auth() */
1397 goto end;
1398 }
1399 isakmp_info_send_n1(iph1, type, NULL);
1400 goto end;
1401 }
1402 }
1403
1404 iph1->status = PHASE1ST_MSG2RECEIVED;
1405
1406 error = 0;
1407
1408 end:
1409 if (pbuf)
1410 vfree(pbuf);
1411 if (msg)
1412 vfree(msg);
1413 if (error) {
1414 oakley_delcert(iph1->cert_p);
1415 iph1->cert_p = NULL;
1416 oakley_delcert(iph1->crl_p);
1417 iph1->crl_p = NULL;
1418 VPTRINIT(iph1->sig_p);
1419 }
1420
1421 return error;
1422 }
1423
1424 /*
1425 * status update and establish isakmp sa.
1426 */
1427 int
1428 agg_r2send(iph1, msg)
1429 struct ph1handle *iph1;
1430 vchar_t *msg;
1431 {
1432 int error = -1;
1433
1434 /* validity check */
1435 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1436 plog(LLV_ERROR, LOCATION, NULL,
1437 "status mismatched %d.\n", iph1->status);
1438 goto end;
1439 }
1440
1441 /* IV synchronized when packet encrypted. */
1442 /* see handler.h about IV synchronization. */
1443 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1444 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1445
1446 /* set encryption flag */
1447 iph1->flags |= ISAKMP_FLAG_E;
1448
1449 iph1->status = PHASE1ST_ESTABLISHED;
1450
1451 error = 0;
1452
1453 end:
1454 return error;
1455 }