Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_ident.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>