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