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