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

6-freebsd-12
Last change on this file was b376ae1, checked in by Christian Mauderer <christian.mauderer@…>, on 05/03/18 at 12:15:11

ipsec-tools: Port libipsec, setkey and racoon.

Note that this replaces the libipsec from FreeBSD with the one provided
by ipsec-tools.

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