Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_base.c, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: isakmp_base.c,v 1.12 2009/03/12 10:57:26 tteras Exp $ */
2:
3: /* $KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane 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: /* Base Exchange (Base 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_base.h"
79: #include "isakmp_inf.h"
80: #include "vendorid.h"
81: #ifdef ENABLE_NATT
82: #include "nattraversal.h"
83: #endif
84: #ifdef ENABLE_FRAG
85: #include "isakmp_frag.h"
86: #endif
87: #ifdef ENABLE_HYBRID
88: #include "isakmp_xauth.h"
89: #include "isakmp_cfg.h"
90: #endif
91:
92: /* %%%
93: * begin Identity Protection Mode as initiator.
94: */
95: /*
96: * send to responder
97: * psk: HDR, SA, Idii, Ni_b
98: * sig: HDR, SA, Idii, Ni_b
99: * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
100: * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
101: */
102: int
103: base_i1send(iph1, msg)
104: struct ph1handle *iph1;
105: vchar_t *msg; /* must be null */
106: {
107: struct payload_list *plist = NULL;
108: int error = -1;
109: #ifdef ENABLE_NATT
110: vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
111: int i, vid_natt_i = 0;
112: #endif
113: #ifdef ENABLE_FRAG
114: vchar_t *vid_frag = NULL;
115: #endif
116: #ifdef ENABLE_HYBRID
117: vchar_t *vid_xauth = NULL;
118: vchar_t *vid_unity = NULL;
119: #endif
120: #ifdef ENABLE_DPD
121: vchar_t *vid_dpd = NULL;
122: #endif
123:
124:
125: /* validity check */
126: if (msg != NULL) {
127: plog(LLV_ERROR, LOCATION, NULL,
128: "msg has to be NULL in this function.\n");
129: goto end;
130: }
131: if (iph1->status != PHASE1ST_START) {
132: plog(LLV_ERROR, LOCATION, NULL,
133: "status mismatched %d.\n", iph1->status);
134: goto end;
135: }
136:
137: /* create isakmp index */
138: memset(&iph1->index, 0, sizeof(iph1->index));
139: isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
140:
141: /* make ID payload into isakmp status */
142: if (ipsecdoi_setid1(iph1) < 0)
143: goto end;
144:
145: /* create SA payload for my proposal */
146: iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf,
147: iph1->rmconf->proposal);
148: if (iph1->sa == NULL)
149: goto end;
150:
151: /* generate NONCE value */
152: iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
153: if (iph1->nonce == NULL)
154: goto end;
155:
156: #ifdef ENABLE_HYBRID
157: /* Do we need Xauth VID? */
158: switch (iph1->rmconf->proposal->authmethod) {
159: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
160: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
161: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
162: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
163: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
164: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
165: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
166: if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
167: plog(LLV_ERROR, LOCATION, NULL,
168: "Xauth vendor ID generation failed\n");
169:
170: if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
171: plog(LLV_ERROR, LOCATION, NULL,
172: "Unity vendor ID generation failed\n");
173: break;
174: default:
175: break;
176: }
177: #endif
178: #ifdef ENABLE_FRAG
179: if (iph1->rmconf->ike_frag) {
180: vid_frag = set_vendorid(VENDORID_FRAG);
181: if (vid_frag != NULL)
182: vid_frag = isakmp_frag_addcap(vid_frag,
183: VENDORID_FRAG_BASE);
184: if (vid_frag == NULL)
185: plog(LLV_ERROR, LOCATION, NULL,
186: "Frag vendorID construction failed\n");
187: }
188: #endif
189: #ifdef ENABLE_NATT
190: /* Is NAT-T support allowed in the config file? */
191: if (iph1->rmconf->nat_traversal) {
192: /* Advertise NAT-T capability */
193: memset (vid_natt, 0, sizeof (vid_natt));
194: #ifdef VENDORID_NATT_00
195: if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL)
196: vid_natt_i++;
197: #endif
198: #ifdef VENDORID_NATT_02
199: if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL)
200: vid_natt_i++;
201: #endif
202: #ifdef VENDORID_NATT_02_N
203: if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL)
204: vid_natt_i++;
205: #endif
206: #ifdef VENDORID_NATT_RFC
207: if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL)
208: vid_natt_i++;
209: #endif
210: }
211: #endif
212:
213: /* set SA payload to propose */
214: plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
215:
216: /* create isakmp ID payload */
217: plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
218:
219: /* create isakmp NONCE payload */
220: plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
221:
222: #ifdef ENABLE_FRAG
223: if (vid_frag)
224: plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
225: #endif
226: #ifdef ENABLE_HYBRID
227: if (vid_xauth)
228: plist = isakmp_plist_append(plist,
229: vid_xauth, ISAKMP_NPTYPE_VID);
230: if (vid_unity)
231: plist = isakmp_plist_append(plist,
232: vid_unity, ISAKMP_NPTYPE_VID);
233: #endif
234: #ifdef ENABLE_DPD
235: if (iph1->rmconf->dpd) {
236: vid_dpd = set_vendorid(VENDORID_DPD);
237: if (vid_dpd != NULL)
238: plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
239: }
240: #endif
241: #ifdef ENABLE_NATT
242: /* set VID payload for NAT-T */
243: for (i = 0; i < vid_natt_i; i++)
244: plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID);
245: #endif
246: iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
247:
248:
249: #ifdef HAVE_PRINT_ISAKMP_C
250: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
251: #endif
252:
253: /* send the packet, add to the schedule to resend */
254: if (isakmp_ph1send(iph1) == -1)
255: goto end;
256:
257: iph1->status = PHASE1ST_MSG1SENT;
258:
259: error = 0;
260:
261: end:
262: #ifdef ENABLE_FRAG
263: if (vid_frag)
264: vfree(vid_frag);
265: #endif
266: #ifdef ENABLE_NATT
267: for (i = 0; i < vid_natt_i; i++)
268: vfree(vid_natt[i]);
269: #endif
270: #ifdef ENABLE_HYBRID
271: if (vid_xauth != NULL)
272: vfree(vid_xauth);
273: if (vid_unity != NULL)
274: vfree(vid_unity);
275: #endif
276: #ifdef ENABLE_DPD
277: if (vid_dpd != NULL)
278: vfree(vid_dpd);
279: #endif
280:
281: return error;
282: }
283:
284: /*
285: * receive from responder
286: * psk: HDR, SA, Idir, Nr_b
287: * sig: HDR, SA, Idir, Nr_b, [ CR ]
288: * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
289: * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
290: */
291: int
292: base_i2recv(iph1, msg)
293: struct ph1handle *iph1;
294: vchar_t *msg;
295: {
296: vchar_t *pbuf = NULL;
297: struct isakmp_parse_t *pa;
298: vchar_t *satmp = NULL;
299: int error = -1;
300: #ifdef ENABLE_HYBRID
301: vchar_t *unity_vid;
302: vchar_t *xauth_vid;
303: #endif
304:
305: /* validity check */
306: if (iph1->status != PHASE1ST_MSG1SENT) {
307: plog(LLV_ERROR, LOCATION, NULL,
308: "status mismatched %d.\n", iph1->status);
309: goto end;
310: }
311:
312: /* validate the type of next payload */
313: pbuf = isakmp_parse(msg);
314: if (pbuf == NULL)
315: goto end;
316: pa = (struct isakmp_parse_t *)pbuf->v;
317:
318: /* SA payload is fixed postion */
319: if (pa->type != ISAKMP_NPTYPE_SA) {
320: plog(LLV_ERROR, LOCATION, iph1->remote,
321: "received invalid next payload type %d, "
322: "expecting %d.\n",
323: pa->type, ISAKMP_NPTYPE_SA);
324: goto end;
325: }
326: if (isakmp_p2ph(&satmp, pa->ptr) < 0)
327: goto end;
328: pa++;
329:
330: for (/*nothing*/;
331: pa->type != ISAKMP_NPTYPE_NONE;
332: pa++) {
333:
334: switch (pa->type) {
335: case ISAKMP_NPTYPE_NONCE:
336: if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
337: goto end;
338: break;
339: case ISAKMP_NPTYPE_ID:
340: if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
341: goto end;
342: break;
343: case ISAKMP_NPTYPE_VID:
344: handle_vendorid(iph1, pa->ptr);
345: break;
346: default:
347: /* don't send information, see ident_r1recv() */
348: plog(LLV_ERROR, LOCATION, iph1->remote,
349: "ignore the packet, "
350: "received unexpecting payload type %d.\n",
351: pa->type);
352: goto end;
353: }
354: }
355:
356: if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
357: plog(LLV_ERROR, LOCATION, iph1->remote,
358: "few isakmp message received.\n");
359: goto end;
360: }
361:
362: /* verify identifier */
363: if (ipsecdoi_checkid1(iph1) != 0) {
364: plog(LLV_ERROR, LOCATION, iph1->remote,
365: "invalid ID payload.\n");
366: goto end;
367: }
368:
369: #ifdef ENABLE_NATT
370: if (NATT_AVAILABLE(iph1))
371: plog(LLV_INFO, LOCATION, iph1->remote,
372: "Selected NAT-T version: %s\n",
373: vid_string_by_id(iph1->natt_options->version));
374: #endif
375:
376: /* check SA payload and set approval SA for use */
377: if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
378: plog(LLV_ERROR, LOCATION, iph1->remote,
379: "failed to get valid proposal.\n");
380: /* XXX send information */
381: goto end;
382: }
383: VPTRINIT(iph1->sa_ret);
384:
385: iph1->status = PHASE1ST_MSG2RECEIVED;
386:
387: error = 0;
388:
389: end:
390: if (pbuf)
391: vfree(pbuf);
392: if (satmp)
393: vfree(satmp);
394:
395: if (error) {
396: VPTRINIT(iph1->nonce_p);
397: VPTRINIT(iph1->id_p);
398: }
399:
400: return error;
401: }
402:
403: /*
404: * send to responder
405: * psk: HDR, KE, HASH_I
406: * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
407: * rsa: HDR, KE, HASH_I
408: * rev: HDR, <KE>Ke_i, HASH_I
409: */
410: int
411: base_i2send(iph1, msg)
412: struct ph1handle *iph1;
413: vchar_t *msg;
414: {
415: struct payload_list *plist = NULL;
416: vchar_t *vid = NULL;
417: int need_cert = 0;
418: int error = -1;
419:
420: /* validity check */
421: if (iph1->status != PHASE1ST_MSG2RECEIVED) {
422: plog(LLV_ERROR, LOCATION, NULL,
423: "status mismatched %d.\n", iph1->status);
424: goto end;
425: }
426:
427: /* fix isakmp index */
428: memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
429: sizeof(cookie_t));
430:
431: /* generate DH public value */
432: if (oakley_dh_generate(iph1->approval->dhgrp,
433: &iph1->dhpub, &iph1->dhpriv) < 0)
434: goto end;
435:
436: /* generate SKEYID to compute hash if not signature mode */
437: switch (iph1->approval->authmethod) {
438: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
439: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
440: #ifdef ENABLE_HYBRID
441: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
442: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
443: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
444: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
445: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
446: #endif
447: break;
448: default:
449: if (oakley_skeyid(iph1) < 0)
450: goto end;
451: break;
452: }
453:
454: /* generate HASH to send */
455: plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
456: iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE);
457: if (iph1->hash == NULL)
458: goto end;
459: switch (iph1->approval->authmethod) {
460: case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
461: #ifdef ENABLE_HYBRID
462: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
463: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
464: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
465: #endif
466: vid = set_vendorid(iph1->approval->vendorid);
467:
468: /* create isakmp KE payload */
469: plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
470:
471: /* create isakmp HASH payload */
472: plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
473:
474: /* append vendor id, if needed */
475: if (vid)
476: plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
477: break;
478: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
479: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
480: #ifdef ENABLE_HYBRID
481: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
482: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
483: #endif
484: /* XXX if there is CR or not ? */
485:
486: if (oakley_getmycert(iph1) < 0)
487: goto end;
488:
489: if (oakley_getsign(iph1) < 0)
490: goto end;
491:
492: if (iph1->cert && iph1->rmconf->send_cert)
493: need_cert = 1;
494:
495: /* create isakmp KE payload */
496: plist = isakmp_plist_append(plist, iph1->dhpub,
497: ISAKMP_NPTYPE_KE);
498:
499: /* add CERT payload if there */
500: if (need_cert)
501: plist = isakmp_plist_append(plist, iph1->cert,
502: ISAKMP_NPTYPE_CERT);
503:
504: /* add SIG payload */
505: plist = isakmp_plist_append(plist,
506: iph1->sig, ISAKMP_NPTYPE_SIG);
507:
508: break;
509: #ifdef HAVE_GSSAPI
510: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
511: /* ... */
512: break;
513: #endif
514: case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
515: case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
516: #ifdef ENABLE_HYBRID
517: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
518: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
519: #endif
520: break;
521: }
522:
523: #ifdef ENABLE_NATT
524: /* generate NAT-D payloads */
525: if (NATT_AVAILABLE(iph1))
526: {
527: vchar_t *natd[2] = { NULL, NULL };
528:
529: plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
530: if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
531: plog(LLV_ERROR, LOCATION, NULL,
532: "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
533: goto end;
534: }
535:
536: if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
537: plog(LLV_ERROR, LOCATION, NULL,
538: "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
539: goto end;
540: }
541:
542: plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
543: plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
544: }
545: #endif
546:
547: iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
548:
549: #ifdef HAVE_PRINT_ISAKMP_C
550: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
551: #endif
552:
553: /* send the packet, add to the schedule to resend */
554: if (isakmp_ph1send(iph1) == -1)
555: goto end;
556:
557: /* the sending message is added to the received-list. */
558: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
559: plog(LLV_ERROR , LOCATION, NULL,
560: "failed to add a response packet to the tree.\n");
561: goto end;
562: }
563:
564: iph1->status = PHASE1ST_MSG2SENT;
565:
566: error = 0;
567:
568: end:
569: if (vid)
570: vfree(vid);
571: return error;
572: }
573:
574: /*
575: * receive from responder
576: * psk: HDR, KE, HASH_R
577: * sig: HDR, KE, [CERT,] SIG_R
578: * rsa: HDR, KE, HASH_R
579: * rev: HDR, <KE>_Ke_r, HASH_R
580: */
581: int
582: base_i3recv(iph1, msg)
583: struct ph1handle *iph1;
584: vchar_t *msg;
585: {
586: vchar_t *pbuf = NULL;
587: struct isakmp_parse_t *pa;
588: int error = -1, ptype;
589: #ifdef ENABLE_NATT
590: vchar_t *natd_received;
591: int natd_seq = 0, natd_verified;
592: #endif
593:
594: /* validity check */
595: if (iph1->status != PHASE1ST_MSG2SENT) {
596: plog(LLV_ERROR, LOCATION, NULL,
597: "status mismatched %d.\n", iph1->status);
598: goto end;
599: }
600:
601: /* validate the type of next payload */
602: pbuf = isakmp_parse(msg);
603: if (pbuf == NULL)
604: goto end;
605:
606: for (pa = (struct isakmp_parse_t *)pbuf->v;
607: pa->type != ISAKMP_NPTYPE_NONE;
608: pa++) {
609:
610: switch (pa->type) {
611: case ISAKMP_NPTYPE_KE:
612: if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
613: goto end;
614: break;
615: case ISAKMP_NPTYPE_HASH:
616: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
617: break;
618: case ISAKMP_NPTYPE_CERT:
619: if (oakley_savecert(iph1, pa->ptr) < 0)
620: goto end;
621: break;
622: case ISAKMP_NPTYPE_SIG:
623: if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
624: goto end;
625: break;
626: case ISAKMP_NPTYPE_VID:
627: handle_vendorid(iph1, pa->ptr);
628: break;
629:
630: #ifdef ENABLE_NATT
631: case ISAKMP_NPTYPE_NATD_DRAFT:
632: case ISAKMP_NPTYPE_NATD_RFC:
633: if (NATT_AVAILABLE(iph1) && iph1->natt_options &&
634: pa->type == iph1->natt_options->payload_nat_d) {
635: natd_received = NULL;
636: if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
637: goto end;
638:
639: /* set both bits first so that we can clear them
640: upon verifying hashes */
641: if (natd_seq == 0)
642: iph1->natt_flags |= NAT_DETECTED;
643:
644: /* this function will clear appropriate bits bits
645: from iph1->natt_flags */
646: natd_verified = natt_compare_addr_hash (iph1,
647: natd_received, natd_seq++);
648:
649: plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
650: natd_seq - 1,
651: natd_verified ? "verified" : "doesn't match");
652:
653: vfree (natd_received);
654: break;
655: }
656: /* passthrough to default... */
657: #endif
658:
659: default:
660: /* don't send information, see ident_r1recv() */
661: plog(LLV_ERROR, LOCATION, iph1->remote,
662: "ignore the packet, "
663: "received unexpecting payload type %d.\n",
664: pa->type);
665: goto end;
666: }
667: }
668:
669: #ifdef ENABLE_NATT
670: if (NATT_AVAILABLE(iph1)) {
671: plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
672: iph1->natt_flags & NAT_DETECTED ?
673: "detected:" : "not detected",
674: iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
675: iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
676: if (iph1->natt_flags & NAT_DETECTED)
677: natt_float_ports (iph1);
678: }
679: #endif
680:
681: /* payload existency check */
682: /* validate authentication value */
683: ptype = oakley_validate_auth(iph1);
684: if (ptype != 0) {
685: if (ptype == -1) {
686: /* message printed inner oakley_validate_auth() */
687: goto end;
688: }
689: evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
690: isakmp_info_send_n1(iph1, ptype, NULL);
691: goto end;
692: }
693:
694: /* compute sharing secret of DH */
695: if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
696: iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
697: goto end;
698:
699: /* generate SKEYID to compute hash if signature mode */
700: switch (iph1->approval->authmethod) {
701: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
702: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
703: #ifdef ENABLE_HYBRID
704: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
705: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
706: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
707: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
708: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
709: #endif
710: if (oakley_skeyid(iph1) < 0)
711: goto end;
712: break;
713: default:
714: break;
715: }
716:
717: /* generate SKEYIDs & IV & final cipher key */
718: if (oakley_skeyid_dae(iph1) < 0)
719: goto end;
720: if (oakley_compute_enckey(iph1) < 0)
721: goto end;
722: if (oakley_newiv(iph1) < 0)
723: goto end;
724:
725: /* see handler.h about IV synchronization. */
726: memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
727:
728: /* set encryption flag */
729: iph1->flags |= ISAKMP_FLAG_E;
730:
731: iph1->status = PHASE1ST_MSG3RECEIVED;
732:
733: error = 0;
734:
735: end:
736: if (pbuf)
737: vfree(pbuf);
738:
739: if (error) {
740: VPTRINIT(iph1->dhpub_p);
741: VPTRINIT(iph1->cert_p);
742: VPTRINIT(iph1->crl_p);
743: VPTRINIT(iph1->sig_p);
744: }
745:
746: return error;
747: }
748:
749: /*
750: * status update and establish isakmp sa.
751: */
752: int
753: base_i3send(iph1, msg)
754: struct ph1handle *iph1;
755: vchar_t *msg;
756: {
757: int error = -1;
758:
759: /* validity check */
760: if (iph1->status != PHASE1ST_MSG3RECEIVED) {
761: plog(LLV_ERROR, LOCATION, NULL,
762: "status mismatched %d.\n", iph1->status);
763: goto end;
764: }
765:
766: iph1->status = PHASE1ST_ESTABLISHED;
767:
768: error = 0;
769:
770: end:
771: return error;
772: }
773:
774: /*
775: * receive from initiator
776: * psk: HDR, SA, Idii, Ni_b
777: * sig: HDR, SA, Idii, Ni_b
778: * rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
779: * rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
780: */
781: int
782: base_r1recv(iph1, msg)
783: struct ph1handle *iph1;
784: vchar_t *msg;
785: {
786: vchar_t *pbuf = NULL;
787: struct isakmp_parse_t *pa;
788: int error = -1;
789: int vid_numeric;
790:
791: /* validity check */
792: if (iph1->status != PHASE1ST_START) {
793: plog(LLV_ERROR, LOCATION, NULL,
794: "status mismatched %d.\n", iph1->status);
795: goto end;
796: }
797:
798: /* validate the type of next payload */
799: pbuf = isakmp_parse(msg);
800: if (pbuf == NULL)
801: goto end;
802: pa = (struct isakmp_parse_t *)pbuf->v;
803:
804: /* check the position of SA payload */
805: if (pa->type != ISAKMP_NPTYPE_SA) {
806: plog(LLV_ERROR, LOCATION, iph1->remote,
807: "received invalid next payload type %d, "
808: "expecting %d.\n",
809: pa->type, ISAKMP_NPTYPE_SA);
810: goto end;
811: }
812: if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
813: goto end;
814: pa++;
815:
816: for (/*nothing*/;
817: pa->type != ISAKMP_NPTYPE_NONE;
818: pa++) {
819:
820: switch (pa->type) {
821: case ISAKMP_NPTYPE_NONCE:
822: if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
823: goto end;
824: break;
825: case ISAKMP_NPTYPE_ID:
826: if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
827: goto end;
828: break;
829: case ISAKMP_NPTYPE_VID:
830: vid_numeric = handle_vendorid(iph1, pa->ptr);
831: #ifdef ENABLE_FRAG
832: if ((vid_numeric == VENDORID_FRAG) &&
833: (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE))
834: iph1->frag = 1;
835: #endif
836: break;
837: default:
838: /* don't send information, see ident_r1recv() */
839: plog(LLV_ERROR, LOCATION, iph1->remote,
840: "ignore the packet, "
841: "received unexpecting payload type %d.\n",
842: pa->type);
843: goto end;
844: }
845: }
846:
847: if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
848: plog(LLV_ERROR, LOCATION, iph1->remote,
849: "few isakmp message received.\n");
850: goto end;
851: }
852:
853: /* verify identifier */
854: if (ipsecdoi_checkid1(iph1) != 0) {
855: plog(LLV_ERROR, LOCATION, iph1->remote,
856: "invalid ID payload.\n");
857: goto end;
858: }
859:
860: #ifdef ENABLE_NATT
861: if (NATT_AVAILABLE(iph1))
862: plog(LLV_INFO, LOCATION, iph1->remote,
863: "Selected NAT-T version: %s\n",
864: vid_string_by_id(iph1->natt_options->version));
865: #endif
866:
867: /* check SA payload and set approval SA for use */
868: if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
869: plog(LLV_ERROR, LOCATION, iph1->remote,
870: "failed to get valid proposal.\n");
871: /* XXX send information */
872: goto end;
873: }
874:
875: iph1->status = PHASE1ST_MSG1RECEIVED;
876:
877: error = 0;
878:
879: end:
880: if (pbuf)
881: vfree(pbuf);
882:
883: if (error) {
884: VPTRINIT(iph1->sa);
885: VPTRINIT(iph1->nonce_p);
886: VPTRINIT(iph1->id_p);
887: }
888:
889: return error;
890: }
891:
892: /*
893: * send to initiator
894: * psk: HDR, SA, Idir, Nr_b
895: * sig: HDR, SA, Idir, Nr_b, [ CR ]
896: * rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
897: * rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
898: */
899: int
900: base_r1send(iph1, msg)
901: struct ph1handle *iph1;
902: vchar_t *msg;
903: {
904: struct payload_list *plist = NULL;
905: int error = -1;
906: #ifdef ENABLE_NATT
907: vchar_t *vid_natt = NULL;
908: #endif
909: #ifdef ENABLE_HYBRID
910: vchar_t *vid_xauth = NULL;
911: vchar_t *vid_unity = NULL;
912: #endif
913: #ifdef ENABLE_FRAG
914: vchar_t *vid_frag = NULL;
915: #endif
916: #ifdef ENABLE_DPD
917: vchar_t *vid_dpd = NULL;
918: #endif
919:
920: /* validity check */
921: if (iph1->status != PHASE1ST_MSG1RECEIVED) {
922: plog(LLV_ERROR, LOCATION, NULL,
923: "status mismatched %d.\n", iph1->status);
924: goto end;
925: }
926:
927: /* set responder's cookie */
928: isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
929:
930: /* make ID payload into isakmp status */
931: if (ipsecdoi_setid1(iph1) < 0)
932: goto end;
933:
934: /* generate NONCE value */
935: iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
936: if (iph1->nonce == NULL)
937: goto end;
938:
939: /* set SA payload to reply */
940: plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA);
941:
942: /* create isakmp ID payload */
943: plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
944:
945: /* create isakmp NONCE payload */
946: plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
947:
948: #ifdef ENABLE_NATT
949: /* has the peer announced nat-t? */
950: if (NATT_AVAILABLE(iph1))
951: vid_natt = set_vendorid(iph1->natt_options->version);
952: if (vid_natt)
953: plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
954: #endif
955: #ifdef ENABLE_HYBRID
956: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
957: plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
958: if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) {
959: plog(LLV_ERROR, LOCATION, NULL,
960: "Cannot create Xauth vendor ID\n");
961: goto end;
962: }
963: plist = isakmp_plist_append(plist,
964: vid_xauth, ISAKMP_NPTYPE_VID);
965: }
966:
967: if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
968: if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) {
969: plog(LLV_ERROR, LOCATION, NULL,
970: "Cannot create Unity vendor ID\n");
971: goto end;
972: }
973: plist = isakmp_plist_append(plist,
974: vid_unity, ISAKMP_NPTYPE_VID);
975: }
976: #endif
977: #ifdef ENABLE_DPD
978: /*
979: * Only send DPD support if remote announced DPD
980: * and if DPD support is active
981: */
982: if (iph1->dpd_support && iph1->rmconf->dpd) {
983: if ((vid_dpd = set_vendorid(VENDORID_DPD)) == NULL) {
984: plog(LLV_ERROR, LOCATION, NULL,
985: "DPD vendorID construction failed\n");
986: } else {
987: plist = isakmp_plist_append(plist, vid_dpd,
988: ISAKMP_NPTYPE_VID);
989: }
990: }
991: #endif
992: #ifdef ENABLE_FRAG
993: if (iph1->rmconf->ike_frag) {
994: if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) {
995: plog(LLV_ERROR, LOCATION, NULL,
996: "Frag vendorID construction failed\n");
997: } else {
998: vid_frag = isakmp_frag_addcap(vid_frag,
999: VENDORID_FRAG_BASE);
1000: plist = isakmp_plist_append(plist,
1001: vid_frag, ISAKMP_NPTYPE_VID);
1002: }
1003: }
1004: #endif
1005:
1006: iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1007:
1008: #ifdef HAVE_PRINT_ISAKMP_C
1009: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1010: #endif
1011:
1012: /* send the packet, add to the schedule to resend */
1013: if (isakmp_ph1send(iph1) == -1) {
1014: iph1 = NULL;
1015: goto end;
1016: }
1017:
1018: /* the sending message is added to the received-list. */
1019: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1020: plog(LLV_ERROR , LOCATION, NULL,
1021: "failed to add a response packet to the tree.\n");
1022: goto end;
1023: }
1024:
1025: iph1->status = PHASE1ST_MSG1SENT;
1026:
1027: error = 0;
1028:
1029: end:
1030: #ifdef ENABLE_NATT
1031: if (vid_natt)
1032: vfree(vid_natt);
1033: #endif
1034: #ifdef ENABLE_HYBRID
1035: if (vid_xauth != NULL)
1036: vfree(vid_xauth);
1037: if (vid_unity != NULL)
1038: vfree(vid_unity);
1039: #endif
1040: #ifdef ENABLE_FRAG
1041: if (vid_frag)
1042: vfree(vid_frag);
1043: #endif
1044: #ifdef ENABLE_DPD
1045: if (vid_dpd)
1046: vfree(vid_dpd);
1047: #endif
1048:
1049: if (iph1 != NULL)
1050: VPTRINIT(iph1->sa_ret);
1051:
1052: return error;
1053: }
1054:
1055: /*
1056: * receive from initiator
1057: * psk: HDR, KE, HASH_I
1058: * sig: HDR, KE, [ CR, ] [CERT,] SIG_I
1059: * rsa: HDR, KE, HASH_I
1060: * rev: HDR, <KE>Ke_i, HASH_I
1061: */
1062: int
1063: base_r2recv(iph1, msg)
1064: struct ph1handle *iph1;
1065: vchar_t *msg;
1066: {
1067: vchar_t *pbuf = NULL;
1068: struct isakmp_parse_t *pa;
1069: int error = -1, ptype;
1070: #ifdef ENABLE_NATT
1071: int natd_seq = 0;
1072: #endif
1073:
1074: /* validity check */
1075: if (iph1->status != PHASE1ST_MSG1SENT) {
1076: plog(LLV_ERROR, LOCATION, NULL,
1077: "status mismatched %d.\n", iph1->status);
1078: goto end;
1079: }
1080:
1081: /* validate the type of next payload */
1082: pbuf = isakmp_parse(msg);
1083: if (pbuf == NULL)
1084: goto end;
1085:
1086: iph1->pl_hash = NULL;
1087:
1088: for (pa = (struct isakmp_parse_t *)pbuf->v;
1089: pa->type != ISAKMP_NPTYPE_NONE;
1090: pa++) {
1091:
1092: switch (pa->type) {
1093: case ISAKMP_NPTYPE_KE:
1094: if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
1095: goto end;
1096: break;
1097: case ISAKMP_NPTYPE_HASH:
1098: iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1099: break;
1100: case ISAKMP_NPTYPE_CERT:
1101: if (oakley_savecert(iph1, pa->ptr) < 0)
1102: goto end;
1103: break;
1104: case ISAKMP_NPTYPE_SIG:
1105: if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1106: goto end;
1107: break;
1108: case ISAKMP_NPTYPE_VID:
1109: handle_vendorid(iph1, pa->ptr);
1110: break;
1111:
1112: #ifdef ENABLE_NATT
1113: case ISAKMP_NPTYPE_NATD_DRAFT:
1114: case ISAKMP_NPTYPE_NATD_RFC:
1115: if (pa->type == iph1->natt_options->payload_nat_d)
1116: {
1117: vchar_t *natd_received = NULL;
1118: int natd_verified;
1119:
1120: if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
1121: goto end;
1122:
1123: if (natd_seq == 0)
1124: iph1->natt_flags |= NAT_DETECTED;
1125:
1126: natd_verified = natt_compare_addr_hash (iph1,
1127: natd_received, natd_seq++);
1128:
1129: plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
1130: natd_seq - 1,
1131: natd_verified ? "verified" : "doesn't match");
1132:
1133: vfree (natd_received);
1134: break;
1135: }
1136: /* passthrough to default... */
1137: #endif
1138:
1139: default:
1140: /* don't send information, see ident_r1recv() */
1141: plog(LLV_ERROR, LOCATION, iph1->remote,
1142: "ignore the packet, "
1143: "received unexpecting payload type %d.\n",
1144: pa->type);
1145: goto end;
1146: }
1147: }
1148:
1149: /* generate DH public value */
1150: if (oakley_dh_generate(iph1->approval->dhgrp,
1151: &iph1->dhpub, &iph1->dhpriv) < 0)
1152: goto end;
1153:
1154: /* compute sharing secret of DH */
1155: if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
1156: iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
1157: goto end;
1158:
1159: /* generate SKEYID */
1160: if (oakley_skeyid(iph1) < 0)
1161: goto end;
1162:
1163: #ifdef ENABLE_NATT
1164: if (NATT_AVAILABLE(iph1))
1165: plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1166: iph1->natt_flags & NAT_DETECTED ?
1167: "detected:" : "not detected",
1168: iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1169: iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1170: #endif
1171:
1172: /* payload existency check */
1173: /* validate authentication value */
1174: ptype = oakley_validate_auth(iph1);
1175: if (ptype != 0) {
1176: if (ptype == -1) {
1177: /* message printed inner oakley_validate_auth() */
1178: goto end;
1179: }
1180: evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
1181: isakmp_info_send_n1(iph1, ptype, NULL);
1182: goto end;
1183: }
1184:
1185: iph1->status = PHASE1ST_MSG2RECEIVED;
1186:
1187: error = 0;
1188:
1189: end:
1190: if (pbuf)
1191: vfree(pbuf);
1192:
1193: if (error) {
1194: VPTRINIT(iph1->dhpub_p);
1195: VPTRINIT(iph1->cert_p);
1196: VPTRINIT(iph1->crl_p);
1197: VPTRINIT(iph1->sig_p);
1198: }
1199:
1200: return error;
1201: }
1202:
1203: /*
1204: * send to initiator
1205: * psk: HDR, KE, HASH_R
1206: * sig: HDR, KE, [CERT,] SIG_R
1207: * rsa: HDR, KE, HASH_R
1208: * rev: HDR, <KE>_Ke_r, HASH_R
1209: */
1210: int
1211: base_r2send(iph1, msg)
1212: struct ph1handle *iph1;
1213: vchar_t *msg;
1214: {
1215: struct payload_list *plist = NULL;
1216: vchar_t *vid = NULL;
1217: int need_cert = 0;
1218: int error = -1;
1219:
1220: /* validity check */
1221: if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1222: plog(LLV_ERROR, LOCATION, NULL,
1223: "status mismatched %d.\n", iph1->status);
1224: goto end;
1225: }
1226:
1227: /* generate HASH to send */
1228: plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
1229: switch (iph1->approval->authmethod) {
1230: case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1231: #ifdef ENABLE_HYBRID
1232: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1233: #endif
1234: case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1235: case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1236: #ifdef ENABLE_HYBRID
1237: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1238: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1239: #endif
1240: iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1241: break;
1242: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1243: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1244: #ifdef ENABLE_HYBRID
1245: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1246: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1247: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1248: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1249: #endif
1250: #ifdef HAVE_GSSAPI
1251: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1252: #endif
1253: iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE);
1254: break;
1255: default:
1256: plog(LLV_ERROR, LOCATION, NULL,
1257: "invalid authentication method %d\n",
1258: iph1->approval->authmethod);
1259: goto end;
1260: }
1261: if (iph1->hash == NULL)
1262: goto end;
1263:
1264: switch (iph1->approval->authmethod) {
1265: case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1266: #ifdef ENABLE_HYBRID
1267: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1268: #endif
1269: vid = set_vendorid(iph1->approval->vendorid);
1270:
1271: /* create isakmp KE payload */
1272: plist = isakmp_plist_append(plist,
1273: iph1->dhpub, ISAKMP_NPTYPE_KE);
1274:
1275: /* create isakmp HASH payload */
1276: plist = isakmp_plist_append(plist,
1277: iph1->hash, ISAKMP_NPTYPE_HASH);
1278:
1279: /* append vendor id, if needed */
1280: if (vid)
1281: plist = isakmp_plist_append(plist,
1282: vid, ISAKMP_NPTYPE_VID);
1283: break;
1284: case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1285: case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1286: #ifdef ENABLE_HYBRID
1287: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1288: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1289: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1290: case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1291: #endif
1292: /* XXX if there is CR or not ? */
1293:
1294: if (oakley_getmycert(iph1) < 0)
1295: goto end;
1296:
1297: if (oakley_getsign(iph1) < 0)
1298: goto end;
1299:
1300: if (iph1->cert && iph1->rmconf->send_cert)
1301: need_cert = 1;
1302:
1303: /* create isakmp KE payload */
1304: plist = isakmp_plist_append(plist, iph1->dhpub,
1305: ISAKMP_NPTYPE_KE);
1306:
1307: /* add CERT payload if there */
1308: if (need_cert)
1309: plist = isakmp_plist_append(plist, iph1->cert,
1310: ISAKMP_NPTYPE_CERT);
1311:
1312: /* add SIG payload */
1313: plist = isakmp_plist_append(plist, iph1->sig,
1314: ISAKMP_NPTYPE_SIG);
1315: break;
1316: #ifdef HAVE_GSSAPI
1317: case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1318: /* ... */
1319: break;
1320: #endif
1321: case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1322: case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1323: #ifdef ENABLE_HYBRID
1324: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1325: case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1326: #endif
1327: break;
1328: }
1329:
1330: #ifdef ENABLE_NATT
1331: /* generate NAT-D payloads */
1332: if (NATT_AVAILABLE(iph1)) {
1333: vchar_t *natd[2] = { NULL, NULL };
1334:
1335: plog(LLV_INFO, LOCATION,
1336: NULL, "Adding remote and local NAT-D payloads.\n");
1337: if ((natd[0] = natt_hash_addr(iph1, iph1->remote)) == NULL) {
1338: plog(LLV_ERROR, LOCATION, NULL,
1339: "NAT-D hashing failed for %s\n",
1340: saddr2str(iph1->remote));
1341: goto end;
1342: }
1343:
1344: if ((natd[1] = natt_hash_addr(iph1, iph1->local)) == NULL) {
1345: plog(LLV_ERROR, LOCATION, NULL,
1346: "NAT-D hashing failed for %s\n",
1347: saddr2str(iph1->local));
1348: goto end;
1349: }
1350:
1351: plist = isakmp_plist_append(plist,
1352: natd[0], iph1->natt_options->payload_nat_d);
1353: plist = isakmp_plist_append(plist,
1354: natd[1], iph1->natt_options->payload_nat_d);
1355: }
1356: #endif
1357:
1358: iph1->sendbuf = isakmp_plist_set_all(&plist, iph1);
1359:
1360: #ifdef HAVE_PRINT_ISAKMP_C
1361: isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1362: #endif
1363:
1364: /* send HDR;KE;NONCE to responder */
1365: if (isakmp_send(iph1, iph1->sendbuf) < 0)
1366: goto end;
1367:
1368: /* the sending message is added to the received-list. */
1369: if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1370: plog(LLV_ERROR , LOCATION, NULL,
1371: "failed to add a response packet to the tree.\n");
1372: goto end;
1373: }
1374:
1375: /* generate SKEYIDs & IV & final cipher key */
1376: if (oakley_skeyid_dae(iph1) < 0)
1377: goto end;
1378: if (oakley_compute_enckey(iph1) < 0)
1379: goto end;
1380: if (oakley_newiv(iph1) < 0)
1381: goto end;
1382:
1383: /* set encryption flag */
1384: iph1->flags |= ISAKMP_FLAG_E;
1385:
1386: iph1->status = PHASE1ST_ESTABLISHED;
1387:
1388: error = 0;
1389:
1390: end:
1391: if (vid)
1392: vfree(vid);
1393: return error;
1394: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>