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

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

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