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

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

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