1 /* $NetBSD: isakmp_agg.c,v 1.17 2018/05/19 19:23:15 maxv Exp $ */
2
3 /* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /* Aggressive Exchange (Aggressive Mode) */
35
36 #include "config.h"
37
38 #include <sys/types.h>
39 #include <sys/param.h>
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <errno.h>
45 #if TIME_WITH_SYS_TIME
46 # include <sys/time.h>
47 # include <time.h>
48 #else
49 # if HAVE_SYS_TIME_H
50 # include <sys/time.h>
51 # else
52 # include <time.h>
53 # endif
54 #endif
55
56 #include "var.h"
57 #include "misc.h"
58 #include "vmbuf.h"
59 #include "plog.h"
60 #include "sockmisc.h"
61 #include "schedule.h"
62 #include "debug.h"
63
64 #ifdef ENABLE_HYBRID
65 #include <resolv.h>
66 #endif
67
68 #include "localconf.h"
69 #include "remoteconf.h"
70 #include "isakmp_var.h"
71 #include "isakmp.h"
72 #include "evt.h"
73 #include "oakley.h"
74 #include "handler.h"
75 #include "ipsec_doi.h"
76 #include "crypto_openssl.h"
77 #include "pfkey.h"
78 #include "isakmp_agg.h"
79 #include "isakmp_inf.h"
80 #ifdef ENABLE_HYBRID
81 #include "isakmp_xauth.h"
82 #include "isakmp_cfg.h"
83 #endif
84 #ifdef ENABLE_FRAG
85 #include "isakmp_frag.h"
86 #endif
87 #include "vendorid.h"
88 #include "strnames.h"
89
90 #ifdef ENABLE_NATT
91 #include "nattraversal.h"
92 #endif
93
94 #ifdef HAVE_GSSAPI
95 #include "gssapi.h"
96 #endif
97
98 /*
99 * begin Aggressive Mode as initiator.
100 */
101 /*
102 * send to responder
103 * psk: HDR, SA, KE, Ni, IDi1
104 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
105 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi
106 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
107 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
108 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
109 */
110 int
agg_i1send(iph1,msg)111 agg_i1send(iph1, msg)
112 struct ph1handle *iph1;
113 vchar_t *msg; /* must be null */
114 {
115 struct payload_list *plist = NULL;
116 int error = -1;
117 #ifdef ENABLE_NATT
118 vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
119 int i;
120 #endif
121 #ifdef ENABLE_HYBRID
122 vchar_t *vid_xauth = NULL;
123 vchar_t *vid_unity = NULL;
124 #endif
125 #ifdef ENABLE_FRAG
126 vchar_t *vid_frag = NULL;
127 #endif
128 #ifdef HAVE_GSSAPI
129 vchar_t *gsstoken = NULL;
130 int len;
131 #endif
132 #ifdef ENABLE_DPD
133 vchar_t *vid_dpd = NULL;
134 #endif
135
136 /* validity check */
137 if (msg != NULL) {
138 plog(LLV_ERROR, LOCATION, NULL,
139 "msg has to be NULL in this function.\n");
140 goto end;
141 }
142 if (iph1->status != PHASE1ST_START) {
143 plog(LLV_ERROR, LOCATION, NULL,
144 "status mismatched %d.\n", iph1->status);
145 goto end;
146 }
147
148 /* create isakmp index */
149 memset(&iph1->index, 0, sizeof(iph1->index));
150 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
151
152 /* make ID payload into isakmp status */
153 if (ipsecdoi_setid1(iph1) < 0)
154 goto end;
155
156 /* create SA payload for my proposal */
157 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->rmconf->proposal);
158 if (iph1->sa == NULL)
159 goto end;
160
161 /* consistency check of proposals */
162 if (iph1->rmconf->dhgrp == NULL) {
163 plog(LLV_ERROR, LOCATION, NULL,
164 "configuration failure about DH group.\n");
165 goto end;
166 }
167
168 /* generate DH public value */
169 if (oakley_dh_generate(iph1->rmconf->dhgrp,
170 &iph1->dhpub, &iph1->dhpriv) < 0)
171 goto end;
172
173 /* generate NONCE value */
174 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
175 if (iph1->nonce == NULL)
176 goto end;
177
178 #ifdef ENABLE_HYBRID
179 /* Do we need Xauth VID? */
180 switch (iph1->rmconf->proposal->authmethod) {
181 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
182 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
183 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
184 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
185 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
186 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
187 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
188 if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
189 plog(LLV_ERROR, LOCATION, NULL,
190 "Xauth vendor ID generation failed\n");
191 if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
192 plog(LLV_ERROR, LOCATION, NULL,
193 "Unity vendor ID generation failed\n");
194 break;
195 default:
196 break;
197 }
198 #endif
199
200 #ifdef ENABLE_FRAG
201 if (iph1->rmconf->ike_frag) {
202 vid_frag = set_vendorid(VENDORID_FRAG);
203 if (vid_frag != NULL)
204 vid_frag = isakmp_frag_addcap(vid_frag,
205 VENDORID_FRAG_AGG);
206 if (vid_frag == NULL)
207 plog(LLV_ERROR, LOCATION, NULL,
208 "Frag vendorID construction failed\n");
209 }
210 #endif
211
212 plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
213 s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
214 #ifdef HAVE_GSSAPI
215 if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
216 gssapi_get_itoken(iph1, &len);
217 #endif
218
219 /* set SA payload to propose */
220 plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
221
222 /* create isakmp KE payload */
223 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
224
225 /* create isakmp NONCE payload */
226 plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
227
228 /* create isakmp ID payload */
229 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
230
231 #ifdef HAVE_GSSAPI
232 if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
233 if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
234 plog(LLV_ERROR, LOCATION, NULL,
235 "Failed to get gssapi token.\n");
236 goto end;
237 }
238 plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
239 }
240 #endif
241 /* create isakmp CR payload */
242 if (oakley_needcr(iph1->rmconf->proposal->authmethod))
243 plist = oakley_append_cr(plist, iph1);
244
245 #ifdef ENABLE_FRAG
246 if (vid_frag)
247 plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
248 #endif
249 #ifdef ENABLE_NATT
250 /*
251 * set VID payload for NAT-T if NAT-T
252 * support allowed in the config file
253 */
254 if (iph1->rmconf->nat_traversal)
255 plist = isakmp_plist_append_natt_vids(plist, vid_natt);
256 #endif
257 #ifdef ENABLE_HYBRID
258 if (vid_xauth)
259 plist = isakmp_plist_append(plist,
260 vid_xauth, ISAKMP_NPTYPE_VID);
261 if (vid_unity)
262 plist = isakmp_plist_append(plist,
263 vid_unity, ISAKMP_NPTYPE_VID);
264 #endif
265 #ifdef ENABLE_DPD
266 if(iph1->rmconf->dpd){
267 vid_dpd = set_vendorid(VENDORID_DPD);
268 if (vid_dpd != NULL)
269 plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
270 }
271 #endif
272
273 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
274
275 #ifdef HAVE_PRINT_ISAKMP_C
276 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
277 #endif
278
279 /* send the packet, add to the schedule to resend */
280 if (isakmp_ph1send(iph1) == -1)
281 goto end;
282
283 iph1->status = PHASE1ST_MSG1SENT;
284
285 error = 0;
286
287 end:
288 #ifdef HAVE_GSSAPI
289 if (gsstoken)
290 vfree(gsstoken);
291 #endif
292 #ifdef ENABLE_FRAG
293 if (vid_frag)
294 vfree(vid_frag);
295 #endif
296 #ifdef ENABLE_NATT
297 for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
298 vfree(vid_natt[i]);
299 #endif
300 #ifdef ENABLE_HYBRID
301 if (vid_xauth != NULL)
302 vfree(vid_xauth);
303 if (vid_unity != NULL)
304 vfree(vid_unity);
305 #endif
306 #ifdef ENABLE_DPD
307 if (vid_dpd != NULL)
308 vfree(vid_dpd);
309 #endif
310
311 return error;
312 }
313
314 /*
315 * receive from responder
316 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
317 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
318 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
319 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
320 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
321 */
322 int
agg_i2recv(iph1,msg)323 agg_i2recv(iph1, msg)
324 struct ph1handle *iph1;
325 vchar_t *msg;
326 {
327 vchar_t *pbuf = NULL;
328 struct isakmp_parse_t *pa;
329 vchar_t *satmp = NULL;
330 int error = -1;
331 int ptype;
332 #ifdef HAVE_GSSAPI
333 vchar_t *gsstoken = NULL;
334 #endif
335
336 #ifdef ENABLE_NATT
337 int natd_seq = 0;
338 struct natd_payload {
339 int seq;
340 vchar_t *payload;
341 TAILQ_ENTRY(natd_payload) chain;
342 };
343 TAILQ_HEAD(_natd_payload, natd_payload) natd_tree;
344 TAILQ_INIT(&natd_tree);
345 #endif
346
347 /* validity check */
348 if (iph1->status != PHASE1ST_MSG1SENT) {
349 plog(LLV_ERROR, LOCATION, NULL,
350 "status mismatched %d.\n", iph1->status);
351 goto end;
352 }
353
354 /* validate the type of next payload */
355 pbuf = isakmp_parse(msg);
356 if (pbuf == NULL)
357 goto end;
358 pa = (struct isakmp_parse_t *)pbuf->v;
359
360 iph1->pl_hash = NULL;
361
362 /* SA payload is fixed postion */
363 if (pa->type != ISAKMP_NPTYPE_SA) {
364 plog(LLV_ERROR, LOCATION, iph1->remote,
365 "received invalid next payload type %d, "
366 "expecting %d.\n",
367 pa->type, ISAKMP_NPTYPE_SA);
368 goto end;
369 }
370
371 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
372 goto end;
373 pa++;
374
375 for (/*nothing*/;
376 pa->type != ISAKMP_NPTYPE_NONE;
377 pa++) {
378
379 switch (pa->type) {
380 case ISAKMP_NPTYPE_KE:
381 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
382 goto end;
383 break;
384 case ISAKMP_NPTYPE_NONCE:
385 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
386 goto end;
387 break;
388 case ISAKMP_NPTYPE_ID:
389 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
390 goto end;
391 break;
392 case ISAKMP_NPTYPE_HASH:
393 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
394 break;
395 case ISAKMP_NPTYPE_CR:
396 if (oakley_savecr(iph1, pa->ptr) < 0)
397 goto end;
398 break;
399 case ISAKMP_NPTYPE_CERT:
400 if (oakley_savecert(iph1, pa->ptr) < 0)
401 goto end;
402 break;
403 case ISAKMP_NPTYPE_SIG:
404 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
405 goto end;
406 break;
407 case ISAKMP_NPTYPE_VID:
408 handle_vendorid(iph1, pa->ptr);
409 break;
410 case ISAKMP_NPTYPE_N:
411 isakmp_log_notify(iph1,
412 (struct isakmp_pl_n *) pa->ptr,
413 "aggressive exchange");
414 break;
415 #ifdef HAVE_GSSAPI
416 case ISAKMP_NPTYPE_GSS:
417 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
418 goto end;
419 gssapi_save_received_token(iph1, gsstoken);
420 break;
421 #endif
422
423 #ifdef ENABLE_NATT
424 case ISAKMP_NPTYPE_NATD_DRAFT:
425 case ISAKMP_NPTYPE_NATD_RFC:
426 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
427 pa->type == iph1->natt_options->payload_nat_d) {
428 struct natd_payload *natd;
429 natd = (struct natd_payload *)racoon_malloc(sizeof(*natd));
430 if (!natd)
431 goto end;
432
433 natd->payload = NULL;
434
435 if (isakmp_p2ph (&natd->payload, pa->ptr) < 0)
436 goto end;
437
438 natd->seq = natd_seq++;
439
440 TAILQ_INSERT_TAIL(&natd_tree, natd, chain);
441 break;
442 }
443 /* passthrough to default... */
444 #endif
445
446 default:
447 /* don't send information, see isakmp_ident_r1() */
448 plog(LLV_ERROR, LOCATION, iph1->remote,
449 "ignore the packet, "
450 "received unexpecting payload type %d.\n",
451 pa->type);
452 goto end;
453 }
454 }
455
456 /* payload existency check */
457 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
458 plog(LLV_ERROR, LOCATION, iph1->remote,
459 "few isakmp message received.\n");
460 goto end;
461 }
462
463 /* verify identifier */
464 if (ipsecdoi_checkid1(iph1) != 0) {
465 plog(LLV_ERROR, LOCATION, iph1->remote,
466 "invalid ID payload.\n");
467 goto end;
468 }
469
470 /* check SA payload and set approval SA for use */
471 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
472 plog(LLV_ERROR, LOCATION, iph1->remote,
473 "failed to get valid proposal.\n");
474 /* XXX send information */
475 goto end;
476 }
477 VPTRINIT(iph1->sa_ret);
478
479 /* fix isakmp index */
480 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
481 sizeof(cookie_t));
482
483 #ifdef ENABLE_NATT
484 if (NATT_AVAILABLE(iph1)) {
485 struct natd_payload *natd = NULL;
486 int natd_verified;
487
488 plog(LLV_INFO, LOCATION, iph1->remote,
489 "Selected NAT-T version: %s\n",
490 vid_string_by_id(iph1->natt_options->version));
491
492 /* set both bits first so that we can clear them
493 upon verifying hashes */
494 iph1->natt_flags |= NAT_DETECTED;
495
496 while ((natd = TAILQ_FIRST(&natd_tree)) != NULL) {
497 /* this function will clear appropriate bits bits
498 from iph1->natt_flags */
499 natd_verified = natt_compare_addr_hash (iph1,
500 natd->payload, natd->seq);
501
502 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
503 natd->seq - 1,
504 natd_verified ? "verified" : "doesn't match");
505
506 vfree (natd->payload);
507
508 TAILQ_REMOVE(&natd_tree, natd, chain);
509 racoon_free (natd);
510 }
511
512 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
513 iph1->natt_flags & NAT_DETECTED ?
514 "detected:" : "not detected",
515 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
516 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
517
518 if (iph1->natt_flags & NAT_DETECTED)
519 natt_float_ports (iph1);
520 }
521 #endif
522
523 /* compute sharing secret of DH */
524 if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
525 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
526 goto end;
527
528 /* generate SKEYIDs & IV & final cipher key */
529 if (oakley_skeyid(iph1) < 0)
530 goto end;
531 if (oakley_skeyid_dae(iph1) < 0)
532 goto end;
533 if (oakley_compute_enckey(iph1) < 0)
534 goto end;
535 if (oakley_newiv(iph1) < 0)
536 goto end;
537
538 /* validate authentication value */
539 ptype = oakley_validate_auth(iph1);
540 if (ptype != 0) {
541 if (ptype == -1) {
542 /* message printed inner oakley_validate_auth() */
543 goto end;
544 }
545 evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
546 isakmp_info_send_n1(iph1, ptype, NULL);
547 goto end;
548 }
549
550 if (oakley_checkcr(iph1) < 0) {
551 /* Ignore this error in order to be interoperability. */
552 ;
553 }
554
555 /* change status of isakmp status entry */
556 iph1->status = PHASE1ST_MSG2RECEIVED;
557
558 error = 0;
559
560 end:
561 #ifdef HAVE_GSSAPI
562 if (gsstoken)
563 vfree(gsstoken);
564 #endif
565 if (pbuf)
566 vfree(pbuf);
567 if (satmp)
568 vfree(satmp);
569 if (error) {
570 VPTRINIT(iph1->dhpub_p);
571 VPTRINIT(iph1->nonce_p);
572 VPTRINIT(iph1->id_p);
573 VPTRINIT(iph1->cert_p);
574 VPTRINIT(iph1->crl_p);
575 VPTRINIT(iph1->sig_p);
576 VPTRINIT(iph1->cr_p);
577 }
578
579 return error;
580 }
581
582 /*
583 * send to responder
584 * psk: HDR, HASH_I
585 * gssapi: HDR, HASH_I
586 * sig: HDR, [ CERT, ] SIG_I
587 * rsa: HDR, HASH_I
588 * rev: HDR, HASH_I
589 */
590 int
agg_i2send(iph1,msg)591 agg_i2send(iph1, msg)
592 struct ph1handle *iph1;
593 vchar_t *msg;
594 {
595 struct payload_list *plist = NULL;
596 int need_cert = 0;
597 int error = -1;
598 vchar_t *gsshash = NULL;
599
600 /* validity check */
601 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
602 plog(LLV_ERROR, LOCATION, NULL,
603 "status mismatched %d.\n", iph1->status);
604 goto end;
605 }
606
607 /* generate HASH to send */
608 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
609 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
610 if (iph1->hash == NULL) {
611 #ifdef HAVE_GSSAPI
612 if (gssapi_more_tokens(iph1) &&
613 #ifdef ENABLE_HYBRID
614 !iph1->rmconf->xauth &&
615 #endif
616 1)
617 isakmp_info_send_n1(iph1,
618 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
619 #endif
620 goto end;
621 }
622
623 switch (iph1->approval->authmethod) {
624 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
625 #ifdef ENABLE_HYBRID
626 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
627 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
628 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
629 #endif
630 /* set HASH payload */
631 plist = isakmp_plist_append(plist,
632 iph1->hash, ISAKMP_NPTYPE_HASH);
633 break;
634
635 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
636 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
637 #ifdef ENABLE_HYBRID
638 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
639 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
640 #endif
641 /* XXX if there is CR or not ? */
642
643 if (oakley_getmycert(iph1) < 0)
644 goto end;
645
646 if (oakley_getsign(iph1) < 0)
647 goto end;
648
649 if (iph1->cert != NULL && iph1->rmconf->send_cert)
650 need_cert = 1;
651
652 /* add CERT payload if there */
653 if (need_cert)
654 plist = isakmp_plist_append(plist, iph1->cert,
655 ISAKMP_NPTYPE_CERT);
656
657 /* add SIG payload */
658 plist = isakmp_plist_append(plist,
659 iph1->sig, ISAKMP_NPTYPE_SIG);
660 break;
661
662 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
663 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
664 #ifdef ENABLE_HYBRID
665 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
666 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
667 #endif
668 break;
669 #ifdef HAVE_GSSAPI
670 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
671 gsshash = gssapi_wraphash(iph1);
672 if (gsshash == NULL) {
673 plog(LLV_ERROR, LOCATION, NULL,
674 "failed to wrap hash\n");
675 isakmp_info_send_n1(iph1,
676 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
677 goto end;
678 }
679
680 plist = isakmp_plist_append(plist,
681 gsshash, ISAKMP_NPTYPE_HASH);
682 break;
683 #endif
684 }
685
686 #ifdef ENABLE_NATT
687 /* generate NAT-D payloads */
688 if (NATT_AVAILABLE(iph1)) {
689 vchar_t *natd[2] = { NULL, NULL };
690
691 plog(LLV_INFO, LOCATION,
692 NULL, "Adding remote and local NAT-D payloads.\n");
693
694 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
695 plog(LLV_ERROR, LOCATION, NULL,
696 "NAT-D hashing failed for %s\n",
697 saddr2str(iph1->remote));
698 goto end;
699 }
700
701 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
702 plog(LLV_ERROR, LOCATION, NULL,
703 "NAT-D hashing failed for %s\n",
704 saddr2str(iph1->local));
705 goto end;
706 }
707
708 plist = isakmp_plist_append(plist,
709 natd[0], iph1->natt_options->payload_nat_d);
710 plist = isakmp_plist_append(plist,
711 natd[1], iph1->natt_options->payload_nat_d);
712 }
713 #endif
714
715 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
716
717 #ifdef HAVE_PRINT_ISAKMP_C
718 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
719 #endif
720
721 /* send to responder */
722 if (isakmp_send(iph1, iph1->sendbuf) < 0)
723 goto end;
724
725 /* the sending message is added to the received-list. */
726 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
727 plog(LLV_ERROR , LOCATION, NULL,
728 "failed to add a response packet to the tree.\n");
729 goto end;
730 }
731
732 /* set encryption flag */
733 iph1->flags |= ISAKMP_FLAG_E;
734
735 iph1->status = PHASE1ST_ESTABLISHED;
736
737 error = 0;
738
739 end:
740 if (gsshash)
741 vfree(gsshash);
742 return error;
743 }
744
745 /*
746 * receive from initiator
747 * psk: HDR, SA, KE, Ni, IDi1
748 * sig: HDR, SA, KE, Ni, IDi1 [, CR ]
749 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
750 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
751 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
752 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
753 */
754 int
agg_r1recv(iph1,msg)755 agg_r1recv(iph1, msg)
756 struct ph1handle *iph1;
757 vchar_t *msg;
758 {
759 int error = -1;
760 vchar_t *pbuf = NULL;
761 struct isakmp_parse_t *pa;
762 int vid_numeric;
763 #ifdef HAVE_GSSAPI
764 vchar_t *gsstoken = NULL;
765 #endif
766
767 /* validity check */
768 if (iph1->status != PHASE1ST_START) {
769 plog(LLV_ERROR, LOCATION, NULL,
770 "status mismatched %d.\n", iph1->status);
771 goto end;
772 }
773
774 /* validate the type of next payload */
775 pbuf = isakmp_parse(msg);
776 if (pbuf == NULL)
777 goto end;
778 pa = (struct isakmp_parse_t *)pbuf->v;
779
780 /* SA payload is fixed postion */
781 if (pa->type != ISAKMP_NPTYPE_SA) {
782 plog(LLV_ERROR, LOCATION, iph1->remote,
783 "received invalid next payload type %d, "
784 "expecting %d.\n",
785 pa->type, ISAKMP_NPTYPE_SA);
786 goto end;
787 }
788 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
789 goto end;
790 pa++;
791
792 for (/*nothing*/;
793 pa->type != ISAKMP_NPTYPE_NONE;
794 pa++) {
795
796 plog(LLV_DEBUG, LOCATION, NULL,
797 "received payload of type %s\n",
798 s_isakmp_nptype(pa->type));
799
800 switch (pa->type) {
801 case ISAKMP_NPTYPE_KE:
802 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
803 goto end;
804 break;
805 case ISAKMP_NPTYPE_NONCE:
806 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
807 goto end;
808 break;
809 case ISAKMP_NPTYPE_ID:
810 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
811 goto end;
812 break;
813 case ISAKMP_NPTYPE_VID:
814 vid_numeric = handle_vendorid(iph1, pa->ptr);
815 #ifdef ENABLE_FRAG
816 if ((vid_numeric == VENDORID_FRAG) &&
817 (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG))
818 iph1->frag = 1;
819 #endif
820 break;
821
822 case ISAKMP_NPTYPE_CR:
823 if (oakley_savecr(iph1, pa->ptr) < 0)
824 goto end;
825 break;
826
827 #ifdef HAVE_GSSAPI
828 case ISAKMP_NPTYPE_GSS:
829 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
830 goto end;
831 gssapi_save_received_token(iph1, gsstoken);
832 break;
833 #endif
834 default:
835 /* don't send information, see isakmp_ident_r1() */
836 plog(LLV_ERROR, LOCATION, iph1->remote,
837 "ignore the packet, "
838 "received unexpecting payload type %d.\n",
839 pa->type);
840 goto end;
841 }
842 }
843
844 /* payload existency check */
845 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
846 plog(LLV_ERROR, LOCATION, iph1->remote,
847 "few isakmp message received.\n");
848 goto end;
849 }
850
851 /* verify identifier */
852 if (ipsecdoi_checkid1(iph1) != 0) {
853 plog(LLV_ERROR, LOCATION, iph1->remote,
854 "invalid ID payload.\n");
855 goto end;
856 }
857
858 #ifdef ENABLE_NATT
859 if (NATT_AVAILABLE(iph1))
860 plog(LLV_INFO, LOCATION, iph1->remote,
861 "Selected NAT-T version: %s\n",
862 vid_string_by_id(iph1->natt_options->version));
863 #endif
864
865 /* check SA payload and set approval SA for use */
866 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
867 plog(LLV_ERROR, LOCATION, iph1->remote,
868 "failed to get valid proposal.\n");
869 /* XXX send information */
870 goto end;
871 }
872
873 if (oakley_checkcr(iph1) < 0) {
874 /* Ignore this error in order to be interoperability. */
875 ;
876 }
877
878 iph1->status = PHASE1ST_MSG1RECEIVED;
879
880 error = 0;
881
882 end:
883 #ifdef HAVE_GSSAPI
884 if (gsstoken)
885 vfree(gsstoken);
886 #endif
887 if (pbuf)
888 vfree(pbuf);
889 if (error) {
890 VPTRINIT(iph1->sa);
891 VPTRINIT(iph1->dhpub_p);
892 VPTRINIT(iph1->nonce_p);
893 VPTRINIT(iph1->id_p);
894 VPTRINIT(iph1->cr_p);
895 }
896
897 return error;
898 }
899
900 /*
901 * send to initiator
902 * psk: HDR, SA, KE, Nr, IDr1, HASH_R
903 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
904 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
905 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
906 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
907 */
908 int
agg_r1send(iph1,msg)909 agg_r1send(iph1, msg)
910 struct ph1handle *iph1;
911 vchar_t *msg;
912 {
913 struct payload_list *plist = NULL;
914 int need_cert = 0;
915 int error = -1;
916 #ifdef ENABLE_HYBRID
917 vchar_t *xauth_vid = NULL;
918 vchar_t *unity_vid = NULL;
919 #endif
920 #ifdef ENABLE_NATT
921 vchar_t *vid_natt = NULL;
922 vchar_t *natd[2] = { NULL, NULL };
923 #endif
924 #ifdef ENABLE_DPD
925 vchar_t *vid_dpd = NULL;
926 #endif
927 #ifdef ENABLE_FRAG
928 vchar_t *vid_frag = NULL;
929 #endif
930
931 #ifdef HAVE_GSSAPI
932 int gsslen;
933 vchar_t *gsstoken = NULL, *gsshash = NULL;
934 vchar_t *gss_sa = NULL;
935 int free_gss_sa = 0;
936 #endif
937
938 /* validity check */
939 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
940 plog(LLV_ERROR, LOCATION, NULL,
941 "status mismatched %d.\n", iph1->status);
942 goto end;
943 }
944
945 /* set responder's cookie */
946 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
947
948 /* make ID payload into isakmp status */
949 if (ipsecdoi_setid1(iph1) < 0)
950 goto end;
951
952 /* generate DH public value */
953 if (oakley_dh_generate(iph1->rmconf->dhgrp,
954 &iph1->dhpub, &iph1->dhpriv) < 0)
955 goto end;
956
957 /* generate NONCE value */
958 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
959 if (iph1->nonce == NULL)
960 goto end;
961
962 /* compute sharing secret of DH */
963 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
964 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
965 goto end;
966
967 /* generate SKEYIDs & IV & final cipher key */
968 if (oakley_skeyid(iph1) < 0)
969 goto end;
970 if (oakley_skeyid_dae(iph1) < 0)
971 goto end;
972 if (oakley_compute_enckey(iph1) < 0)
973 goto end;
974 if (oakley_newiv(iph1) < 0)
975 goto end;
976
977 #ifdef HAVE_GSSAPI
978 if (iph1->rmconf->proposal->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
979 gssapi_get_rtoken(iph1, &gsslen);
980 #endif
981
982 /* generate HASH to send */
983 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
984 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
985 if (iph1->hash == NULL) {
986 #ifdef HAVE_GSSAPI
987 if (gssapi_more_tokens(iph1))
988 isakmp_info_send_n1(iph1,
989 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
990 #endif
991 goto end;
992 }
993
994 #ifdef ENABLE_NATT
995 /* Has the peer announced NAT-T? */
996 if (NATT_AVAILABLE(iph1)) {
997 /* set chosen VID */
998 vid_natt = set_vendorid(iph1->natt_options->version);
999
1000 /* generate NAT-D payloads */
1001 plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1002 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1003 plog(LLV_ERROR, LOCATION, NULL,
1004 "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1005 goto end;
1006 }
1007
1008 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1009 plog(LLV_ERROR, LOCATION, NULL,
1010 "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1011 goto end;
1012 }
1013 }
1014 #endif
1015 #ifdef ENABLE_DPD
1016 /* Only send DPD support if remote announced DPD and if DPD support is active */
1017 if (iph1->dpd_support && iph1->rmconf->dpd)
1018 vid_dpd = set_vendorid(VENDORID_DPD);
1019 #endif
1020 #ifdef ENABLE_FRAG
1021 if (iph1->frag) {
1022 vid_frag = set_vendorid(VENDORID_FRAG);
1023 if (vid_frag != NULL)
1024 vid_frag = isakmp_frag_addcap(vid_frag,
1025 VENDORID_FRAG_AGG);
1026 if (vid_frag == NULL)
1027 plog(LLV_ERROR, LOCATION, NULL,
1028 "Frag vendorID construction failed\n");
1029 }
1030 #endif
1031
1032 switch (iph1->approval->authmethod) {
1033 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1034 #ifdef ENABLE_HYBRID
1035 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1036 #endif
1037 /* set SA payload to reply */
1038 plist = isakmp_plist_append(plist,
1039 iph1->sa_ret, ISAKMP_NPTYPE_SA);
1040
1041 /* create isakmp KE payload */
1042 plist = isakmp_plist_append(plist,
1043 iph1->dhpub, ISAKMP_NPTYPE_KE);
1044
1045 /* create isakmp NONCE payload */
1046 plist = isakmp_plist_append(plist,
1047 iph1->nonce, ISAKMP_NPTYPE_NONCE);
1048
1049 /* create isakmp ID payload */
1050 plist = isakmp_plist_append(plist,
1051 iph1->id, ISAKMP_NPTYPE_ID);
1052
1053 /* create isakmp HASH payload */
1054 plist = isakmp_plist_append(plist,
1055 iph1->hash, ISAKMP_NPTYPE_HASH);
1056
1057 /* create isakmp CR payload if needed */
1058 if (oakley_needcr(iph1->approval->authmethod))
1059 plist = oakley_append_cr(plist, iph1);
1060 break;
1061 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1062 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1063 #ifdef ENABLE_HYBRID
1064 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1065 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1066 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1067 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1068 #endif
1069 /* XXX if there is CR or not ? */
1070
1071 if (oakley_getmycert(iph1) < 0)
1072 goto end;
1073
1074 if (oakley_getsign(iph1) < 0)
1075 goto end;
1076
1077 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1078 need_cert = 1;
1079
1080 /* set SA payload to reply */
1081 plist = isakmp_plist_append(plist,
1082 iph1->sa_ret, ISAKMP_NPTYPE_SA);
1083
1084 /* create isakmp KE payload */
1085 plist = isakmp_plist_append(plist,
1086 iph1->dhpub, ISAKMP_NPTYPE_KE);
1087
1088 /* create isakmp NONCE payload */
1089 plist = isakmp_plist_append(plist,
1090 iph1->nonce, ISAKMP_NPTYPE_NONCE);
1091
1092 /* add ID payload */
1093 plist = isakmp_plist_append(plist,
1094 iph1->id, ISAKMP_NPTYPE_ID);
1095
1096 /* add CERT payload if there */
1097 if (need_cert)
1098 plist = isakmp_plist_append(plist, iph1->cert,
1099 ISAKMP_NPTYPE_CERT);
1100
1101 /* add SIG payload */
1102 plist = isakmp_plist_append(plist,
1103 iph1->sig, ISAKMP_NPTYPE_SIG);
1104
1105 /* create isakmp CR payload if needed */
1106 if (oakley_needcr(iph1->approval->authmethod))
1107 plist = oakley_append_cr(plist, iph1);
1108 break;
1109
1110 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1111 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1112 #ifdef ENABLE_HYBRID
1113 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1114 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1115 #endif
1116 break;
1117 #ifdef HAVE_GSSAPI
1118 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1119 /* create buffer to send isakmp payload */
1120 gsshash = gssapi_wraphash(iph1);
1121 if (gsshash == NULL) {
1122 plog(LLV_ERROR, LOCATION, NULL,
1123 "failed to wrap hash\n");
1124 /*
1125 * This is probably due to the GSS
1126 * roundtrips not being finished yet.
1127 * Return this error in the hope that
1128 * a fallback to main mode will be done.
1129 */
1130 isakmp_info_send_n1(iph1,
1131 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1132 goto end;
1133 }
1134 if (iph1->approval->gssid != NULL)
1135 gss_sa = ipsecdoi_setph1proposal(iph1->rmconf,
1136 iph1->approval);
1137 else
1138 gss_sa = iph1->sa_ret;
1139
1140 if (gss_sa != iph1->sa_ret)
1141 free_gss_sa = 1;
1142
1143 /* set SA payload to reply */
1144 plist = isakmp_plist_append(plist,
1145 gss_sa, ISAKMP_NPTYPE_SA);
1146
1147 /* create isakmp KE payload */
1148 plist = isakmp_plist_append(plist,
1149 iph1->dhpub, ISAKMP_NPTYPE_KE);
1150
1151 /* create isakmp NONCE payload */
1152 plist = isakmp_plist_append(plist,
1153 iph1->nonce, ISAKMP_NPTYPE_NONCE);
1154
1155 /* create isakmp ID payload */
1156 plist = isakmp_plist_append(plist,
1157 iph1->id, ISAKMP_NPTYPE_ID);
1158
1159 /* create GSS payload */
1160 if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
1161 plog(LLV_ERROR, LOCATION, NULL,
1162 "Failed to get gssapi token.\n");
1163 goto end;
1164 }
1165 plist = isakmp_plist_append(plist,
1166 gsstoken, ISAKMP_NPTYPE_GSS);
1167
1168 /* create isakmp HASH payload */
1169 plist = isakmp_plist_append(plist,
1170 gsshash, ISAKMP_NPTYPE_HASH);
1171
1172 /* append vendor id, if needed */
1173 break;
1174 #endif
1175 }
1176
1177 #ifdef ENABLE_HYBRID
1178 if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
1179 plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
1180 if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) {
1181 plog(LLV_ERROR, LOCATION, NULL,
1182 "Cannot create Xauth vendor ID\n");
1183 goto end;
1184 }
1185 plist = isakmp_plist_append(plist,
1186 xauth_vid, ISAKMP_NPTYPE_VID);
1187 }
1188
1189 if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
1190 if ((unity_vid = set_vendorid(VENDORID_UNITY)) == NULL) {
1191 plog(LLV_ERROR, LOCATION, NULL,
1192 "Cannot create Unity vendor ID\n");
1193 goto end;
1194 }
1195 plist = isakmp_plist_append(plist,
1196 unity_vid, ISAKMP_NPTYPE_VID);
1197 }
1198 #endif
1199
1200 #ifdef ENABLE_NATT
1201 /* append NAT-T payloads */
1202 if (vid_natt) {
1203 /* chosen VID */
1204 plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
1205 /* NAT-D */
1206 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1207 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1208 }
1209 #endif
1210
1211 #ifdef ENABLE_FRAG
1212 if (vid_frag)
1213 plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
1214 #endif
1215
1216 #ifdef ENABLE_DPD
1217 if (vid_dpd)
1218 plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
1219 #endif
1220
1221 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1222
1223 #ifdef HAVE_PRINT_ISAKMP_C
1224 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1225 #endif
1226
1227 /* send the packet, add to the schedule to resend */
1228 if (isakmp_ph1send(iph1) == -1)
1229 goto end;
1230
1231 /* the sending message is added to the received-list. */
1232 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1233 plog(LLV_ERROR , LOCATION, NULL,
1234 "failed to add a response packet to the tree.\n");
1235 goto end;
1236 }
1237
1238 iph1->status = PHASE1ST_MSG1SENT;
1239
1240 error = 0;
1241
1242 end:
1243 #ifdef ENABLE_HYBRID
1244 if (xauth_vid)
1245 vfree(xauth_vid);
1246 if (unity_vid)
1247 vfree(unity_vid);
1248 #endif
1249 #ifdef HAVE_GSSAPI
1250 if (gsstoken)
1251 vfree(gsstoken);
1252 if (gsshash)
1253 vfree(gsshash);
1254 if (free_gss_sa)
1255 vfree(gss_sa);
1256 #endif
1257 #ifdef ENABLE_DPD
1258 if (vid_dpd)
1259 vfree(vid_dpd);
1260 #endif
1261 #ifdef ENABLE_FRAG
1262 if (vid_frag)
1263 vfree(vid_frag);
1264 #endif
1265
1266 return error;
1267 }
1268
1269 /*
1270 * receive from initiator
1271 * psk: HDR, HASH_I
1272 * gssapi: HDR, HASH_I
1273 * sig: HDR, [ CERT, ] SIG_I
1274 * rsa: HDR, HASH_I
1275 * rev: HDR, HASH_I
1276 */
1277 int
agg_r2recv(iph1,msg0)1278 agg_r2recv(iph1, msg0)
1279 struct ph1handle *iph1;
1280 vchar_t *msg0;
1281 {
1282 vchar_t *msg = NULL;
1283 vchar_t *pbuf = NULL;
1284 struct isakmp_parse_t *pa;
1285 int error = -1, ptype;
1286 #ifdef ENABLE_NATT
1287 int natd_seq = 0;
1288 #endif
1289
1290 /* validity check */
1291 if (iph1->status != PHASE1ST_MSG1SENT) {
1292 plog(LLV_ERROR, LOCATION, NULL,
1293 "status mismatched %d.\n", iph1->status);
1294 goto end;
1295 }
1296
1297 /* decrypting if need. */
1298 /* XXX configurable ? */
1299 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1300 msg = oakley_do_decrypt(iph1, msg0,
1301 iph1->ivm->iv, iph1->ivm->ive);
1302 if (msg == NULL)
1303 goto end;
1304 } else
1305 msg = vdup(msg0);
1306
1307 /* validate the type of next payload */
1308 pbuf = isakmp_parse(msg);
1309 if (pbuf == NULL)
1310 goto end;
1311
1312 iph1->pl_hash = NULL;
1313
1314 for (pa = (struct isakmp_parse_t *)pbuf->v;
1315 pa->type != ISAKMP_NPTYPE_NONE;
1316 pa++) {
1317
1318 switch (pa->type) {
1319 case ISAKMP_NPTYPE_HASH:
1320 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1321 break;
1322 case ISAKMP_NPTYPE_VID:
1323 handle_vendorid(iph1, pa->ptr);
1324 break;
1325 case ISAKMP_NPTYPE_CERT:
1326 if (oakley_savecert(iph1, pa->ptr) < 0)
1327 goto end;
1328 break;
1329 case ISAKMP_NPTYPE_SIG:
1330 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1331 goto end;
1332 break;
1333 case ISAKMP_NPTYPE_N:
1334 isakmp_log_notify(iph1,
1335 (struct isakmp_pl_n *) pa->ptr,
1336 "aggressive exchange");
1337 break;
1338
1339 #ifdef ENABLE_NATT
1340 case ISAKMP_NPTYPE_NATD_DRAFT:
1341 case ISAKMP_NPTYPE_NATD_RFC:
1342 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
1343 pa->type == iph1->natt_options->payload_nat_d)
1344 {
1345 vchar_t *natd_received = NULL;
1346 int natd_verified;
1347
1348 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
1349 goto end;
1350
1351 if (natd_seq == 0)
1352 iph1->natt_flags |= NAT_DETECTED;
1353
1354 natd_verified = natt_compare_addr_hash (iph1,
1355 natd_received, natd_seq++);
1356
1357 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
1358 natd_seq - 1,
1359 natd_verified ? "verified" : "doesn't match");
1360
1361 vfree (natd_received);
1362 break;
1363 }
1364 /* passthrough to default... */
1365 #endif
1366
1367 default:
1368 /* don't send information, see isakmp_ident_r1() */
1369 plog(LLV_ERROR, LOCATION, iph1->remote,
1370 "ignore the packet, "
1371 "received unexpecting payload type %d.\n",
1372 pa->type);
1373 goto end;
1374 }
1375 }
1376
1377 #ifdef ENABLE_NATT
1378 if (NATT_AVAILABLE(iph1))
1379 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1380 iph1->natt_flags & NAT_DETECTED ?
1381 "detected:" : "not detected",
1382 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1383 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1384 #endif
1385
1386 /* validate authentication value */
1387 ptype = oakley_validate_auth(iph1);
1388 if (ptype != 0) {
1389 if (ptype == -1) {
1390 /* message printed inner oakley_validate_auth() */
1391 goto end;
1392 }
1393 evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
1394 isakmp_info_send_n1(iph1, ptype, NULL);
1395 goto end;
1396 }
1397
1398 iph1->status = PHASE1ST_MSG2RECEIVED;
1399
1400 error = 0;
1401
1402 end:
1403 if (pbuf)
1404 vfree(pbuf);
1405 if (msg)
1406 vfree(msg);
1407 if (error) {
1408 VPTRINIT(iph1->cert_p);
1409 VPTRINIT(iph1->crl_p);
1410 VPTRINIT(iph1->sig_p);
1411 }
1412
1413 return error;
1414 }
1415
1416 /*
1417 * status update and establish isakmp sa.
1418 */
1419 int
agg_r2send(iph1,msg)1420 agg_r2send(iph1, msg)
1421 struct ph1handle *iph1;
1422 vchar_t *msg;
1423 {
1424 int error = -1;
1425
1426 /* validity check */
1427 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1428 plog(LLV_ERROR, LOCATION, NULL,
1429 "status mismatched %d.\n", iph1->status);
1430 goto end;
1431 }
1432
1433 /* IV synchronized when packet encrypted. */
1434 /* see handler.h about IV synchronization. */
1435 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1436 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1437
1438 /* set encryption flag */
1439 iph1->flags |= ISAKMP_FLAG_E;
1440
1441 iph1->status = PHASE1ST_ESTABLISHED;
1442
1443 error = 0;
1444
1445 end:
1446 return error;
1447 }
1448