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