]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/isakmp_agg.c
2f1ebc56b4dd85043f2696fceff0eb554ef520f4
[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 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
424 plog(LLV_ERROR, LOCATION, iph1->remote,
425 "required payloads missing from isakmp message.\n");
426 goto end;
427 }
428
429 /* verify identifier */
430 if (ipsecdoi_checkid1(iph1) != 0) {
431 plog(LLV_ERROR, LOCATION, iph1->remote,
432 "invalid ID payload.\n");
433 goto end;
434 }
435
436 /* check SA payload and set approval SA for use */
437 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
438 plog(LLV_ERROR, LOCATION, iph1->remote,
439 "failed to get valid proposal.\n");
440 /* XXX send information */
441 goto end;
442 }
443 if (iph1->sa_ret) {
444 vfree(iph1->sa_ret);
445 iph1->sa_ret = NULL;
446 }
447
448 /* fix isakmp index */
449 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
450 sizeof(cookie_t));
451
452
453 #ifdef IKE_NAT_T
454
455 /* check natd payloads */
456 for (pa = (struct isakmp_parse_t *)pbuf->v;
457 pa->type != ISAKMP_NPTYPE_NONE;
458 pa++)
459 {
460 if (pa->type == iph1->natd_payload_type) {
461 natd_match_t match = natd_matches(iph1, pa->ptr);
462 iph1->natt_flags |= natt_natd_received;
463 if ((match & natd_match_local) != 0)
464 iph1->natt_flags |= natt_no_local_nat;
465 if ((match & natd_match_remote) != 0)
466 iph1->natt_flags |= natt_no_remote_nat;
467 }
468 }
469 #endif
470
471 /* compute sharing secret of DH */
472 if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
473 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
474 goto end;
475
476 /* generate SKEYIDs & IV & final cipher key */
477 if (oakley_skeyid(iph1) < 0)
478 goto end;
479 if (oakley_skeyid_dae(iph1) < 0)
480 goto end;
481 if (oakley_compute_enckey(iph1) < 0)
482 goto end;
483 if (oakley_newiv(iph1) < 0)
484 goto end;
485
486 #ifdef IKE_NAT_T
487 /* Determine if we need to switch to port 4500 */
488 if (natd_hasnat(iph1))
489 {
490 /* There is a NAT between us! Switch to port 4500. */
491 if (iph1->remote->sa_family == AF_INET)
492 {
493 struct sockaddr_in *sin = (struct sockaddr_in*)iph1->remote;
494 plog(LLV_INFO, LOCATION, NULL,
495 "detected NAT, switching to port %d for %s",
496 PORT_ISAKMP_NATT, saddr2str(iph1->remote));
497 sin->sin_port = htons(PORT_ISAKMP_NATT);
498 sin = (struct sockaddr_in*)iph1->local;
499 sin->sin_port = htons(PORT_ISAKMP_NATT);
500 }
501 }
502 #endif
503
504 /* validate authentication value */
505 {
506 int type;
507 type = oakley_validate_auth(iph1);
508 if (type != 0) {
509 if (type == -1) {
510 /* message printed inner oakley_validate_auth() */
511 goto end;
512 }
513 isakmp_info_send_n1(iph1, type, NULL);
514 goto end;
515 }
516 }
517
518 #ifdef HAVE_SIGNING_C
519 if (oakley_checkcr(iph1) < 0) {
520 /* Ignore this error in order to be interoperability. */
521 ;
522 }
523 #endif
524
525 /* change status of isakmp status entry */
526 iph1->status = PHASE1ST_MSG2RECEIVED;
527
528 error = 0;
529
530 end:
531 if (pbuf)
532 vfree(pbuf);
533 if (satmp)
534 vfree(satmp);
535 if (error) {
536 VPTRINIT(iph1->dhpub_p);
537 VPTRINIT(iph1->nonce_p);
538 VPTRINIT(iph1->id_p);
539 oakley_delcert(iph1->cert_p);
540 iph1->cert_p = NULL;
541 oakley_delcert(iph1->crl_p);
542 iph1->crl_p = NULL;
543 VPTRINIT(iph1->sig_p);
544 oakley_delcert(iph1->cr_p);
545 iph1->cr_p = NULL;
546 }
547
548 return error;
549 }
550
551 /*
552 * send to responder
553 * psk: HDR, HASH_I
554 * gssapi: HDR, HASH_I
555 * sig: HDR, [ CERT, ] SIG_I
556 * rsa: HDR, HASH_I
557 * rev: HDR, HASH_I
558 */
559 int
560 agg_i2send(iph1, msg)
561 struct ph1handle *iph1;
562 vchar_t *msg;
563 {
564 struct isakmp_gen *gen;
565 char *p = NULL;
566 int tlen;
567 int need_cert = 0;
568 int error = -1;
569 vchar_t *gsshash = NULL;
570 int natd_type = 0;
571
572 /* validity check */
573 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
574 plog(LLV_ERROR, LOCATION, NULL,
575 "status mismatched %d.\n", iph1->status);
576 goto end;
577 }
578
579 /* generate HASH to send */
580 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
581 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
582 if (iph1->hash == NULL) {
583 #ifdef HAVE_GSSAPI
584 if (gssapi_more_tokens(iph1))
585 isakmp_info_send_n1(iph1,
586 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
587 #endif
588 goto end;
589 }
590
591 tlen = sizeof(struct isakmp);
592
593 #ifdef IKE_NAT_T
594 if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) {
595 natd_type = iph1->natd_payload_type;
596 natd_create(iph1);
597 if (iph1->local_natd)
598 tlen += sizeof(*gen) + iph1->local_natd->l;
599 if (iph1->remote_natd)
600 tlen += sizeof(*gen) + iph1->remote_natd->l;
601 }
602 #endif
603
604 switch (iph1->approval->authmethod) {
605 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
606 tlen += sizeof(*gen) + iph1->hash->l;
607
608 iph1->sendbuf = vmalloc(tlen);
609 if (iph1->sendbuf == NULL) {
610 plog(LLV_ERROR, LOCATION, NULL,
611 "failed to get buffer to send.\n");
612 goto end;
613 }
614
615 /* set isakmp header */
616 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
617 if (p == NULL)
618 goto end;
619
620 /* set HASH payload */
621 p = set_isakmp_payload(p, iph1->hash,
622 natd_type ? natd_type
623 : ISAKMP_NPTYPE_NONE);
624 break;
625 #ifdef HAVE_SIGNING_C
626 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
627 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
628 /* XXX if there is CR or not ? */
629
630 if (oakley_getmycert(iph1) < 0)
631 goto end;
632
633 if (oakley_getsign(iph1) < 0)
634 goto end;
635
636 if (iph1->cert != NULL && iph1->rmconf->send_cert)
637 need_cert = 1;
638
639 tlen += sizeof(*gen) + iph1->sig->l;
640 if (need_cert)
641 tlen += sizeof(*gen) + iph1->cert->pl->l;
642
643 iph1->sendbuf = vmalloc(tlen);
644 if (iph1->sendbuf == NULL) {
645 plog(LLV_ERROR, LOCATION, NULL,
646 "failed to get buffer to send.\n");
647 goto end;
648 }
649
650 /* set isakmp header */
651 p = set_isakmp_header(iph1->sendbuf, iph1, need_cert
652 ? ISAKMP_NPTYPE_CERT
653 : ISAKMP_NPTYPE_SIG);
654 if (p == NULL)
655 goto end;
656
657 /* add CERT payload if there */
658 if (need_cert)
659 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
660 /* add SIG payload */
661 p = set_isakmp_payload(p, iph1->sig,
662 natd_type ? natd_type
663 : ISAKMP_NPTYPE_NONE);
664 break;
665 #endif
666 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
667 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
668 tlen += sizeof(*gen) + iph1->hash->l;
669 break;
670 #ifdef HAVE_GSSAPI
671 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
672 gsshash = gssapi_wraphash(iph1);
673 if (gsshash == NULL) {
674 plog(LLV_ERROR, LOCATION, NULL,
675 "failed to wrap hash\n");
676 isakmp_info_send_n1(iph1,
677 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
678 goto end;
679 }
680 tlen += sizeof(*gen) + gsshash->l;
681
682 iph1->sendbuf = vmalloc(tlen);
683 if (iph1->sendbuf == NULL) {
684 plog(LLV_ERROR, LOCATION, NULL,
685 "failed to get buffer to send.\n");
686 goto end;
687 }
688 /* set isakmp header */
689 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH);
690 if (p == NULL)
691 goto end;
692 p = set_isakmp_payload(p, gsshash,
693 natd_type ? natd_type
694 : ISAKMP_NPTYPE_NONE);
695 break;
696 #endif
697 }
698
699 #ifdef IKE_NAT_T
700 if (natd_type) {
701 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
702 if (iph1->local_natd)
703 p = set_isakmp_payload(p, iph1->local_natd, natd_type);
704 if (iph1->remote_natd)
705 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
706 } else {
707 if (iph1->remote_natd)
708 p = set_isakmp_payload(p, iph1->remote_natd, natd_type);
709 if (iph1->local_natd)
710 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
711 }
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 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
851 plog(LLV_ERROR, LOCATION, iph1->remote,
852 "required payloads missing from isakmp message.\n");
853 goto end;
854 }
855
856 /* verify identifier */
857 if (ipsecdoi_checkid1(iph1) != 0) {
858 plog(LLV_ERROR, LOCATION, iph1->remote,
859 "invalid ID payload.\n");
860 goto end;
861 }
862
863 /* check SA payload and set approval SA for use */
864 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
865 plog(LLV_ERROR, LOCATION, iph1->remote,
866 "failed to get valid proposal.\n");
867 /* XXX send information */
868 goto end;
869 }
870
871 #ifdef IKE_NAT_T
872 /* if natt vid(s) received - select type to use */
873 natt_select_type(iph1);
874 #endif
875
876 #ifdef HAVE_SIGNING_C
877 if (oakley_checkcr(iph1) < 0) {
878 /* Ignore this error in order to be interoperability. */
879 ;
880 }
881 #endif
882
883 iph1->status = PHASE1ST_MSG1RECEIVED;
884
885 error = 0;
886
887 end:
888 if (pbuf)
889 vfree(pbuf);
890 if (error) {
891 VPTRINIT(iph1->sa);
892 VPTRINIT(iph1->dhpub_p);
893 VPTRINIT(iph1->nonce_p);
894 VPTRINIT(iph1->id_p);
895 oakley_delcert(iph1->cr_p);
896 iph1->cr_p = NULL;
897 }
898
899 return error;
900 }
901
902 /*
903 * send to initiator
904 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
905 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
906 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
907 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
908 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
909 */
910 int
911 agg_r1send(iph1, msg)
912 struct ph1handle *iph1;
913 vchar_t *msg;
914 {
915 struct isakmp_gen *gen;
916 char *p = NULL;
917 int tlen;
918 int need_cr = 0;
919 int need_cert = 0;
920 vchar_t *cr = NULL;
921 vchar_t *vid = NULL;
922 int error = -1;
923 #ifdef HAVE_GSSAPI
924 int gsslen;
925 vchar_t *gsstoken = NULL, *gsshash = NULL;
926 vchar_t *gss_sa = NULL;
927 #endif
928 vchar_t *nattvid = NULL;
929
930 /* validity check */
931 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
932 plog(LLV_ERROR, LOCATION, NULL,
933 "status mismatched %d.\n", iph1->status);
934 goto end;
935 }
936
937 /* set responder's cookie */
938 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
939
940 /* make ID payload into isakmp status */
941 if (ipsecdoi_setid1(iph1) < 0)
942 goto end;
943
944 /* generate DH public value */
945 if (oakley_dh_generate(iph1->rmconf->dhgrp,
946 &iph1->dhpub, &iph1->dhpriv) < 0)
947 goto end;
948
949 /* generate NONCE value */
950 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
951 if (iph1->nonce == NULL)
952 goto end;
953
954 /* compute sharing secret of DH */
955 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
956 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
957 goto end;
958
959 /* generate SKEYIDs & IV & final cipher key */
960 if (oakley_skeyid(iph1) < 0)
961 goto end;
962 if (oakley_skeyid_dae(iph1) < 0)
963 goto end;
964 if (oakley_compute_enckey(iph1) < 0)
965 goto end;
966 if (oakley_newiv(iph1) < 0)
967 goto end;
968
969 #ifdef HAVE_GSSAPI
970 if (iph1->rmconf->proposal->authmethod ==
971 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
972 gssapi_get_rtoken(iph1, &gsslen);
973 #endif
974
975 /* generate HASH to send */
976 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
977 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
978 if (iph1->hash == NULL) {
979 #ifdef HAVE_GSSAPI
980 if (gssapi_more_tokens(iph1))
981 isakmp_info_send_n1(iph1,
982 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
983 #endif
984 goto end;
985 }
986
987 #ifdef HAVE_SIGNING_C
988 /* create CR if need */
989 if (iph1->rmconf->send_cr
990 && oakley_needcr(iph1->approval->authmethod)
991 && iph1->rmconf->peerscertfile == NULL) {
992 need_cr = 1;
993 cr = oakley_getcr(iph1);
994 if (cr == NULL) {
995 plog(LLV_ERROR, LOCATION, NULL,
996 "failed to get cr buffer.\n");
997 goto end;
998 }
999 }
1000 #endif
1001
1002 tlen = sizeof(struct isakmp);
1003
1004 #ifdef IKE_NAT_T
1005 if ((iph1->natt_flags & NATT_TYPE_MASK) != 0) {
1006 int vid_type;
1007 int natt_type = iph1->natt_flags & NATT_TYPE_MASK;
1008 if (natt_type == natt_type_rfc)
1009 vid_type = VENDORID_NATT_RFC;
1010 else if (natt_type == natt_type_apple)
1011 vid_type = VENDORID_NATT_APPLE;
1012 else if (natt_type == natt_type_02)
1013 vid_type = VENDORID_NATT_02;
1014 else
1015 vid_type = VENDORID_NATT_02N;
1016 nattvid = set_vendorid(vid_type);
1017 natd_create(iph1);
1018 if (nattvid) {
1019 tlen += sizeof(*gen) + nattvid->l;
1020 if (iph1->local_natd)
1021 tlen += sizeof(*gen) + iph1->local_natd->l;
1022 if (iph1->remote_natd)
1023 tlen += sizeof(*gen) + iph1->remote_natd->l;
1024 }
1025 }
1026 #endif
1027
1028 switch (iph1->approval->authmethod) {
1029 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1030 /* create buffer to send isakmp payload */
1031 tlen += sizeof(*gen) + iph1->sa_ret->l
1032 + sizeof(*gen) + iph1->dhpub->l
1033 + sizeof(*gen) + iph1->nonce->l
1034 + sizeof(*gen) + iph1->id->l
1035 + sizeof(*gen) + iph1->hash->l;
1036 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1037 tlen += sizeof(*gen) + vid->l;
1038 if (need_cr)
1039 tlen += sizeof(*gen) + cr->l;
1040
1041 iph1->sendbuf = vmalloc(tlen);
1042 if (iph1->sendbuf == NULL) {
1043 plog(LLV_ERROR, LOCATION, NULL,
1044 "failed to get buffer to send\n");
1045 goto end;
1046 }
1047
1048 /* set isakmp header */
1049 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1050 if (p == NULL)
1051 goto end;
1052
1053 /* set SA payload to reply */
1054 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1055
1056 /* create isakmp KE payload */
1057 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1058
1059 /* create isakmp NONCE payload */
1060 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1061
1062 /* create isakmp ID payload */
1063 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_HASH);
1064
1065 /* create isakmp HASH payload */
1066 p = set_isakmp_payload(p, iph1->hash,
1067 vid ? ISAKMP_NPTYPE_VID
1068 : (need_cr ? ISAKMP_NPTYPE_CR
1069 : (nattvid ? ISAKMP_NPTYPE_VID
1070 : ISAKMP_NPTYPE_NONE)));
1071
1072 /* append vendor id, if needed */
1073 if (vid)
1074 p = set_isakmp_payload(p, vid,
1075 need_cr ? ISAKMP_NPTYPE_CR
1076 : (nattvid ? ISAKMP_NPTYPE_VID
1077 : ISAKMP_NPTYPE_NONE));
1078
1079 /* create isakmp CR payload if needed */
1080 if (need_cr)
1081 p = set_isakmp_payload(p, cr,
1082 nattvid ? ISAKMP_NPTYPE_VID
1083 : ISAKMP_NPTYPE_NONE);
1084 break;
1085 #ifdef HAVE_SIGNING_C
1086 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1087 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1088 /* XXX if there is CR or not ? */
1089
1090 if (oakley_getmycert(iph1) < 0)
1091 goto end;
1092
1093 if (oakley_getsign(iph1) < 0)
1094 goto end;
1095
1096 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1097 need_cert = 1;
1098
1099 tlen += sizeof(*gen) + iph1->sa_ret->l
1100 + sizeof(*gen) + iph1->dhpub->l
1101 + sizeof(*gen) + iph1->nonce->l
1102 + sizeof(*gen) + iph1->id->l
1103 + sizeof(*gen) + iph1->sig->l;
1104 if (need_cert)
1105 tlen += sizeof(*gen) + iph1->cert->pl->l;
1106 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1107 tlen += sizeof(*gen) + vid->l;
1108 if (need_cr)
1109 tlen += sizeof(*gen) + cr->l;
1110
1111 iph1->sendbuf = vmalloc(tlen);
1112 if (iph1->sendbuf == NULL) {
1113 plog(LLV_ERROR, LOCATION, NULL,
1114 "failed to get buffer to send.\n");
1115 goto end;
1116 }
1117
1118 /* set isakmp header */
1119 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1120 if (p == NULL)
1121 goto end;
1122
1123 /* set SA payload to reply */
1124 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE);
1125
1126 /* create isakmp KE payload */
1127 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1128
1129 /* create isakmp NONCE payload */
1130 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1131
1132 /* add ID payload */
1133 p = set_isakmp_payload(p, iph1->id, need_cert
1134 ? ISAKMP_NPTYPE_CERT
1135 : ISAKMP_NPTYPE_SIG);
1136
1137 /* add CERT payload if there */
1138 if (need_cert)
1139 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG);
1140 /* add SIG payload */
1141 p = set_isakmp_payload(p, iph1->sig,
1142 vid ? ISAKMP_NPTYPE_VID
1143 : (need_cr ? ISAKMP_NPTYPE_CR
1144 : ISAKMP_NPTYPE_NONE));
1145
1146 /* append vendor id, if needed */
1147 if (vid)
1148 p = set_isakmp_payload(p, vid,
1149 need_cr ? ISAKMP_NPTYPE_CR
1150 : (nattvid ? ISAKMP_NPTYPE_VID
1151 : ISAKMP_NPTYPE_NONE));
1152
1153 /* create isakmp CR payload if needed */
1154 if (need_cr)
1155 p = set_isakmp_payload(p, cr,
1156 nattvid ? ISAKMP_NPTYPE_VID
1157 : ISAKMP_NPTYPE_NONE);
1158
1159 #ifdef IKE_NAT_T
1160 if (nattvid) {
1161 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1162 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
1163 if (iph1->local_natd)
1164 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1165 if (iph1->remote_natd)
1166 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1167 } else {
1168 if (iph1->remote_natd)
1169 p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
1170 if (iph1->local_natd)
1171 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
1172 }
1173 }
1174 #endif
1175 break;
1176 #endif
1177 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1178 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1179 tlen += sizeof(*gen) + iph1->hash->l;
1180 break;
1181 #ifdef HAVE_GSSAPI
1182 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1183 /* create buffer to send isakmp payload */
1184 gsshash = gssapi_wraphash(iph1);
1185 if (gsshash == NULL) {
1186 plog(LLV_ERROR, LOCATION, NULL,
1187 "failed to wrap hash\n");
1188 /*
1189 * This is probably due to the GSS roundtrips not
1190 * being finished yet. Return this error in
1191 * the hope that a fallback to main mode will
1192 * be done.
1193 */
1194 isakmp_info_send_n1(iph1,
1195 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1196 goto end;
1197 }
1198 if (iph1->approval->gssid != NULL)
1199 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
1200 else
1201 gss_sa = iph1->sa_ret;
1202
1203 tlen += sizeof(*gen) + gss_sa->l
1204 + sizeof(*gen) + iph1->dhpub->l
1205 + sizeof(*gen) + iph1->nonce->l
1206 + sizeof(*gen) + iph1->id->l
1207 + sizeof(*gen) + gsslen
1208 + sizeof(*gen) + gsshash->l;
1209 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL)
1210 tlen += sizeof(*gen) + vid->l;
1211 iph1->sendbuf = vmalloc(tlen);
1212 if (iph1->sendbuf == NULL) {
1213 plog(LLV_ERROR, LOCATION, NULL,
1214 "failed to get buffer to send\n");
1215 goto end;
1216 }
1217
1218 /* set isakmp header */
1219 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA);
1220 if (p == NULL)
1221 goto end;
1222
1223 /* set SA payload to reply */
1224 p = set_isakmp_payload(p, gss_sa, ISAKMP_NPTYPE_KE);
1225
1226 /* create isakmp KE payload */
1227 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE);
1228
1229 /* create isakmp NONCE payload */
1230 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID);
1231
1232 /* create isakmp ID payload */
1233 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_GSS);
1234
1235 /* create GSS payload */
1236 gssapi_get_token_to_send(iph1, &gsstoken);
1237 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_HASH);
1238
1239 /* create isakmp HASH payload */
1240 p = set_isakmp_payload(p, gsshash,
1241 vid != NULL || nattvid != NULL ? ISAKMP_NPTYPE_VID
1242 : ISAKMP_NPTYPE_NONE);
1243
1244 /* append vendor id, if needed */
1245 if (vid)
1246 p = set_isakmp_payload(p, vid,
1247 nattvid != NULL ? ISAKMP_NPTYPE_VID
1248 : ISAKMP_NPTYPE_NONE);
1249 break;
1250 #endif
1251 }
1252
1253 #ifdef IKE_NAT_T
1254 if (nattvid) {
1255 p = set_isakmp_payload(p, nattvid, iph1->natd_payload_type);
1256 if ((iph1->natt_flags & NATT_TYPE_MASK) == natt_type_apple) {
1257 if (iph1->local_natd)
1258 p = set_isakmp_payload(p, iph1->local_natd, iph1->natd_payload_type);
1259 if (iph1->remote_natd)
1260 p = set_isakmp_payload(p, iph1->remote_natd, ISAKMP_NPTYPE_NONE);
1261 } else {
1262 if (iph1->remote_natd)
1263 p = set_isakmp_payload(p, iph1->remote_natd, iph1->natd_payload_type);
1264 if (iph1->local_natd)
1265 p = set_isakmp_payload(p, iph1->local_natd, ISAKMP_NPTYPE_NONE);
1266 }
1267 }
1268 #endif
1269
1270
1271 #ifdef HAVE_PRINT_ISAKMP_C
1272 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1273 #endif
1274
1275 /* send the packet, add to the schedule to resend */
1276 iph1->retry_counter = iph1->rmconf->retry_counter;
1277 if (isakmp_ph1resend(iph1) == -1)
1278 goto end;
1279
1280 /* the sending message is added to the received-list. */
1281 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1282 plog(LLV_ERROR , LOCATION, NULL,
1283 "failed to add a response packet to the tree.\n");
1284 goto end;
1285 }
1286
1287 iph1->status = PHASE1ST_MSG1SENT;
1288
1289 error = 0;
1290
1291 end:
1292 if (cr)
1293 vfree(cr);
1294 if (vid)
1295 vfree(vid);
1296 if (nattvid)
1297 vfree(nattvid);
1298 #ifdef HAVE_GSSAPI
1299 if (gsstoken)
1300 vfree(gsstoken);
1301 if (gsshash)
1302 vfree(gsshash);
1303 if (gss_sa != iph1->sa_ret)
1304 vfree(gss_sa);
1305 #endif
1306
1307 return error;
1308 }
1309
1310 /*
1311 * receive from initiator
1312 * psk: HDR, HASH_I
1313 * gssapi: HDR, HASH_I
1314 * sig: HDR, [ CERT, ] SIG_I
1315 * rsa: HDR, HASH_I
1316 * rev: HDR, HASH_I
1317 */
1318 int
1319 agg_r2recv(iph1, msg0)
1320 struct ph1handle *iph1;
1321 vchar_t *msg0;
1322 {
1323 vchar_t *msg = NULL;
1324 vchar_t *pbuf = NULL;
1325 struct isakmp_parse_t *pa;
1326 int error = -1;
1327
1328 /* validity check */
1329 if (iph1->status != PHASE1ST_MSG1SENT) {
1330 plog(LLV_ERROR, LOCATION, NULL,
1331 "status mismatched %d.\n", iph1->status);
1332 goto end;
1333 }
1334
1335 /* decrypting if need. */
1336 /* XXX configurable ? */
1337 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1338 msg = oakley_do_decrypt(iph1, msg0,
1339 iph1->ivm->iv, iph1->ivm->ive);
1340 if (msg == NULL)
1341 goto end;
1342 } else
1343 msg = vdup(msg0);
1344
1345 /* validate the type of next payload */
1346 pbuf = isakmp_parse(msg);
1347 if (pbuf == NULL)
1348 goto end;
1349
1350 iph1->pl_hash = NULL;
1351
1352 for (pa = (struct isakmp_parse_t *)pbuf->v;
1353 pa->type != ISAKMP_NPTYPE_NONE;
1354 pa++) {
1355
1356 switch (pa->type) {
1357 case ISAKMP_NPTYPE_HASH:
1358 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1359 break;
1360 case ISAKMP_NPTYPE_VID:
1361 (void)check_vendorid(pa->ptr);
1362 break;
1363 #ifdef HAVE_SIGNING_C
1364 case ISAKMP_NPTYPE_CERT:
1365 if (oakley_savecert(iph1, pa->ptr) < 0)
1366 goto end;
1367 break;
1368 case ISAKMP_NPTYPE_SIG:
1369 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1370 goto end;
1371 break;
1372 #endif
1373 case ISAKMP_NPTYPE_N:
1374 isakmp_check_notify(pa->ptr, iph1);
1375 break;
1376 case ISAKMP_NPTYPE_NATD_RFC:
1377 case ISAKMP_NPTYPE_NATD_DRAFT:
1378 case ISAKMP_NPTYPE_NATD_BADDRAFT:
1379 #ifdef IKE_NAT_T
1380 if (pa->type == iph1->natd_payload_type) {
1381 natd_match_t match = natd_matches(iph1, pa->ptr);
1382 iph1->natt_flags |= natt_natd_received;
1383 if ((match & natd_match_local) != 0)
1384 iph1->natt_flags |= natt_no_local_nat;
1385 if ((match & natd_match_remote) != 0)
1386 iph1->natt_flags |= natt_no_remote_nat;
1387 }
1388 #endif
1389 break;
1390 default:
1391 /* don't send information, see isakmp_ident_r1() */
1392 plog(LLV_ERROR, LOCATION, iph1->remote,
1393 "ignore the packet, "
1394 "received unexpecting payload type %d.\n",
1395 pa->type);
1396 goto end;
1397 }
1398 }
1399
1400 /* validate authentication value */
1401 {
1402 int type;
1403 type = oakley_validate_auth(iph1);
1404 if (type != 0) {
1405 if (type == -1) {
1406 /* message printed inner oakley_validate_auth() */
1407 goto end;
1408 }
1409 isakmp_info_send_n1(iph1, type, NULL);
1410 goto end;
1411 }
1412 }
1413
1414 iph1->status = PHASE1ST_MSG2RECEIVED;
1415
1416 error = 0;
1417
1418 end:
1419 if (pbuf)
1420 vfree(pbuf);
1421 if (msg)
1422 vfree(msg);
1423 if (error) {
1424 oakley_delcert(iph1->cert_p);
1425 iph1->cert_p = NULL;
1426 oakley_delcert(iph1->crl_p);
1427 iph1->crl_p = NULL;
1428 VPTRINIT(iph1->sig_p);
1429 }
1430
1431 return error;
1432 }
1433
1434 /*
1435 * status update and establish isakmp sa.
1436 */
1437 int
1438 agg_r2send(iph1, msg)
1439 struct ph1handle *iph1;
1440 vchar_t *msg;
1441 {
1442 int error = -1;
1443
1444 /* validity check */
1445 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1446 plog(LLV_ERROR, LOCATION, NULL,
1447 "status mismatched %d.\n", iph1->status);
1448 goto end;
1449 }
1450
1451 /* IV synchronized when packet encrypted. */
1452 /* see handler.h about IV synchronization. */
1453 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1454 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1455
1456 /* set encryption flag */
1457 iph1->flags |= ISAKMP_FLAG_E;
1458
1459 iph1->status = PHASE1ST_ESTABLISHED;
1460
1461 error = 0;
1462
1463 end:
1464 return error;
1465 }