1 /* $NetBSD: isakmp_ident.c,v 1.6 2006/10/02 21:41:59 manu Exp $ */
2
3 /* Id: isakmp_ident.c,v 1.21 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 /* Identity Protecion Exchange (Main 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 #include "localconf.h"
65 #include "remoteconf.h"
66 #include "isakmp_var.h"
67 #include "isakmp.h"
68 #include "evt.h"
69 #include "oakley.h"
70 #include "handler.h"
71 #include "ipsec_doi.h"
72 #include "crypto_openssl.h"
73 #include "pfkey.h"
74 #include "isakmp_ident.h"
75 #include "isakmp_inf.h"
76 #include "vendorid.h"
77
78 #ifdef ENABLE_NATT
79 #include "nattraversal.h"
80 #endif
81 #ifdef HAVE_GSSAPI
82 #include "gssapi.h"
83 #endif
84 #ifdef ENABLE_HYBRID
85 #include <resolv.h>
86 #include "isakmp_xauth.h"
87 #include "isakmp_cfg.h"
88 #endif
89 #ifdef ENABLE_FRAG
90 #include "isakmp_frag.h"
91 #endif
92
93 static vchar_t *ident_ir2mx __P((struct ph1handle *));
94 static vchar_t *ident_ir3mx __P((struct ph1handle *));
95
96 /* %%%
97 * begin Identity Protection Mode as initiator.
98 */
99 /*
100 * send to responder
101 * psk: HDR, SA
102 * sig: HDR, SA
103 * rsa: HDR, SA
104 * rev: HDR, SA
105 */
106 int
ident_i1send(iph1,msg)107 ident_i1send(iph1, msg)
108 struct ph1handle *iph1;
109 vchar_t *msg; /* must be null */
110 {
111 struct payload_list *plist = NULL;
112 int error = -1;
113 #ifdef ENABLE_NATT
114 vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
115 int i;
116 #endif
117 #ifdef ENABLE_HYBRID
118 vchar_t *vid_xauth = NULL;
119 vchar_t *vid_unity = NULL;
120 #endif
121 #ifdef ENABLE_FRAG
122 vchar_t *vid_frag = NULL;
123 #endif
124 #ifdef ENABLE_DPD
125 vchar_t *vid_dpd = NULL;
126 #endif
127 /* validity check */
128 if (msg != NULL) {
129 plog(LLV_ERROR, LOCATION, NULL,
130 "msg has to be NULL in this function.\n");
131 goto end;
132 }
133 if (iph1->status != PHASE1ST_START) {
134 plog(LLV_ERROR, LOCATION, NULL,
135 "status mismatched %d.\n", iph1->status);
136 goto end;
137 }
138
139 /* create isakmp index */
140 memset(&iph1->index, 0, sizeof(iph1->index));
141 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
142
143 /* create SA payload for my proposal */
144 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
145 if (iph1->sa == NULL)
146 goto end;
147
148 /* set SA payload to propose */
149 plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
150
151 #ifdef ENABLE_NATT
152 /* set VID payload for NAT-T if NAT-T support allowed in the config file */
153 if (iph1->rmconf->nat_traversal)
154 plist = isakmp_plist_append_natt_vids(plist, vid_natt);
155 #endif
156 #ifdef ENABLE_HYBRID
157 /* Do we need Xauth VID? */
158 switch (RMAUTHMETHOD(iph1)) {
159 case FICTIVE_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 else
170 plist = isakmp_plist_append(plist,
171 vid_xauth, ISAKMP_NPTYPE_VID);
172
173 if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
174 plog(LLV_ERROR, LOCATION, NULL,
175 "Unity vendor ID generation failed\n");
176 else
177 plist = isakmp_plist_append(plist,
178 vid_unity, ISAKMP_NPTYPE_VID);
179 break;
180 default:
181 break;
182 }
183 #endif
184 #ifdef ENABLE_FRAG
185 if (iph1->rmconf->ike_frag) {
186 if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) {
187 plog(LLV_ERROR, LOCATION, NULL,
188 "Frag vendorID construction failed\n");
189 } else {
190 vid_frag = isakmp_frag_addcap(vid_frag,
191 VENDORID_FRAG_IDENT);
192 plist = isakmp_plist_append(plist,
193 vid_frag, ISAKMP_NPTYPE_VID);
194 }
195 }
196 #endif
197 #ifdef ENABLE_DPD
198 if(iph1->rmconf->dpd){
199 vid_dpd = set_vendorid(VENDORID_DPD);
200 if (vid_dpd != NULL)
201 plist = isakmp_plist_append(plist, vid_dpd,
202 ISAKMP_NPTYPE_VID);
203 }
204 #endif
205
206 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
207
208 #ifdef HAVE_PRINT_ISAKMP_C
209 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
210 #endif
211
212 /* send the packet, add to the schedule to resend */
213 iph1->retry_counter = iph1->rmconf->retry_counter;
214 if (isakmp_ph1resend(iph1) == -1)
215 goto end;
216
217 iph1->status = PHASE1ST_MSG1SENT;
218
219 error = 0;
220
221 end:
222 #ifdef ENABLE_FRAG
223 if (vid_frag)
224 vfree(vid_frag);
225 #endif
226 #ifdef ENABLE_NATT
227 for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
228 vfree(vid_natt[i]);
229 #endif
230 #ifdef ENABLE_HYBRID
231 if (vid_xauth != NULL)
232 vfree(vid_xauth);
233 if (vid_unity != NULL)
234 vfree(vid_unity);
235 #endif
236 #ifdef ENABLE_DPD
237 if (vid_dpd != NULL)
238 vfree(vid_dpd);
239 #endif
240
241 return error;
242 }
243
244 /*
245 * receive from responder
246 * psk: HDR, SA
247 * sig: HDR, SA
248 * rsa: HDR, SA
249 * rev: HDR, SA
250 */
251 int
ident_i2recv(iph1,msg)252 ident_i2recv(iph1, msg)
253 struct ph1handle *iph1;
254 vchar_t *msg;
255 {
256 vchar_t *pbuf = NULL;
257 struct isakmp_parse_t *pa;
258 vchar_t *satmp = NULL;
259 int error = -1;
260 int vid_numeric;
261
262 /* validity check */
263 if (iph1->status != PHASE1ST_MSG1SENT) {
264 plog(LLV_ERROR, LOCATION, NULL,
265 "status mismatched %d.\n", iph1->status);
266 goto end;
267 }
268
269 /* validate the type of next payload */
270 /*
271 * NOTE: RedCreek(as responder) attaches N[responder-lifetime] here,
272 * if proposal-lifetime > lifetime-redcreek-wants.
273 * (see doi-08 4.5.4)
274 * => According to the seciton 4.6.3 in RFC 2407, This is illegal.
275 * NOTE: we do not really care about ordering of VID and N.
276 * does it matters?
277 * NOTE: even if there's multiple VID/N, we'll ignore them.
278 */
279 pbuf = isakmp_parse(msg);
280 if (pbuf == NULL)
281 goto end;
282 pa = (struct isakmp_parse_t *)pbuf->v;
283
284 /* SA payload is fixed postion */
285 if (pa->type != ISAKMP_NPTYPE_SA) {
286 plog(LLV_ERROR, LOCATION, iph1->remote,
287 "received invalid next payload type %d, "
288 "expecting %d.\n",
289 pa->type, ISAKMP_NPTYPE_SA);
290 goto end;
291 }
292 if (isakmp_p2ph(&satmp, pa->ptr) < 0)
293 goto end;
294 pa++;
295
296 for (/*nothing*/;
297 pa->type != ISAKMP_NPTYPE_NONE;
298 pa++) {
299
300 switch (pa->type) {
301 case ISAKMP_NPTYPE_VID:
302 handle_vendorid(iph1, pa->ptr);
303 break;
304 default:
305 /* don't send information, see ident_r1recv() */
306 plog(LLV_ERROR, LOCATION, iph1->remote,
307 "ignore the packet, "
308 "received unexpecting payload type %d.\n",
309 pa->type);
310 goto end;
311 }
312 }
313
314 #ifdef ENABLE_NATT
315 if (NATT_AVAILABLE(iph1))
316 plog(LLV_INFO, LOCATION, iph1->remote,
317 "Selected NAT-T version: %s\n",
318 vid_string_by_id(iph1->natt_options->version));
319 #endif
320
321 /* check SA payload and set approval SA for use */
322 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
323 plog(LLV_ERROR, LOCATION, iph1->remote,
324 "failed to get valid proposal.\n");
325 /* XXX send information */
326 goto end;
327 }
328 VPTRINIT(iph1->sa_ret);
329
330 iph1->status = PHASE1ST_MSG2RECEIVED;
331
332 error = 0;
333
334 end:
335 if (pbuf)
336 vfree(pbuf);
337 if (satmp)
338 vfree(satmp);
339 return error;
340 }
341
342 /*
343 * send to responder
344 * psk: HDR, KE, Ni
345 * sig: HDR, KE, Ni
346 * gssapi: HDR, KE, Ni, GSSi
347 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
348 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
349 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
350 */
351 int
ident_i2send(iph1,msg)352 ident_i2send(iph1, msg)
353 struct ph1handle *iph1;
354 vchar_t *msg;
355 {
356 int error = -1;
357
358 /* validity check */
359 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
360 plog(LLV_ERROR, LOCATION, NULL,
361 "status mismatched %d.\n", iph1->status);
362 goto end;
363 }
364
365 /* fix isakmp index */
366 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
367 sizeof(cookie_t));
368
369 /* generate DH public value */
370 if (oakley_dh_generate(iph1->approval->dhgrp,
371 &iph1->dhpub, &iph1->dhpriv) < 0)
372 goto end;
373
374 /* generate NONCE value */
375 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
376 if (iph1->nonce == NULL)
377 goto end;
378
379 #ifdef HAVE_GSSAPI
380 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
381 gssapi_get_itoken(iph1, NULL) < 0)
382 goto end;
383 #endif
384
385 /* create buffer to send isakmp payload */
386 iph1->sendbuf = ident_ir2mx(iph1);
387 if (iph1->sendbuf == NULL)
388 goto end;
389
390 #ifdef HAVE_PRINT_ISAKMP_C
391 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
392 #endif
393
394 /* send the packet, add to the schedule to resend */
395 iph1->retry_counter = iph1->rmconf->retry_counter;
396 if (isakmp_ph1resend(iph1) == -1)
397 goto end;
398
399 /* the sending message is added to the received-list. */
400 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
401 plog(LLV_ERROR , LOCATION, NULL,
402 "failed to add a response packet to the tree.\n");
403 goto end;
404 }
405
406 iph1->status = PHASE1ST_MSG2SENT;
407
408 error = 0;
409
410 end:
411 return error;
412 }
413
414 /*
415 * receive from responder
416 * psk: HDR, KE, Nr
417 * sig: HDR, KE, Nr [, CR ]
418 * gssapi: HDR, KE, Nr, GSSr
419 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
420 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
421 */
422 int
ident_i3recv(iph1,msg)423 ident_i3recv(iph1, msg)
424 struct ph1handle *iph1;
425 vchar_t *msg;
426 {
427 vchar_t *pbuf = NULL;
428 struct isakmp_parse_t *pa;
429 int error = -1;
430 #ifdef HAVE_GSSAPI
431 vchar_t *gsstoken = NULL;
432 #endif
433 #ifdef ENABLE_NATT
434 vchar_t *natd_received;
435 int natd_seq = 0, natd_verified;
436 #endif
437
438 /* validity check */
439 if (iph1->status != PHASE1ST_MSG2SENT) {
440 plog(LLV_ERROR, LOCATION, NULL,
441 "status mismatched %d.\n", iph1->status);
442 goto end;
443 }
444
445 /* validate the type of next payload */
446 pbuf = isakmp_parse(msg);
447 if (pbuf == NULL)
448 goto end;
449
450 for (pa = (struct isakmp_parse_t *)pbuf->v;
451 pa->type != ISAKMP_NPTYPE_NONE;
452 pa++) {
453
454 switch (pa->type) {
455 case ISAKMP_NPTYPE_KE:
456 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
457 goto end;
458 break;
459 case ISAKMP_NPTYPE_NONCE:
460 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
461 goto end;
462 break;
463 case ISAKMP_NPTYPE_VID:
464 handle_vendorid(iph1, pa->ptr);
465 break;
466 case ISAKMP_NPTYPE_CR:
467 if (oakley_savecr(iph1, pa->ptr) < 0)
468 goto end;
469 break;
470 #ifdef HAVE_GSSAPI
471 case ISAKMP_NPTYPE_GSS:
472 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
473 goto end;
474 gssapi_save_received_token(iph1, gsstoken);
475 break;
476 #endif
477
478 #ifdef ENABLE_NATT
479 case ISAKMP_NPTYPE_NATD_DRAFT:
480 case ISAKMP_NPTYPE_NATD_RFC:
481 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
482 pa->type == iph1->natt_options->payload_nat_d) {
483 natd_received = NULL;
484 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
485 goto end;
486
487 /* set both bits first so that we can clear them
488 upon verifying hashes */
489 if (natd_seq == 0)
490 iph1->natt_flags |= NAT_DETECTED;
491
492 /* this function will clear appropriate bits bits
493 from iph1->natt_flags */
494 natd_verified = natt_compare_addr_hash (iph1,
495 natd_received, natd_seq++);
496
497 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
498 natd_seq - 1,
499 natd_verified ? "verified" : "doesn't match");
500
501 vfree (natd_received);
502 break;
503 }
504 /* passthrough to default... */
505 #endif
506
507 default:
508 /* don't send information, see ident_r1recv() */
509 plog(LLV_ERROR, LOCATION, iph1->remote,
510 "ignore the packet, "
511 "received unexpecting payload type %d.\n",
512 pa->type);
513 goto end;
514 }
515 }
516
517 #ifdef ENABLE_NATT
518 if (NATT_AVAILABLE(iph1)) {
519 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
520 iph1->natt_flags & NAT_DETECTED ?
521 "detected:" : "not detected",
522 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
523 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
524 if (iph1->natt_flags & NAT_DETECTED)
525 natt_float_ports (iph1);
526 }
527 #endif
528
529 /* payload existency check */
530 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
531 plog(LLV_ERROR, LOCATION, iph1->remote,
532 "few isakmp message received.\n");
533 goto end;
534 }
535
536 if (oakley_checkcr(iph1) < 0) {
537 /* Ignore this error in order to be interoperability. */
538 ;
539 }
540
541 iph1->status = PHASE1ST_MSG3RECEIVED;
542
543 error = 0;
544
545 end:
546 #ifdef HAVE_GSSAPI
547 if (gsstoken)
548 vfree(gsstoken);
549 #endif
550 if (pbuf)
551 vfree(pbuf);
552 if (error) {
553 VPTRINIT(iph1->dhpub_p);
554 VPTRINIT(iph1->nonce_p);
555 VPTRINIT(iph1->id_p);
556 oakley_delcert(iph1->cr_p);
557 iph1->cr_p = NULL;
558 }
559
560 return error;
561 }
562
563 /*
564 * send to responder
565 * psk: HDR*, IDi1, HASH_I
566 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
567 * gssapi: HDR*, IDi1, < Gssi(n) | HASH_I >
568 * rsa: HDR*, HASH_I
569 * rev: HDR*, HASH_I
570 */
571 int
ident_i3send(iph1,msg0)572 ident_i3send(iph1, msg0)
573 struct ph1handle *iph1;
574 vchar_t *msg0;
575 {
576 int error = -1;
577 int dohash = 1;
578 #ifdef HAVE_GSSAPI
579 int len;
580 #endif
581
582 /* validity check */
583 if (iph1->status != PHASE1ST_MSG3RECEIVED) {
584 plog(LLV_ERROR, LOCATION, NULL,
585 "status mismatched %d.\n", iph1->status);
586 goto end;
587 }
588
589 /* compute sharing secret of DH */
590 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
591 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
592 goto end;
593
594 /* generate SKEYIDs & IV & final cipher key */
595 if (oakley_skeyid(iph1) < 0)
596 goto end;
597 if (oakley_skeyid_dae(iph1) < 0)
598 goto end;
599 if (oakley_compute_enckey(iph1) < 0)
600 goto end;
601 if (oakley_newiv(iph1) < 0)
602 goto end;
603
604 /* make ID payload into isakmp status */
605 if (ipsecdoi_setid1(iph1) < 0)
606 goto end;
607
608 #ifdef HAVE_GSSAPI
609 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
610 gssapi_more_tokens(iph1)) {
611 plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n");
612 if (gssapi_get_itoken(iph1, &len) < 0)
613 goto end;
614 if (len != 0)
615 dohash = 0;
616 }
617 #endif
618
619 /* generate HASH to send */
620 if (dohash) {
621 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
622 if (iph1->hash == NULL)
623 goto end;
624 } else
625 iph1->hash = NULL;
626
627 /* set encryption flag */
628 iph1->flags |= ISAKMP_FLAG_E;
629
630 /* create HDR;ID;HASH payload */
631 iph1->sendbuf = ident_ir3mx(iph1);
632 if (iph1->sendbuf == NULL)
633 goto end;
634
635 /* send the packet, add to the schedule to resend */
636 iph1->retry_counter = iph1->rmconf->retry_counter;
637 if (isakmp_ph1resend(iph1) == -1)
638 goto end;
639
640 /* the sending message is added to the received-list. */
641 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) {
642 plog(LLV_ERROR , LOCATION, NULL,
643 "failed to add a response packet to the tree.\n");
644 goto end;
645 }
646
647 /* see handler.h about IV synchronization. */
648 memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
649
650 iph1->status = PHASE1ST_MSG3SENT;
651
652 error = 0;
653
654 end:
655 return error;
656 }
657
658 /*
659 * receive from responder
660 * psk: HDR*, IDr1, HASH_R
661 * sig: HDR*, IDr1, [ CERT, ] SIG_R
662 * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
663 * rsa: HDR*, HASH_R
664 * rev: HDR*, HASH_R
665 */
666 int
ident_i4recv(iph1,msg0)667 ident_i4recv(iph1, msg0)
668 struct ph1handle *iph1;
669 vchar_t *msg0;
670 {
671 vchar_t *pbuf = NULL;
672 struct isakmp_parse_t *pa;
673 vchar_t *msg = NULL;
674 int error = -1;
675 int type;
676 #ifdef HAVE_GSSAPI
677 vchar_t *gsstoken = NULL;
678 #endif
679
680 /* validity check */
681 if (iph1->status != PHASE1ST_MSG3SENT) {
682 plog(LLV_ERROR, LOCATION, NULL,
683 "status mismatched %d.\n", iph1->status);
684 goto end;
685 }
686
687 /* decrypting */
688 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
689 plog(LLV_ERROR, LOCATION, iph1->remote,
690 "ignore the packet, "
691 "expecting the packet encrypted.\n");
692 goto end;
693 }
694 msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
695 if (msg == NULL)
696 goto end;
697
698 /* validate the type of next payload */
699 pbuf = isakmp_parse(msg);
700 if (pbuf == NULL)
701 goto end;
702
703 iph1->pl_hash = NULL;
704
705 for (pa = (struct isakmp_parse_t *)pbuf->v;
706 pa->type != ISAKMP_NPTYPE_NONE;
707 pa++) {
708
709 switch (pa->type) {
710 case ISAKMP_NPTYPE_ID:
711 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
712 goto end;
713 break;
714 case ISAKMP_NPTYPE_HASH:
715 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
716 break;
717 case ISAKMP_NPTYPE_CERT:
718 if (oakley_savecert(iph1, pa->ptr) < 0)
719 goto end;
720 break;
721 case ISAKMP_NPTYPE_SIG:
722 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
723 goto end;
724 break;
725 #ifdef HAVE_GSSAPI
726 case ISAKMP_NPTYPE_GSS:
727 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
728 goto end;
729 gssapi_save_received_token(iph1, gsstoken);
730 break;
731 #endif
732 case ISAKMP_NPTYPE_VID:
733 handle_vendorid(iph1, pa->ptr);
734 break;
735 case ISAKMP_NPTYPE_N:
736 isakmp_check_notify(pa->ptr, iph1);
737 break;
738 default:
739 /* don't send information, see ident_r1recv() */
740 plog(LLV_ERROR, LOCATION, iph1->remote,
741 "ignore the packet, "
742 "received unexpecting payload type %d.\n",
743 pa->type);
744 goto end;
745 }
746 }
747
748 /* payload existency check */
749
750 /* verify identifier */
751 if (ipsecdoi_checkid1(iph1) != 0) {
752 plog(LLV_ERROR, LOCATION, iph1->remote,
753 "invalid ID payload.\n");
754 goto end;
755 }
756
757 /* validate authentication value */
758 #ifdef HAVE_GSSAPI
759 if (gsstoken == NULL) {
760 #endif
761 type = oakley_validate_auth(iph1);
762 if (type != 0) {
763 if (type == -1) {
764 /* msg printed inner oakley_validate_auth() */
765 goto end;
766 }
767 EVT_PUSH(iph1->local, iph1->remote,
768 EVTT_PEERPH1AUTH_FAILED, NULL);
769 isakmp_info_send_n1(iph1, type, NULL);
770 goto end;
771 }
772 #ifdef HAVE_GSSAPI
773 }
774 #endif
775
776 /*
777 * XXX: Should we do compare two addresses, ph1handle's and ID
778 * payload's.
779 */
780
781 plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:");
782 plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
783
784 /* see handler.h about IV synchronization. */
785 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
786
787 /*
788 * If we got a GSS token, we need to this roundtrip again.
789 */
790 #ifdef HAVE_GSSAPI
791 iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED :
792 PHASE1ST_MSG4RECEIVED;
793 #else
794 iph1->status = PHASE1ST_MSG4RECEIVED;
795 #endif
796
797 error = 0;
798
799 end:
800 if (pbuf)
801 vfree(pbuf);
802 if (msg)
803 vfree(msg);
804 #ifdef HAVE_GSSAPI
805 if (gsstoken)
806 vfree(gsstoken);
807 #endif
808
809 if (error) {
810 VPTRINIT(iph1->id_p);
811 oakley_delcert(iph1->cert_p);
812 iph1->cert_p = NULL;
813 oakley_delcert(iph1->crl_p);
814 iph1->crl_p = NULL;
815 VPTRINIT(iph1->sig_p);
816 }
817
818 return error;
819 }
820
821 /*
822 * status update and establish isakmp sa.
823 */
824 int
ident_i4send(iph1,msg)825 ident_i4send(iph1, msg)
826 struct ph1handle *iph1;
827 vchar_t *msg;
828 {
829 int error = -1;
830
831 /* validity check */
832 if (iph1->status != PHASE1ST_MSG4RECEIVED) {
833 plog(LLV_ERROR, LOCATION, NULL,
834 "status mismatched %d.\n", iph1->status);
835 goto end;
836 }
837
838 /* see handler.h about IV synchronization. */
839 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
840
841 iph1->status = PHASE1ST_ESTABLISHED;
842
843 error = 0;
844
845 end:
846 return error;
847 }
848
849 /*
850 * receive from initiator
851 * psk: HDR, SA
852 * sig: HDR, SA
853 * rsa: HDR, SA
854 * rev: HDR, SA
855 */
856 int
ident_r1recv(iph1,msg)857 ident_r1recv(iph1, msg)
858 struct ph1handle *iph1;
859 vchar_t *msg;
860 {
861 vchar_t *pbuf = NULL;
862 struct isakmp_parse_t *pa;
863 int error = -1;
864 int vid_numeric;
865
866 /* validity check */
867 if (iph1->status != PHASE1ST_START) {
868 plog(LLV_ERROR, LOCATION, NULL,
869 "status mismatched %d.\n", iph1->status);
870 goto end;
871 }
872
873 /* validate the type of next payload */
874 /*
875 * NOTE: XXX even if multiple VID, we'll silently ignore those.
876 */
877 pbuf = isakmp_parse(msg);
878 if (pbuf == NULL)
879 goto end;
880 pa = (struct isakmp_parse_t *)pbuf->v;
881
882 /* check the position of SA payload */
883 if (pa->type != ISAKMP_NPTYPE_SA) {
884 plog(LLV_ERROR, LOCATION, iph1->remote,
885 "received invalid next payload type %d, "
886 "expecting %d.\n",
887 pa->type, ISAKMP_NPTYPE_SA);
888 goto end;
889 }
890 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
891 goto end;
892 pa++;
893
894 for (/*nothing*/;
895 pa->type != ISAKMP_NPTYPE_NONE;
896 pa++) {
897
898 switch (pa->type) {
899 case ISAKMP_NPTYPE_VID:
900 vid_numeric = handle_vendorid(iph1, pa->ptr);
901 #ifdef ENABLE_FRAG
902 if ((vid_numeric == VENDORID_FRAG) &&
903 (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT))
904 iph1->frag = 1;
905 #endif
906 break;
907 default:
908 /*
909 * We don't send information to the peer even
910 * if we received malformed packet. Because we
911 * can't distinguish the malformed packet and
912 * the re-sent packet. And we do same behavior
913 * when we expect encrypted packet.
914 */
915 plog(LLV_ERROR, LOCATION, iph1->remote,
916 "ignore the packet, "
917 "received unexpecting payload type %d.\n",
918 pa->type);
919 goto end;
920 }
921 }
922
923 #ifdef ENABLE_NATT
924 if (NATT_AVAILABLE(iph1))
925 plog(LLV_INFO, LOCATION, iph1->remote,
926 "Selected NAT-T version: %s\n",
927 vid_string_by_id(iph1->natt_options->version));
928 #endif
929
930 /* check SA payload and set approval SA for use */
931 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
932 plog(LLV_ERROR, LOCATION, iph1->remote,
933 "failed to get valid proposal.\n");
934 /* XXX send information */
935 goto end;
936 }
937
938 iph1->status = PHASE1ST_MSG1RECEIVED;
939
940 error = 0;
941
942 end:
943 if (pbuf)
944 vfree(pbuf);
945 if (error) {
946 VPTRINIT(iph1->sa);
947 }
948
949 return error;
950 }
951
952 /*
953 * send to initiator
954 * psk: HDR, SA
955 * sig: HDR, SA
956 * rsa: HDR, SA
957 * rev: HDR, SA
958 */
959 int
ident_r1send(iph1,msg)960 ident_r1send(iph1, msg)
961 struct ph1handle *iph1;
962 vchar_t *msg;
963 {
964 struct payload_list *plist = NULL;
965 int error = -1;
966 vchar_t *gss_sa = NULL;
967 #ifdef HAVE_GSSAPI
968 int free_gss_sa = 0;
969 #endif
970 #ifdef ENABLE_NATT
971 vchar_t *vid_natt = NULL;
972 #endif
973 #ifdef ENABLE_HYBRID
974 vchar_t *vid_xauth = NULL;
975 vchar_t *vid_unity = NULL;
976 #endif
977 #ifdef ENABLE_DPD
978 vchar_t *vid_dpd = NULL;
979 #endif
980 #ifdef ENABLE_FRAG
981 vchar_t *vid_frag = NULL;
982 #endif
983
984 /* validity check */
985 if (iph1->status != PHASE1ST_MSG1RECEIVED) {
986 plog(LLV_ERROR, LOCATION, NULL,
987 "status mismatched %d.\n", iph1->status);
988 goto end;
989 }
990
991 /* set responder's cookie */
992 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
993
994 #ifdef HAVE_GSSAPI
995 if (iph1->approval->gssid != NULL) {
996 gss_sa = ipsecdoi_setph1proposal(iph1->approval);
997 if (gss_sa != iph1->sa_ret)
998 free_gss_sa = 1;
999 } else
1000 #endif
1001 gss_sa = iph1->sa_ret;
1002
1003 /* set SA payload to reply */
1004 plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA);
1005
1006 #ifdef ENABLE_HYBRID
1007 if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
1008 plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
1009 if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) {
1010 plog(LLV_ERROR, LOCATION, NULL,
1011 "Cannot create Xauth vendor ID\n");
1012 goto end;
1013 }
1014 plist = isakmp_plist_append(plist,
1015 vid_xauth, ISAKMP_NPTYPE_VID);
1016 }
1017
1018 if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
1019 if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) {
1020 plog(LLV_ERROR, LOCATION, NULL,
1021 "Cannot create Unity vendor ID\n");
1022 goto end;
1023 }
1024 plist = isakmp_plist_append(plist,
1025 vid_unity, ISAKMP_NPTYPE_VID);
1026 }
1027 #endif
1028 #ifdef ENABLE_NATT
1029 /* Has the peer announced NAT-T? */
1030 if (NATT_AVAILABLE(iph1))
1031 vid_natt = set_vendorid(iph1->natt_options->version);
1032
1033 if (vid_natt)
1034 plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
1035 #endif
1036 #ifdef ENABLE_DPD
1037 /* XXX only send DPD VID if remote sent it ? */
1038 if(iph1->rmconf->dpd){
1039 vid_dpd = set_vendorid(VENDORID_DPD);
1040 if (vid_dpd != NULL)
1041 plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
1042 }
1043 #endif
1044 #ifdef ENABLE_FRAG
1045 if (iph1->frag) {
1046 vid_frag = set_vendorid(VENDORID_FRAG);
1047 if (vid_frag != NULL)
1048 vid_frag = isakmp_frag_addcap(vid_frag,
1049 VENDORID_FRAG_IDENT);
1050 if (vid_frag == NULL)
1051 plog(LLV_ERROR, LOCATION, NULL,
1052 "Frag vendorID construction failed\n");
1053 else
1054 plist = isakmp_plist_append(plist,
1055 vid_frag, ISAKMP_NPTYPE_VID);
1056 }
1057 #endif
1058
1059 iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1060
1061 #ifdef HAVE_PRINT_ISAKMP_C
1062 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1063 #endif
1064
1065 /* send the packet, add to the schedule to resend */
1066 iph1->retry_counter = iph1->rmconf->retry_counter;
1067 if (isakmp_ph1resend(iph1) == -1) {
1068 goto end;
1069 }
1070
1071 /* the sending message is added to the received-list. */
1072 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1073 plog(LLV_ERROR , LOCATION, NULL,
1074 "failed to add a response packet to the tree.\n");
1075 goto end;
1076 }
1077
1078 iph1->status = PHASE1ST_MSG1SENT;
1079
1080 error = 0;
1081
1082 end:
1083 #ifdef HAVE_GSSAPI
1084 if (free_gss_sa)
1085 vfree(gss_sa);
1086 #endif
1087 #ifdef ENABLE_NATT
1088 if (vid_natt)
1089 vfree(vid_natt);
1090 #endif
1091 #ifdef ENABLE_HYBRID
1092 if (vid_xauth != NULL)
1093 vfree(vid_xauth);
1094 if (vid_unity != NULL)
1095 vfree(vid_unity);
1096 #endif
1097 #ifdef ENABLE_DPD
1098 if (vid_dpd != NULL)
1099 vfree(vid_dpd);
1100 #endif
1101 #ifdef ENABLE_FRAG
1102 if (vid_frag != NULL)
1103 vfree(vid_frag);
1104 #endif
1105
1106 return error;
1107 }
1108
1109 /*
1110 * receive from initiator
1111 * psk: HDR, KE, Ni
1112 * sig: HDR, KE, Ni
1113 * gssapi: HDR, KE, Ni, GSSi
1114 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
1115 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
1116 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
1117 */
1118 int
ident_r2recv(iph1,msg)1119 ident_r2recv(iph1, msg)
1120 struct ph1handle *iph1;
1121 vchar_t *msg;
1122 {
1123 vchar_t *pbuf = NULL;
1124 struct isakmp_parse_t *pa;
1125 int error = -1;
1126 #ifdef HAVE_GSSAPI
1127 vchar_t *gsstoken = NULL;
1128 #endif
1129 #ifdef ENABLE_NATT
1130 int natd_seq = 0;
1131 #endif
1132
1133 /* validity check */
1134 if (iph1->status != PHASE1ST_MSG1SENT) {
1135 plog(LLV_ERROR, LOCATION, NULL,
1136 "status mismatched %d.\n", iph1->status);
1137 goto end;
1138 }
1139
1140 /* validate the type of next payload */
1141 pbuf = isakmp_parse(msg);
1142 if (pbuf == NULL)
1143 goto end;
1144
1145 for (pa = (struct isakmp_parse_t *)pbuf->v;
1146 pa->type != ISAKMP_NPTYPE_NONE;
1147 pa++) {
1148 switch (pa->type) {
1149 case ISAKMP_NPTYPE_KE:
1150 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
1151 goto end;
1152 break;
1153 case ISAKMP_NPTYPE_NONCE:
1154 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
1155 goto end;
1156 break;
1157 case ISAKMP_NPTYPE_VID:
1158 handle_vendorid(iph1, pa->ptr);
1159 break;
1160 case ISAKMP_NPTYPE_CR:
1161 plog(LLV_WARNING, LOCATION, iph1->remote,
1162 "CR received, ignore it. "
1163 "It should be in other exchange.\n");
1164 break;
1165 #ifdef HAVE_GSSAPI
1166 case ISAKMP_NPTYPE_GSS:
1167 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
1168 goto end;
1169 gssapi_save_received_token(iph1, gsstoken);
1170 break;
1171 #endif
1172
1173 #ifdef ENABLE_NATT
1174 case ISAKMP_NPTYPE_NATD_DRAFT:
1175 case ISAKMP_NPTYPE_NATD_RFC:
1176 if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
1177 pa->type == iph1->natt_options->payload_nat_d)
1178 {
1179 vchar_t *natd_received = NULL;
1180 int natd_verified;
1181
1182 if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
1183 goto end;
1184
1185 if (natd_seq == 0)
1186 iph1->natt_flags |= NAT_DETECTED;
1187
1188 natd_verified = natt_compare_addr_hash (iph1,
1189 natd_received, natd_seq++);
1190
1191 plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
1192 natd_seq - 1,
1193 natd_verified ? "verified" : "doesn't match");
1194
1195 vfree (natd_received);
1196 break;
1197 }
1198 /* passthrough to default... */
1199 #endif
1200
1201 default:
1202 /* don't send information, see ident_r1recv() */
1203 plog(LLV_ERROR, LOCATION, iph1->remote,
1204 "ignore the packet, "
1205 "received unexpecting payload type %d.\n",
1206 pa->type);
1207 goto end;
1208 }
1209 }
1210
1211 #ifdef ENABLE_NATT
1212 if (NATT_AVAILABLE(iph1))
1213 plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1214 iph1->natt_flags & NAT_DETECTED ?
1215 "detected:" : "not detected",
1216 iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1217 iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1218 #endif
1219
1220 /* payload existency check */
1221 if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
1222 plog(LLV_ERROR, LOCATION, iph1->remote,
1223 "few isakmp message received.\n");
1224 goto end;
1225 }
1226
1227 iph1->status = PHASE1ST_MSG2RECEIVED;
1228
1229 error = 0;
1230
1231 end:
1232 if (pbuf)
1233 vfree(pbuf);
1234 #ifdef HAVE_GSSAPI
1235 if (gsstoken)
1236 vfree(gsstoken);
1237 #endif
1238
1239 if (error) {
1240 VPTRINIT(iph1->dhpub_p);
1241 VPTRINIT(iph1->nonce_p);
1242 VPTRINIT(iph1->id_p);
1243 }
1244
1245 return error;
1246 }
1247
1248 /*
1249 * send to initiator
1250 * psk: HDR, KE, Nr
1251 * sig: HDR, KE, Nr [, CR ]
1252 * gssapi: HDR, KE, Nr, GSSr
1253 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
1254 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
1255 */
1256 int
ident_r2send(iph1,msg)1257 ident_r2send(iph1, msg)
1258 struct ph1handle *iph1;
1259 vchar_t *msg;
1260 {
1261 int error = -1;
1262
1263 /* validity check */
1264 if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1265 plog(LLV_ERROR, LOCATION, NULL,
1266 "status mismatched %d.\n", iph1->status);
1267 goto end;
1268 }
1269
1270 /* generate DH public value */
1271 if (oakley_dh_generate(iph1->approval->dhgrp,
1272 &iph1->dhpub, &iph1->dhpriv) < 0)
1273 goto end;
1274
1275 /* generate NONCE value */
1276 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
1277 if (iph1->nonce == NULL)
1278 goto end;
1279
1280 #ifdef HAVE_GSSAPI
1281 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1282 gssapi_get_rtoken(iph1, NULL);
1283 #endif
1284
1285 /* create HDR;KE;NONCE payload */
1286 iph1->sendbuf = ident_ir2mx(iph1);
1287 if (iph1->sendbuf == NULL)
1288 goto end;
1289
1290 #ifdef HAVE_PRINT_ISAKMP_C
1291 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1292 #endif
1293
1294 /* send the packet, add to the schedule to resend */
1295 iph1->retry_counter = iph1->rmconf->retry_counter;
1296 if (isakmp_ph1resend(iph1) == -1)
1297 goto end;
1298
1299 /* the sending message is added to the received-list. */
1300 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1301 plog(LLV_ERROR , LOCATION, NULL,
1302 "failed to add a response packet to the tree.\n");
1303 goto end;
1304 }
1305
1306 /* compute sharing secret of DH */
1307 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
1308 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
1309 goto end;
1310
1311 /* generate SKEYIDs & IV & final cipher key */
1312 if (oakley_skeyid(iph1) < 0)
1313 goto end;
1314 if (oakley_skeyid_dae(iph1) < 0)
1315 goto end;
1316 if (oakley_compute_enckey(iph1) < 0)
1317 goto end;
1318 if (oakley_newiv(iph1) < 0)
1319 goto end;
1320
1321 iph1->status = PHASE1ST_MSG2SENT;
1322
1323 error = 0;
1324
1325 end:
1326 return error;
1327 }
1328
1329 /*
1330 * receive from initiator
1331 * psk: HDR*, IDi1, HASH_I
1332 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
1333 * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
1334 * rsa: HDR*, HASH_I
1335 * rev: HDR*, HASH_I
1336 */
1337 int
ident_r3recv(iph1,msg0)1338 ident_r3recv(iph1, msg0)
1339 struct ph1handle *iph1;
1340 vchar_t *msg0;
1341 {
1342 vchar_t *msg = NULL;
1343 vchar_t *pbuf = NULL;
1344 struct isakmp_parse_t *pa;
1345 int error = -1;
1346 int type;
1347 #ifdef HAVE_GSSAPI
1348 vchar_t *gsstoken = NULL;
1349 #endif
1350
1351 /* validity check */
1352 if (iph1->status != PHASE1ST_MSG2SENT) {
1353 plog(LLV_ERROR, LOCATION, NULL,
1354 "status mismatched %d.\n", iph1->status);
1355 goto end;
1356 }
1357
1358 /* decrypting */
1359 if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1360 plog(LLV_ERROR, LOCATION, iph1->remote,
1361 "reject the packet, "
1362 "expecting the packet encrypted.\n");
1363 goto end;
1364 }
1365 msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
1366 if (msg == NULL)
1367 goto end;
1368
1369 /* validate the type of next payload */
1370 pbuf = isakmp_parse(msg);
1371 if (pbuf == NULL)
1372 goto end;
1373
1374 iph1->pl_hash = NULL;
1375
1376 for (pa = (struct isakmp_parse_t *)pbuf->v;
1377 pa->type != ISAKMP_NPTYPE_NONE;
1378 pa++) {
1379
1380 switch (pa->type) {
1381 case ISAKMP_NPTYPE_ID:
1382 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
1383 goto end;
1384 break;
1385 case ISAKMP_NPTYPE_HASH:
1386 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1387 break;
1388 case ISAKMP_NPTYPE_CR:
1389 if (oakley_savecr(iph1, pa->ptr) < 0)
1390 goto end;
1391 break;
1392 case ISAKMP_NPTYPE_CERT:
1393 if (oakley_savecert(iph1, pa->ptr) < 0)
1394 goto end;
1395 break;
1396 case ISAKMP_NPTYPE_SIG:
1397 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1398 goto end;
1399 break;
1400 #ifdef HAVE_GSSAPI
1401 case ISAKMP_NPTYPE_GSS:
1402 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
1403 goto end;
1404 gssapi_save_received_token(iph1, gsstoken);
1405 break;
1406 #endif
1407 case ISAKMP_NPTYPE_VID:
1408 handle_vendorid(iph1, pa->ptr);
1409 break;
1410 case ISAKMP_NPTYPE_N:
1411 isakmp_check_notify(pa->ptr, iph1);
1412 break;
1413 default:
1414 /* don't send information, see ident_r1recv() */
1415 plog(LLV_ERROR, LOCATION, iph1->remote,
1416 "ignore the packet, "
1417 "received unexpecting payload type %d.\n",
1418 pa->type);
1419 goto end;
1420 }
1421 }
1422
1423 /* payload existency check */
1424 /* XXX same as ident_i4recv(), should be merged. */
1425 {
1426 int ng = 0;
1427
1428 switch (AUTHMETHOD(iph1)) {
1429 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1430 #ifdef ENABLE_HYBRID
1431 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1432 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1433 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1434 #endif
1435 if (iph1->id_p == NULL || iph1->pl_hash == NULL)
1436 ng++;
1437 break;
1438 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1439 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1440 #ifdef ENABLE_HYBRID
1441 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1442 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1443 #endif
1444 if (iph1->id_p == NULL || iph1->sig_p == NULL)
1445 ng++;
1446 break;
1447 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1448 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1449 #ifdef ENABLE_HYBRID
1450 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1451 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1452 #endif
1453 if (iph1->pl_hash == NULL)
1454 ng++;
1455 break;
1456 #ifdef HAVE_GSSAPI
1457 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1458 if (gsstoken == NULL && iph1->pl_hash == NULL)
1459 ng++;
1460 break;
1461 #endif
1462 default:
1463 plog(LLV_ERROR, LOCATION, iph1->remote,
1464 "invalid authmethod %d why ?\n",
1465 iph1->approval->authmethod);
1466 goto end;
1467 }
1468 if (ng) {
1469 plog(LLV_ERROR, LOCATION, iph1->remote,
1470 "few isakmp message received.\n");
1471 goto end;
1472 }
1473 }
1474
1475 /* verify identifier */
1476 if (ipsecdoi_checkid1(iph1) != 0) {
1477 plog(LLV_ERROR, LOCATION, iph1->remote,
1478 "invalid ID payload.\n");
1479 goto end;
1480 }
1481
1482 /* validate authentication value */
1483 #ifdef HAVE_GSSAPI
1484 if (gsstoken == NULL) {
1485 #endif
1486 type = oakley_validate_auth(iph1);
1487 if (type != 0) {
1488 if (type == -1) {
1489 /* msg printed inner oakley_validate_auth() */
1490 goto end;
1491 }
1492 EVT_PUSH(iph1->local, iph1->remote,
1493 EVTT_PEERPH1AUTH_FAILED, NULL);
1494 isakmp_info_send_n1(iph1, type, NULL);
1495 goto end;
1496 }
1497 #ifdef HAVE_GSSAPI
1498 }
1499 #endif
1500
1501 if (oakley_checkcr(iph1) < 0) {
1502 /* Ignore this error in order to be interoperability. */
1503 ;
1504 }
1505
1506 /*
1507 * XXX: Should we do compare two addresses, ph1handle's and ID
1508 * payload's.
1509 */
1510
1511 plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n");
1512 plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
1513
1514 /* see handler.h about IV synchronization. */
1515 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
1516
1517 #ifdef HAVE_GSSAPI
1518 iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED :
1519 PHASE1ST_MSG3RECEIVED;
1520 #else
1521 iph1->status = PHASE1ST_MSG3RECEIVED;
1522 #endif
1523
1524 error = 0;
1525
1526 end:
1527 if (pbuf)
1528 vfree(pbuf);
1529 if (msg)
1530 vfree(msg);
1531 #ifdef HAVE_GSSAPI
1532 if (gsstoken)
1533 vfree(gsstoken);
1534 #endif
1535
1536 if (error) {
1537 VPTRINIT(iph1->id_p);
1538 oakley_delcert(iph1->cert_p);
1539 iph1->cert_p = NULL;
1540 oakley_delcert(iph1->crl_p);
1541 iph1->crl_p = NULL;
1542 VPTRINIT(iph1->sig_p);
1543 oakley_delcert(iph1->cr_p);
1544 iph1->cr_p = NULL;
1545 }
1546
1547 return error;
1548 }
1549
1550 /*
1551 * send to initiator
1552 * psk: HDR*, IDr1, HASH_R
1553 * sig: HDR*, IDr1, [ CERT, ] SIG_R
1554 * gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
1555 * rsa: HDR*, HASH_R
1556 * rev: HDR*, HASH_R
1557 */
1558 int
ident_r3send(iph1,msg)1559 ident_r3send(iph1, msg)
1560 struct ph1handle *iph1;
1561 vchar_t *msg;
1562 {
1563 int error = -1;
1564 int dohash = 1;
1565 #ifdef HAVE_GSSAPI
1566 int len;
1567 #endif
1568
1569 /* validity check */
1570 if (iph1->status != PHASE1ST_MSG3RECEIVED) {
1571 plog(LLV_ERROR, LOCATION, NULL,
1572 "status mismatched %d.\n", iph1->status);
1573 goto end;
1574 }
1575
1576 /* make ID payload into isakmp status */
1577 if (ipsecdoi_setid1(iph1) < 0)
1578 goto end;
1579
1580 #ifdef HAVE_GSSAPI
1581 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
1582 gssapi_more_tokens(iph1)) {
1583 gssapi_get_rtoken(iph1, &len);
1584 if (len != 0)
1585 dohash = 0;
1586 }
1587 #endif
1588
1589 if (dohash) {
1590 /* generate HASH to send */
1591 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
1592 iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1593 if (iph1->hash == NULL)
1594 goto end;
1595 } else
1596 iph1->hash = NULL;
1597
1598 /* set encryption flag */
1599 iph1->flags |= ISAKMP_FLAG_E;
1600
1601 /* create HDR;ID;HASH payload */
1602 iph1->sendbuf = ident_ir3mx(iph1);
1603 if (iph1->sendbuf == NULL)
1604 goto end;
1605
1606 /* send HDR;ID;HASH to responder */
1607 if (isakmp_send(iph1, iph1->sendbuf) < 0)
1608 goto end;
1609
1610 /* the sending message is added to the received-list. */
1611 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1612 plog(LLV_ERROR , LOCATION, NULL,
1613 "failed to add a response packet to the tree.\n");
1614 goto end;
1615 }
1616
1617 /* see handler.h about IV synchronization. */
1618 memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
1619
1620 iph1->status = PHASE1ST_ESTABLISHED;
1621
1622 error = 0;
1623
1624 end:
1625
1626 return error;
1627 }
1628
1629 /*
1630 * This is used in main mode for:
1631 * initiator's 3rd exchange send to responder
1632 * psk: HDR, KE, Ni
1633 * sig: HDR, KE, Ni
1634 * rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
1635 * rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
1636 * <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
1637 * responders 2nd exchnage send to initiator
1638 * psk: HDR, KE, Nr
1639 * sig: HDR, KE, Nr [, CR ]
1640 * rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
1641 * rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
1642 */
1643 static vchar_t *
ident_ir2mx(iph1)1644 ident_ir2mx(iph1)
1645 struct ph1handle *iph1;
1646 {
1647 vchar_t *buf = 0;
1648 struct payload_list *plist = NULL;
1649 int need_cr = 0;
1650 vchar_t *cr = NULL;
1651 vchar_t *vid = NULL;
1652 int error = -1;
1653 #ifdef HAVE_GSSAPI
1654 vchar_t *gsstoken = NULL;
1655 #endif
1656 #ifdef ENABLE_NATT
1657 vchar_t *natd[2] = { NULL, NULL };
1658 #endif
1659
1660 /* create CR if need */
1661 if (iph1->side == RESPONDER
1662 && iph1->rmconf->send_cr
1663 && oakley_needcr(iph1->approval->authmethod)
1664 && iph1->rmconf->peerscertfile == NULL) {
1665 need_cr = 1;
1666 cr = oakley_getcr(iph1);
1667 if (cr == NULL) {
1668 plog(LLV_ERROR, LOCATION, NULL,
1669 "failed to get cr buffer.\n");
1670 goto end;
1671 }
1672 }
1673
1674 #ifdef HAVE_GSSAPI
1675 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1676 gssapi_get_token_to_send(iph1, &gsstoken);
1677 #endif
1678
1679 /* create isakmp KE payload */
1680 plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1681
1682 /* create isakmp NONCE payload */
1683 plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
1684
1685 #ifdef HAVE_GSSAPI
1686 if (AUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1687 plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
1688 #endif
1689
1690 /* append vendor id, if needed */
1691 if (vid)
1692 plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
1693
1694 /* create isakmp CR payload if needed */
1695 if (need_cr)
1696 plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
1697
1698 #ifdef ENABLE_NATT
1699 /* generate and append NAT-D payloads */
1700 if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED)
1701 {
1702 if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1703 plog(LLV_ERROR, LOCATION, NULL,
1704 "NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1705 goto end;
1706 }
1707
1708 if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1709 plog(LLV_ERROR, LOCATION, NULL,
1710 "NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1711 goto end;
1712 }
1713
1714 plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1715 plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1716 plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1717 }
1718 #endif
1719
1720 buf = isakmp_plist_set_all (&plist, iph1);
1721
1722 error = 0;
1723
1724 end:
1725 if (error && buf != NULL) {
1726 vfree(buf);
1727 buf = NULL;
1728 }
1729 if (cr)
1730 vfree(cr);
1731 #ifdef HAVE_GSSAPI
1732 if (gsstoken)
1733 vfree(gsstoken);
1734 #endif
1735 if (vid)
1736 vfree(vid);
1737
1738 #ifdef ENABLE_NATT
1739 if (natd[0])
1740 vfree(natd[0]);
1741 if (natd[1])
1742 vfree(natd[1]);
1743 #endif
1744
1745 return buf;
1746 }
1747
1748 /*
1749 * This is used in main mode for:
1750 * initiator's 4th exchange send to responder
1751 * psk: HDR*, IDi1, HASH_I
1752 * sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
1753 * gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
1754 * rsa: HDR*, HASH_I
1755 * rev: HDR*, HASH_I
1756 * responders 3rd exchnage send to initiator
1757 * psk: HDR*, IDr1, HASH_R
1758 * sig: HDR*, IDr1, [ CERT, ] SIG_R
1759 * gssapi: HDR*, [ IDr1, ] < GSSr(n) | HASH_R >
1760 * rsa: HDR*, HASH_R
1761 * rev: HDR*, HASH_R
1762 */
1763 static vchar_t *
ident_ir3mx(iph1)1764 ident_ir3mx(iph1)
1765 struct ph1handle *iph1;
1766 {
1767 struct payload_list *plist = NULL;
1768 vchar_t *buf = NULL, *new = NULL;
1769 int need_cr = 0;
1770 int need_cert = 0;
1771 vchar_t *cr = NULL;
1772 int error = -1;
1773 #ifdef HAVE_GSSAPI
1774 int nptype;
1775 vchar_t *gsstoken = NULL;
1776 vchar_t *gsshash = NULL;
1777 #endif
1778
1779 switch (AUTHMETHOD(iph1)) {
1780 case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1781 #ifdef ENABLE_HYBRID
1782 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1783 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1784 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1785 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1786 #endif
1787 /* create isakmp ID payload */
1788 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1789
1790 /* create isakmp HASH payload */
1791 plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
1792 break;
1793 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1794 case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1795 #ifdef ENABLE_HYBRID
1796 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1797 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1798 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1799 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1800 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1801 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1802 #endif
1803 if (oakley_getmycert(iph1) < 0)
1804 goto end;
1805
1806 if (oakley_getsign(iph1) < 0)
1807 goto end;
1808
1809 /* create CR if need */
1810 if (iph1->side == INITIATOR
1811 && iph1->rmconf->send_cr
1812 && oakley_needcr(iph1->approval->authmethod)
1813 && iph1->rmconf->peerscertfile == NULL) {
1814 need_cr = 1;
1815 cr = oakley_getcr(iph1);
1816 if (cr == NULL) {
1817 plog(LLV_ERROR, LOCATION, NULL,
1818 "failed to get cr buffer.\n");
1819 goto end;
1820 }
1821 }
1822
1823 if (iph1->cert != NULL && iph1->rmconf->send_cert)
1824 need_cert = 1;
1825
1826 /* add ID payload */
1827 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1828
1829 /* add CERT payload if there */
1830 if (need_cert)
1831 plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
1832 /* add SIG payload */
1833 plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
1834
1835 /* create isakmp CR payload */
1836 if (need_cr)
1837 plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
1838 break;
1839 #ifdef HAVE_GSSAPI
1840 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1841 if (iph1->hash != NULL) {
1842 gsshash = gssapi_wraphash(iph1);
1843 if (gsshash == NULL)
1844 goto end;
1845 } else {
1846 gssapi_get_token_to_send(iph1, &gsstoken);
1847 }
1848
1849 if (!gssapi_id_sent(iph1)) {
1850 /* create isakmp ID payload */
1851 plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
1852 gssapi_set_id_sent(iph1);
1853 }
1854
1855 if (iph1->hash != NULL)
1856 /* create isakmp HASH payload */
1857 plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH);
1858 else
1859 plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
1860 break;
1861 #endif
1862 case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1863 case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1864 #ifdef ENABLE_HYBRID
1865 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1866 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1867 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1868 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1869 #endif
1870 plog(LLV_ERROR, LOCATION, NULL,
1871 "not supported authentication type %d\n",
1872 iph1->approval->authmethod);
1873 goto end;
1874 default:
1875 plog(LLV_ERROR, LOCATION, NULL,
1876 "invalid authentication type %d\n",
1877 iph1->approval->authmethod);
1878 goto end;
1879 }
1880
1881 buf = isakmp_plist_set_all (&plist, iph1);
1882
1883 #ifdef HAVE_PRINT_ISAKMP_C
1884 isakmp_printpacket(buf, iph1->local, iph1->remote, 1);
1885 #endif
1886
1887 /* encoding */
1888 new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv);
1889 if (new == NULL)
1890 goto end;
1891
1892 vfree(buf);
1893
1894 buf = new;
1895
1896 error = 0;
1897
1898 end:
1899 #ifdef HAVE_GSSAPI
1900 if (gsstoken)
1901 vfree(gsstoken);
1902 #endif
1903 if (cr)
1904 vfree(cr);
1905 if (error && buf != NULL) {
1906 vfree(buf);
1907 buf = NULL;
1908 }
1909
1910 return buf;
1911 }
1912