source: rtems-libbsd/ipsec-tools/src/racoon/isakmp_agg.c @ ff36f5e

55-freebsd-126-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on 05/30/18 at 12:27:35

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

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