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