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

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

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